qiskit icon indicating copy to clipboard operation
qiskit copied to clipboard

Modeling and compiling circuits with classical instructions and data

Open kdk opened this issue 3 years ago • 3 comments

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 QuantumCircuits 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 3 alias.
  • 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)
  • [ ] <<, >>
  • [ ] <, <=, >, >=
  • [ ] !=, ==
  • [ ] &, ^, |, &&, ||

Parameters and ParameterExpressions

Parameters and ParameterExpressions 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-simplifies ParameterExpressions, but this will generally violate the expression order one would expect from hardware. i.e. If a circuit contains the equivalent of Parameter('x') + 0, the corresponding Add 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 of Parameters 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 a Parameter

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/Gates 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.

kdk avatar Jan 25 '22 15:01 kdk

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.

jakelishman avatar Jan 25 '22 17:01 jakelishman

Are we still planning to close this issue for 0.20?

HuangJunye avatar Mar 22 '22 15:03 HuangJunye

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.

jakelishman avatar Mar 22 '22 17:03 jakelishman