Interfaces

Interfaces to external packages all operate under the same overall design strategy. They are each subclassed off Interface and are each a singleton class with a standard set of functions to enable conversion to and from True-Q™. Each interface defines a default_config(), which is a Config object defining gates which True-Q™ can convert into.

However, these default config objects typically have multiple GateFactorys that implement the same Gate for different parameters. For example Identity is a special case of both Z(phi) and X(phi) when phi=0. Each interface fixes this degeneracy by preferentially converting using the ordering of the factories present in a set config. What this means is that if the config for a given interface contains both a GateFactory for an X(phi) rotation followed by a factory for an I gate, and a True-Q™ gate representing the identity is converted using that interface, then the interface will preferentially convert the gate into a X(0) gate in the external format.

The currently set config may be accessed on any interface via the get_config() method, which will return a config containing the factories in the preferred order of conversion. This config may be set through the set_config().

When an interface is successfully loaded, Circuit gets additional functionality in the form of a Circuit.to_<interface>(), which will convert the True-Q™ circuit representation into the representation of the external package. By altering the set config for the specified package, the user can select specific gates to build into by default.

class trueq.interface.metadata.Metadata(mapping=None)

Stores data not recorded in Circuit objects to enable lossless conversion.

Parameters

mapping (dict) – A dictionary mapping True-Q™ qubit labels to the indexing of the target framework.

Interface

class trueq.interface.base.Interface

Base class for interfaces to external software libraries or standards.

Each interface maintains a Config containing a collection of GateFactorys that the interface may build into. A complete collection of all gate conversions supported may be found in the default_config() for the respective interface.

In addition to this default config, the interfaces each keep track of a subset of this config which defines the current gates they will preferentially build into. This active subset of the default config may be manipulated via the get_config() and set_config() defined by each interface.

When there is a possible degeneracy in the conversions, such as when converting an identity gate into either an I gate or X(0) in the external standard, the first usable factory listed in the currently set config is used.

The interfaces rely on introspection of the external software to build the possible gate conversions, in many cases when new gates are added to an external package the True-Q™ interface will automatically support the conversion without any required changes.

All software interfaces to True-Q™ are subclassed off of this class.

abstract classmethod to_trueq_circ(other_circuit)

Converts a circuit defined through the external standard into a Circuit.

Parameters

other_circuit – A circuit which is defined in the external standard.

Return type

Circuit

abstract classmethod from_trueq_circ(circuit, passes=None)

Converts a Circuit into the external standard.

Parameters
  • circuit (Circuit) – The Circuit to be converted.

  • passes (list) – A list of compiler passes to use during the conversion, this defaults to the HARDWARE_PASSES.

abstract classmethod to_trueq_gate(other_gate)

Converts a gate defined through the external standard into a NativeGate.

Parameters

other_gate – A gate which is defined in the external standard.

Return type

NativeGate

abstract classmethod from_trueq_gate(labels, gate)

Converts a Gate into an external standard.

Parameters
  • labels (tuple) – A tuple of labels on which the gate operates.

  • gate (Gate) – The Gate to be converted.

abstract classmethod set_config(config)

Sets the config containing the gates which the interface should build into, this config must be a subset of the default_config().

Parameters

config (Config) – The Config which defines the gates to build into.

classmethod get_config()

Gets the current configuration which defines the gates which the interface builds into.

Return type

Config

abstract classmethod default_config()

Returns a config which contains all of the available gate conversions present in the interface.

Gates present in this config are defined exactly one-to-one equivalent to the gate in the external standard, including the naming convention for the gate and parameters (if present).

Return type

Config

Cirq

class trueq.interface.cirq
classmethod set_config(config=None)

Defines the gates which the Cirq interface should build into, accepting any of the following

import trueq as tq
# convert strictly into these gates:
tq.interface.cirq.set_config(["CX", "XPowGate", "ZPowGate"])

# reset and allow any gates available
tq.interface.cirq.set_config()
Parameters

config (Config | NoneType | list) – The Config which defines the gates to build into.

classmethod to_trueq_circ(cirq_circ)

Converts a cirq.Circuit into a Circuit.

This returns a tuple of the True-Q™ circuit and a CirqMetadata which contains information present in the Cirq circuit which is not represented in True-Q™ circuits and is required for the reverse conversion (see from_trueq_circ()).

Note

Measurements are always placed at the end of the circuit.

Currently only supports Cirq circuits using GridQubits.

Parameters

cirq_circ – A Cirq representation of a circuit.

Type

cirq.Circuit

Return type

tuple of (Circuit, CirqMetadata)

classmethod from_trueq_circ(circuit, metadata=None, passes=None, device=None, join_meas=True)

Converts a Circuit into a cirq.Circuit.

import trueq as tq

# A round trip, to cirq and back
circ = tq.Circuit([{(0, 1): tq.Gate.cx}])
cirq_circ = tq.interface.cirq.from_trueq_circ(circ)
cirq_circ.to_trueq().draw()
0 1 Key: 1 Labels: (0, 1) Name: Gate.cx Aliases: Gate.cx Gate.cnot Locally Equivalent: CNOT Generators: ZI: 90.00 IX: 90.00 ZX: -90.00 1.00 1.00 1.00 1.00 CX CX

Note

By default, arbitrary single-qubit operations are decomposed using the ZXZ QubitMode by default. This may be changed by setting the config to have another mode.

If a gate is provided which is not directly equivalent to a single gate in get_config(), it is decomposed using the Compiler.

Parameters
  • circuit (Circuit) – The True-Q™ circuit to be converted into a Cirq circuit.

  • metadata (CirqMetadata) – Metadata required to accurately reproduce the original Cirq circuit. If this is not provided, measurements are added at the end of the circuit.

  • passes (list) – A list of compiler passes to use during the conversion, this defaults to the HARDWARE_PASSES.

  • device (None or cirq.Device) – A cirq.Device, if no device is provided, an unconstrained device with cirq.GridQubit is assumed.

  • join_meas (bool) – This determines if Meas are joined into single cirq.meas() objects, or single meas object in parallel in the given moment/cycle.

Return type

cirq.Circuit

classmethod to_trueq_gate(other_gate)

Converts a Cirq gate operation into a Gate.

Parameters

other_gate – A Cirq gate.

Return type

Gate

classmethod from_trueq_gate(labels, gate)

Converts a Gate into a Cirq gate.

Parameters
  • labels (tuple) – A tuple of labels on which the gate operates.

  • gate (Gate) – The Gate to be converted.

classmethod default_config()

Returns a Config containing a definition of all Cirq gates which True-Q™ is able to convert into.

Return type

Config

class trueq.interface.metadata.CirqMetadata(mapping=None, measure_mapping=None)

Stores data not recorded in Circuit objects to enable lossless conversion.

Note

Measurements recorded in cirq.Circuit objects are always assumed to be placed at the end of the circuit.

If no measurements are provided through measure_mapping, then Measurements are automatically added on all qubits

Parameters
  • mapping (dict) – A dictionary mapping True-Q™ qubit labels to cirq.Devices.

  • measure_mapping (dict) – A dictionary mapping True-Q™ labels to the name of a measurement as defined by cirq.measure().

class CirqMeasure(tq_qubits, meas_name, invert)
property invert

Alias for field number 2

property meas_name

Alias for field number 1

property tq_qubits

Alias for field number 0

measure(tq_qubits, meas_name=None, invert=())

Adds a record of a measurement on a given qubit.

This assumes that all measurements happen at the end of the circuit.

Parameters
  • tq_qubits (list) – A list of True-Q™ label tuples for the qubits.

  • meas_name (str) – The name of the measurement in Cirq.

  • invert (Iterable) – Bitmask of whether the output of the measurement is expected to be inverted, see the Cirq documentation on measurements for more information.

PyQuil

class trueq.interface.pyquil
classmethod set_config(config=None)

Defines the gates which the PyQuil interface should build into, accepting any of the following

import trueq as tq
# convert strictly into these gates:
tq.interface.pyquil.set_config(["CNOT", "RX", "RZ"])

# reset and allow any gates available
tq.interface.pyquil.set_config()
Parameters

config (Config) – The Config which defines the gates to build into.

classmethod to_trueq_circ(program)

Converts a pyquil.Program into a Circuit.

This returns a tuple of the True-Q™ circuit and a PyQuilMetadata which contains information present in the PyQuil program which is not represented in True-Q™ circuits and is required for the reverse conversion (see from_trueq_circ()).

Parameters

program (pyquil.Program) – The pyquil program to be converted into a True-Q™ circuit.

Return type

tuple of (Circuit, PyQuilMetadata)

classmethod from_trueq_circ(circuit, metadata=None, passes=None)

Converts a Circuit into a pyquil.Program.

import pyquil
import trueq as tq

circ = tq.Circuit([{(0, 1): tq.Gate.cx}])

ext_circ = tq.interface.pyquil.from_trueq_circ(circ)

ext_circ.to_trueq().draw()
0 1 Key: Labels: (0, 1) Name: CNOT Aliases: Gate.cx Gate.cnot Parameters: Locally Equivalent: CNOT Generators: ZI: 90.00 IX: 90.00 ZX: -90.00 1.00 1.00 1.00 1.00 CX CX

Note

Arbitrary single-qubit operations are decomposed using the ZXZXZ QubitMode by default.

If an SU(4) gate is provided which is not directly equivalent to a single gate in default_config(), it is decomposed using the Compiler().

Parameters
  • circ (Circuit) – The True-Q™ circuit to be converted into a PyQuil Program.

  • metadata (PyQuilMetadata | NoneType) – Metadata required to accurately reproduce the original PyQuil program. If no metadata is provided, measurements are read into a classical register named ro.

  • passes (list) – A list of compiler passes to use during the conversion, this defaults to the HARDWARE_PASSES.

Return type

pyquil.Program

classmethod to_trueq_gate(other_gate, config=None)

Converts a PyQuil Gate into a NativeGate.

Parameters
  • other_gate – A gate which is defined by the PyQuil.

  • config (Config) – The Config which defines the gates to build into.

Return type

NativeGate

classmethod from_trueq_gate(labels, gate)

Converts a Gate into a PyQuil gate.

Parameters
  • labels (tuple) – A tuple of labels on which the gate operates.

  • gate (Gate) – The Gate to be converted.

classmethod default_config()

Returns a Config containing a definition of all PyQuil gates which True-Q™ is able to convert into.

Returns

Config

classmethod config_from_isa(isa)

Construct a Config containing the definitions for PyQuil gates as specified by a PyQuil pyquil.external.rpcq.CompilerISA.

Parameters

isa (pyquil.external.rpcq.CompilerISA) – A pyquil.external.rpcq.CompilerISA object defined in PyQuil.

classmethod set_from_isa(isa)

Defines the gates which the PyQuil interface should build into as defined by a PyQuil pyquil.external.rpcq.CompilerISA.

Parameters

isa (pyquil.external.rpcq.CompilerISA) – A pyquil.external.rpcq.CompilerISA object defined in PyQuil.

class trueq.interface.metadata.PyQuilMetadata(mapping=None, classical_regs=None, measure_mapping=None)

Stores data not recorded in Circuit objects to enable lossless conversion.

Note

Measurements recorded in pyquil.Program objects are always assumed to be placed at the end of the circuit.

Parameters
  • mapping (dict) – A dictionary mapping True-Q™ qubit labels to pyquil.device.Qubits.

  • classical_regs (dict of pyquil.quilbase.Declares) – A dictionary containing all of the pyquil.quilbase.Declares, where the keys are the names of the classical registers.

  • measure_mapping (dict) – A dictionary mapping True-Q™ labels to the name of a measurement as defined by pyquil.quilbase.Measurement().

Qiskit

class trueq.interface.qiskit
classmethod set_config(config=None)

Defines the gates which the Qiskit interface should build into, accepting any of the following:

import trueq as tq
# convert strictly into these gates:
tq.interface.qiskit.set_config(["CXGate", "RXGate", "RZGate"])

# reset and allow any gates available
tq.interface.qiskit.set_config()
Parameters

config (Config) – The Config which defines the gates to build into.

classmethod to_trueq_circ(other_circuit)

Converts a qiskit.QuantumCircuit into a Circuit.

This returns a tuple of the True-Q™ circuit and a QiskitMetadata which contains information present in the Qiskit circuit which is not represented in True-Q™ circuits and is required for the reverse conversion (see from_trueq_circ()).

Note

Barriers are not preserved, and measurements are always placed at the end of the circuits.

Parameters

other_circuit (qiskit.QuantumCircuit) – A Qiskit circuit representation of a circuit.

Return type

tuple of (Circuit, QiskitMetadata)

classmethod from_trueq_circ(circuit, metadata=None, passes=None)

Converts a Circuit into an external standard.

Parameters
  • circuit (Circuit) – The Circuit to be converted.

  • metadata (QiskitMetadata) – Metadata required to accurately reproduce the original Qiskit circuit.

  • passes (list) – A list of compiler passes to use during the conversion, this defaults to the HARDWARE_PASSES.

classmethod to_trueq_gate(other_gate)

Converts a Qiskit gate into a NativeGate.

Parameters

other_gate – A gate which is defined by the external standard.

Returns

Operation

classmethod from_trueq_gate(labels, gate)

Converts a Gate into a Qiskit gate.

Parameters
  • labels (tuple) – A tuple of labels on which the gate operates.

  • gate (Gate) – The Gate to be converted.

classmethod default_config()

Returns a Config containing a definition of all Qiskit gates which True-Q™ is able to convert into.

Returns

Config

classmethod qiskit_dag_to_tq_circ(dag)

Takes a Qiskit DAG and convert it into a True-Q™ Circuit.

Note

Barriers are not preserved, and measurements are always placed at the end of the circuits.

Parameters

dag (qiskit.dagcircuit.DAGCircuit) – A Qiskit DAG representation of a circuit.

Returns

the exact input required by from_trueq_circ(), see that function for a full description of values returned.

Return type

tuple of (Circuit, QiskitMetadata)

classmethod set_from_backend(backend)

Sets the active config for the interface to one compatible with the target backend.

This returns the active config after it is set.

import qiskit as qk
from trueq.interface import qiskit as tqk
from qiskit.test import ibmq_mock

tqk.set_from_backend(ibmq_mock.backend_mocks.FakeMelbourne())
Mode: ZXZXZ
Dimension: 2
Gates:
- IGate:
    Hamiltonian:
    - [I, 0]
- U3Gate(theta, phi, lam):
    Hamiltonian:
    - [Z, 57.29577951308235*phi]
    - [Y, 57.295779513082294*theta]
    - [Z, 57.29577951308192*lam]
- CXGate:
    Matrix:
    - [1.0, 0.0, 0.0, 0.0]
    - [0.0, 1.0, 0.0, 0.0]
    - [0.0, 0.0, 0.0, 1.0]
    - [0.0, 0.0, 1.0, 0.0]
- U1Gate(theta):
    Hamiltonian:
    - [Z, 57.29577951308232*theta]
- U2Gate(phi, lam):
    Hamiltonian:
    - [Z, 57.29577951308235*phi]
    - [X, 57.29577951308237*lam]
    - [Y, 90.0]
Parameters

backend (qiskit.provider.BaseBackend) – A backend from Qiskit.

Return type

Config

classmethod config_from_backend(backend)

Takes an IBM Backend and converts it into a Config object.

The resulting config will contain the chip topology constraints as well as the gates themselves.

import qiskit as qk
from trueq.interface import qiskit as tqk
from qiskit.test import ibmq_mock

tqk.config_from_backend(ibmq_mock.backend_mocks.FakeMelbourne())
Mode: ZXZXZ
Dimension: 2
Gates:
- IGate:
    Hamiltonian:
    - [I, 0]
- U3Gate(theta, phi, lam):
    Hamiltonian:
    - [Z, 57.29577951308235*phi]
    - [Y, 57.295779513082294*theta]
    - [Z, 57.29577951308192*lam]
- CXGate:
    Matrix:
    - [1.0, 0.0, 0.0, 0.0]
    - [0.0, 1.0, 0.0, 0.0]
    - [0.0, 0.0, 0.0, 1.0]
    - [0.0, 0.0, 1.0, 0.0]
- U1Gate(theta):
    Hamiltonian:
    - [Z, 57.29577951308232*theta]
- U2Gate(phi, lam):
    Hamiltonian:
    - [Z, 57.29577951308235*phi]
    - [X, 57.29577951308237*lam]
    - [Y, 90.0]
Parameters

backend (qiskit.provider.BaseBackend) – A backend from Qiskit.

Returns

A config which contains gates and topology of a given backend.

Return type

Config

class trueq.interface.Executor(circuits, backend, filename=None, n_shots=128, max_submissions=5, overwrite=False)

A class to asynchronously submit a CircuitCollection to a qiskit.providers.Backend.

Since current hardware devices have a limit to the number of circuits that can be run at any one time, batching of circuits must be performed. An example of this is the ibmqx2 chip provided by IBM, it has a stated limit of 75 circuits which may be submitted to it at any one time. This means that if a user wishes to submit more than 75 circuits, the total collection of circuits needs to be broken up into groups (or batches) of no more than 75 circuits. True-Q™ circuit collections have native support for batching circuits like this, see batch().

The Executor converts batched circuits into Qiskit formatted objects, and submits them to the provided backend as jobs on the physical devices. The executor then keeps track of the status of each job asynchronously, updating the status periodically as to where the jobs are in the device’s queue.

Since most devices have a limit as to the number of batches that can be submitted by one user at any given time, the executor will only submit up to a max_submissions number of batches at any one time. Once a batch has run on the device, and has been removed from the job queue, the executor will place another batch into the queue until there are a total of max_submissions submitted jobs at any one time.

Here is a worked example, where a simple circuit is submitted to the IBMQ simulator backend:

import trueq as tq
import qiskit as qk
from qiskit.test import ibmq_mock

# loading IBMQ account and selecting a backend
# qk.IBMQ.load_account()
# provider = qk.IBMQ.get_provider()
# backend = provider.get_backend('ibmq_qasm_simulator')
# using a mock device as an example
backend = ibmq_mock.backend_mocks.FakeMelbourne()

# Generating a simple circuit of only the H gate
circs = tq.Circuit([{0: tq.Gate.h}, {0: tq.Meas()}])

# The handling of the submission of the circuits
ex = tq.interface.Executor(circs, backend)

# This is a blocking operation, and will block until all data has been acquired
ex.results()
circs.results.plot()
../_images/interface_7_1.png
# A more complicated example using advanced batching options
circs2 = tq.make_srb((0, 1), [4, 64, 128])

# Batch the circuits into groups of 75, including readout calibration circuits
# in each batch
ro_circuits = tq.make_rcal([0, 1])
batches = circs2.batch(75, extra_circuits=ro_circuits)

ex2 = tq.interface.Executor(batches, backend)
ex2.results()
circs2.fit()
True-Q formatting will not be loaded without trusting this notebook or rerunning the affected cells. Notebooks can be marked as trusted by clicking "File -> Trust Notebook".
SRB
Streamlined Randomized Benchmarking
Cliffords
(0,)
Key:
  • backend: fake_melbourne
  • labels: (0,)
  • protocol: SRB
  • twirl: Cliffords on [0, 1]
Cliffords
(1,)
Key:
  • backend: fake_melbourne
  • labels: (1,)
  • protocol: SRB
  • twirl: Cliffords on [0, 1]
${e}_{F}$
The probability of an error acting on the targeted systems during a random gate.
1.2e-04 (5.3e-05)
0.00012328483041262883, 5.325205135411193e-05
1.2e-04 (6.1e-05)
0.00011885408331874237, 6.0865125496411834e-05
${p}$
Decay parameter of the exponential decay $Ap^m$.
1.0e+00 (7.1e-05)
0.9998356202261165, 7.100273513881592e-05
1.0e+00 (8.1e-05)
0.9998415278889083, 8.115350066188245e-05
${A}$
SPAM parameter of the exponential decay $Ap^m$.
1.0e+00 (5.4e-03)
1.0316014523534331, 0.005389975499488433
1.0e+00 (6.3e-03)
1.021636970403084, 0.006274370616098949
RCAL
Readout Calibration
Confusion
(0,) P(0 | 0) = 1.000
P(1 | 1) = 0.938
Confusion Matrix:
1.000 0.062 0.938
Key:
  • backend: fake_melbourne
  • batch: 1
  • labels: (0, 1)
  • protocol: RCAL
(1,) P(0 | 0) = 0.977
P(1 | 1) = 0.953
Confusion Matrix:
0.977 0.047 0.023 0.953
Key:
  • backend: fake_melbourne
  • batch: 1
  • labels: (0, 1)
  • protocol: RCAL
RCAL
Readout Calibration
Confusion
(0,) P(0 | 0) = 0.977
P(1 | 1) = 0.938
Confusion Matrix:
0.977 0.062 0.023 0.938
Key:
  • backend: fake_melbourne
  • batch: 0
  • labels: (0, 1)
  • protocol: RCAL
(1,) P(0 | 0) = 0.977
P(1 | 1) = 0.930
Confusion Matrix:
0.977 0.070 0.023 0.930
Key:
  • backend: fake_melbourne
  • batch: 0
  • labels: (0, 1)
  • protocol: RCAL
Parameters
  • circuits (CircuitCollection | Circuit | generator) –

    The circuits which are to be submitted to the Qiskit backend. Depending on what is submitted here, there are several possible outcomes:

    • Circuit

      It will be converted to a CircuitCollection. Results will be placed back inside of the original circuit object itself, and can be viewed as data is retrieved from the backend without having to wait.

    • CircuitCollection

      It will be batched using the maximum allowed batch size for the given backend. For very long circuits this may result in errors due to limited memory of the classical hardware which control the backend. If errors occur during the submission of a CircuitCollection, it is recommended to resubmit using the third submission type. Results are placed back inside of the original circuits as data is retrieved from the server.

    • batch

      The circuits will be batched exactly as given by the batch generator. This can be used to submit automatic readout correction circuits, see above example or batch() for more details about possible options. Results are placed inside original circuits as data comes in, note that some batching options may result in additional circuits being added to the collection.

  • backend (qiskit.providers.Backend) – The Qiskit backend to which the circuits will be submitted.

  • filename (str) – Optional filename where results will be saved. If this is provided the Executor will also be able to partially recover from a crash of the Python session, loss of internet, or other interruption in data acquisition.

  • n_shots (int) – The number of shots of the circuits to be aquired.

  • max_submissions (int) – The maximum number of batches allowed in a backend queue at any one time. This number is set by the backend provider and should be set here accordingly.

  • overwrite (bool) – Whether to overwrite the file on disk if it exists before these circuits are executed. Note that regardless of the value of this flag, after this first check, the file on disk will continually be updated as new results come in.

property n_shots

The number of shots to be aquired by the backend.

Type

int

property backend

Qiskit backend where the circuits will be submitted.

Type

qiskit.providers.Backend

property filename

The filename where circuits with results will be saved.

Type

str

property circuits

Batched CircuitCollection, if a single circuit was provided, it will have been converted into a CircuitCollection. See Executor documentation for more details.

Type

list

results()

Returns the CircuitCollection complete with results.

Note

This is a blocking operation, and once called you will have to wait until all circuits have completed acquisition on the backend.

This is not required to be called in order to get results, as results are automatically placed into the provided circuits when they are retrieved from the backend. This function is simply a means to force code to wait until the backend returns all of the results.

Return type

CircuitCollection

property status

A text representation for the current status of all jobs.

This is a string equivalent of the html output provided in jupyter.

Type

str

save(overwrite=False)

Saves the current CircuitCollection regardless of status of acquisition.

This is called automatically whenever a new batch is either submitted or retrieved from the backend.

Parameters

overwrite (bool) – Whether to force an overwrite of the existing file.

cancel()

Cancels all currently submitted jobs if possible.

It is recommended that this be run any time a submission mistake is made, as circuits that have been submitted to the backend will stay in queue otherwise.

class trueq.interface.metadata.QiskitMetadata(mapping=None, meas_pairs=None)

Stores data not recorded in Circuit objects to enable lossless conversion.

Parameters
  • mapping (dict) – A dictionary mapping True-Q™ qubit labels to qiskit.Qubits.

  • meas_pairs (list) – A list of pairs, each with type (qiskit.Qubit, qiskit.Bit), whose order matches that of meas_locs. This stores which classical register each quantum measurement is to be stored into.

QASM

class trueq.interface.QASM

Interface class to convert Circuits into the QASM 2.0 language.

QASM 2.0 only defines two possible gate operations natively:

  • U

    This is an arbitrary single qubit unitary with three free parameters.

  • CX

    This is a fixed two qubit gate, more commonly called CNOT.

A config containing these two gates is accessable via default_config(). Any other gates used in a QASM file must be defined as a subroutine using these two fundamental gates.

The QASM interface supports Config objects which contain any one or two qubit fixed gates, as well as any of the following parameterized single qubit operations:

  1. Pauli rotation on a single qubit.

  2. u1_factory

  3. u2_factory

  4. u3_factory

This config the interface uses may be altered via set_config() and get_config(), and gates defined by it will automatically be converted to QASM formatted gate definitions inside of the QASM header.

A commonly available standard library of QASM gates called QELIB1 can be accessed through QELIB1().

import trueq as tq
circ = tq.make_xrb([0], [5], 1)[0]
print(circ.to_qasm())
// True-Q Version: 2.10.3
// Circuit Key:
// {'measurement_basis': 'X', 'n_random_cycles': 5, 'protocol': 'XRB', 'seq_label': 1078, 'twirl': ('trueq.Twirl', {'dim': 2, (0,): 'C'})}
OPENQASM 2.0;

qreg q[1];
creg c[1];
U(1.5707963267948966,-1.5707963267948966,-1.5707963267948966) q[0];
barrier q;
U(0.0,3.141592653589793,0.0) q[0];
barrier q;
U(1.5707963267948966,-1.5707963267948966,-1.5707963267948966) q[0];
barrier q;
U(1.5707963267948966,1.5707963267948966,0.0) q[0];
barrier q;
U(1.5707963267948966,-3.141592653589793,0.0) q[0];
barrier q;
measure q[0] -> c[0];

Building into custom defined QASM gates:

import trueq as tq

zz_fact = tq.config.GateFactory.from_matrix("ZZ", tq.Gate.rp("ZZ", 90))
factories = [tq.interface.QASM.QELIB1().u1,
             tq.interface.QASM.QELIB1().u2,
             tq.interface.QASM.QELIB1().u3,
             zz_fact]
config = tq.Config(factories=factories)

tq.interface.QASM.set_config(config)

circ = tq.make_xrb([0], [5], 1)[0]
print(circ.to_qasm())
// True-Q Version: 2.10.3
// Circuit Key:
// {'measurement_basis': 'X', 'n_random_cycles': 5, 'protocol': 'XRB', 'seq_label': 1972, 'twirl': ('trueq.Twirl', {'dim': 2, (0,): 'C'})}
OPENQASM 2.0;
gate u1(lambda) q { U(0,0,lambda) q; }
gate u2(phi,lambda) q { U(pi/2,phi,lambda) q; }
gate u3(theta,phi,lambda) q { U(theta,phi,lambda) q; }
gate ZZ q0, q1
{
    U(0.0,3.141592653589793,0.0) q0;
    U(1.5707963267948966,-3.141592653589793,0.0) q1;
    CX q0,q1;
    U(0.0,1.5707963267948966,0.0) q0;
    U(1.5707963267948966,-1.5707963267948966,0.0) q1;
}
qreg q[1];
creg c[1];
u2(1.5707963267948966,0.0) q[0];
barrier q;
u1(-1.5707963267948966) q[0];
barrier q;
u3(3.141592653589793,-1.5707963267948966,0.0) q[0];
barrier q;
u2(3.141592653589793,-1.5707963267948966) q[0];
barrier q;
u3(3.141592653589793,-3.141592653589793,0.0) q[0];
barrier q;
measure q[0] -> c[0];
classmethod set_config(config=None)

Sets the Config which contains any one or two qubit fixed gates, as well as any of the following parameterized single qubit operations:

The provided config will automatically be converted to QASM compatible gate definitions inside of the QASM header and may be used inside of the QASM file itself.

Parameters

config (Config) – The config containing gate definitions that are desired for the QASM representation.

classmethod get_header()

Returns the lines of the header currently associated with the currently desired QASM representation as defined by the get_config().

Return type

str

classmethod from_trueq_gate(labels, gate)

Converts a Gate into a QASM gate in the currently specified QASM respresentation as defined by get_config().

Parameters
  • labels (tuple) – A tuple of labels on which the gate operates.

  • gate (Gate) – The Gate to be converted.

Return type

str

Raises

ValueError – If conversion is not possible.

classmethod from_trueq_circ(circuit, custom_header=None, include_auto_header=True, passes=None)

Converts a Circuit into a QASM 2.0 text string.

Circuits converted to QASM will use the gate definitions found in the get_config(). These definitions will by default be included at the top of the output QASM file (this behavior can be disabled by setting include_auto_header=False). Additional lines in the header can be included by providing a list of strings to custom_header, which will be appended as new lines at the top of the file.

Note

Barriers are added into the QASM string when there is a marker change between two sequential Cycles.

Parameters
  • circuit (Circuit) – The circuit to be converted to QASM.

  • custom_header (list) – A list of strings which will be put at the top of the file, with each string being placed on a seperate line.

  • include_auto_header (bool) – If the get_config is not the qelib1 config, then QASM requires all gates present to be written as combinations of U3 and CNOT gates (see the docs for QASM, for more details), this flag determines if these definitions should be included in the header of the QASM file.

  • passes (list) – A list of compiler passes to use during the conversion, this defaults to the HARDWARE_PASSES.

Return type

str

classmethod to_trueq_circ(other_circ)

Loads a QASM 2.0 string, and returns a tuple containing the Circuit and the parsed Config, as defined by the QASM string.

If the standard qelib1 library is included in the QASM string, then this is automatically loaded without requiring the associated file.

import trueq as tq
qasm_str = '''
    OPENQASM 2.0;
    include "qelib1";

    qreg q[3];
    creg c[3];

    u3(1.91063,0,0) q[0];
    ch q[0],q[1];
    ccx q[0],q[1],q[2];
    x q[0];
    x q[1];
    cx q[0],q[1];
'''
circ, config = tq.interface.QASM.to_trueq_circ(qasm_str)
circ.draw()
0 1 2 Key: qasm: 2.0 meas: () qregs: (('q', (0, 1, 2)),) cregs: (('c', (0, 1, 2)),) Labels: (0,) Name: u3 Parameters: theta: 1.91 phi: 0.00 lam: 0.00 Generators: Y: 109.47 0.58 -0.82 0.82 0.58 Labels: (0, 1) Name: ch Aliases: Gate.ch Parameters: Locally Equivalent: CNOT Generators: ZI: 90.00 IZ: 63.64 ZZ: -63.64 IX: 63.64 ZX: -63.64 1.00 1.00 0.71 0.71 0.71 -0.71 CH CH Labels: (0, 1, 2) Name: ccx Parameters: Generators: IZI: 45.00 ZIX: -45.00 ZZI: -45.00 IZX: -45.00 ZZX: 45.00 IIX: 45.00 ZII: 45.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 Labels: (0,) Name: x Aliases: Gate.x Gate.cliff1 Parameters: Generators: X: 180.00 1.00 1.00 X Labels: (1,) Name: x Aliases: Gate.x Gate.cliff1 Parameters: Generators: X: 180.00 1.00 1.00 X Labels: (0, 1) Name: cx Aliases: Gate.cx Gate.cnot Parameters: Locally Equivalent: CNOT Generators: ZI: 90.00 IX: 90.00 ZX: -90.00 1.00 1.00 1.00 1.00 CX CX

The QASM standard does not define the concept of a clock cycle, as a result of this the Circuit which is returned will have operations justified as far foward in time as is allowed.

When a QASM barrier is encountered, on either a single qubit or a collection of qubits, all future Cycles in the circuit will have their markers incremented.

The operations opaque and if are not currently supported by True-Q™ and will result in an exception being raised if encountered.

Parameters

other_circ (str) – A string containing a QASM file.

Return type

tuple

classmethod to_trueq_gate(other_gate)

Alias of to_trueq_circ(), see that method for more details.

Parameters

other_gate (str) – A string containing a QASM file.

Return type

tuple

classmethod default_config()

Returns a Config containing the two possible gate operations defined by QASM natively:

  • U

    This is an arbitrary single qubit unitary with three free parameters.

  • CX

    This is a fixed two qubit gate, more commonly called CNOT.

Return type

Config

classmethod QELIB1()

Returns a Config which contains the gates found in the qelib1 library commonly used in QASM representations.

See: https://github.com/Qiskit/openqasm/blob/OpenQASM2.x/examples/qelib1.inc

Return type

Config

class trueq.interface.qasm_parser.QASMParse(string)

Parser for QASM 2.0 strings. Calling any of this class’s attributes will parse the QASM text owned by this instance and populate all attributes of this instance with the information obtained from translating QASM to True-Q™.

If the standard qelib1 library is included in the QASM string, then this is automatically loaded without requiring the associated file. Below is an example QASM string which generates a circuit, utilizing some of the gates defined in qelib1.

import trueq as tq
qasm_str = '''
    OPENQASM 2.0;
    include "qelib1";

    qreg q[3];
    creg c[3];

    u3(1.91063,0,0) q[0];
    ch q[0],q[1];
    ccx q[0],q[1],q[2];
    x q[0];
    x q[1];
    cx q[0],q[1];
'''
parser = tq.interface.qasm_parser.QASMParse(qasm_str)
circuit = parser.circuit
circuit.draw()
0 1 2 Key: qasm: 2.0 meas: () qregs: (('q', (0, 1, 2)),) cregs: (('c', (0, 1, 2)),) Labels: (0,) Name: u3 Parameters: theta: 1.91 phi: 0.00 lam: 0.00 Generators: Y: 109.47 0.58 -0.82 0.82 0.58 Labels: (0, 1) Name: ch Aliases: Gate.ch Parameters: Locally Equivalent: CNOT Generators: ZI: 90.00 IZ: 63.64 ZZ: -63.64 IX: 63.64 ZX: -63.64 1.00 1.00 0.71 0.71 0.71 -0.71 CH CH Labels: (0, 1, 2) Name: ccx Parameters: Generators: IZI: 45.00 ZIX: -45.00 ZZI: -45.00 IZX: -45.00 ZZX: 45.00 IIX: 45.00 ZII: 45.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 Labels: (0,) Name: x Aliases: Gate.x Gate.cliff1 Parameters: Generators: X: 180.00 1.00 1.00 X Labels: (1,) Name: x Aliases: Gate.x Gate.cliff1 Parameters: Generators: X: 180.00 1.00 1.00 X Labels: (0, 1) Name: cx Aliases: Gate.cx Gate.cnot Parameters: Locally Equivalent: CNOT Generators: ZI: 90.00 IX: 90.00 ZX: -90.00 1.00 1.00 1.00 1.00 CX CX

The QASM standard does not define the concept of a clock cycle. As a result of this, the Circuit which is created will have operations justified as far foward in time as is allowed, respecting any defined barriers.

When a QASM barrier is encountered, all future Cycles in the circuit will have their markers incremented. Compiler passes obey markers, meaning future simplifications will only happen when neighboring cycles have matching markers. Thus, an incremented marker serves as an effective barrier. This further implies that partial barriers are not supported during the conversion to True-Q™; a barrier on a single qubit is translated as a barrier across all qubits in the circuit.

The operations opaque and if are not currently supported by True-Q™ and will result in an exception being raised if encountered.

Parameters

string (str) – A string of QASM 2.0 text to be parsed.

property string

The string of QASM text used to intialize this instance to be parsed. Accessing this attribute does not trigger parsing of the string.

Type

str

property version

The version of QASM parsed by this instance. Currently only OPENQASM 2.0 is supported.

Type

float

property meas

A list of the labels of all measured qubits in the parsed circuit.

Type

list

property n_clabels

The number of classical registers initialized during the parsing of this instance.

Type

int

property n_labels

The number of quantum registers (qubits) initialized during the parsing of this instance.

Type

int

property cregs

A dictionary with classical register names as the keys and allowed labels as the values, for each classical register initialized during parsing of this instance.

Type

dict

property qregs

A dictionary with quantum register names as the keys and allowed labels as the values, for each quantum register initialized during parsing of this instance.

Type

dict

property factories

A dictionary with gate alias keys and their associated GateFactory values, for each gate definition evaluated when parsing this instance. By default, QASM defines two factories, the parameterized U gate and the fixed CX gate.

Type

dict

property circuit

The circuit generated from parsing this instance.

Type

Circuit

property config

Config containing all of the gates defined inside of a parsed QASM string, where each parsed gate definition is translated as a GateFactory.

Type

Config