-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Move numeric parameters from Instruction
to the data tuple
#7624
Comments
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
If I understand correctly, this removes the "quantum gate" concept from Qiskit. For example, it would no longer be possible to construct an object that represents the gate |
To some degree, yeah, but it's also kind of like saying that Qiskit doesn't have a concept of For ease of use: we don't expect the internal data structures to be the preferred way for how users interact with our systems. There's no changes planned for the interface of |
This syntax does not work for gates which don't have a corresponding method on QuantumCircuit. This is an important use case, and one which is very commonly understood in terms of the gate concept (rather than the instruction/operation concept you refer to). With this change, how would one obtain the matrix of a gate, say, |
The with QuantumCircuit.build() as circuit:
RX(0.1) | (0,)
X | (1,)
... but this is still a long way off - the internal discussions are very preliminary (and have been for a year). The first priority is to get the internal components of dynamic circuits working end-to-end, from Terra to backends, because it's no good having nice syntax if the system doesn't work. In the internal-only structure, the current plan is to make I appreciate that your applications think of gates as "gate + parameters" and that that's common, but equally common is the alternative of " |
I should also be clear that this won't happen overnight: we're committed to maintaining the API stability, so we'll be doing all we can to ensure that |
This commit expands the recently added instruction_supported() method of the Target class to also enable optionally checking if a parameter on an instruction is supported. This is anticipating future changes around how instruction parameters are represented in terra more generally as part of Qiskit#7624 and specifically in the Target for Qiskit#7797. Before we do any refactoring around this having a standard API for checking if a parameter is supported is useful. This commit expands the interface for the insturction_supported() method to check any combination of operation name, qargs, operation class, or parameters (either operation name or class is required) and the method will return True if that instruction can be run on the Target device.
* Expand instruction_supported() to optionally check parameters This commit expands the recently added instruction_supported() method of the Target class to also enable optionally checking if a parameter on an instruction is supported. This is anticipating future changes around how instruction parameters are represented in terra more generally as part of #7624 and specifically in the Target for #7797. Before we do any refactoring around this having a standard API for checking if a parameter is supported is useful. This commit expands the interface for the insturction_supported() method to check any combination of operation name, qargs, operation class, or parameters (either operation name or class is required) and the method will return True if that instruction can be run on the Target device. * Fix docs build * Expand test coverage * Apply suggestions from code review Co-authored-by: Ali Javadi-Abhari <[email protected]> * Update fake backend name in tests * Fix handling of multiple parameters in gate name case * Fix parameter checking in class gate input case * Add missing test path * Add release note * Fix release-note typo Co-authored-by: Ali Javadi-Abhari <[email protected]> Co-authored-by: Jake Lishman <[email protected]> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
This issue was obsoleted by the Rust-space work on |
What should we add?
This is the first step in adding full classical data and instructions to
QuantumCircuit
. This is a partial step; it may well not be the only change to the data tuple that we make over the course of this, and it doesn't try to fix everything we dislike aboutInstruction
yet, but it's a start.I do recognise that what I suggest here is a breaking API change, but I think some degree of that is going to be unavoidable when we're making changes to basically the entirety of our core data structure and flow. I've tried to limit the damage.
Apologies that this is a bit long, I'm trying to write down all my thoughts about this step so we can get started while I'm out writing my thesis. @kdk is managing this issue while I'm out.
Why we chose this
We chose this because it should yield some tangible benefits immediately, without needing to consider the new type system yet:
Instruction
instances when binding parameters in circuits, in these lines: https://github.com/Qiskit/qiskit-terra/blob/13370342bca77000bf7321d8c581d5661b1a7fb7/qiskit/circuit/quantumcircuit.py#L1232-L1236QuantumCircuit.data
list entry, i.e. these (quite inefficient) lines should be made redundant: https://github.com/Qiskit/qiskit-terra/blob/13370342bca77000bf7321d8c581d5661b1a7fb7/qiskit/circuit/quantumcircuit.py#L2680-L2691What to do
The aim is to move any
params
of existingInstruction
s that may beParameterExpression
into a fourth element of the(instruction, qargs, cargs)
tuple. It might be convenient to do this in two steps:instruction.operation
,instruction.qargs
andinstruction.cargs
). For now, it might need to be called something private (like_Instruction
) because we haven't quite sorted out the migration path from the currentInstruction
. It would be good to makeqargs
andcargs
intotuple
, notlist
at this step - the immutability will help later.parameters
by analogy to the current name, though strictly they'd be arguments not parameters!), and teach all the neceessary parts of Terra that to get the concrete definition or matrix form, they need to pass these in. This should also be a tuple, not a list.Moving to named access is useful for updating the class in the future; it's easier to catch a name change with
pylint
than it is to catch the positional elements changing type or reordering. There may be a slight performance impact to this on the surface, but I think making this object mutable (but all its contents eventually immutable) will be much better performing in the long-run - copies of circuits and binding of parameters will become much cheaper, and getting to a point of internal immutability should let us massively reduce our memory footprint, which is great of itself but also has indirect performance advantages (even in Python).In order to limit the immediate API breakage, it may be worth defining the
Sequence
interface on this new class as if it were still the old 3-tuple, so most tuple-like access on it will continue to work in user code. I would want to test suite to pass without this interface defined, though - we need to make sure Terra is fully updated.Without actually trying it, it's hard to predict all the consequences, but here's some potential implementation considerations and pitfalls:
Instruction
/Operation
will probably need to gain a new variablenum_parameters
for type checking.Instruction.definition
should likely be a pointer to a parameterisedQuantumCircuit
, and it will be up to the caller to bind the parameters, when they need them to be bound. We need to ensure that the parameter order is fixed and correct.Gate.inverse
would ideally be defined to return a parameterisedQuantumCircuit
, which the caller will be responsible for binding when it needs to be bound.Instruction.__array__
(orGate.__array__
) will probably cease to exist, because the operation will not hold all the state necessary to construct a concrete array. That's deliberate - we don't want the operation (currently theInstruction
instance) to hold the state any more.ParameterTable
structure inQuantumCircuit
will need updating. A lot of UseParameterReferences
type forParameterTable
values #7408 is absolutely relevant here.Parameter
s as well. I think there are some subleties here (especially withIfElseContext
andIfElseOp
, which manage two circuit bodies), but I've not got so far as sketching out that process yet.Limitations during this step
We don't want to do everything at once. There are lots of things that need more thought and design, and this change is already going to be very big, so we're trying to work incrementally. Several things in this step we know aren't perfect, but it will be easier to review the effects of changes and iterate the design if we go step-by-step.
ControlFlowOp
'sblocks
,ControlledGate
'sctrl_state
orUnitaryGate
's matrix out of the relevantInstruction
. For now, the newparameters
should be exactly the tuple of things that can validly beParameterExpression
.ForLoopOp
'sloop_parameter
in the class, not in the new tuple - this is because the scoping of it may be internal toForLoopOp
.Instruction.broadcast_arguments
at this point - it's inconsistent and weird, and it can just stay that wayInstruction
/abstractOperation
split - that's not fully in place yet, but the changes here should largely be orthogonal (except perhapsOperation
needs thenum_parameters
variable).cargs
andparameters
. This may change in the future once we have a stronger classical type system, butClbit
is always going to be special in some way (it's the only valid l-value of ameasure
), so it's good to keep it separate.my_creg[i] = measure my_qreg[i];
in this step)Some other things considered
Using a
tuple
ornamedtuple
for the elements ofQuantumCircuit.data
It's hard to do
ParameterTable
and parameter binding efficiently if the elements are immutable - you would need a way to store a pointer into theQuantumCircuit.data
structure that can be assigned to in constant time. Forlist
, that's an integer index, except the index is kind of state-dependent; using that makes it impossible to insert or remove instructions in any efficient way at all - we'd have to loop throughParameterTable
each time updating everything. We also need to think about the swap to a DAG data structure - there, it's going to be hard to store an "assignable" pointer.These issues aren't so much of a problem if the
qc.data
element is mutable itself; we can use the same trick we currently do of storing it in theParameterTable
, and mutating it in-place to replace theparameters
item. The current state ofQuantumCircuit
needs to deepcopy itsInstruction
s to be safe. We wouldn't need to do this any more; the new lazier pattern means that we could safely simply shallow-copy the data element that's currently a tuple, since its components should be (or at least end up being) immutable.Moving the entirety of
Instruction.params
into the tupleWe have rough desires to get the state out of
Instruction
entirely, but don't have a full plan for getting there. Separating out just theParameterExpression
bits first is something we know we'll need, because we need to start tracking data that gets fed into these slots for dynamic circuits, and there are the tangible benefits listed above to these. We will need to get these slots separately in the future in some form or another in order to make/bind QASM-ishgate my_gate(a, b, c) q1, q2 { ... }
logical statements, asa
,b
andc
are the only values that can be modified dynamically during the circuit.If we move everything out immediately, we've mostly just shifted the issue, and we don't get most of the nice immediate benefits at the start of this issue.
The text was updated successfully, but these errors were encountered: