Skip to main content

Generating OpenQASM 3 + OpenPulse in Python

Project description

OQpy: Generating OpenQASM 3 + OpenPulse in Python

The goal of oqpy ("ock-pie") is to make it easy to generate OpenQASM 3 + OpenPulse in Python. The oqpy library builds off of the openqasm3 and openpulse packages, which serve as Python reference implementations of the abstract syntax tree (AST) for the OpenQASM 3 and OpenPulse grammars.

What are OpenQASM 3 and OpenPulse?

OpenQASM is an imperative programming language designed for near-term quantum computing algorithms and applications. OpenQASM 3 extends the original specification by adding support for classical logic, explicit timing, and pulse-level definitions. The latter is enabled via the use of [calibration grammars][pulse-docs] which allow quantum hardware builders to extend the language to support hardware-specific directives via cal and defcal blocks. One such grammar is OpenPulse, which provides the instructions required for pulse-based control of many common quantum computing architectures (e.g. superconducting qubits).

Installation and Getting Started

OQpy can be installed from PyPI or from source in an environment with Python 3.7 or greater.

To install it from PyPI (via pip), do the following:

pip install oqpy

To instead install OQpy from source, do the following from within the repository after cloning it:

poetry install

Next, check out the following example to get a sense of the kinds of programs we can write with OQpy.

Example: Ramsey Interferometry

A common and useful experiment for qubit characterization is Ramsey interferometry, which can be used for two purposes: performing a careful measurement of a qubit’s resonant frequency, and for investigating how long a qubit retains its coherence. In a typical Ramsey experiment, one varies the length of a delay between the two π/2 pulses, and then measures the state of the qubit. Below, we'll create a Ramsey interferometry experiment in OpenQASM 3 using OQpy. As part of this, we’ll use the OpenPulse grammar to allow this experiment to specify its operation implementations at the calibrated pulse level.

import oqpy
prog = oqpy.Program()  # create a new oqpy program

# Declare frames: transmon driving frame and readout receive/transmit frames
xy_frame = oqpy.FrameVar(oqpy.PortVar("dac0"), 6.431e9, name="xy_frame")
rx_frame = oqpy.FrameVar(oqpy.PortVar("adc0"), 5.752e9, name="rx_frame")
tx_frame = oqpy.FrameVar(oqpy.PortVar("dac1"), 5.752e9, name="tx_frame")

# Declare the type of waveform we are working with
constant_waveform = oqpy.declare_waveform_generator(
    "constant",
    [("length", oqpy.duration),
     ("amplitude", oqpy.float64)],
)
gaussian_waveform = oqpy.declare_waveform_generator(
    "gaussian",
    [("length", oqpy.duration),
     ("sigma", oqpy.duration),
     ("amplitude", oqpy.float64)],
)

# Provide gate / operation definitions as defcals
qubit = oqpy.PhysicalQubits[1]  # get physical qubit 1

with oqpy.defcal(prog, qubit, "reset"):
    prog.delay(1e-3)  # reset to ground state by waiting 1 ms

with oqpy.defcal(prog, qubit, "measure"):
    prog.play(tx_frame, constant_waveform(2.4e-6, 0.2))
    prog.capture(rx_frame, constant_waveform(2.4e-6, 1))

with oqpy.defcal(prog, qubit, "x90"):
    prog.play(xy_frame, gaussian_waveform(32e-9, 8e-9, 0.2063))

# Loop over shots (i.e. repetitions)
delay_time = oqpy.DurationVar(0, "delay_time")  # initialize a duration
with oqpy.ForIn(prog, range(100), "shot_index"):
    prog.set(delay_time, 0)                     # reset delay time to zero
    # Loop over delays
    with oqpy.ForIn(prog, range(101), "delay_index"):
        (prog.reset(qubit)                      # prepare in ground state
         .gate(qubit, "x90")                    # pi/2 pulse (90° rotation about the x-axis)
         .delay(delay_time, qubit)              # variable delay
         .gate(qubit, "x90")                    # pi/2 pulse (90° rotation about the x-axis)
         .measure(qubit)                        # final measurement
         .increment(delay_time, 100e-9))        # increase delay by 100 ns

Running print(prog.to_qasm(encal_declarations=True)) generates the following OpenQASM:

OPENQASM 3.0;
defcalgrammar "openpulse";
cal {
    extern constant(duration, float[64]) -> waveform;
    extern gaussian(duration, duration, float[64]) -> waveform;
    port dac1;
    port adc0;
    port dac0;
    frame tx_frame = newframe(dac1, 5752000000.0, 0);
    frame rx_frame = newframe(adc0, 5752000000.0, 0);
    frame xy_frame = newframe(dac0, 6431000000.0, 0);
}
duration delay_time = 0.0ns;
defcal reset $1 {
    delay[1000000.0ns];
}
defcal measure $1 {
    play(tx_frame, constant(2400.0ns, 0.2));
    capture(rx_frame, constant(2400.0ns, 1));
}
defcal x90 $1 {
    play(xy_frame, gaussian(32.0ns, 8.0ns, 0.2063));
}
for int shot_index in [0:99] {
    delay_time = 0.0ns;
    for int delay_index in [0:100] {
        reset $1;
        x90 $1;
        delay[delay_time] $1;
        x90 $1;
        measure $1;
        delay_time += 100.0ns;
    }
}

Contributing

We welcome contributions to OQpy including bug fixes, feature requests, etc. To get started, check out our contributing guidelines.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

oqpy-0.1.0.tar.gz (23.3 kB view details)

Uploaded Source

Built Distribution

oqpy-0.1.0-py3-none-any.whl (26.5 kB view details)

Uploaded Python 3

File details

Details for the file oqpy-0.1.0.tar.gz.

File metadata

  • Download URL: oqpy-0.1.0.tar.gz
  • Upload date:
  • Size: 23.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.10.6

File hashes

Hashes for oqpy-0.1.0.tar.gz
Algorithm Hash digest
SHA256 75834fa4d30a1926355def16bbf5e47a24767170bb0221b5a28e958d46c60e40
MD5 71b5d1489486272f91fbb18ac9edab27
BLAKE2b-256 2baa6aeee24d5a191514ab431efa41da7b0c209f1a2995f7e7c53e1884622833

See more details on using hashes here.

File details

Details for the file oqpy-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: oqpy-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 26.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.10.6

File hashes

Hashes for oqpy-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 efc35e286d328265d717b78b0851a13c76fc1537dab2d43b3062a06ae176d68f
MD5 73de08330df4e0bfe7319e78d954c7ef
BLAKE2b-256 48036781cdf1fb7900cd52ead002b3b100abf19c89d702cb6e9c36222e6efadf

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page