qiskit-documentation/docs/api/qiskit/0.43/qasm3.mdx

263 lines
12 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: qasm3
description: API reference for qiskit.qasm3
in_page_toc_min_heading_level: 2
python_api_type: module
python_api_name: qiskit.qasm3
---
<span id="module-qiskit.qasm3" />
<span id="qiskit-qasm3" />
<span id="openqasm-3-qiskit-qasm3" />
# OpenQASM 3
<span id="module-qiskit.qasm3" />
`qiskit.qasm3`
Qiskit provides some tools for converting between [OpenQASM 3](https://openqasm.com) representations of quantum programs, and the [`QuantumCircuit`](qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit") class. These will continue to evolve as Qiskits support for the dynamic-circuit capabilities expressed by OpenQASM 3 increases.
## Exporting to OpenQASM 3
The high-level functions are simply [`dump()`](#qiskit.qasm3.dump "qiskit.qasm3.dump") and [`dumps()`](#qiskit.qasm3.dumps "qiskit.qasm3.dumps"), which respectively export to a file (given as a filename) and to a Python string.
### dump
<Function id="qiskit.qasm3.dump" github="https://github.com/qiskit/qiskit/tree/stable/0.24/qiskit/qasm3/__init__.py" signature="dump(circuit, stream, **kwargs)">
Serialize a [`QuantumCircuit`](qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit") object as a OpenQASM3 stream to file-like object.
**Parameters**
* **circuit** ([*QuantumCircuit*](qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit")) Circuit to serialize.
* **stream** (*TextIOBase*) stream-like object to dump the OpenQASM3 serialization
* **\*\*kwargs** Arguments for the [`Exporter`](#qiskit.qasm3.Exporter "qiskit.qasm3.Exporter") constructor.
</Function>
### dumps
<Function id="qiskit.qasm3.dumps" github="https://github.com/qiskit/qiskit/tree/stable/0.24/qiskit/qasm3/__init__.py" signature="dumps(circuit, **kwargs)">
Serialize a [`QuantumCircuit`](qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit") object in an OpenQASM3 string.
**Parameters**
* **circuit** ([*QuantumCircuit*](qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit")) Circuit to serialize.
* **\*\*kwargs** Arguments for the [`Exporter`](#qiskit.qasm3.Exporter "qiskit.qasm3.Exporter") constructor.
**Returns**
The OpenQASM3 serialization
**Return type**
str
</Function>
Both of these exporter functions are single-use wrappers around the main [`Exporter`](#qiskit.qasm3.Exporter "qiskit.qasm3.Exporter") class. For more complex exporting needs, including dumping multiple circuits in a single session, it may be more convenient or faster to use the complete interface.
### Exporter
<Class id="qiskit.qasm3.Exporter" github="https://github.com/qiskit/qiskit/tree/stable/0.24/qiskit/qasm3/exporter.py" signature="Exporter(includes=('stdgates.inc', ), basis_gates=('U', ), disable_constants=False, alias_classical_registers=False, indent='  ', experimental=ExperimentalFeatures.None)" modifiers="class">
QASM3 exporter main class.
**Parameters**
* **includes** (*Sequence\[str]*) the filenames that should be emitted as includes. These files will be parsed for gates, and any objects dumped from this exporter will use those definitions where possible.
* **basis\_gates** (*Sequence\[str]*) the basic defined gate set of the backend.
* **disable\_constants** (*bool*) if `True`, always emit floating-point constants for numeric parameter values. If `False` (the default), then values close to multiples of QASM 3 constants (`pi`, `euler`, and `tau`) will be emitted in terms of those constants instead, potentially improving accuracy in the output.
* **alias\_classical\_registers** (*bool*) If `True`, then classical bit and classical register declarations will look similar to quantum declarations, where the whole set of bits will be declared in a flat array, and the registers will just be aliases to collections of these bits. This is inefficient for running OpenQASM 3 programs, however, and may not be well supported on backends. Instead, the default behaviour of `False` means that individual classical registers will gain their own `bit[size] register;` declarations, and loose [`Clbit`](qiskit.circuit.Clbit "qiskit.circuit.Clbit")s will go onto their own declaration. In this form, each [`Clbit`](qiskit.circuit.Clbit "qiskit.circuit.Clbit") must be in either zero or one [`ClassicalRegister`](qiskit.circuit.ClassicalRegister "qiskit.circuit.ClassicalRegister")s.
* **indent** (*str*) the indentation string to use for each level within an indented block. Can be set to the empty string to disable indentation.
* **experimental** ([*ExperimentalFeatures*](#qiskit.qasm3.ExperimentalFeatures "qiskit.qasm3.experimental.ExperimentalFeatures")) any experimental features to enable during the export. See [`ExperimentalFeatures`](#qiskit.qasm3.ExperimentalFeatures "qiskit.qasm3.ExperimentalFeatures") for more details.
#### dump
<Function id="qiskit.qasm3.Exporter.dump" signature="dump(circuit, stream)">
Convert the circuit to QASM 3, dumping the result to a file or text stream.
</Function>
#### dumps
<Function id="qiskit.qasm3.Exporter.dumps" signature="dumps(circuit)">
Convert the circuit to QASM 3, returning the result as a string.
</Function>
</Class>
All of these interfaces will raise [`QASM3ExporterError`](#qiskit.qasm3.QASM3ExporterError "qiskit.qasm3.QASM3ExporterError") on failure.
### QASM3ExporterError
<Class id="qiskit.qasm3.QASM3ExporterError" github="https://github.com/qiskit/qiskit/tree/stable/0.24/qiskit/qasm3/exceptions.py" signature="QASM3ExporterError(*message)" modifiers="exception">
An error raised during running the OpenQASM 3 exporter.
Set the error message.
</Class>
### Experimental features
The OpenQASM 3 language is still evolving as hardware capabilities improve, so there is no final syntax that Qiskit can reliably target. In order to represent the evolving language, we will sometimes release features before formal standardization, which may need to change as the review process in the OpenQASM 3 design committees progresses. By default, the exporters will only support standardised features of the language. To enable these early-release features, use the `experimental` keyword argument of [`dump()`](#qiskit.qasm3.dump "qiskit.qasm3.dump") and [`dumps()`](#qiskit.qasm3.dumps "qiskit.qasm3.dumps"). The available feature flags are:
#### ExperimentalFeatures
<Class id="qiskit.qasm3.ExperimentalFeatures" github="https://github.com/qiskit/qiskit/tree/stable/0.24/qiskit/qasm3/experimental.py" signature="ExperimentalFeatures(value)" modifiers="class">
Flags for experimental features that the OpenQASM 3 exporter supports.
These are experimental and are more liable to change, because the OpenQASM 3 specification has not formally accepted them yet, so the syntax may not be finalized.
##### SWITCH\_CASE\_V1
<Attribute id="qiskit.qasm3.ExperimentalFeatures.SWITCH_CASE_V1" attributeValue="1">
Support exporting switch-case statements as proposed by [https://github.com/openqasm/openqasm/pull/463](https://github.com/openqasm/openqasm/pull/463) at [commit bfa787aa3078](https://github.com/openqasm/openqasm/pull/463/commits/bfa787aa3078).
</Attribute>
</Class>
If you want to enable multiple experimental features, you should combine the flags using the `|` operator, such as `flag1 | flag2`.
For example, to perform an export using the early semantics of `switch` support:
```python
from qiskit import qasm3, QuantumCircuit, QuantumRegister, ClassicalRegister
# Build the circuit
qreg = QuantumRegister(3)
creg = ClassicalRegister(3)
qc = QuantumCircuit(qreg, creg)
with qc.switch(creg) as case:
with case(0):
qc.x(0)
with case(1, 2):
qc.x(1)
with case(case.DEFAULT):
qc.x(2)
# Export to an OpenQASM 3 string.
qasm_string = qasm3.dumps(qc, experimental=qasm3.ExperimentalFeatures.SWITCH_CASE_V1)
```
<Admonition title="Note" type="note">
All features enabled by the experimental flags are naturally transient. If it becomes necessary to remove flags, they will be subject to [the standard Qiskit deprecation policy](https://qiskit.org/documentation/deprecation_policy.html). We will leave these experimental flags in place for as long as is reasonable.
However, we cannot guarantee any support windows for *consumers* of OpenQASM 3 code generated using these experimental flags, if the OpenQASM 3 language specification changes the proposal that the flag is based on. It is possible that any tool you are using to consume OpenQASM 3 code created using these flags may update or remove their support while Qiskit continues to offer the flag. You should not rely on the resultant experimental OpenQASM 3 code for long-term storage of programs.
</Admonition>
## Importing from OpenQASM 3
Currently only two high-level functions are offered, as Qiskit support for importing from OpenQASM 3 is in its infancy, and the implementation is expected to change significantly. The two functions are [`load()`](#qiskit.qasm3.load "qiskit.qasm3.load") and [`loads()`](#qiskit.qasm3.loads "qiskit.qasm3.loads"), which are direct counterparts of [`dump()`](#qiskit.qasm3.dump "qiskit.qasm3.dump") and [`dumps()`](#qiskit.qasm3.dumps "qiskit.qasm3.dumps"), respectively loading a program indirectly from a named file and directly from a given string.
<Admonition title="Note" type="note">
While we are still in the exploratory release period, to use either function, the package `qiskit_qasm3_import` must be installed. This can be done by installing Qiskit Terra with the `qasm3-import` extra, such as by:
```python
pip install qiskit-terra[qasm3-import]
```
We expect that this functionality will eventually be merged into core Terra, and no longer require an optional import, but we do not yet have a timeline for this.
</Admonition>
### load
<Function id="qiskit.qasm3.load" github="https://github.com/qiskit/qiskit/tree/stable/0.24/qiskit/qasm3/__init__.py" signature="load(filename)">
Load an OpenQASM 3 program from the file `filename`.
**Parameters**
**filename** (*str*) the filename to load the program from.
**Returns**
a circuit representation of the OpenQASM 3 program.
**Return type**
[QuantumCircuit](qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit")
**Raises**
[**QASM3ImporterError**](#qiskit.qasm3.QASM3ImporterError "qiskit.qasm3.QASM3ImporterError") if the OpenQASM 3 file is invalid, or cannot be represented by a [`QuantumCircuit`](qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit").
</Function>
### loads
<Function id="qiskit.qasm3.loads" github="https://github.com/qiskit/qiskit/tree/stable/0.24/qiskit/qasm3/__init__.py" signature="loads(program)">
Load an OpenQASM 3 program from the given string.
**Parameters**
**program** (*str*) the OpenQASM 3 program.
**Returns**
a circuit representation of the OpenQASM 3 program.
**Return type**
[QuantumCircuit](qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit")
**Raises**
[**QASM3ImporterError**](#qiskit.qasm3.QASM3ImporterError "qiskit.qasm3.QASM3ImporterError") if the OpenQASM 3 file is invalid, or cannot be represented by a [`QuantumCircuit`](qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit").
</Function>
Both of these two functions raise [`QASM3ImporterError`](#qiskit.qasm3.QASM3ImporterError "qiskit.qasm3.QASM3ImporterError") on failure.
### QASM3ImporterError
<Class id="qiskit.qasm3.QASM3ImporterError" github="https://github.com/qiskit/qiskit/tree/stable/0.24/qiskit/qasm3/exceptions.py" signature="QASM3ImporterError(*message)" modifiers="exception">
An error raised during the OpenQASM 3 importer.
Set the error message.
</Class>
For example, we can define a quantum program using OpenQASM 3, and use [`loads()`](#qiskit.qasm3.loads "qiskit.qasm3.loads") to directly convert it into a [`QuantumCircuit`](qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit"):
```python
import qiskit.qasm3
program = """
OPENQASM 3.0;
include "stdgates.inc";
input float[64] a;
qubit[3] q;
bit[2] mid;
bit[3] out;
let aliased = q[0:1];
gate my_gate(a) c, t {
gphase(a / 2);
ry(a) c;
cx c, t;
}
gate my_phase(a) c {
ctrl @ inv @ gphase(a) c;
}
my_gate(a * 2) aliased[0], q[{1, 2}][0];
measure q[0] -> mid[0];
measure q[1] -> mid[1];
while (mid == "00") {
reset q[0];
reset q[1];
my_gate(a) q[0], q[1];
my_phase(a - pi/2) q[1];
mid[0] = measure q[0];
mid[1] = measure q[1];
}
if (mid[0]) {
let inner_alias = q[{0, 1}];
reset inner_alias;
}
out = measure q;
"""
circuit = qiskit.qasm3.loads(program)
circuit.draw("mpl")
```
![../\_images/qasm3-1.png](/images/api/qiskit/0.43/qasm3-1.png)