Skip to content

Commit

Permalink
Update plot to seaborn, add QAOA example
Browse files Browse the repository at this point in the history
  • Loading branch information
Cryoris committed Jan 30, 2021
1 parent e83c866 commit d41dc23
Show file tree
Hide file tree
Showing 13 changed files with 121 additions and 22 deletions.
23 changes: 13 additions & 10 deletions benchmarks/benchmark.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,13 @@ def run_benchmark(self, library_circuit, target_parameters='all', filename=None)
args = self.nreps * [(ansatz, operator, state_in, free_parameters,
parameter_binds)]

# all_results = []
# for i, arg in enumerate(args):
# all_results.append(single_run(arg))
with Pool(processes=NUM_PROCESSES) as pool:
all_results = pool.map(single_run, args)
if NUM_PROCESSES == 1:
all_results = []
for i, arg in enumerate(args):
all_results.append(single_run(arg))
else:
with Pool(processes=NUM_PROCESSES) as pool:
all_results = pool.map(single_run, args)

# extract the results
grad_runtimes, itgrad_runtimes = [], []
Expand Down Expand Up @@ -129,11 +131,12 @@ def plot(self, filename=None, saveas=None, show=False, cutoffs=None):
else:
data = self.load_benchmark(filename)

colors = ['tab:blue', 'tab:orange']
plt.style.use('seaborn')
colors = ['tab:blue', 'tab:green']
markers = ['o', '^']
linestyles = ['--', ':']
methods = ['grad', 'itgrad']
labels = ['reference', 'reverse mode']
labels = ['standard', 'reverse mode']
if cutoffs is None:
cutoffs = [0, 0]

Expand Down Expand Up @@ -166,16 +169,16 @@ def plot(self, filename=None, saveas=None, show=False, cutoffs=None):

handles, labels = plt.gca().get_legend_handles_labels()
order = [2, 3, 0, 1]
plt.legend([handles[idx] for idx in order], [labels[idx] for idx in order], loc='best',
ncol=2)
plt.legend([handles[idx] for idx in order], [labels[idx] for idx in order],
loc='upper left', ncol=2)
# plt.legend(loc='best', ncol=2)
plt.xticks([50, 100, 500], [r'$0.5 \cdot 10^2$',
r'$10^2$', r'$0.5 \cdot 10^3$'])
if saveas is None:
saveas = f'ep_r{self.num_reps[0]}_{self.num_reps[-1]}.pdf'

plt.grid()
plt.savefig('img/' + saveas, bbox_inches='tight')
plt.ylim(top=1e4)
if show:
plt.show()

Expand Down
2 changes: 1 addition & 1 deletion benchmarks/featuremap.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,6 @@ def _build(self):
def run_featuremap():
circuit = Classification(4)

benchmark = Benchmark(2 ** np.arange(2, 5), H, 10)
benchmark = Benchmark(2 ** np.arange(2, 8), H, 24)
benchmark.run_benchmark(circuit, 'free')
benchmark.plot(show=True)
66 changes: 66 additions & 0 deletions benchmarks/maxcut.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
"""Maxcut example."""

import numpy as np
from qiskit.algorithms.minimum_eigen_solvers.qaoa.var_form import QAOAVarForm
from qiskit.circuit import QuantumCircuit, ParameterVector
from qiskit.circuit.parametertable import ParameterTable
from qiskit.opflow import Z, I, H

from .benchmark import Benchmark

class QAOAAnsatz(QuantumCircuit):
"""QAOA ansatz as a quantum circuit."""

def __init__(self, operator, reps=1):
self._reps = reps
self._operator = operator
super().__init__(operator.num_qubits)
self._build()

@property
def reps(self):
"""Get the number of repetitions of the circuit."""
return self._reps

@reps.setter
def reps(self, value):
"""Set the number of repetitions. Rebuilds the circuit."""
self._reps = value
self._build() # rebuild

def assign_parameters(self, params, inplace=False):
"""Assign parameters."""
if isinstance(params, (list, np.ndarray)):
params = dict(zip(self._params[:], params))

return super().assign_parameters(params, inplace=inplace)

@property
def ordered_parameters(self):
return self._params[:]

def _build(self):
# wipe current state
self._data = []
self._parameter_table = ParameterTable()

# get QAOA circuit
qaoa = QAOAVarForm(self._operator, self._reps)
params = ParameterVector('th', qaoa.num_parameters)
circuit = qaoa.construct_circuit(params)

# store the parameters in a list for assigning them
self._params = params


# combine the circuit
self.compose(circuit, inplace=True)


def run_maxcut():
operator = (I ^ I ^ Z ^ Z) + (I ^ Z ^ I ^ Z) + (Z ^ I ^ I ^ Z) + (I ^ Z ^ Z ^ I)
circuit = QAOAAnsatz(operator)

benchmark = Benchmark(2 ** np.arange(2, 8), H, 24)
benchmark.run_benchmark(circuit, 'free')
benchmark.plot(show=True)
Binary file removed data/good/efficient_su2_q3_r4_128_a50.npy
Binary file not shown.
Binary file removed data/good/efficient_su2_q5_r8_128_a24.npy
Binary file not shown.
3 changes: 1 addition & 2 deletions gradients/circuit_gradients.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,7 @@ def _accumulate_product_rule(self, gradients):
# pylint: disable=inconsistent-return-statements
def _bind(circuits, parameter_binds, inplace=False):
if not isinstance(circuits, list):
existing_parameter_binds = {
p: parameter_binds[p] for p in circuits.parameters}
existing_parameter_binds = {p: parameter_binds[p] for p in circuits.parameters}
return circuits.assign_parameters(existing_parameter_binds, inplace=inplace)

bound = []
Expand Down
16 changes: 12 additions & 4 deletions gradients/split_circuit.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from qiskit.circuit import QuantumCircuit, ParameterExpression
from qiskit.circuit import QuantumCircuit, ParameterExpression, Parameter


def split(circuit, parameters='all',
Expand All @@ -24,10 +24,18 @@ def split(circuit, parameters='all',
params = op[0].params
elif parameters == 'free':
params = [param for param in op[0].params if isinstance(param, ParameterExpression)]
elif isinstance(parameters, ParameterExpression):
params = [parameters] if parameters in op[0].params else []
elif isinstance(parameters, Parameter):
if op[0].definition is not None:
free_op_params = op[0].definition.parameters
else:
free_op_params = {}
params = [parameters] if parameters in free_op_params else []
elif isinstance(parameters, list):
params = [p for p in parameters if p in op[0].params]
if op[0].definition is not None:
free_op_params = op[0].definition.parameters
else:
free_op_params = {}
params = [p for p in parameters if p in free_op_params]
else:
raise NotImplementedError('Unsupported type of parameters:', parameters)

Expand Down
Binary file added img/efficient_su2.pdf
Binary file not shown.
Binary file removed img/good/efficient_su2_q3_r4_128_a50.pdf
Binary file not shown.
Binary file removed img/good/efficient_su2_q5_r8_128_a24.pdf
Binary file not shown.
Binary file added img/qaoa.pdf
Binary file not shown.
Binary file added img/vqc.pdf
Binary file not shown.
33 changes: 28 additions & 5 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,38 @@
"""Script to run the benchmarks."""

# pylint: disable=invalid-name

import sys
from benchmarks.benchmark import Benchmark
from benchmarks.efficient_su2 import run_efficientsu2
from benchmarks.featuremap import run_featuremap
from benchmarks.maxcut import run_maxcut

if len(sys.argv) < 2:
print('Please specify a benchmark to run. Available: efficientsu2 featuremap maxcut')
sys.exit()

task = sys.argv[1]

if task == 'plot':
if len(sys.argv) < 3:
print('To plot please specify the filename as second argument.')
sys.exit()
fname = sys.argv[2]

if len(sys.argv) != 2:
print('Please specify a benchmark to run. Available: efficientsu2 uccsd')
if len(sys.argv) > 3:
saveas = sys.argv[3]
else:
saveas = None

if sys.argv[1] == 'efficientsu2':
if task == 'efficientsu2':
run_efficientsu2()
elif sys.argv[1] == 'featuremap':
elif task == 'featuremap':
run_featuremap()
elif task == 'maxcut':
run_maxcut()
elif task == 'plot':
benchmark = Benchmark([0], None, None)
benchmark.plot(fname, saveas=saveas, show=True)
else:
raise ValueError(f'Invalid benchmark name: {sys.argv[1]}')
raise ValueError(f'Invalid argument: {task}')

0 comments on commit d41dc23

Please sign in to comment.