Interfaces
Interfaces to external packages all operate under the same overall design strategy.
They are each subclassed off Interface
with a
standard set of functions to enable conversion to and from True-Q™. For convenience,
one instance of each inteface class is instantiated when True-Q™ is imported. 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
GateFactory
s 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.
- trueq.interface.cirq = <trueq.interface.cirq_interface.CirqInterface object>
An instance of the
CirqInterface
interface. This particular instance is used by theto_cirq()
converter, and also for the reverse convertercirq.Circuit.to_trueq()
.
- trueq.interface.pyquil = <trueq.interface.pyquil_interface.PyQuilInterface object>
An instance of the
PyQuilInterface
interface. This particular instance is used by theto_pyquil()
converter, and also for the reverse converterpyquil.Program.to_trueq()
.
- class trueq.interface.Executor(circuits, backend, filename=None, n_shots=128, max_submissions=None, overwrite=False, store_compiled=True)
A class to asynchronously submit a
CircuitCollection
to aqiskit.providers.Backend
.Since many Qiskit backends have a limit to the number of circuits that can be submitted in a single job, batching of circuits must be performed. True-Q™ circuit collections have support for batching circuits like this, see
batch()
.The
Executor
accepts a list of batched circuits (or just a list of circuits and batches them automatically), converts all circuits in each batch into the Qiskit circuit format, and submits each batch as a job to run on the specifiedbackend
. The executor then keeps track of the status of each job asynchronously, updating the status of each job periodically. The results of the input circuits are updated with results as each job finishes.Note
The executor uses rich display inside of Jupyter notebooks. Make sure you have
ipywidgets
installed, and that you have enabled the extensionpip install ipywidgets jupyter nbextension enable --py widgetsnbextension
Since most devices have a limit as to the number of jobs that can be active on a backend 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 ofmax_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_aer import AerSimulator from qiskit.providers.fake_provider import FakeMelbourneV2 # 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 = AerSimulator.from_backend(FakeMelbourneV2()) # 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.block() # circs.results.plot()
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".# 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.block() 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".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".SRBStreamlined Randomized BenchmarkingCliffords (0,)- Key:
-
- backend: aer_simulator_from(fake_melbourne)
- labels: (0,)
- protocol: SRB
- twirl: Cliffords on [0, 1]
Cliffords (1,)- Key:
-
- backend: aer_simulator_from(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.3e-03 (1.1e-04) 0.0013116004714736895, 0.00010715199796118072.9e-03 (1.7e-04) 0.0028629188253865567, 0.00016793071885101566${p}$Decay parameter of the exponential decay $Ap^m$.1.0e+00 (1.4e-04) 0.9982511993713684, 0.00014286933061490761.0e+00 (2.2e-04) 0.9961827748994846, 0.00022390762513468756${A}$SPAM parameter of the exponential decay $Ap^m$.1.0e+00 (8.1e-03) 1.0137033679136773, 0.0080773683157850569.8e-01 (1.0e-02) 0.9776469829140171, 0.010026522866775318RCALReadout CalibrationConfusion (0,) P(0 | 0) = 0.969
P(1 | 1) = 0.984
- Confusion Matrix:
- Key:
-
- backend: aer_simulator_from(fake_melbourne)
- batch: 1
- labels: (0, 1)
- protocol: RCAL
(1,) P(0 | 0) = 0.953
P(1 | 1) = 0.930
- Confusion Matrix:
- Key:
-
- backend: aer_simulator_from(fake_melbourne)
- batch: 1
- labels: (0, 1)
- protocol: RCAL
RCALReadout CalibrationConfusion (0,) P(0 | 0) = 0.961
P(1 | 1) = 0.969
- Confusion Matrix:
- Key:
-
- backend: aer_simulator_from(fake_melbourne)
- batch: 0
- labels: (0, 1)
- protocol: RCAL
(1,) P(0 | 0) = 0.969
P(1 | 1) = 0.961
- Confusion Matrix:
- Key:
-
- backend: aer_simulator_from(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
|None
) – The maximum number of batches allowed in a backend queue at any one time. IfNone
, we will ask the backend how many remaining queue positions you are allowed, which will depend on whether you have other jobs running.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.store_compiled (
bool
) – Whether to store (and save iffilename
is present) the compiled version of each circuit rather than the circuits as they were provided to this constructor. The compiled circuits are True-Q™ circuits after they have been compiled into the native gates of the givenbackend
, but before they have been converted into Qiskit circuits. Note that during Qiskit conversion full system barriers are added between cycles with unequal markers.
- property n_batches
The number of batches the circuits have been divided into.
int
- property backend
Qiskit backend where the circuits will be submitted.
- Type:
qiskit.providers.Backend
- property batches
A list of
CircuitCollection
s, each of which is submitted separately to the backend.- Type:
list
- block()
Blocks the main thread until all circuits have completed acquisition on the backend.
- property circuits
All submitted circuits.
- 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()
Saves the current
CircuitCollection
regardless of status of acquisition.
- 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.
- trueq.interface.QASM = <trueq.interface.qasm_interface.QASMInterface object>
An instance of the
QASMInterface
interface. This particular instance is used by theto_qasm()
converter.
- trueq.interface.qiskit = <trueq.interface.qiskit_interface.QiskitInterface object>
An instance of the
QiskitInterface
interface. This particular instance is used by theto_qiskit()
converter, and also for the reverse converterqiskit.QuantumCircuit()
.j
- 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.
- 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 topyquil.device.Qubit
s.classical_regs (
dict
ofpyquil.quilbase.Declare
s) – A dictionary containing all of thepyquil.quilbase.Declare
s, 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 bypyquil.quilbase.Measurement()
.
- 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 tocirq.Device
s.measure_mapping (
dict
) – A dictionary mapping True-Q™ labels to the name of a measurement as defined bycirq.measure()
.
- class CirqMeasure(tq_qubits, meas_name, invert)
- invert
Alias for field number 2
- meas_name
Alias for field number 1
- 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.
- class trueq.interface.metadata.QiskitMetadata(registers=None, mapping=None, meas_mapping=None)
Stores data not recorded in
Circuit
objects to enable lossless conversion.- Parameters:
registers (
list
) – A list of quantum and classicalqiskit.circuit.register.Register
s used by the circuit.mapping (
dict
) – A dictionary mapping True-Q™ qubit labels to tuples(idx_register, idx)
whereidx_register
is the index of the quantum register inregisters
andidx
is the index of theqiskit.Qubit
inside of the register.meas_mapping (
list
) – A list of triples(label, idx_register, idx)
wherelabel
is the True-Q™ label of the qubit being measured,idx_register
is the index of the classical register inregisters
where the result is assigned, andidx
is the index of theqiskit.Bit
inside of the register.
Interface
- class trueq.interface.base.Interface
Base class for interfaces to external software libraries or standards.
Each interface maintains a
Config
containing a collection ofGateFactory
s that the interface may build into. A complete collection of all gate conversions supported may be found in thedefault_config()
for the respective interface.In addition to this default config, an interface instance keeps track of a subset of the default 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()
andset_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 orX(0)
in the external standard, the first usable factory listed in the currently set config is used.- load()
Loads the library we are interfacing to (if any) and adds a method called to_trueq() to its circuit class.
- precompile(circuit, passes=None)
Precompiles a
Circuit
into the gates available in the external standard.- Parameters:
passes (
list
) – A list of compiler passes to use during the conversion, this defaults to theHARDWARE_PASSES
.
- Return type:
- abstract 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:
- abstract pair_from_trueq_circ(circuit, passes=None)
Returns a pair
(compiled_circuit, external_format)
wherecompiled_circuit
has typeCircuit
and is the givencircuit
after it has been compiled by this interface according toget_config()
and the givenpasses
, but immediately before it has been converted intoexternal_format
which has circuit type of the external library.- Parameters:
passes (
list
) – A list of compiler passes to use during the conversion, this defaults to theHARDWARE_PASSES
.
- Return type:
tuple
- from_trueq_circ(circuit, passes=None)
Converts a
Circuit
into the external standard, equal to the second element of a call topair_from_trueq_circ()
.- Parameters:
passes (
list
) – A list of compiler passes to use during the conversion, this defaults to theHARDWARE_PASSES
.
- abstract 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:
- set_config(config, strict=True)
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
) – TheConfig
which defines the gates to build into.strict (
bool
) – Whether the givenconfig
must be a subset of thedefault_config()
.
- get_config()
Gets the current configuration which defines the gates which the interface builds into.
- Return type:
- abstract 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:
- class trueq.interface.base.InterfaceProperties(name, version, attach_point)
Defines the external package to import, including the name of the package, the minimum required version, and optionally where to attach a
to_trueq()
function, which monkey patches the external circuit object to convert into aCircuit
.- attach_point
Alias for field number 2
- name
Alias for field number 0
- version
Alias for field number 1
Cirq
- class trueq.interface.cirq_interface.CirqInterface
An interface to the Cirq library.
- set_config(config=None)
Defines the gates which the Cirq interface should build into, accepting any of the following
A subset of the config defined in the
default_config()
.None
, which will set the config to thedefault_config()
.- A list of factory names which are a subset of the factory names in the
default_config()
.
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()
- to_trueq_circ(cirq_circ)
Converts a
cirq.Circuit
into aCircuit
.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 (seefrom_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
)
- pair_from_trueq_circ(circuit, metadata=None, passes=None, device=None, join_meas=True)
Returns a pair
(compiled_circuit, cirq_circuit)
wherecompiled_circuit
has typeCircuit
and is the givencircuit
after it has been compiled by this interface according toget_config()
and the givenpasses
, but immediately before it has been converted intocirq_circuit
which has typecirq.Circuit
.- Parameters:
passes (
list
) – A list of compiler passes to use during the conversion, this defaults to theHARDWARE_PASSES
.
- Return type:
tuple
- from_trueq_circ(circuit, metadata=None, passes=None, device=None, join_meas=True)
Converts a
Circuit
into acirq.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()
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 theCompiler
.See also
pair_from_trueq_circ
.- 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 theHARDWARE_PASSES
.device (
None
orcirq.Device
) – Acirq.Device
, if no device is provided, an unconstrained device withcirq.GridQubit
is assumed.join_meas (
bool
) – This determines ifMeas
are joined into singlecirq.meas()
objects, or single meas object in parallel in the given moment/cycle.
- Return type:
cirq.Circuit
- to_trueq_gate(other_gate)
Converts a
Cirq
gate operation into aGate
.- Parameters:
other_gate – A
Cirq
gate.- Return type:
PyQuil
- class trueq.interface.pyquil_interface.PyQuilInterface
An interface to the PyQuil library.
- set_config(config=None)
Defines the gates which the PyQuil interface should build into, accepting any of the following
A subset of the config defined in the
default_config()
.None
, which will set the config to thedefault_config()
.- A list of factory names which are a subset of the factory names in the
default_config()
.
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()
- to_trueq_circ(program)
Converts a
pyquil.Program
into aCircuit
.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 (seefrom_trueq_circ()
).- Parameters:
program (
pyquil.Program
) – The pyquil program to be converted into a True-Q™ circuit.- Return type:
tuple
of (Circuit
,PyQuilMetadata
)
- pair_from_trueq_circ(circuit, metadata=None, passes=None)
Returns a pair
(compiled_circuit, pyquil_circuit)
wherecompiled_circuit
has typeCircuit
and is the givencircuit
after it has been compiled by this interface according toget_config()
and the givenpasses
, but immediately before it has been converted intopyquil_circuit
which has typepyquil.Program
.- Parameters:
passes (
list
) – A list of compiler passes to use during the conversion, this defaults to theHARDWARE_PASSES
.
- Return type:
tuple
- from_trueq_circ(circuit, metadata=None, passes=None)
Converts a
Circuit
into apyquil.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: ZX: -90.00 IX: 90.00 ZI: 90.00 1.00 1.00 1.00 1.00 CX CX See also
pair_from_trueq_circ()
.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 theCompiler()
.- 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 namedro
.passes (
list
) – A list of compiler passes to use during the conversion, this defaults to theHARDWARE_PASSES
.
- Return type:
pyquil.Program
- static defgate_to_factory(defgate)
Converts a PyQuil
DefGate
into aGateFactory
.- Parameters:
defgate (
DefGate
) – TheDefGate
to convert.- Return type:
- to_trueq_gate(other_gate, config=None)
Converts a
PyQuil
Gate into aNativeGate
.- Parameters:
- Return type:
- default_config()
Returns a
Config
containing a definition of allPyQuil
gates which True-Q™ is able to convert into.- Returns:
- config_from_isa(isa)
Construct a
Config
containing the definitions for PyQuil gates as specified by a PyQuilpyquil.external.rpcq.CompilerISA
.- Parameters:
isa (
pyquil.external.rpcq.CompilerISA
) – Apyquil.external.rpcq.CompilerISA
object defined in PyQuil.
- 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
) – Apyquil.external.rpcq.CompilerISA
object defined in PyQuil.
Qiskit
- class trueq.interface.qiskit_interface.QiskitInterface
An interface to the Qiskit library.
- set_config(config=None)
Defines the gates which the Qiskit interface should build into, accepting any of the following:
A subset of the config defined in the
default_config()
.None
, which will set the config to thedefault_config()
.- A list of factory names which are a subset of the factory names in the
default_config()
.
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()
- to_trueq_circ(qk_circuit)
Converts a
qiskit.QuantumCircuit
into aCircuit
.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 (seefrom_trueq_circ()
).Note
Barriers are not preserved, and measurements are always placed at the end of the circuits.
- Parameters:
qk_circuit (
qiskit.QuantumCircuit
) – A Qiskit circuit representation of a circuit.- Return type:
tuple
of (Circuit
,QiskitMetadata
)
- pair_from_trueq_circ(circuit, metadata=None, passes=None)
Returns a pair
(compiled_circuit, qiskit_circuit)
wherecompiled_circuit
has typeCircuit
and is the givencircuit
after it has been compiled by this interface according toget_config()
and the givenpasses
, but immediately before it has been converted intoqiskit_circuit
which has typeqiskit.circuit.quantumcircuit.QuantumCircuit
.- Parameters:
metadata (
QiskitMetadata
|None
) – The metadata detailing how qubits and registers get mapped.passes (
list
) – A list of compiler passes to use during the conversion, this defaults to theHARDWARE_PASSES
.
- Return type:
tuple
- from_trueq_circ(circuit, metadata=None, passes=None)
Converts a
Circuit
into anqiskit.circuit.quantumcircuit.QuantumCircuit
.See also
pair_from_trueq_circ
.- Parameters:
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 theHARDWARE_PASSES
.
- Return type:
qiskit.circuit.quantumcircuit.QuantumCircuit
- to_trueq_gate(other_gate)
Converts a
Qiskit
gate into aNativeGate
.- Parameters:
other_gate – A gate which is defined by the external standard.
- Returns:
- default_config()
Returns a
Config
containing a definition of allQiskit
gates which True-Q™ is able to convert into.- Returns:
- 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
)
- 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.
from trueq.interface import qiskit as tqk from qiskit_aer import AerSimulator from qiskit.providers.fake_provider import FakeMelbourneV2 backend = AerSimulator.from_backend(FakeMelbourneV2()) tqk.set_from_backend(backend)
Mode: ZXZXZ Dimension: 2 Gates: - 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] - RZGate(phi): Hamiltonian: - [Z, 57.29577951308232*phi] - XGate: Hamiltonian: - [X, 180.0] - SXGate: Hamiltonian: - [X, 90.0] - IGate: Hamiltonian: - [I, 0.0]
- Parameters:
backend (
qiskit.provider.BaseBackend
) – A backend from Qiskit.- Return type:
- 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.
from trueq.interface import qiskit as tqk from qiskit_aer import AerSimulator from qiskit.providers.fake_provider import FakeMelbourneV2 backend = AerSimulator.from_backend(FakeMelbourneV2()) tqk.config_from_backend(backend)
Mode: ZXZXZ Dimension: 2 Gates: - 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] - RZGate(phi): Hamiltonian: - [Z, 57.29577951308232*phi] - XGate: Hamiltonian: - [X, 180.0] - SXGate: Hamiltonian: - [X, 90.0] - IGate: Hamiltonian: - [I, 0.0]
- Parameters:
backend (
qiskit.provider.BaseBackend
) – A backend from Qiskit.- Returns:
A config which contains gates and topology of a given backend.
- Return type:
QASM
- class trueq.interface.qasm_interface.QASMInterface
Interface class to convert
Circuit
s 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 supportsConfig
objects which contain any one or two qubit fixed gates, as well as any of the following parameterized single qubit operations:Pauli rotation on a single qubit.
This config the interface uses may be altered via
set_config()
andget_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 throughQELIB1()
.import trueq as tq circ = tq.make_xrb([0], [5], 1)[0] print(circ.to_qasm())
// True-Q Version: 2.14.5 // Circuit Key: // {'measurement_basis': ('trueq.math.Weyls', {'dim': 2, 'powers': array([[1, 0]], dtype=uint64)}), 'n_random_cycles': 5, 'protocol': 'XRB', 'seq_label': 1122, '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(1.5707963267948966,3.141592653589793,3.141592653589793) q[0]; barrier q; U(1.5707963267948966,0.0,1.5707963267948966) q[0]; barrier q; U(3.141592653589793,-3.141592653589793,0.0) q[0]; barrier q; U(1.5707963267948966,3.141592653589793,3.141592653589793) 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.14.5 // Circuit Key: // {'measurement_basis': ('trueq.math.Weyls', {'dim': 2, 'powers': array([[1, 0]], dtype=uint64)}), 'n_random_cycles': 5, 'protocol': 'XRB', 'seq_label': 2923, '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,1.5707963267948966) q[0]; barrier q; u2(0.0,-0.0) q[0]; barrier q; u3(3.141592653589793,-0.0,0.0) q[0]; barrier q; u3(3.141592653589793,-1.5707963267948966,0.0) q[0]; barrier q; u2(1.5707963267948966,0.0) q[0]; barrier q; measure q[0] -> c[0];
- 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:Pauli rotation on a single qubit.
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.
- 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
- from_trueq_gate(labels, gate)
Converts a
Gate
into a QASM gate in the currently specified QASM respresentation as defined byget_config()
.
- pair_from_trueq_circ(circuit, custom_header=None, include_auto_header=True, passes=None)
Returns a pair
(compiled_circuit, qasm_str)
wherecompiled_circuit
has typeCircuit
and is the givencircuit
after it has been compiled by this interface according toget_config()
and the givenpasses
, but immediately before it has been converted intoqasm_str
which is a QASM 2.0 string.- Parameters:
passes (
list
) – A list of compiler passes to use during the conversion, this defaults to theHARDWARE_PASSES
.
- Return type:
tuple
- 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 settinginclude_auto_header=False
). Additional lines in the header can be included by providing a list of strings tocustom_header
, which will be appended as new lines at the top of the file.See also
pair_from_trueq_circ
.Note
Barriers are added into the QASM string when there is a marker change between two sequential
Cycle
s.- 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 theget_config
is not the qelib1 config, then QASM requires all gates present to be written as combinations ofU3
andCNOT
gates (see the docs forQASM
, 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 theHARDWARE_PASSES
.
- Return type:
str
- to_trueq_circ(other_circ)
Loads a QASM 2.0 string, and returns a
tuple
containing theCircuit
and the parsedConfig
, 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: lam: 0.00 phi: 0.00 theta: 1.91 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 ZZ: -63.64 IZ: 63.64 ZX: -63.64 IX: 63.64 1.00 1.00 0.71 0.71 0.71 -0.71 CH CH Labels: (0, 1, 2) Name: ccx Parameters: Generators: ZZX: 45.00 ZIX: -45.00 IZX: -45.00 IIX: 45.00 ZZI: -45.00 ZII: 45.00 IZI: 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: ZX: -90.00 IX: 90.00 ZI: 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 futureCycle
s in the circuit will have their markers incremented.The operations
opaque
andif
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
- 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
- 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:
- QELIB1()
Returns a
Config
which contains the gates found in theqelib1
library commonly used in QASM representations.See: https://github.com/Qiskit/openqasm/blob/OpenQASM2.x/examples/qelib1.inc
- Return type:
- 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 inqelib1
.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: lam: 0.00 phi: 0.00 theta: 1.91 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 ZZ: -63.64 IZ: 63.64 ZX: -63.64 IX: 63.64 1.00 1.00 0.71 0.71 0.71 -0.71 CH CH Labels: (0, 1, 2) Name: ccx Parameters: Generators: ZZX: 45.00 ZIX: -45.00 IZX: -45.00 IIX: 45.00 ZZI: -45.00 ZII: 45.00 IZI: 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: ZX: -90.00 IX: 90.00 ZI: 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 definedbarriers
.When a QASM
barrier
is encountered, all futureCycle
s 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
andif
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 parameterizedU
gate and the fixedCX
gate.- Type:
dict
- 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: