Qx.Export.OpenQASM (Qx - Quantum Computing Simulator v0.6.0)
View SourceExport Qx quantum circuits to OpenQASM format and import OpenQASM 3.0
source back into a Qx.QuantumCircuit.
Importing OpenQASM (since v0.6.0)
from_qasm/1 parses OpenQASM 3 source produced by Qx, by Qiskit, or by
IBM Quantum into a circuit:
{:ok, circuit} = Qx.Export.OpenQASM.from_qasm(qasm_source)Round-trips with to_qasm/1 — any program emitted by to_qasm/1 parses
back to a circuit with a matching state vector.
from_qasm_function/1 parses a gate name(p) a, b { … } definition and
returns Elixir source for an equivalent function:
{:ok, %{name: "bell", arity: 3, source: source}} =
Qx.Export.OpenQASM.from_qasm_function(qasm_with_gate)The generated def name(circuit, params…, qubits…) body composes
Qx.h/2, Qx.cx/3, etc. via the |> pipeline and can be Code.compile_string/1-ed.
Supported gate set on import
Direct mappings: h, x, y, z, s, sdg, t, rx, ry, rz, p, phase, u, u3, cx, CX, cz, swap, iswap, cp, cphase, ccx, cswap.
Decompositions: tdg → phase(-π/4), sx → u(π/2, -π/2, π/2),
u1(λ) → phase(λ), u2(φ, λ) → u(π/2, φ, λ). id is dropped.
Not supported (raises Qx.QasmUnsupportedError)
Multi-register programs, gate modifiers (inv/pow/ctrl/negctrl),
else branches, complex boolean conditions, classical types beyond
bit, def, for, while, switch, defcal, let, pragma,
extern, box, delay, reset, the stdgates cy/ch/crx/cry/crz/cu,
and the Qiskit extensions rxx/ryy/rzz/rzx.
Exporting
This module provides functionality to convert Qx quantum circuits into OpenQASM code that can be executed on real quantum hardware platforms including:
- IBM Quantum (IBM Q)
- AWS Braket
- Google Cirq (via OpenQASM import)
- Rigetti (via AWS Braket)
- IonQ (via AWS Braket or Azure Quantum)
Supports both OpenQASM 2.0 and 3.0 specifications.
OpenQASM Versions
- OpenQASM 2.0: Legacy version, widely supported, no conditional operations
- OpenQASM 3.0: Modern version with conditionals, mid-circuit measurements, and control flow
Supported Features
- Single-qubit gates (H, X, Y, Z, S, T, RX, RY, RZ, Phase)
- Multi-qubit gates (CNOT/CX, CZ, Toffoli/CCX)
- Measurements and classical bits
- Conditional operations (OpenQASM 3.0 only)
- Barriers for visualization organization
Examples
# Export a Bell state circuit to OpenQASM 3.0
circuit = Qx.circuit(2)
|> Qx.h(0)
|> Qx.cnot(0, 1)
|> Qx.measure(0, 0)
|> Qx.measure(1, 1)
qasm = Qx.Export.OpenQASM.to_qasm(circuit)
File.write!("bell_state.qasm", qasm)
# Export to OpenQASM 2.0 (no conditionals)
qasm2 = Qx.Export.OpenQASM.to_qasm(circuit, version: 2)
# Export with custom options
qasm = Qx.Export.OpenQASM.to_qasm(circuit,
version: 3,
include_comments: true,
gate_style: :verbose
)Platform Compatibility
| Platform | Version | Mid-circuit Measurement | Conditionals |
|---|---|---|---|
| IBM Quantum | 2.0, 3.0 | 3.0 only | 3.0 only |
| AWS Braket | 3.0 | Yes | Yes |
| Google Cirq | 2.0 | No | No |
| Rigetti | 2.0, 3.0 | 3.0 only | 3.0 only |
Limitations
- Circuits with conditionals cannot be exported to OpenQASM 2.0
- Custom gate definitions are expanded to standard gates
- Qubit ordering follows MSB convention (qubit 0 is leftmost)
Summary
Functions
Parses OpenQASM 3.0 source and returns a Qx.QuantumCircuit.
Like from_qasm/1 but raises on error.
Parses an OpenQASM 3.0 program containing a gate definition and
returns Elixir source code for an equivalent function.
Like from_qasm_function/1 but raises on error.
Converts a Qx quantum circuit to OpenQASM format.
Functions
@spec from_qasm(String.t()) :: {:ok, Qx.QuantumCircuit.t()} | {:error, Exception.t()}
Parses OpenQASM 3.0 source and returns a Qx.QuantumCircuit.
Round-trips with to_qasm/1: any program produced by to_qasm/1 parses
back to a circuit that simulates to the same state vector.
Returns
{:ok, %Qx.QuantumCircuit{}}on success{:error, %Qx.QasmParseError{}}on grammar/syntax failures{:error, %Qx.QasmUnsupportedError{}}for valid QASM that uses features Qx does not yet support (multi-register programs, gate modifiers,elsebranches, classical types beyondbit, …){:error, %Qx.QubitIndexError{}}/{:error, %Qx.ClassicalBitError{}}for index validation failures
Examples
iex> qasm = ~s"""
...> OPENQASM 3.0;
...> include "stdgates.inc";
...> qubit[2] q;
...> bit[2] c;
...> h q[0];
...> cx q[0], q[1];
...> c[0] = measure q[0];
...> c[1] = measure q[1];
...> """
iex> {:ok, circuit} = Qx.Export.OpenQASM.from_qasm(qasm)
iex> circuit.num_qubits
2Supported features
See the module doc for the supported gate set, decompositions, and the
list of QASM 3 features deliberately excluded from v1 (each raises a
typed Qx.QasmUnsupportedError).
@spec from_qasm!(String.t()) :: Qx.QuantumCircuit.t()
Like from_qasm/1 but raises on error.
@spec from_qasm_function(String.t()) :: {:ok, map()} | {:error, Exception.t()}
Parses an OpenQASM 3.0 program containing a gate definition and
returns Elixir source code for an equivalent function.
The result map is %{name: String.t(), arity: pos_integer(), source: String.t()}
where source is a def definition that can be inserted into a module
via Code.compile_string/1 (or stored verbatim by callers like
qxportal). The function takes (circuit, params..., qubits...) and
returns the new circuit.
When the source contains multiple gate definitions, the last is
treated as the "main" function — earlier ones are usually helpers
which the main one references. Since user-defined gate references
inside a gate body are rejected (Qx.QasmUnsupportedError), helpers
themselves cannot be code-generated through this entry point.
If no gate definition is present, returns {:error, %Qx.QasmParseError{}}.
Example
iex> qasm = ~s"""
...> OPENQASM 3.0;
...> include "stdgates.inc";
...> gate bell a, b {
...> h a;
...> cx a, b;
...> }
...> """
iex> {:ok, %{name: "bell", arity: 3, source: source}} =
...> Qx.Export.OpenQASM.from_qasm_function(qasm)
iex> source =~ "def bell(circuit, a, b)"
true
Like from_qasm_function/1 but raises on error.
Converts a Qx quantum circuit to OpenQASM format.
Parameters
circuit- AQx.QuantumCircuitstructoptions- Keyword list of options (default: [])
Options
:version- OpenQASM version (2 or 3, default: 3):include_comments- Add descriptive comments (default: false):gate_style- Gate naming style (:standardor:verbose, default::standard)
Returns
A string containing the OpenQASM program.
Raises
Qx.GateError- If circuit contains unsupported gatesQx.ConditionalError- If circuit has conditionals but version is 2ArgumentError- If invalid options are provided
Examples
circuit = Qx.circuit(2) |> Qx.h(0) |> Qx.cnot(0, 1)
qasm = Qx.Export.OpenQASM.to_qasm(circuit)
# Output:
# OPENQASM 3.0;
# include "stdgates.inc";
#
# qubit[2] q;
# bit[2] c;
#
# h q[0];
# cx q[0], q[1];