Easily integrate Boulder Opal outputs with common electronic controllers

Export Boulder Opal pulses to use in real hardware

Boulder Opal is a general purpose and flexible computational engine that is compatible with any technology type. Most of the functionality is based on Hamiltonian dynamics, allowing it to be encoded with the specifics of any technology domain or specific device architecture.

Exporting waveforms

The main interaction between Boulder Opal and your experimental setup requires sending and receiving signals to the underlying quantum device. For instance, the waveform pulse output from Boulder Opal calculations must be encoded into the proper format of your controller's language. Boulder Opal uses NumPy arrays to represent calculation results, which is a convenient intermediate representation that you can easily convert into the required form to communicate with your hardware or cloud quantum computing platform.

If you are using closed-loop optimization, the optimal parameters in the result will be a NumPy array. In model-based optimization, the values of the optimized piecewise-constant (PWC) signal will also be a NumPy array.

Most quantum computing devices or controllers use a set time step for its waveforms. If you are using our model-based tools to generate the signal, make sure that the durations of the PWC signal match the hardware's time step. For instance, ensuring that the ratio between the total duration and the number of segments of your PWC signal matches the desired time step. You can check that the PWC segmentation matches the desired time step by inspecting the durations attribute of the PWC object.

You can read more about this in the How to format and export control solutions for hardware implementation user guide.

Cloud quantum computing vendors

Beyond the hardware type, specific vendors also have software interfaces to enable easier interaction with that hardware, especially over cloud interfaces. Boulder Opal has integration guidance for the below hardware languages.

Controllers

Because of this, Boulder Opal is natively compatible with most controller vendors, including Keysight, Qblox, Quantum Machines, and Zurich Instruments.

Specific vendors

In some cases, there are specific subroutines that make working with a given controller language easier. Specific examples of those subroutines can be found below, with links to more detailed documentation. This list will be updated with new vendors and subroutines as they become available. If you would like to submit a subroutine for us to post, please reach out to us.

Keysight

You can use pulses you obtain from Boulder Opal with Keysight controllers by adding them to your program from the Keysight QCS package.

The process involves creating an arbitrary envelope using the values and durations of the PWC function obtained from Boulder Opal and using it to define a DC waveform or an RF waveform

For example,

envelope = qcs.ArbitraryEnvelope(
    times=time_samples,
    amplitudes=waveform_array,
)
waveform = qcs.RFWaveform(
    duration=time_samples[-1],
    envelope=envelope,
    amplitude=np.max(waveform_array),
    rf_frequency=rf_frequency,
)
program.add_waveform(waveform, awg)

Here, waveform_array and time_samples are two NumPy arrays representing the values of the pulse and the times at which it is sampled. Note that if the provided time samples don't match the sampling rate of the hardware, interpolation will be used to determine the hardware-sampled values.

You can learn more about pulse envelopes in this Keysight QCS tutorial.

Qblox

You can use pulses you obtain from Boulder Opal with Qblox controllers by adding them to your schedule from the quantify-schedule package.

For example,

schedule.add_resource(
    quantify_scheduler.resources.ClockResource(
        name="transmon:mw", freq=transmon.clock_freqs.f01()
    )
)
schedule.add(
    quantify_scheduler.operations.pulse_library.NumericalPulse(
        samples=waveform_array,
        t_samples=time_samples,
        port="transmon:mw",
        clock="transmon.01",
    )
)

Here, waveform_array and time_samples are two NumPy arrays representing the values of the pulse and the times at which it is sampled. Note that if the provided time samples don't match the sampling rate of the hardware, interpolation will be used to determine the hardware-sampled values.

You can learn more about using schedules and pulses in this Quantify tutorial.

Quantum Machines

You can register pulses you obtain from Boulder Opal in Quantum Machines controllers by adding them to the config dictionary from the QM-QUA SDK under the the corresponding pulse_name and channel_name.

For example,

pulse_name = "boulder_opal_pulse"
channel_name = "drive01"

config["waveforms"][f"{pulse_name}_I"] = {
    "type": "arbitrary", "samples": list(i_signal),
}
config["waveforms"][f"{pulse_name}_Q"] = {
    "type": "arbitrary", "samples": list(q_signal),
}
config["pulses"][pulse_name] = {
    "operation": "control",
    "length": len(i_signal),
    "waveforms": {"I": f"{pulse_name}_I", "Q": f"{pulse_name}_Q"},
}
config["elements"][channel_name]["operations"][f"{pulse_name}_op"] = pulse_name

Here, i_signal and q_signal are two NumPy arrays representing the in-phase and quadrature components of the signal. You can learn more about it in the QUA documentation.

In this application note we present the entire workflow used to demonstrate high-fidelity SU(3) gate on superconducting hardware using Boulder Opal integrated with QUA from Quantum Machines. The notebook defines a convenience function, add_pulse_to_config, to add optimizated Boulder Opal pulses to a QUA config dictionary.

Zurich Instruments

You can use pulses you obtain from Boulder Opal with Zurich Instruments controllers by playing them using the Lab One Q package.

The process involves creating a sampled real or complex pulse with the values of the pulse and playing them in your experiment.

For example,

sampled_pulse_complex = pulse_library.sampled_pulse_complex(
    samples=waveform_array, uid="complex_pulse"
)

experiment = Experiment(signals=[ExperimentSignal("drive")])

with experiment.acquire_loop_rt(count=1):
    experiment.play(signal="drive", pulse=sampled_pulse_complex)

Here, waveform_array is a NumPy array representing the values of the pulse, sampled at the hardware's sampling rate.

You can learn more about using sampled pulses in this Zurich Instruments Lab One Q learning guide.

Quantum technologies

For some of the more common technologies, there are prebuilt application examples in our documentation to show how this general tool can be applied to specific problem areas.

If you have any further questions about the above integrations or you would like to request a new supported integration listing, you can reach out to us.

Was this useful?

cta background

New to Boulder Opal?

Get access to everything you need to automate and optimize quantum hardware performance at scale.