Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow ParameterExpression values in TemplateOptimization pass #6899

Merged
merged 142 commits into from
Mar 28, 2022
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
142 commits
Select commit Hold shift + click to select a range
32ee4db
added new equivalence rzx_zz4
nbronn Apr 19, 2021
8cfc6d9
added another zz-ish template (looks for basis gates)
nbronn Apr 27, 2021
c063402
Merge branch 'master' of github.com:Qiskit/qiskit-terra into template…
nbronn Apr 27, 2021
1d290a4
put the rzx_templates in
nbronn Jun 24, 2021
ad85838
looking at adding additions to rzx templates
nbronn Jul 1, 2021
7098e4f
fixes parsing of Parameter name for sympy during template optimization
nbronn Jul 2, 2021
3e23380
Merge branch 'main' of github.com:nbronn/qiskit-terra into template-p…
nbronn Jul 2, 2021
6e18a54
Merge branch 'main' into template-param-expression
nbronn Jul 2, 2021
c7605d7
generalized fix for multiple parameters in an expression and constant…
nbronn Jul 6, 2021
ed74ccf
one more minor fix to bring inline with qiskit-terra main
nbronn Jul 6, 2021
e308b84
trying to fix parameter parsing for template optimization
nbronn Jul 8, 2021
8fc1fa6
made sure floats were added correctly to (template) parameters
nbronn Jul 9, 2021
78d3339
got template matching to work with floats, sympy still not understand…
nbronn Jul 9, 2021
cc1a55a
Merge branch 'main' of github.com:Qiskit/qiskit-terra into template-p…
nbronn Jul 9, 2021
732e887
further modifications to accept circuit parameters for template optim…
nbronn Jul 12, 2021
0c63ca2
debugging the binding of template parameters
nbronn Jul 21, 2021
6a18dd1
realized I was not treating ParameterExpressions carefully and should…
nbronn Jul 22, 2021
133171c
converted all bindings to ParameterExpressions (via .assign()), set t…
nbronn Jul 25, 2021
caee274
cleaned up _attempt_bind routine
nbronn Jul 26, 2021
bd67056
exploring overriding removing the matched scenarios with parameters
nbronn Jul 28, 2021
38e8bde
introduced a total hack for dealing with ParamterExpressions that con…
nbronn Jul 30, 2021
a99726a
(non-latex) parameters now currently working in template optimization…
nbronn Aug 10, 2021
59009db
cleaned up some whitespace and removed commented-out lines
nbronn Aug 10, 2021
432bb3f
cleaned up some tox/lint errors
nbronn Aug 11, 2021
b308587
removed unneccessary Parameter import
nbronn Aug 11, 2021
5fd736a
Merge branch 'main' into template-param-expression
nbronn Aug 11, 2021
71aa17e
bypassed unit test test_unbound_parameters() and re-tox/lint
nbronn Aug 16, 2021
5c3a62b
Merge branch 'main' of github.com:Qiskit/qiskit-terra into template-p…
nbronn Aug 16, 2021
9f373e9
Merge branch 'template-param-expression' of github.com:nbronn/qiskit-…
nbronn Aug 16, 2021
bf590d3
fixed one last linting issue
nbronn Aug 16, 2021
0f5f0d6
fixed cyclic import error
nbronn Aug 17, 2021
4f5b69e
Merge branch 'main' into template-param-expression
nbronn Aug 17, 2021
bd3f9ed
modified calibration_creator to accept a ParameterExpression containi…
nbronn Aug 17, 2021
6c9831c
Merge branch 'template-param-expression' of github.com:nbronn/qiskit-…
nbronn Aug 17, 2021
d9530e6
fixed an mismatch when trying to add calibrations and addressed a con…
nbronn Aug 25, 2021
06b9cf1
Merge branch 'main' into template-param-expression
nbronn Aug 25, 2021
a9e7cdf
last tox/lint checks i'm sure ;)
nbronn Aug 25, 2021
4ea8ff5
moved try/except from scheduling to calibration
nbronn Aug 31, 2021
443a6c9
now params comes from node_op argument
nbronn Aug 31, 2021
04dfc37
Merge branch 'main' of github.com:Qiskit/qiskit-terra into template-p…
nbronn Sep 3, 2021
168c3cc
handling error in case gate parameters is empty in dagcircuit.py
nbronn Sep 3, 2021
0e9c39f
Merge branch 'main' of github.com:Qiskit/qiskit-terra into template-p…
nbronn Sep 17, 2021
d7b55b3
Merge branch 'main' into template-param-expression
nbronn Sep 22, 2021
0547f53
Merge branch 'main' into template-param-expression
nbronn Sep 29, 2021
fa51c3c
Fix template matching for parameters with LaTeX name.
rafal-pracht Oct 5, 2021
d4044a0
Merge pull request #1 from rafal-pracht/template-param-expression
nbronn Oct 6, 2021
19007b7
Merge branch 'main' into template-param-expression
nbronn Oct 6, 2021
d6e1cd7
Merge branch 'main' into template-param-expression
nbronn Oct 20, 2021
2065826
added missing docstring
nbronn Oct 20, 2021
a8b9b05
removed pdb set_trace
nbronn Oct 20, 2021
72990f5
Merge branch 'main' into template-param-expression
nbronn Oct 22, 2021
d177d84
Merge branch 'main' into template-param-expression
nbronn Oct 22, 2021
bd6dda4
made changes requested in PR 6899
nbronn Nov 2, 2021
6ea9d90
made changes requested in PR 6899 #2
nbronn Nov 2, 2021
592963b
Merge branch 'main' into template-param-expression
nbronn Nov 2, 2021
cebce74
remembered to tighten try/except handling
nbronn Nov 2, 2021
4e2291c
Merge branch 'template-param-expression' of github.com:nbronn/qiskit-…
nbronn Nov 2, 2021
6ccf293
Merge branch 'main' into template-param-expression
nbronn Nov 2, 2021
8b6bf37
finished making changes requested in PR 6899
nbronn Nov 3, 2021
fdffda6
Merge branch 'main' into template-param-expression
nbronn Nov 3, 2021
7721f23
fixed remaining linting issue
nbronn Nov 3, 2021
9130a2a
Merge branch 'main' into template-param-expression
nbronn Nov 3, 2021
5e31398
added comment about templates working for parameterized RZXGates and …
nbronn Nov 3, 2021
eb8ba0d
Merge branch 'template-param-expression' of github.com:nbronn/qiskit-…
nbronn Nov 3, 2021
a92b942
Merge branch 'main' into template-param-expression
nbronn Nov 4, 2021
84d65df
Merge branch 'main' into template-param-expression
nbronn Nov 5, 2021
17d5002
Merge branch 'main' into template-param-expression
nbronn Nov 9, 2021
3db29f0
Merge branch 'main' into template-param-expression
nbronn Nov 11, 2021
31b3d62
Merge branch 'main' into template-param-expression
nbronn Nov 12, 2021
1e8b009
Merge branch 'main' into template-param-expression
nbronn Nov 16, 2021
bdee233
Merge branch 'main' into template-param-expression
nbronn Nov 16, 2021
6d419de
Merge branch 'main' into template-param-expression
nbronn Nov 16, 2021
b362089
Merge branch 'main' into template-param-expression
nbronn Nov 18, 2021
2973339
Fix test unbound parameters
rafal-pracht Nov 19, 2021
bb1c797
Check if matrix with Parameter is unitary
rafal-pracht Nov 23, 2021
d531d95
Merge branch 'template-param-expression' into template-param-expression
rafal-pracht Nov 23, 2021
30706cd
Merge branch 'main' of github.com:Qiskit/qiskit-terra into template-p…
nbronn Nov 23, 2021
9260cf4
Fix merge issue
rafal-pracht Nov 24, 2021
767ccf4
Merge pull request #4 from rafal-pracht/template-param-expression
nbronn Nov 24, 2021
28b384f
Merge branch 'main' into template-param-expression
nbronn Dec 15, 2021
d55e75c
Merge branch 'template-param-expression' of github.com:nbronn/qiskit-…
nbronn Dec 15, 2021
f50c4e6
removed real=True in two symbol Symbol expressions, which was messing…
nbronn Dec 16, 2021
e32d038
generalized to iterate over parameters, and removed reference to priv…
nbronn Dec 16, 2021
c21fdf1
modified .get_sympy_expr() to use symengine if possible
nbronn Dec 16, 2021
bc42afb
made the negation of the RXGate() much less verbose
nbronn Dec 16, 2021
cce7b65
working thru tox/lint checks
nbronn Dec 16, 2021
5506200
added unit test test_unbound_parameters_in_rzx_templates to confirm t…
nbronn Dec 16, 2021
708bfcc
Fix unbund parameters test
rafal-pracht Dec 17, 2021
84d566b
Merge pull request #6 from rafal-pracht/template-param-expression
nbronn Dec 20, 2021
54403b0
fixed issue with adding calibrations without params
nbronn Dec 20, 2021
3c15da0
Merge branch 'main' into template-param-expression
nbronn Dec 20, 2021
9355893
Add real=True to symbols
rafal-pracht Dec 20, 2021
7e9f8d9
fixed linting issue
nbronn Dec 20, 2021
0a179b6
Fix for symengine
rafal-pracht Dec 20, 2021
5f86049
simplified the parameter handling for adding calibrations to gates
nbronn Dec 20, 2021
0835763
Merge pull request #7 from rafal-pracht/template-param-expression
nbronn Dec 20, 2021
680ec53
added a check for unitary on an arbitrary float in the case symengine…
nbronn Dec 20, 2021
f276cd7
Parammeter can be complex
rafal-pracht Dec 29, 2021
a295831
Merge pull request #8 from rafal-pracht/template-param-expression
nbronn Jan 3, 2022
2f244bc
Merge branch 'main' into template-param-expression
nbronn Jan 3, 2022
0434a70
Merge branch 'template-param-expression' of github.com:nbronn/qiskit-…
nbronn Jan 3, 2022
055832d
fixed tox/lint issues
nbronn Jan 4, 2022
2504c2e
removed one more imposition of real parameters
nbronn Jan 5, 2022
0f1cf5d
one last linting issue
nbronn Jan 5, 2022
c672ee3
Merge branch 'main' into template-param-expression
nbronn Jan 26, 2022
9a94bb2
modified release notes
nbronn Jan 26, 2022
48173c1
fixed some transpiler library imports that were out of date
nbronn Jan 27, 2022
24097b5
added sphinx referencing to release notes and print statement for the…
nbronn Jan 27, 2022
2f0203c
fixed some tox/lint issues
nbronn Jan 27, 2022
591763a
Fix review issues
rafal-pracht Jan 28, 2022
4dcf014
Merge branch 'main' into template-param-expression
nbronn Feb 1, 2022
8d1bc2e
Merge pull request #10 from rafal-pracht/template-param-expression
nbronn Feb 1, 2022
4f76b73
Merge branch 'template-param-expression' of github.com:nbronn/qiskit-…
nbronn Feb 2, 2022
c8a08e9
fixing last tox/lint issues
nbronn Feb 2, 2022
ee081e3
looking into tox/lint issues
nbronn Feb 11, 2022
3f740fb
added release notes and fixed tox/lint issues
nbronn Feb 11, 2022
69b8472
added method in template_substitution to compare the number of parame…
nbronn Feb 17, 2022
58c8ccf
Merge branch 'main' of github.com:Qiskit/qiskit-terra into template-p…
nbronn Feb 17, 2022
e09b1e3
fixing up some template matching unit tests
nbronn Feb 17, 2022
f01a671
fixed up template matching unit tests to remove calls to UnitaryGate
nbronn Feb 17, 2022
78a2f47
Update qiskit/dagcircuit/dagcircuit.py
nbronn Feb 23, 2022
8496a8c
Update qiskit/extensions/unitary.py
nbronn Feb 24, 2022
82470fd
Update qiskit/extensions/unitary.py
nbronn Feb 24, 2022
1f17aff
added template test with two parameters and new logic in the case the…
nbronn Feb 27, 2022
fb8ca5c
added two-parameter unit test and a check for overlapping parameters …
nbronn Mar 1, 2022
0ce2fa1
Merge branch 'main' of github.com:Qiskit/qiskit-terra into template-p…
nbronn Mar 1, 2022
9f59e06
Merge branch 'template-param-expression' of github.com:nbronn/qiskit-…
nbronn Mar 1, 2022
5de0384
remove ParameterTypeeException from exceptions.py
nbronn Mar 3, 2022
7906036
Restore lazy symengine imports
jakelishman Mar 24, 2022
092f92b
Rename to_sympify_expression to sympify
jakelishman Mar 24, 2022
95dbcfb
Revert now-unnecessary changes to calibration builder
jakelishman Mar 24, 2022
908f87d
Fixup release note
jakelishman Mar 24, 2022
fc83156
Add explicit tests of template matching pass
jakelishman Mar 24, 2022
a14dc37
Fix template parameter substitution
jakelishman Mar 24, 2022
9d07849
Merge remote-tracking branch 'ibm/main' into template-param-expression
jakelishman Mar 24, 2022
7034789
Fix overlooked documentation comment
jakelishman Mar 24, 2022
16bbffb
Remove qasm.pi import in favour of numpy
jakelishman Mar 24, 2022
317e2a6
Add tests of multi-parameter instructions
jakelishman Mar 24, 2022
6ccc663
Fix template matching with multiparameter expressions
jakelishman Mar 24, 2022
94e1884
Silence overzealous pylint warning
jakelishman Mar 24, 2022
87e5fe8
Merge remote-tracking branch 'ibm/main' into template-param-expression
jakelishman Mar 24, 2022
df9c3d3
Merge branch 'main' into template-param-expression
mergify[bot] Mar 28, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions qiskit/circuit/library/standard_gates/rx.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from qiskit.circuit.controlledgate import ControlledGate
from qiskit.circuit.gate import Gate
from qiskit.circuit.quantumregister import QuantumRegister
from qiskit.circuit.parameterexpression import ParameterValueType
from qiskit.circuit.parameterexpression import ParameterExpression, ParameterValueType


class RXGate(Gate):
Expand Down Expand Up @@ -95,7 +95,17 @@ def inverse(self):

:math:`RX(\lambda)^{\dagger} = RX(-\lambda)`
"""
return RXGate(-self.params[0])
if isinstance(self.params[0], ParameterExpression):
if self.params[0].parameters:
return RXGate(
ParameterExpression(
self.params[0]._parameter_symbols, -self.params[0]._symbol_expr
nbronn marked this conversation as resolved.
Show resolved Hide resolved
)
)
else:
return RXGate(-float(self.params[0]._symbol_expr))
else:
return RXGate(-self.params[0])
nbronn marked this conversation as resolved.
Show resolved Hide resolved

def __array__(self, dtype=None):
"""Return a numpy.array for the RX gate."""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,11 +269,6 @@ def _remove_impossible(self):
list_predecessors = []
remove_list = []

# First remove any scenarios that have parameters in the template.
for scenario in self.substitution_list:
if scenario.has_parameters():
remove_list.append(scenario)

# Initialize predecessors for each group of matches.
for scenario in self.substitution_list:
predecessors = set()
Expand Down Expand Up @@ -500,39 +495,42 @@ def _attempt_bind(self, template_sublist, circuit_sublist):
template_params += template_dag_dep.get_node(t_idx).op.params

# Create the fake binding dict and check
equations, symbols, sol, fake_bind = [], set(), {}, {}
for t_idx, params in enumerate(template_params):
if isinstance(params, ParameterExpression):
equations.append(sym.Eq(parse_expr(str(params)), circuit_params[t_idx]))
for param in params.parameters:
symbols.add(param)

if not symbols:
equations, circ_dict, temp_symbols, sol, fake_bind = [], {}, {}, {}, {}
for t_idx, temp_params in enumerate(template_params):
if isinstance(temp_params, ParameterExpression):
nbronn marked this conversation as resolved.
Show resolved Hide resolved
circ_param_str = str(circuit_params[t_idx])
equations.append(sym.Eq(parse_expr(str(temp_params)), parse_expr(circ_param_str)))

for param in temp_params.parameters:
temp_symbols[param] = sym.Symbol(str(param))

if isinstance(circuit_params[t_idx], ParameterExpression):
for param in circuit_params[t_idx].parameters:
circ_dict[param] = sym.Symbol(str(param))

if not temp_symbols:
return template_dag_dep

# Check compatibility by solving the resulting equation
sym_sol = sym.solve(equations)
sym_sol = sym.solve(equations, set(temp_symbols.values()))
jakelishman marked this conversation as resolved.
Show resolved Hide resolved
for key in sym_sol:
try:
sol[str(key)] = float(sym_sol[key])
sol[str(key)] = ParameterExpression(circ_dict, sym_sol[key])
except TypeError:
return None

if not sol:
return None

for param in symbols:
fake_bind[param] = sol[str(param)]
for key in temp_symbols:
fake_bind[key] = sol[str(key)]

for node in template_dag_dep.get_nodes():
bound_params = []

for param in node.op.params:
if isinstance(param, ParameterExpression):
try:
bound_params.append(float(param.bind(fake_bind)))
except KeyError:
return None
for key in fake_bind:
bound_params.append(param.assign(key, fake_bind[key]))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for key, value in fake_bind.items():, but also, isn't this going to add a whole lot of partially bound parameters to the bound_params list? If fake_bind has more than one item in it, this is going to be called a whole lot of times, and there'll be more items in bound_params than there originally were in node.op.params.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the issue here is that we cannot pass bound_params to .bind() because of the requirement the bound values are numeric, whereas we cannot pass bound_params directly to .assign() because it takes parameter and value separately as arguments. Any obvious solution seems to require modification of how .bind() or .assign() work.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this comment matches up with my issue (also the point about iterating through a dictionary with .items() still stands). I think this code is buggy, and it's just luckily not triggered.

The problem is that if fake_bind has n elements in it, the length of bound_params would be n * len(params), which is incorrect. Logically, this code is trying take param, and bind all instances of Parameter within it to a corresponding value in fake_bind, and return a single value, but instead it adds lots of values to bound_params. This only works because the templates you're considering only have a single Parameter in them. If we had a template that had two parameters in it, this would be broken. It's quite possible it was broken before as well, but this breaks it in a new way.

Please can you add a test case that involves a template (arbitrary - it can just be invented for the test) that has two parameters, and test that it binds correctly to input circuits with either numeric values or parameter values? For example, here's a (nonsensical) template match that fails with a KeyError, even though it should bind just fine:

In [5]: from qiskit.circuit import Parameter, QuantumCircuit
   ...: from qiskit.transpiler import PassManager
   ...: from qiskit.transpiler.passes import TemplateOptimization, RZXCalibrationBuilder
   ...:
   ...: a = Parameter('a')
   ...: b = Parameter('b')
   ...:
   ...: qc = QuantumCircuit(2)
   ...: qc.p(0.1, 0)
   ...: qc.p(-0.2, 1)
   ...:
   ...: template = QuantumCircuit(2)
   ...: template.p(a, 0)
   ...: template.p(b, 1)
   ...: template.cx(0, 1)
   ...:
   ...: pass_ = TemplateOptimization(
   ...:     user_cost_dict={"cx": 0, "p": 0},
   ...:     template_list=[template],
   ...: )
   ...: PassManager(pass_).run(qc).draw()

There are two issues at play: one is the issue with the length of bound_params, which is new in this PR, and the other is that the calls to ParameterExpression.assign during the template match should assign all parameters in that expression in one go, and only those parameters (this issue I think was pre-existing).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it really isn't possible to have it work for multiple parameters in the template circuit, then this should at least enforce that the template circuit only has a single unbound parameter in it, and the pass should loudly fail if it's given a template with more than one parameter.

else:
bound_params.append(param)

Expand Down
7 changes: 6 additions & 1 deletion qiskit/transpiler/passes/scheduling/calibration_creators.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from qiskit.providers import basebackend
from qiskit.dagcircuit import DAGOpNode
from qiskit.circuit.library.standard_gates import RZXGate
from qiskit.circuit.parameterexpression import ParameterExpression
from qiskit.transpiler.basepasses import TransformationPass


Expand Down Expand Up @@ -174,7 +175,11 @@ def get_calibration(self, params: List, qubits: List) -> Schedule:
QiskitError: if the control and target qubits cannot be identified or the backend
does not support cx between the qubits.
"""
theta = params[0]
if isinstance(params[0], ParameterExpression):
theta = float(params[0]._symbol_expr)
nbronn marked this conversation as resolved.
Show resolved Hide resolved
else:
theta = params[0]

q1, q2 = qubits[0], qubits[1]

if not self._inst_map.has("cx", qubits):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
features:
- |
The Parameter class is now allowed in template optimization. It has been
removed from the _remove_impossible() method for scenarios that are
incompatible with template optimization. Inversion of gates is currently
only implemented for the RXGate().
nbronn marked this conversation as resolved.
Show resolved Hide resolved
issues:
- |
Currently Parameters with names written as LaTeX (i.e., contain dollar
signs '$') are incompatible with the parse_expr() method used by Sympy.
Currently the only gate that can be inverted (as done in the template
optimization algorithm) with a Parameter is the RXGate().
nbronn marked this conversation as resolved.
Show resolved Hide resolved
4 changes: 4 additions & 0 deletions test/python/transpiler/test_template_matching.py
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,10 @@ def count_cx(qc):
self.assertEqual(count_cx(circuit_out), 2) # One match => two CX gates.
np.testing.assert_almost_equal(Operator(circuit_in).data, Operator(circuit_out).data)

@unittest.skip(
"Skipping because the inverse gate is defined as a UnitaryGate that is \
currently cast to a complex numpy array"
)
jakelishman marked this conversation as resolved.
Show resolved Hide resolved
def test_unbound_parameters(self):
"""
Test that partial matches with parameters will not raise errors.
Expand Down