Superconducting

Anyon Technologies/Anyon Computing

Setting Credentials

Programmers of CUDA-Q may access the Anyon API from either C++ or Python. Anyon requires a credential configuration file with username and password. The configuration file can be generated as follows, replacing the <username> and <password> in the first line with your Anyon Technologies account details. The credential in the file will be used by CUDA-Q to login to Anyon quantum services and will be updated by CUDA-Q with an obtained API token and refresh token. Note, the credential line will be deleted in the updated configuration file.

echo 'credentials: {"username":"<username>","password":"<password>"}' > $HOME/.anyon_config

Users can also login and get the keys manually using the following commands:

# You may need to run: `apt-get update && apt-get install curl jq`
curl -X POST --user "<username>:<password>"  -H "Content-Type: application/json" \
https://api.anyon.cloud:5000/login > credentials.json
id_token=`cat credentials.json | jq -r '."id_token"'`
refresh_token=`cat credentials.json | jq -r '."refresh_token"'`
echo "key: $id_token" > ~/.anyon_config
echo "refresh: $refresh_token" >> ~/.anyon_config

The path to the configuration can be specified as an environment variable:

export CUDAQ_ANYON_CREDENTIALS=$HOME/.anyon_config

Submitting

The target to which quantum kernels are submitted can be controlled with the cudaq.set_target() function.

To execute your kernels using Anyon Technologies backends, specify which machine to submit quantum kernels to by setting the machine parameter of the target. If machine is not specified, the default machine will be telegraph-8q.

cudaq.set_target('anyon', machine='telegraph-8q')

As shown above, telegraph-8q is an example of a physical QPU.

To emulate the Anyon Technologies machine locally, without submitting through the cloud, you can also set the emulate flag to True. This will emit any target specific compiler warnings and diagnostics, before running a noise free emulation.

cudaq.set_target('anyon', emulate=True)

The number of shots for a kernel execution can be set through the shots_count argument to cudaq.sample or cudaq.observe. By default, the shots_count is set to 1000.

cudaq.sample(kernel, shots_count=10000)

To target quantum kernel code for execution in the Anyon Technologies backends, pass the flag --target anyon to the nvq++ compiler. CUDA-Q will authenticate via the Anyon Technologies REST API using the credential in your configuration file.

nvq++ --target anyon --<backend-type> <machine> src.cpp ...

To execute your kernels using Anyon Technologies backends, pass the --anyon-machine flag to the nvq++ compiler as the --<backend-type> to specify which machine to submit quantum kernels to:

nvq++ --target anyon --anyon-machine telegraph-8q src.cpp ...

where telegraph-8q is an example of a physical QPU (Architecture: Telegraph, Qubit Count: 8).

Currently, telegraph-8q and berkeley-25q are available for access over CUDA-Q.

To emulate the Anyon Technologies machine locally, without submitting through the cloud, you can also pass the --emulate flag as the --<backend-type> to nvq++. This will emit any target specific compiler warnings and diagnostics, before running a noise free emulation.

nvq++ --target anyon --emulate src.cpp

To see a complete example, take a look at Anyon examples.

IQM

Support for submissions to IQM is currently under development. In particular, two-qubit gates can only be performed on adjacent qubits. For more information, we refer to the respective hardware documentation. Support for automatically injecting the necessary operations during compilation to execute arbitrary multi-qubit gates will be added in future versions.

Setting Credentials

Programmers of CUDA-Q may access the IQM Server from either C++ or Python. Following the quick start guide, install iqm-cortex-cli and login to initialize the tokens file. The path to the tokens file can either be passed explicitly via an environment variable or it will be loaded automatically if located in the default location ~/.cache/iqm-cortex-cli/tokens.json.

export IQM_TOKENS_FILE="path/to/tokens.json"

Submitting

The target to which quantum kernels are submitted can be controlled with the cudaq.set_target() function.

cudaq.set_target("iqm", url="https://<IQM Server>/cocos",**{"qpu-architecture": "Crystal_5"})

To emulate the IQM Server locally, without submitting to the IQM Server, you can also set the emulate flag to True. This will emit any target specific compiler diagnostics, before running a noise free emulation.

cudaq.set_target('iqm', emulate=True)

The number of shots for a kernel execution can be set through the shots_count argument to cudaq.sample or cudaq.observe. By default, the shots_count is set to 1000.

cudaq.sample(kernel, shots_count=10000)

To target quantum kernel code for execution on an IQM Server, pass the --target iqm flag to the nvq++ compiler, along with a specified --iqm-machine.

Note

The --iqm-machine is a mandatory argument. This provided architecture must match the device architecture that the program has been compiled against. The hardware architecture for a specific IQM Server may be checked via https://<IQM server>/cocos/quantum-architecture.

nvq++ --target iqm --iqm-machine Crystal_5 src.cpp

Once the binary for a specific IQM QPU architecture is compiled, it can be executed against any IQM Server with the same QPU architecture:

nvq++ --target iqm --iqm-machine Crystal_5 src.cpp -o program
IQM_SERVER_URL="https://demo.qc.iqm.fi/cocos" ./program

# Executing the same program against an IQM Server with a different underlying QPU
# architecture will result in an error.
IQM_SERVER_URL="https://<Crystal_20 IQM Server>/cocos" ./program

To emulate the IQM machine locally, without submitting to the IQM Server, you can also pass the --emulate flag to nvq++. This will emit any target specific compiler diagnostics, before running a noise free emulation.

nvq++ --emulate --target iqm --iqm-machine Crystal_5 src.cpp

To see a complete example, take a look at IQM examples.

OQC

Oxford Quantum Circuits (OQC) is currently providing CUDA-Q integration for multiple Quantum Processing Unit types. The 8 qubit ring topology Lucy device and the 32 qubit Kagome lattice topology Toshiko device are both supported via machine options described below.

Setting Credentials

In order to use the OQC devices you will need to register. Registration is achieved by contacting oqc_qcaas_support@oxfordquantumcircuits.com.

Once registered you will be able to authenticate with your email and password

There are three environment variables that the OQC target will look for during configuration:

  1. OQC_URL

  2. OQC_EMAIL

  3. OQC_PASSWORD - is mandatory

Submitting

To set which OQC URL, set the url parameter. To set which OQC email, set the email parameter. To set which OQC machine, set the machine parameter.

import os
import cudaq
os.environ['OQC_PASSWORD'] = password
cudaq.set_target("oqc", url=url, machine="lucy")

You can then execute a kernel against the platform using the OQC Lucy device

To emulate the OQC device locally, without submitting through the OQC QCaaS services, you can set the emulate flag to True. This will emit any target specific compiler warnings and diagnostics, before running a noise free emulation.

cudaq.set_target("oqc", emulate=True)

To target quantum kernel code for execution on the OQC platform, provide the flag --target oqc to the nvq++ compiler.

Users may provide their email and url as extra arguments

nvq++ --target oqc --oqc-email <email> --oqc-url <url> src.cpp -o executable

Where both environment variables and extra arguments are supplied, precedent is given to the extra arguments. To run the output, provide the runtime loaded variables and invoke the pre-built executable

OQC_PASSWORD=<password> ./executable

To emulate the OQC device locally, without submitting through the OQC QCaaS services, you can pass the --emulate flag to nvq++. This will emit any target specific compiler warnings and diagnostics, before running a noise free emulation.

nvq++ --emulate --target oqc src.cpp -o executable

Note

The oqc target supports a --oqc-machine option. The default is the 8 qubit Lucy device. You can set this to be either toshiko or lucy via this flag.

Note

The OQC quantum assembly toolchain (qat) which is used to compile and execute instructions can be found on github as oqc-community/qat

To see a complete example, take a look at OQC examples.

Quantum Circuits, Inc.

Quantum Circuits offers users the ability to execute CUDA-Q programs on its Seeker QPU and simulate them using its simulator, AquSim. The Seeker is the first dual-rail qubit QPU available over the cloud today, and through CUDA-Q users have access to its universal gate set, high fidelity operations, and fast throughput. Upcoming releases of CUDA-Q will continue to evolve these capabilities to include real-time control flow and access to an expanded collection of actionable data enabled by the Quantum Circuits error aware technology.

AquSim models error detection and real-time control of Quantum Circuits’ Dual-Rail Cavity Qubit systems, and uses a Monte Carlo approach to do so on a shot-by-shot basis. The supported features include all of the single and two-qubit gates offered by CUDA-Q. AquSim additionally supports real-time conditional logic enabled by feed-forward capability. Noise modeling is offered, effectively enabling users to emulate the execution of programs on the Seeker QPU and thereby providing a powerful application prototyping tool to be leveraged in advance of execution on hardware.

With C++ and Python programming supported, users are able to prototype, test and explore quantum applications in CUDA-Q on the Seeker and AquSim. Users who wish to get started with running CUDA-Q with Quantum Circuits should visit our Explore page to learn more about the Quantum Circuits Select Quantum Release Program.

Installation & Getting Started

Until CUDA-Q release 0.13.0 is available, the integration with Quantum Circuits will be supported through the nightly build Docker images.

Instructions on how to install and get started with CUDA-Q using Docker can be found here.

You may present your user token to Quantum Circuits via CUDA-Q by setting an environment variable named QCI_AUTH_TOKEN before running your CUDA-Q program.

For example:

export QCI_AUTH_TOKEN="example-token"

Tokens are provided as part of the Strategic Quantum Release Program. Please visit our Explore page to learn more.

Using CUDA-Q with Quantum Circuits

Quantum Circuits’ Seeker system detects errors in real-time and returns not just 0s and 1s as the measurement outcomes, but unique results tagged as -1, which indicate that an erasure was detected on the Dual-Rail Cavity Qubit. AquSim emulates this execution as well, enabling users to model error aware programs in advance of execution on the QPU. While -1 data is not yet available via the CUDA-Q API, the user still has insight into these dynamics through the number of shots that are collected in a given run.

Yield

Quantum Circuits architecture can detect errors in measurements. The target will return to the user the outcome from every measurement for every shot, regardless of whether errors were detected. However, the data from a shot in which any of the measurements had an error detected will:

  • Every RESULT where an error is detected will be -1 (instead of 0 or 1).

  • The shot will be marked with an exit code of 1 (instead of 0).

  • It will be excluded from the histogram.

Apart from an ideal simulation, most jobs will include at least some shots for which errors were detected.

The shots that have no errors detected are referred to as post-selected and will have an exit code of 0. The yield represents the fraction of executed shots that are not rejected due to detected errors:

\[\text{yield} = \frac{\text{number of post-selected shots}}{\text{number of shots executed}}\]

The yield depends on the number of qubits and the depth of the circuit.

Options

machine

This is a string option with 2 supported values.

  • Seeker

    • Name of the QPU supported by Quantum Circuits.

    • Supports up to 8 qubit programs and the base_profile.

    • Regardless of whether the method is execute or simulate, the program will be fully compiled for strict validation of suitability to run on the QPU.

  • AquSim

    • This “machine” is not associated with a specific QPU and not strictly validated.

    • Supports up to 25 qubits, a square grid coupling map, and the adaptive_profile.

method

This is a string option with 2 supported values.

  • execute

    • If machine="Seeker", the program will run on the QPU (depending on availability).

    • Not supported if machine="AquSim".

  • simulate

    • The program will be run in AquSim.

noisy

This boolean option is only supported for method="simulate".

  • True

    • AquSim will simulate noise and error detection using a Dual-Rail statevector-based noise model on a transpiled program.

  • False

    • An ideal simulation.

repeat_until_shots_requested

This is a boolean option.

  • True

    • The machine will return as many post-selected shots as were requested (unless an upper limit of shots executed is encountered first).

    • The execution time is proportional to 1 / yield.

  • False

    • The machine will execute exactly the number of shots requested, regardless of how many errors are detected.

    • The execution time does not depend on yield.

Submitting

To set the target to Quantum Circuits, add the following to your Python program:

cudaq.set_target('qci')
[... your Python here]

To run on AquSim, simply execute the script using your Python interpreter.

To specify which Quantum Circuits machine to use, set the machine parameter:

# The default machine is AquSim
cudaq.set_target('qci', machine='AquSim')
# or
cudaq.set_target('qci', machine='Seeker')

You can control the execution method using the method parameter:

# For simulation (default)
cudaq.set_target('Seeker', method='simulate')
# For hardware execution
cudaq.set_target('Seeker', method='execute')

For noisy simulation, you can enable the noisy parameter:

cudaq.set_target('qci', noisy=True)

When collecting shots, you can ensure the requested number of shots are obtained by enabling the repeat_until_shots_requested parameter:

cudaq.set_target('qci', repeat_until_shots_requested=True)

When executing programs in C++, they must first be compiled using the CUDA-Q nvq++ compiler, and then submitted to run on the Seeker or AquSim.

Note that your token is fetched from your environment at run time, not at compile time.

In the example below, the compilation step shows two flags being passed to the nvq++ compiler: the Quantum Circuits target --target qci, and the output file -o example.x. The second line executes the program against AquSim. Here are the shell commands in full:

nvq++ example.cpp --target qci -o example.x
./example.x

To specify which Quantum Circuits machine to use, pass the --qci-machine flag:

# The default machine is AquSim
nvq++ --target qci --qci-machine AquSim src.cpp -o example.x
# or
nvq++ --target qci --qci-machine Seeker src.cpp -o example.x

You can control the execution method using the --qci-method flag:

# For simulation (default)
nvq++ --target qci --qci-machine Seeker --qci-method simulate src.cpp -o example.x
# For hardware execution
nvq++ --target qci --qci-machine Seeker --qci-method execute src.cpp -o example.x

For noisy simulation, you can set the --qci-noisy argument to true:

nvq++ --target qci --qci-noisy true src.cpp -o example.x

When collecting shots, you can ensure the requested number of shots are obtained with the --qci-repeat_until_shots_requested argument:

nvq++ --target qci --qci-repeat_until_shots_requested true src.cpp -o example.x

Note

By default, only successful shots are presented to the user and may be fewer than the requested number. Enabling repeat_until_shots_requested ensures the full requested shot count is collected, at the cost of increased execution time.

To see a complete example of using Quantum Circuits’ backends, please take a look at the Quantum Circuits examples.