qiskit
qiskit copied to clipboard
Modeling and compiling circuits with classical instructions and data
With the addition of classical types and the expansion of classical instructions both in the OpenQASM3 language and available on devices, terra should expand the ability of users to build, compile, and simulate QuantumCircuit
s containing classical instructions and classical data types. This meta-issue will serve as a place to track progress, discussions and decisions on this front.
Classical data types:
https://qiskit.github.io/openqasm/language/types.html#classical-types
Scalar types:
- [ ]
bit[size]
- [ ]
bool
- [ ]
{u,}int[width]
- [ ]
angle[width]
- [ ]
float[width]
- [ ]
complex
Questions:
- Should these be typed subclasses of
ClassicalRegister
?- @jakelishman: These should be new types. Qiskit
ClassicalRegisters
are already mapped to OpenQASM 3alias
.
- @jakelishman: These should be new types. Qiskit
- The transpiler will need some capacity to reason about these numeric types (even for simple optimizations like dead code elimination), but arithmetic for variable-width types isn't well supported by python. Would this require building out custom math libraries, or are there other tools we can use?
Array types:
OpenQASM 3 defines two array types, global C-like arrays (backed by memory) with compile-time known size and array references (available as as function arguments) with known sizes at point of entry (if specified in the subroutine description) and compile-time known number of dimensions.
Questions:
Constants:
- [ ]
pi
- [ ]
tau
- [ ]
e
Duration:
https://qiskit.github.io/openqasm/language/delays.html#duration-and-stretch-types
Defined in OpenQASM3 as a numeric type plus one of ns
, μs
, us
, ms
, or s
.
Questions:
- How to represent
dt
? As a "constant" to be resolved at runtime? - How to represent
stretch
?
Casting:
https://qiskit.github.io/openqasm/language/types.html#allowed-casts
Register aliasing/concatenation/slicing
https://qiskit.github.io/openqasm/language/types.html#register-concatenation-and-slicing
ClassicalRegisters
are presently mapped in the Exporter
as aliases, and support slicing and concatenation.
Classical instruction types:
https://qiskit.github.io/openqasm/language/classical.html#low-level-classical-instructions
Classical Instructions:
- [ ]
**
- [ ]
!
,-
(unary negation),~
- [ ]
*
,/
,%
- [ ]
+
,-
(binary subtraction) - [ ]
<<
,>>
- [ ]
<
,<=
,>
,>=
- [ ]
!=
,==
- [ ]
&
,^
,|
,&&
,||
Parameter
s and ParameterExpression
s
Parameter
s and ParameterExpression
s exist in Qiskit as ways to defer assignment of QuantumCircuit
instruction parameters, and overlap just enough with variables in OpenQASM 3 that a unified approach will be needed.
Questions
-
sympy
(sometimes) auto-simplifiesParameterExpression
s, but this will generally violate the expression order one would expect from hardware. i.e. If a circuit contains the equivalent ofParameter('x') + 0
, the correspondingAdd
instruction should be present on the device unless the user or a compiler optimizes it away (in the spirit of faithfully representing device execution). This was foreseen in the design ofParameter
s to some degree, but reliance on sympy auto-simplification has likely sneaked in in and a few places.- @cryoris: If available, gradient framework could i.e deferring simplification prior to taking a gradient
- @jakelishman: Perhaps separate numeric types (
Real
,Complex
) from machine arithmetic and floating point types.- Numeric types wouldn't be able to be cast, or passed to subroutines
- Will require code somewhere to cast numeric parameter types to machine types.
- Currently exists in the exporter, but could be migrated as a lowering pass in the transpiler.
- N.B.
QuantumCircuit.for_loop
currently returns aParameter
Input/Output types on a QuantumCircuit
https://qiskit.github.io/openqasm/language/directives.html#input-output
Subroutines
Qiskit currently supports sub-circuits as composite Instruction
/Gate
s which map most closely to OpenQASM 3.0's hierarchically defined gates ( https://qiskit.github.io/openqasm/language/gates.html#hierarchically-defined-unitary-gates ) with the exception that Qiskit sub-circuits can include OpenQASM 2.0-like register style conditionals. OpenQASM 3.0 defines separate subroutines which are notably pass-by-value. Array's are also passed by value, but the value is a reference to the array.
Some additional preliminary thoughts in no particular order (mostly I'm using this issue as a notepad):
- a fair amount of maths can be automatically built up by whatever
Expression
representation we decide on internally keeping an entire tree, but we'll also need to add additional classical instructions to represent mutations of existing names at runtime. This naturally lets the transpiler see things, but it's probably going to play super weirdly with any internal DAG representation, because mapping arbitrary program flow onto an acyclic graph implies that we've solved the halting problem. - for arbitrary precision types,
gmpy2
is probably going to be our best bet in Python space, if not only because they do the hard work of packaging MPFR for us. In Aer, we're going to hit all those gross headaches ourselves - I know the internal QSS team have had issues with that and Windows. -
width
will be able to be elided in the OpenQASM 3 spec soon in favour of that meaning something backend-specific; Terra may need to be able to reason about that too, but that should come fairly easily.
Are we still planning to close this issue for 0.20?
I've attached it to 0.21, but really this is the containing epic as the tracking issue for "dynamic circuits" on the project board, so it's not actionable as a single item.