8. Importing OpenQASM Circuits

quimb supports importing both OpenQASM 2 and a practical subset of OpenQASM 3 into Circuit objects.

8.1. OpenQASM 3 entry points

Use the classmethods on Circuit:

These parse the source and immediately build a circuit with the imported gates:

import quimb.tensor as qtn

qasm = """
OPENQASM 3.0;
include "stdgates.inc";

qubit[2] q;
h q[0];
cx q[0], q[1];
"""

circ = qtn.Circuit.from_openqasm3_str(qasm)
print(circ)

8.2. Supported OpenQASM 3 subset

The parser focuses on circuit input. It currently does not support the full QASM 3.0 language. Supported features include:

  • qubit declarations

  • input declarations for symbolic gate parameters

  • arithmetic expressions such as pi / 2 or theta / 2

  • const, scalar classical declarations, and array declarations used in parameter expressions

  • custom gate definitions, including nested custom gates

  • register broadcasting such as h q; or cx q, r;

Ignored with warnings:

  • measure

  • barrier

  • gphase

  • plain bit declarations used only for classical measurement targets

Unsupported constructs raise NotImplementedError, including:

  • output declarations

  • control flow such as if, for, and while

  • reset

  • calibration-related constructs

8.3. Symbolic inputs and rebinding

OpenQASM 3 input declarations are registered as named circuit parameters so that values can be bound later with Circuit.set_params:

import quimb.tensor as qtn

qasm = """
OPENQASM 3.0;
include "stdgates.inc";

input float theta;
qubit[1] q;
rx(theta) q[0];
"""

circ = qtn.Circuit.from_openqasm3_str(qasm)
circ.set_params({"theta": 0.3})

The imported circuit exposes:

  • circ.named_params: current named parameter values

  • circ.named_param_names: declared named parameter names

  • circ.param_expressions: symbolic expressions attached to parameterized gates

Unbound named parameters are initialized to nan, and any gate parameters that depend on them are likewise initialized to nan until values are supplied.

Named updates can be mixed with raw gate-index updates in the same set_params(...) call, for example {"theta": 0.3, 5: (0.1, 0.2, 0.3)}. This round-trips with get_params(), which returns named parameters plus only those integer-indexed parametrized gates not managed by named expressions, and works with generic parameter-handling tools such as TNOptimizer. Partial named updates are allowed: expressions that still depend on unbound names remain nan until those names are set. Unknown names raise an error, and expression-managed gates cannot be overridden directly via their integer gate indices.

The same named-parameter mechanism can also be used outside OpenQASM import via Circuit.register_named_params, either by supplying a sequence of names or a mapping of initial values, with string expressions such as cos(theta / 2) or callables attached to arbitrary parametrized gates. String-keyed set_params(...) updates require such named parameters to have been registered first.

8.4. OpenQASM 2 compatibility

Equivalent OpenQASM 2 import helpers remain available:

Where the same gate subset is used, the OpenQASM 2 and OpenQASM 3 import paths produce matching circuits.