terminal
Docs

Hello Many Worlds in Seven Quantum Languages

Last updated: March 14, 2024
IonQ Staff

The incredible promise of quantum computing—to revolutionize industry, to tackle humanity’s most complex problems—is increasingly a point of consensus across academia, commerce, and government. But so, too, is the appreciation of the distance between where we are today and where we aspire to be tomorrow.

To cross that distance, we have a choice: to build moats and walls around cutting-edge quantum computer resources, or to build bridges, to meet people where they are, to bring the world-changing potential of quantum computing to as many people as possible. At IonQ, we believe strongly in making sure that everyone that wants to work on advancing the state-of-the-art in our emerging field has the ability to access great hardware, using whatever tools they find best suited to their needs. We believe the paradigm-shattering quantum app is as likely to come from a kid in a garage as it is from a corporate research park.

Just a few years ago, quantum computers only had two or three qubits, and programs for these machines were lovingly hand-crafted by physics graduate students in a lab in the basement of a university building. The only tools available to program these were patched-together code, handed down from grad student to grad student, that still treated these devices more as physics experiments than computational tools.

But today, as quantum computers with dozens of qubits are being built, and systems with hundreds or even thousands of qubits are on the horizon, the complexity of programming a quantum computer requires a more structured approach. This has led to the birth of a large number of quantum programming frameworks and languages, ranging from fully-fledged programming languages like Microsoft’s Q#, to Python frameworks like IBM’s Qiskit, to basic assembly languages like QASM.

Anyone can use these software packages to run simulations from their own computer, but the real value comes in using these languages to run quantum programs on actual quantum hardware.

To that end, we’re happy to announce that, with the addition of ProjectQ to our supported libraries, you can now access IonQ hardware using every major quantum framework and language. In celebration, here’s a basic quantum program the quantum version of a “Hello World” program — a ”Hello Many Worlds,” if you will —in seven of the platforms that enable remote execution on IonQ quantum computers.

Failed to load HTML

Hello Many Worlds

The basic quantum program we’ll write is simple. It creates a fully-entangled state between two qubits, and then measures this state. This state is sometimes called a Bell Stateor Bell Pair, after physicist John Stewart Bell.

The measurement results for this program should give us 0 for both qubits or 1 for both qubits, in equal amounts. When running these, we’ll be able to tell that we’re running on real hardware because that’s not always what we get! These errors are what currently limit quantum computers, but the first steps to overcome this with quantum error correction have already begun.

Hello Qiskit

IBM’s Qiskit was one of the first frameworks for programming quantum computers. It provides robust tools for writing quantum programs in python, as well as a variety of additional packages for working with quantum hardware, running common algorithms, and more. Qiskit has a large body of educational materials for learning quantum computing, including an entire textbook that is a great place for quantum beginners to start learning about this field.

Qiskit can be used to run quantum programs against IonQ’s trapped ion quantum computers using our recently announced integration with Google Cloud Marketplace. If you haven’t signed up yet, these instructions will walk you through that process, and this guide will help you obtain an API key for accessing the IonQ service to run quantum programs. We call this API key API_KEY below — if you’re following along with this guide, be sure to replace that with a real key, or the programs won’t run!

First let’s create the quantum circuit that creates an entangled Bell pair and measures it in Qiskit — you’ll need the qiskit and qiskit_ionq python packages installed before you begin.

from qiskit import QuantumCircuit
# Create a basic Bell State.
qc = QuantumCircuit(2, 2) # 2 qubits, 2 bits
qc.h(0)
qc.cx(0, 1)

# Measure and put the result into the two bits.
qc.measure([0, 1], [0, 1])

# Display circuit.
print(qc)

Which prints out the nice looking circuit:

     ┌───┐     ┌─┐   
q_0: ┤ H ├──■──┤M├───
     └───┘┌─┴─┐└╥┘┌─┐
q_1: ─────┤ X ├─╫─┤M├
          └───┘ ║ └╥┘
c: 2/═══════════╩══╩═
                0  1

To run this circuit on an IonQ Quantum Processing Unit (QPU for short), you need to first get the QPU backend from the IonQ Provider:

from qiskit_ionq import IonQProvider
provider = IonQProvider(API_KEY)
qpu = provider.get_backend("ionq_qpu")

Then one sends the job to run on the qubit and waits for the job to be run from the queue of jobs on the IonQ service.

from qiskit.providers.jobstatus import JobStatus
import time
# Submit the job for execution.
qpu_job = qpu.run(qc, shots=1000)

# Check if the job is done.
while qpu_job.status() is not JobStatus.DONE:
    print("Job status is", qpu_job.status() )
    time.sleep(60)

# Grab a coffee! This can take up to a few minutes.
print("Job status is", qpu_job.status() )
print(qpu_job.get_counts())
Job status is JobStatus.QUEUED
Job status is JobStatus.QUEUED
Job status is JobStatus.DONE
{'00': 513, '01': 6, '10': 4, '11': 477}

Which we see, after a few moments in the queue, produces some results!

Our ideal outcome is 00: 512, 11: 512. The results we got are mostly correct, but like we said earlier, they’re not all correct because of the computational noise that comes from running on real hardware.

Hello Q#

Microsoft has a long history of writing their own programming languages, a history they’ve continued with quantum. Their offering for running quantum computations comes is in the form of an entire language, called Q#.

Using Q#, anyone with an account on Microsoft’s cloud service Azure Quantum can run against IonQ’s quantum computers. See these instructions for getting started on Azure Quantum. In this example we assume that you’ve already set up an Azure Quantum account and quantum workspace.

First let’s write the actual quantum program. Q# is written in a C-like dialect that should look familiar to anyone that’s written C# or similar:

namespace Bell {
    open Microsoft.Quantum.Intrinsic;
    open Microsoft.Quantum.Measurement;
    operation MeasureEntanglement() : Result[] {
        use qubits = Qubit[2];
        H(qubits[0]);
        CNOT(qubits[0], qubits[1]);
        return MultiM(qubits);
    }
}

Save this in a file called Operation.qs and then in the same directory, create a Python file to run this program. You can also use Azure’s az command line interface to do this — see the above-linked guide for more details — but we find using python a little easier to set up for demo purposes.

import qsharp
import qsharp.azure
from Bell import MeasureEntanglement
qsharp.azure.connect(
    resourceId="the name of your quantum resource",
    location="East US",
)
qsharp.azure.target("ionq.qpu")
result = qsharp.azure.execute(MeasureEntanglement, shots=1000, jobName="Bell")
print(result)
{‘[0, 0]’: 0.50, ‘[1, 1]’: 0.48, ‘[0, 1]’: 0.02}

Note that unlike the previous example, these are returned as a histogram of measurement probabilities; the percentage of our 1000 shots that ended up as each state. This is the other common way you’ll see quantum circuit output represented.

Hello Braket

Braket is Amazon’s quantum computing service, which includes a python-based SDK for creating and submitting quantum programs. To run a job on Braket you will need an AWS account on, and have installed the Amazon braket sdk. Additionally, you’ll need to have set up an s3 bucket to store your results. There are more Braket setup details in our full Braket guide.

First let’s create our bell circuit

from braket.circuits import Circuit
qc = Circuit().h(0).cnot(control=0, target=1)
print(qc)

Which prints out our same friendly little quantum circuit — even though the formatting is different here, the circuit is the same!

T  : |0|1|
q0 : -H-C-
        |
q1 : ---X-
T  : |0|1|

Now let’s get the ionq device and setup the our S3 bucket information:

from braket.aws import AwsDevice

device = AwsDevice("arn:aws:braket:us-east-1::device/qpu/ionq/Aria-1")

# Enter the name of S3 bucket you created earlier
my_bucket = "amazon-braket-Your-Bucket-Name" # the name of the bucket
my_prefix = "Your-Folder-Name" # the name of the folder in the bucket
s3_folder = (my_bucket, my_prefix)

And run it, which produces good, correlated outputs!

result = device.run(qc, s3_folder, shots=1000).result()

# Get measurement counts
counts = result.measurement_counts
print(counts)
Counter({'11': 506, '00': 494})

Hello Cirq

Cirq is an open source Python framework for quantum programming developed by a team at Google. Cirq can be used to run quantum programs against IonQ’s trapped ion quantum computers using our recently announced integration with Google Cloud Marketplace. And since Cirq is developed by Google, this is of course, the most synergistic way to run on GCM.

You can use these instructions to get started on GCM, and this guide will help you obtain an API key for accessing the IonQ service. Again, we call this API key API_KEY below, but if you’re following along with this guide, be sure to replace that with a real key!

Again, we'll start by first creating the circuit for our Bell pair and printing it, which produces another nice ascii diagram:

import cirq
q0, q1 = cirq.LineQubit.range(2)
qc = cirq.Circuit(cirq.H(q0), cirq.CX(q0, q1), cirq.measure(q0, q1, key='b'))

print(qc)
0: ───H───@───M('b')───
          │   │
1: ───────X───M────────

To run on IonQ hardware, create a ionq.Service object, authenticate with your API key, and run against the Service:

import cirq_ionq as ionq

# Create a ionq.Service object.
service = ionq.Service(api_key=API_KEY)

# In cirq_ionq <= 0.15, this helper will transpile the circuit.
# qc = ionq.decompose_to_device(qc)

# In cirq_ionq >= 0.15, you can use the IonQTargetGateset and compile
# more complex custom gates!
# qc = cirq.optimize_for_target_gateset(qc, gateset=ionq_gateset.IonQTargetGateset(), 

# Run a program against the service.
result = service.run(circuit=qc, repetitions=1000, target='qpu')

# The return object of the ru is a cirq.Result object.
# From this object you can get a histogram of results.
histogram = result.histogram(key='b')
print(f'Histogram: {histogram}')
Histogram: Counter({0: 523, 3: 466, 1: 9, 2: 2})

Here we see another common output pattern in quantum languages and SDKs: our bitstrings are represented in their integer format, where 11 is represented as 310 as 2, and so-on.

Hello Pennylane

Pennylane is a bit different from the previous frameworks, as it’s primarily focused on quantum machine learning, not just basic circuit synthesis. Still, we can use it in a form that allows us to create a Bell pair like in the previous examples.

Start by using a terminal to create an environment variable called IONQ_API_KEY with your API key — if you’re skimming around, the Cirq and Qiskit examples explain in more detail how to get a key.

Once we’ve set our api key in the environment, the following short snippet of code creates and runs our Bell pair.

import collections
import pennylane as qml
from pennylane_ionq import ops
dev = qml.device("ionq.qpu", wires=2, shots=1000)

@qml.qnode(dev)
def circuit():
    qml.Hadamard(wires=0)
    qml.CNOT(wires=[0, 1])
    return qml.probs(wires=[0, 1])

results = collections.Counter(dict(enumerate(circuit().tolist())))
print(results)
Counter({3: 0.504, 0: 0.485, 1: 0.006, 2: 0.005})

Hello ProjectQ

ProjectQ is an open source quantum programming framework developed out of ETH Zurich. One cool thing about this framework is that it has many optimizations useful for emulation: that is, mimicking the action of large oracles in simulating quantum systems without needing to compile these to low level gates. More details on getting started with ProjectQ and IonQ can be found here.

Like our other SDKs, we can also use it to create and measure a Bell pair.

First we need to create an engine for executing circuits on IonQ hardware using our api key:

import projectq.setups.ionq
from projectq import MainEngine
from projectq.backends import IonQBackend

# Set your IonQ API token
token = API_KEY

# Create and IonQ backend and respective compilers:
device = 'ionq_qpu'
backend = IonQBackend(
    verbose=True,
    token=token,
    device=device,
    num_runs=1000,
)
compilers = projectq.setups.ionq.get_engine_list(
    token=token,
    device=device,
)

# Create the main engine:
engine = MainEngine(backend, engine_list=compilers)

Now let’s create our Bell pair. ProjectQ uses the pipe operator `|` to apply gates to qubits.

from projectq.ops import All, H, CNOT, Measure

# Define a function to apply a bell state using a ProjectQ engine
def bell_state(eng):
    # Allocate two qubits
    circuit = eng.allocate_qureg(2)
    q0, q1 = circuit

    # Create a Bell pair and measure it.
    H | q0
    CNOT | (q0, q1)
    All(Measure) | circuit

    # flushing submits the circuit to IonQ's API
    eng.flush()

    # Now, return the job results
    return eng.backend.get_probabilities(circuit)

# Apply the bell state circuit to our engine
probs = bell_state(engine)
print(probs)
{'00': 0.489, '10': 0.004, '01': 0.009, '11': 0.498}

Hello Pytket

Next up, Pytket!

Pytket is a python toolkit for quantum programming developed by Cambridge Quantum Computing, an extension of their larger tket toolchain.

Let’s create a Bell pair circuit using Pytket:

from pytket import Circuit
qc = Circuit(2, 2)
qc.H(0)
qc.CX(0, 1)
qc.measure_all()

Once we have our circuit built, all that's left is to create a backend, compile the circuit for the backend, and then running it.

from pytket.extensions.ionq import IonQBackend
backend = IonQBackend(api_key=API_KEY, device_name="qpu")
backend.compile_circuit(qc)
handle = backend.process_circuit(qc, 1000)
counts = backend.get_result(handle).get_counts()
print(counts)
Counter({(1, 1): 500, (0, 0): 490, (1, 0): 7, (0, 1): 3})

Hello XACC

Last but not least, XACC is a framework for hybrid quantum / classical architectures. XACC was produced by a team at Oak Ridge National Lab, and has support for a large number of compilers, simulators, and quantum hardware. Let’s use it to create our now-familiar Bell pair.

import xacc
ionq = xacc.getAccelerator('ionq:qpu')
compiler = xacc.getCompiler("xasm")
ir = compiler.compile(r"""__qpu__ void hellobell(qbit q) {
    H(q[0]);
    CX(q[0], q[1]);
    Measure(q[0]);
    Measure(q[1]);
} """, ionq)

buffer = xacc.qalloc(2)
r = ionq.execute(buffer, ir.getComposite("hellobell"))
results = buffer.getMeasurementCounts()
print(results)
{'00': 500, '01': 4, '10': 6, '11': 490}

Which provides us with our now-familiar results!

Wrapping up and next steps

There you have it, seven ways to say “Hello Many Worlds” across seven quantum SDKs (and three cloud providers)!

We’re proud to be able to provide hardware access to all of them — no matter what tools you want to use to come up with the next great breakthrough in quantum computing, you can use them with IonQ hardware.

If you're interested in working on your own tools to interact with the API, the full API Reference has details on HTTP verbs and endpoints, expected response formats, and other features not covered in this guide. We’d also be happy to help if and when you run into any issues — reach out to us using our contact form, our twitter, or the support center.

Also, if you’re building tools and work as part of work at an academic institution, consider applying for free time on our systems through our research credits program.

We also have a full docs and guides page with step-by-step quickstart guides that go into more detail about getting set up with the above languages and SDKs, and a best practices page provides detailed instructions for getting the most out of our trapped-ion systems, and our support center is always available to help you solve any problems you might run into.

Failed to load HTML