# Example: Interfacing with Other Software

You can use the unique functionality of True-Q™ for projects developed in other quantum computing software libraries by converting objects created by those projects to True-Q™. You can also use functionality from other quantum computing software libraries by converting True-Q™ objects into their format. True-Q™ can natively convert to and from:

1. QASM A quantum assembly language used by many quantum hardware makers.

2. Qiskit IBM’s quantum computing software package.

3. Cirq Google’s quantum computing software package.

4. PyQuil Rigetti’s quantum computing software package.

Before converting a circuit to/from a software package, the first thing to consider is what gates you want the outputted circuit to use—since each software package is independently written, the primitive gates they each use may differ. By default, True-Q™ will recompile using only the gates supported by the software package. However, more advanced users can specify a subset of supported gates to compile into when converting between software platforms by using a custom configuration, as shown below.

Note

Before starting, make sure that you have installed the software that you want to convert from, by trying to import it into your Python notebook. If they are successfully installed, continue on to the next section. True-Q™ does not automatically install the third-party libraries from above, so if you want to use them you need to install them separately.

## Examples of Back and Forth Conversions

To get a feel for converting between True-Q™ and other software packages, we will show an example converting from True-Q™ to Cirq and back. Try constructing a circuit in True-Q™ then running to_cirq(), like this:

[2]:

import trueq as tq

# True-Q does not attempt to load the third party module---in this example, Cirq---until
# it is needed, for example by to_cirq(), or until load() is called. the method
# to_trueq() is attached to the third party library's circuit object at this time.

circuit = tq.Circuit({(0, 1): tq.Gate.cz})
circuit.draw(interactive=False)

cirq_circuit = circuit.to_cirq()
cirq_circuit

[2]:

(0, 0): ───@───
│
(1, 0): ───@───

Notice that the cirq_circuit object is a Cirq circuit, so the output for that object is drawn using Cirq’s visualization tools. If we want to convert back to True-Q™, we can use the following code and use draw() to draw a circuit diagram.

[3]:

circ = cirq_circuit.to_trueq()
circ.draw(interactive=False)

[3]:


In this case, we get back the same circuit that we initially converted to a Cirq object.

If we use a gate that is not directly available in Cirq in our circuit, the conversion will look a little different. For example, tq.Gate.cy is not supported by Cirq. Here’s what happens when we run the same steps as above for tq.Gate.cy:

[4]:

# construct and draw a TrueQ circuit
circuit = tq.Circuit({(0, 1): tq.Gate.cy})
circuit.draw(interactive=False)

# convert to Cirq and draw
cirq_circuit = circuit.to_cirq()
cirq_circuit

# convert back to TrueQ and draw
circ = cirq_circuit.to_trueq()
circ.draw(interactive=False)

[4]:


Notice that True-Q™’s compilation tools automatically rewrote the circuit in order to reflect the input accurately when converting to a different software platform. When we convert back, the circuit does not automatically get simplified back to its original form because True-Q™ supports any gate. This is where configuration files (see Example: Configuring Native Gates) come in handy; had we carefully specified which gates we wanted the final True-Q™ circuit to use, we could have ended with the original True-Q™ circuit.

For this example, we used the interface with Cirq, but we might also have used the analogous methods to_qiskit() and to_pyquil() to convert to and from Qiskit and PyQuil. Try these methods out and see if you can find examples of gates that are and are not supported by these other platforms.

## Interface Config

During conversion between representations in True-Q™ and other software packages, there is often a degeneracy in how a gate may be converted. For example, an identity gate could be written as Z(phi), X(phi), Y(phi), … with phi = 0.

In these cases, this degeneracy can be broken by setting the preferred order of gate conversion. This is done in the interfaces through a Config which contains a collection of GateFactorys. Each of these factories has the exact name and parameters of the corresponding gate representation in the external software. During the conversion of any specific gate from True-Q™ into the external software, each of these factories is used in order until the conversion is possible.

The default settings for all interfaces is to have the defined config contain all possible gates allowed in the external software, even though there are typically degeneracies. This default configuration is available through the default_config() method on every interface.

The current active config may be changed through the respective set_config() and get_config() which are also available on every interface.

Look at the config list for the interface between True-Q™ and Cirq:

[5]:

std_config = tq.interface.cirq.default_config()


Set a reduced config, containing only CNOT, XPowGate, and ZPowGate:

[6]:

tq.interface.cirq.set_config(["CNOT", "XPowGate", "ZPowGate"])


This may have also been set through a subset of the default config:

[7]:

tq.interface.cirq.set_config(std_config.subset(names=["CNOT", "XPowGate", "ZPowGate"]))


Convert the circuit defined above to Cirq using the updated config:

[8]:

circuit.to_cirq()

[8]:

(0, 0): ───X^0───X^0───S^-1───@───X^0───X^0───S───
│
(1, 0): ───X^0───X─────S──────X───X^0───X─────S───

Note

Setting the config to None resets to the default config.

Reset the config to the default:

[9]:

tq.interface.cirq.set_config(None)


Convert the circuit to Cirq using the default config

[10]:

circuit.to_cirq()

[10]:

(0, 0): ───H^0───H^0─────Rz(-0.5π)───@───H^0───H^0─────Rz(0.5π)───
│
(1, 0): ───H^0───Rx(π)───Rz(0.5π)────X───H^0───Rx(π)───Rz(0.5π)───

As you can see in the printed circuits, changing the config alters the gates used in converting from True-Q™ to other software. For example, removing the X gate from the config causes the interface to pick the next viable representation of this operation, so that the X gates are given as rotations about X by $$\pi$$.