Platform

class qililab.Platform(runcard)

Bases: object

Platform object representing the laboratory setup used to control quantum devices.

The platform is responsible for managing the initializations, connections, setups, and executions of the laboratory, which mainly consists of:

  • Chip

  • Buses

  • Instruments

Note

This class should be instantiated with the ql.build_platform() function, either by passing a runcard (serialized platform dictionary) or a path to the location of the YAML file containing it.

More information about the runcard structure, in the Runcards section of the documentation.

After initializing a Platform, the typical first three steps (which are usually only required at the start) are:

>>> platform.connect()  # Connects to all the instruments.
>>> platform.initial_setup()  # Sets the parameters defined in the runcard.
>>> platform.turn_on_instruments()  # Turns on the signal outputs.

And then, for each experiment you want to run, you would typically repeat:

>>> platform.set_parameter(...)  # Sets any parameter of the Platform.
>>> result = platform.execute(...)  # Executes the platform.
Parameters:

runcard (Runcard) – Dataclass containing the serialized platform (chip, instruments, buses…), created during ql.build_platform() with the given runcard dictionary.

Examples

Note

The following examples contain made up results. These will soon be updated with real results.

Note

All the following examples are explained in detail in the Platform section of the documentation. However, here are a few thing to keep in mind:

  • To connect, your computer must be in the same network of the instruments specified in the runcard, with their IP’s addresses. Connection is necessary for the subsequent steps.

  • You might want to skip the platform.initial_setup() and the platform.turn_on_instruments() steps if you think nothing has been modified, but we recommend doing them every time.

  • platform.turn_on_instruments() is used to turn on the signal output of all the sources defined in the runcard (RF, Voltage and Current sources).

  • You can print platform.chip and platform.buses at any time to check the platform’s structure.

1. Executing a circuit with Platform:

To execute a circuit you first need to define your circuit, for example, one with a pi pulse and a measurement gate in qubit q (int). Then you also need to build, connect, set up, and execute the platform, which together look like:

import qililab as ql

from qibo.models import Circuit
from qibo import gates

# Defining the Rabi circuit:
circuit = Circuit(q + 1)
circuit.add(gates.X(q))
circuit.add(gates.M(q))

# Building the platform:
platform = ql.build_platform(runcard="runcards/galadriel.yml")

# Connecting and setting up the platform:
platform.connect()
platform.initial_setup()
platform.turn_on_instruments()

# Executing the platform:
result = platform.execute(program=circuit, num_avg=1000, repetition_duration=6000)

The results would look something like this:

>>> result.array
array([[6.],
        [6.]])

Note

The obtained values correspond to the integral of the I/Q signals received by the digitizer. And they have shape (#sequencers, 2, #bins), in this case you only have 1 sequencer and 1 bin.

You could also get the results in a more standard format, as already classified counts or probabilities dictionaries. To do so the call to execute circuit must be slightly different, as the number of averages must be 1:

# Executing the platform with the same amount of loops but using bins:
result = platform.execute(program=circuit, num_avg=1, num_bins=1000, repetition_duration=6000)

Then:

>>> result.counts
{'0': 501, '1': 499}
>>> result.probabilities
{'0': .501, '1': .499}

Note

You can find more information about the results, in the Results class documentation.


2. Running a Rabi sweep with Platform:

To perform a Rabi sweep, you need the previous circuit, and again, you also need to build, connect and setup the platform. But this time, instead than executing the circuit once, you will loop changing the amplitude parameter of the AWG (generator of the pi pulse):

# Looping over the AWG amplitude to execute the Rabi sweep:
results = []
amp_values = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.9, 1.0]

for amp in amp_values:
    platform.set_parameter(alias="drive_q", parameter=ql.Parameter.AMPLITUDE, value=amp)
    result = platform.execute(program=circuit, num_avg=1000, repetition_duration=6000)
    results.append(result.array)

Now you can use np.hstack to stack the results horizontally. By doing this, you would obtain an array with shape (2, N), where N is the number of elements inside the loop:

>>> import numpy as np
>>> np.hstack(results)
array([[5, 4, 3, 2, 1, 2, 3, 4, 5, 4, 3],
        [5, 4, 3, 2, 1, 2, 3, 4, 5, 4, 3]])

You can see how the integrated I/Q values oscillate, indicating that qubit q oscillates between the ground and excited states!


3. A faster Rabi sweep, translating the circuit to pulses:

Since you are looping over variables that are independent of the circuit (in this case, the amplitude of the AWG), you can speed up the experiment by translating the circuit into pulses beforehand, only once, and then, executing the obtained pulses inside the loop.

Which is the same as before, but passing the pulse_schedule instead than the circuit, to the execute() method:

from qililab.pulse.circuit_to_pulses import CircuitToPulses

# Translating the circuit to pulses:
pulse_schedule = CircuitToPulses(platform=platform).translate(circuits=[circuit])

# Looping over the AWG amplitude to execute the Rabi sweep:
results = []
amp_values = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.9, 1.0]

for amp in amp_values:
    platform.set_parameter(alias="drive_q", parameter=ql.Parameter.AMPLITUDE, value=amp)
    result = platform.execute(program=pulse_schedule, num_avg=1000, repetition_duration=6000)
    results.append(result.array)

If you now stack and print the results, you will obtain similar results, but much faster!

>>> np.hstack(results)
array([[5, 4, 3, 2, 1, 2, 3, 4, 5, 4, 3],
        [5, 4, 3, 2, 1, 2, 3, 4, 5, 4, 3]])
TODO: !!! Change this results for the actual ones !!!

4. Ramsey sequence, looping over a parameter inside the circuit:

To run a Ramsey sequence you also need to build, connect and set up the platform as before. However, the circuit will be different from the previous one, and also, this time, you need to loop over a parameter of the circuit itself, specifically over the time of the Wait gate.

To do this, since the parameter is inside the Qibo circuit, you will need to use Qibo own circuit.set_parameters() method, specifying the parameters you want to set, in the same order they appear in the circuit construction:

import qililab as ql

from qibo.models import Circuit
from qibo import gates

# Building the platform:
platform = ql.build_platform(runcard="runcards/galadriel.yml")

# Connecting and setting up the platform:
platform.connect()
platform.initial_setup()
platform.turn_on_instruments()

# Defining the Ramsey circuit:
circuit = Circuit(q + 1)
circuit.add(gates.RX(q, theta=np.pi / 2))
circuit.add(ql.Wait(q, t=0))
circuit.add(gates.RX(q, theta=np.pi / 2))
circuit.add(gates.M(q))

# Looping over the wait time t to execute the Ramsey:
results = []
wait_times = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

for wait in wait_times:
    circuit.set_parameters([np.pi / 2, wait, np.pi / 2])
    result = platform.execute(program=circuit, num_avg=1000, repetition_duration=6000)
    results.append(result.array)

which for each execution, would set np.pi/2 to the theta parameters of the RX gates, and the looped wait time to the t parameter of the Wait gate.

If you print the results, you’ll see how you obtain the sinusoidal expected behavior!

>>> results = np.hstack(results)
>>> results
array([[5, 4, 3, 2, 1, 2, 3, 4, 5, 4, 3],
        [5, 4, 3, 2, 1, 2, 3, 4, 5, 4, 3]])
TODO: !!! Change this results for the actual sinusoidal ones (change wait_times of execution if needed) !!!

Methods

calibrate_mixers(alias, cal_type[, channel_id])

compile_annealing_program(...[, ...])

Compile an annealing program into a QProgram by mapping Ising coefficients to flux waveforms.

compile_circuit(circuit, nshots, *[, ...])

Compiles the circuit / pulse schedule into a set of assembly programs, to be uploaded into the awg buses.

compile_qprogram(qprogram[, bus_mapping, ...])

connect()

Connects to all the instruments and blocks the connection for other users.

db_real_time_saving(shape, loops, ...[, ...])

Allows for real time saving of results from an experiment.

db_save_results(experiment_name, results, loops)

Uses the same StreamArray class as for live saving but it saves full chunks of data in the same format as platform.stream_array.

disconnect()

Closes the connection to all the instruments.

draw(qprogram[, time_window, ...])

Draw the QProgram using QBlox Compiler whilst adding the knowledge of the platform

execute_annealing_program(...[, ...])

Given an annealing program execute it as a qprogram.

execute_circuit(circuit[, nshots, qubit_mapping])

execute_compilation_output(output[, debug])

execute_compilation_outputs_parallel(outputs)

Execute compiled qprograms in parallel.

execute_experiment(experiment[, job_id, ...])

Executes a quantum experiment on the platform.

execute_qprogram(qprogram[, bus_mapping, ...])

Execute a QProgram using the platform instruments.

execute_qprograms_parallel(qprograms[, ...])

Compiles a list of qprograms to be executed in parallel.

get_element(alias)

Gets the platform element and to which bus it is connected, using its alias.

get_parameter(alias, parameter[, ...])

Get platform parameter.

initial_setup()

Sets the values of the cache of the Platform object to the connected instruments.

load_db_manager([db_ini_path])

Load Database Manager from an .ini path containing user DB user information or if no path is given it uses '~/database.ini'.

session()

Context manager to manage platform session, ensuring that resources are always released.

set_bias_to_zero([bus_list])

Set all lines inside the crosstalk / bus list to 0 Volts / Amperes.

set_crosstalk(crosstalk)

Sets the crosstalk matrix using the crosstalk matrix class.

set_flux_to_zero([bus_list])

Set all lines inside the crosstalk / bus list to 0 Phi0, sets everything into the crosstalk offsets.

set_parameter(alias, parameter, value[, ...])

Set a parameter for a platform element.

to_dict()

Returns all platform information as a dictionary, called the runcard.

turn_off_instruments()

Turns off the signal output for the generator instruments (local oscillators, voltage sources and current sources).

turn_on_instruments()

Turns on the signal output for the generator instruments (RF, voltage sources and current sources).

Attributes

name

Name of the platform (str)

instruments

All the instruments of the platform and their necessary settings (dataclass).

instrument_controllers

All the instrument controllers of the platform and their necessary settings (dataclass).

buses

All the buses of the platform and their necessary settings (dataclass).

digital_compilation_settings

Gate settings and definitions (dataclass).

analog_compilation_settings

Flux to bus mapping for analog control

crosstalk

Crosstalk matrix information, defaults to None (only used on FLUX parameters)

qdac_buses

List of buses that use the instrument QDevilQDac2, defaults to an empty list for no qdac buses.

qdac_instruments

List of QDevilQDac2 instruments inside the runcard, defaults to an empty list for no qdac instruments.

flux_vector

Flux vector information, defaults to None (only used on FLUX parameters)

flux_parameter

Flux dictionary with information for the get parameter (only used on FLUX parameters)

db_manager

Database manager for experiment class and db stream array

qblox_alias_module

List of dict with key the alias of qblox module and value the module_id.

qblox_active_filter_exponential

List of exponential_idx with an active exponential filter.

qblox_active_filter_fir

Bool to determine if any FIR filter is active.

name

Name of the platform (str)

instruments

All the instruments of the platform and their necessary settings (dataclass). Each individual instrument is contained in a list within the dataclass.

instrument_controllers

All the instrument controllers of the platform and their necessary settings (dataclass). Each individual instrument controller is contained in a list within the dataclass.

buses

All the buses of the platform and their necessary settings (dataclass). Each individual bus is contained in a list within the dataclass.

digital_compilation_settings

Gate settings and definitions (dataclass). These setting contain how to decompose gates into pulses.

analog_compilation_settings

Flux to bus mapping for analog control

crosstalk

Crosstalk matrix information, defaults to None (only used on FLUX parameters)

qdac_buses

List of buses that use the instrument QDevilQDac2, defaults to an empty list for no qdac buses.

qdac_instruments

List of QDevilQDac2 instruments inside the runcard, defaults to an empty list for no qdac instruments.

flux_vector

Flux vector information, defaults to None (only used on FLUX parameters)

flux_parameter

Flux dictionary with information for the get parameter (only used on FLUX parameters)

db_manager

Database manager for experiment class and db stream array

qblox_alias_module

List of dict with key the alias of qblox module and value the module_id. Used for the qblox distortions

qblox_active_filter_exponential

List of exponential_idx with an active exponential filter. Active is considered as either “enabled” or “delay_comp”. Used for the qblox distortions

qblox_active_filter_fir

Bool to determine if any FIR filter is active. Active is considered as either “enabled” or “delay_comp”. Used for the qblox distortions

connect()

Connects to all the instruments and blocks the connection for other users.

You must be connected in order to set up and turn on instruments, or in order to execute the platform.

To connect, your computer must be in the same network of the instruments specified in the runcard (with their corresponding IP’s addresses).

initial_setup()

Sets the values of the cache of the Platform object to the connected instruments.

If called after a ql.build_platform(), where the Platform object is built with the provided runcard, this function sets the values of the runcard into the connected instruments.

It is recommended to use this function after a ql.build_platform() + platform.connect() to ensure that no parameter differs from the current runcard settings.

If a platform.set_parameter() is called between platform building and initial setup, the value set in the instruments will be the new “set” value, as the cache values of the Platform object are modified.

turn_on_instruments()

Turns on the signal output for the generator instruments (RF, voltage sources and current sources).

This does not actually turn on the laboratory instruments, it only opens the signal output generation of the sources.

We recommend you to do this always after a connection and a setup, to ensure that everything is ready for an execution.

turn_off_instruments()

Turns off the signal output for the generator instruments (local oscillators, voltage sources and current sources).

This does not actually turn the laboratory instruments off, it only closes their signal output generation.

disconnect()

Closes the connection to all the instruments.

get_element(alias)

Gets the platform element and to which bus it is connected, using its alias.

Parameters:

alias (str) – Element alias to identify it.

Returns:

Element class together with the index of the bus where the element is located.

Return type:

tuple[object, list | None]

get_parameter(alias, parameter, channel_id=None, output_id=None)

Get platform parameter.

Parameters:
  • parameter (Parameter) – Name of the parameter to get.

  • alias (str) – Alias of the bus where the parameter is set.

  • channel_id (int, optional) – ID of the channel we want to use to set the parameter. Defaults to None.

  • output_id (int, optional) – ID of the module we want to use to set the parameter, used for Qblox distortion filters. Defaults to None.

set_parameter(alias, parameter, value, channel_id=None, output_id=None)

Set a parameter for a platform element.

If connected to an instrument, this function updates both the cache of the Platform object and the instrument’s value. Otherwise, it only stores the value in the cache. Subsequent connect() + initial_setup() will apply the cached values into the real instruments.

If you use set_parameter + ql.save_platform(), the saved runcard will include the new “set” value, even without an instrument connection, as the cache values of the Platform object are modified.

Parameters:
  • parameter (Parameter) – Name of the parameter to change.

  • value (float | str | bool) – New value to set in the parameter.

  • alias (str) – Alias of the bus where the parameter is set.

  • channel_id (int, optional) – ID of the channel you want to use to set the parameter. Defaults to None.

  • output_id (int, optional) – ID of the module we want to use to set the parameter, used for Qblox distortion filters. Defaults to None.

set_crosstalk(crosstalk)

Sets the crosstalk matrix using the crosstalk matrix class.

Parameters:

crosstalk (CrosstalkMatrix) – Crosstalk matrix to implement on the sample

set_flux_to_zero(bus_list=None)

Set all lines inside the crosstalk / bus list to 0 Phi0, sets everything into the crosstalk offsets.

Parameters:

bus_list (list[str] | None, optional) – Optional bus list for all the flux used in the experiment. Defaults to the Crosstalk buses.

set_bias_to_zero(bus_list=None)

Set all lines inside the crosstalk / bus list to 0 Volts / Amperes.

Parameters:

bus_list (list[str] | None, optional) – Optional bus list for all the flux used in the experiment. Defaults to the Crosstalk buses.

to_dict()

Returns all platform information as a dictionary, called the runcard. Used for the platform serialization.

Returns:

Dictionary of the serialized platform

Return type:

dict

session()

Context manager to manage platform session, ensuring that resources are always released.

compile_annealing_program(annealing_program_dict, transpiler, calibration, num_averages=1000, num_shots=1, preparation_block='preparation', measurement_block='measurement')

Compile an annealing program into a QProgram by mapping Ising coefficients to flux waveforms.

This method takes an annealing program, represented as a time-ordered list of circuit elements with corresponding Ising coefficients, and compiles it into a quantum program (QProgram) that can be executed on a quantum annealing hardware setup.

The input annealing_program_dict is structured as a list of dictionaries, each representing a specific time point. Each dictionary maps qubit and coupler identifiers to Ising terms (sigma_x, sigma_y, sigma_z), indicating the coefficient values for each term. For example:

[
    {"qubit_0": {"sigma_x": 0, "sigma_y": 1, "sigma_z": 2}, "coupler_1_0": {...}},
    {...},  # time=1ns
    ...,
]

Using the provided transpiler, these Ising coefficients are converted to flux values. These fluxes are then transformed into waveforms assigned to specific hardware buses, as defined by a flux_to_bus mapping in the analog compilation settings.

Parameters:
  • annealing_program_dict (list[dict[str, dict[str, float]]]) – The time-ordered list of qubit and coupler Ising coefficients to be compiled.

  • transpiler (Callable) – A function to convert Ising parameters (delta, epsilon) to flux values (phix, phiz).

  • calibration (Calibration) – Calibration data containing the required blocks (e.g., preparation, measurement) and any applicable crosstalk corrections.

  • num_averages (int, optional) – Number of times the program should be averaged per shot. Defaults to 1000.

  • num_shots (int, optional) – Number of shots to execute the program. Defaults to 1.

  • preparation_block (str, optional) – Name of the calibration block used for preparation. Defaults to “preparation”.

  • measurement_block (str, optional) – Name of the calibration block used for measurement. Defaults to “measurement”.

Returns:

A compiled quantum program (QProgram) ready for execution on the target hardware.

Return type:

QProgram

Raises:
  • ValueError – If the flux-to-bus topology is not defined in the analog compilation settings.

  • ValueError – If the specified measurement_block is not available in the calibration.

Notes

  • The method checks for essential compilation settings and calibrated blocks, ensuring the program can be executed successfully.

  • Transpiled waveforms are adjusted for crosstalk when a crosstalk matrix is available in the calibration.

  • Execution includes optional preparation_block and synchronizes waveforms before the final measurement_block.

execute_annealing_program(annealing_program_dict, transpiler, calibration, num_averages=1000, num_shots=1, preparation_block='preparation', measurement_block='measurement', bus_mapping=None, debug=False)

Given an annealing program execute it as a qprogram. The annealing program should contain a time ordered list of circuit elements and their corresponding ising coefficients as a dictionary. Example structure:

[
    {"qubit_0": {"sigma_x" : 0, "sigma_y" : 1, "sigma_z" : 2},
    "coupler_1_0 : {...},
    },      # time=0ns
    {...},  # time=1ns
.
.
.
]

This dictionary containing ising coefficients is transpiled to fluxes using the given transpiler. Then the corresponding waveforms are obtained and assigned to a bus from the bus to flux mapping given by the runcard.

Parameters:
  • annealing_program_dict (list[dict[str, dict[str, float]]]) – annealing program to run

  • transpiler (Callable) – ising to flux transpiler. The transpiler should take 2 values as arguments (delta, epsilon) and return 2 values (phix, phiz)

  • averages (int, optional) – Amount of times to run and average the program over. Defaults to 1.

  • debug (bool, optional) – Whether to create debug information. For Qblox clusters all the program information is printed on screen. For Quantum Machines clusters a .py file is created containing the QUA and config compilation. Defaults to False.

execute_experiment(experiment, job_id=None, sample=None, cooldown=None)

Executes a quantum experiment on the platform.

This method manages the execution of a given Experiment on the platform by utilizing an ExperimentExecutor. It orchestrates the entire process, including traversing the experiment’s structure, handling loops and operations, and streaming results in real-time to ensure data integrity. Result storage paths, live plotting, and database persistence are configured through qililab.qililab_settings.get_settings().

Parameters:

experiment (Experiment) – The experiment object defining the sequence of operations and loops.

Returns:

The path to the file where the results are stored.

Return type:

str

Example

from qililab import Experiment

# Initialize your experiment
experiment = Experiment(label="my_experiment")
# Add variables, loops, and operations to the experiment
# ...

# Execute the experiment on the platform
results_path = platform.execute_experiment(experiment=experiment)
print(f"Results saved to {results_path}")
Example with database:
from qililab import Experiment, get_settings

# Initialize your experiment
experiment = Experiment(label="my_experiment")
# Add variables, loops, and operations to the experiment
# ...

# Define the database manager. Optional, as this can be done inside execute_experiment
db_manager = platform.load_db_manager(db_manager_ini_path)
db_manager.set_sample_and_cooldown(sample=sample, cooldown=cooldown)

settings = get_settings()
settings.experiment_results_save_in_database = True

# Execute the experiment on the platform
results_path = platform.execute_experiment(experiment=experiment)
print(f"Results saved to {results_path}")

Note

  • Ensure that the experiment is properly configured before execution.

  • The results will be saved in a directory within the load_db_manager config file. The default format is {date}/{time}/{label}.h5.

  • This method handles the setup and execution internally, providing a simplified interface for experiment execution.

execute_qprogram(qprogram, bus_mapping=None, calibration=None, crosstalk=True, debug=False)

Execute a QProgram using the platform instruments.


The execution is done in the following steps:

  1. Compile the QProgram.

  2. Run the compiled QProgram.

  3. Acquire the results.


The execution can be done for (buses associated to) two different type of clusters:

  • For Qblox modules, the compilation is done using the QbloxCompiler. Which compiles the QProgram into``Q1ASM`` for multiple sequencers based on each bus, uploads and executes the sequences, and acquires the results.

  • For Quantum Machines clusters, the compilation is done using the QuantumMachinesCompiler. This compiler transforms the QProgram into QUA, the programming language of Quantum Machines hardware. It then executes the resulting QUA program and returns the results, organized by bus.

Parameters:
  • qprogram (QProgram) – The QProgram to execute.

  • bus_mapping (dict[str, str], optional) – A dictionary mapping the buses in the QProgram (keys )to the buses in the platform (values). It is useful for mapping a generic QProgram to a specific experiment. Defaults to None.

  • calibration (Calibration, optional) – Calibration instance containing information of previously calibrated values, like waveforms, weights and crosstalk matrix. Defaults to None.

  • debug (bool, optional) – Whether to create debug information. For Qblox clusters all the program information is printed on screen. For Quantum Machines clusters a .py file is created containing the QUA and config compilation. Defaults to False.

  • crosstalk (bool, optional) – Trigger that allows crosstalk compensation, if false it ignores all existing crosstalk matrices added to execute with bias. If no crosstalk has been added inside platform or the calibration file, this trigger will not apply the crosstalk. Defaults to None.

Returns:

The results of the execution. QProgramResults.results() returns a dictionary (dict[str, list[Result]]) of measurement results. The keys correspond to the buses a measurement were performed upon, and the values are the list of measurement results in chronological order.

Return type:

QProgramResults

execute_qprograms_parallel(qprograms, bus_mappings=None, calibrations=None, crosstalk=True, debug=False)

Compiles a list of qprograms to be executed in parallel. Then it calls the execute_compilation_outputs_parallel method to execute the compiled qprograms. It loads each qprogram into a different sequencer and uses the multiplexing capabilities of QBlox to run all sequencers at the same time.

The execution can be done for (buses associated to) Qblox only. And it can only be done for qprograms that do not share buses.

Parameters:
  • qprograms (list[QProgram]) – A list of the QProgram to execute.

  • bus_mapping (ist[dict[str, str] | None] | dict[str, str], optional) – A list of dictionaries mapping the buses in the QProgram (keys )to the buses in the platform (values). In this case, each bus mapping gets assigned to the QProgram in the same index of the list of qprograms passed as first parameter. A single dictionary mapping the buses in the QProgram (keys )to the buses in the platform (values). In this case the same bus mapping is used for each one of the qprograms. None, in this case there is not a bus mapping between QProgram (keys )to the buses in the platform (values) and the buses are as defined in each qprogram. It is useful for mapping a generic QProgram to a specific experiment. Defaults to None.

  • calibrations (list[Calibration], Calibration, optional) – A list of Calibration instances, one per QProgram instance in the qprograms parameter. A single instance of Calibration, in this case the same .Calibration instance gets associated to all qprograms. None. In this case no .Calibration instance is used. Defaults to None.

  • debug (bool, optional) – Whether to create debug information. For Qblox clusters all the program information is printed on screen. Defaults to False.

  • crosstalk (bool, optional) – Trigger that allows crosstalk compensation, if false it ignores all existing crosstalk matrices added to execute with bias. If no crosstalk has been added inside platform or the calibration file, this trigger will not apply the crosstalk. Defaults to None.

Returns:

The results of the execution. QProgramResults.results() returns a list of dictionary (dict[str, list[Result]]) of measurement results. Each element of the list corresponds to a sequencer. The keys correspond to the buses a measurement were performed upon, and the values are the list of measurement results in chronological order.

Return type:

QProgramResults

execute_compilation_outputs_parallel(outputs, debug=False)

Execute compiled qprograms in parallel. It loads each qprogram into a different sequencer and uses the multiplexing capabilities of QBlox to run all sequencers at the same time.


The execution is done in the following steps:

  1. Upload all sequences.

  2. Execute all sequences.

  3. Acquire the results.


The execution can be done for (buses associated to) Qblox only.

Parameters:
  • outputs – A list of the compiled qprograms.

  • debug (bool, optional) – Whether to create debug information. For Qblox clusters all the program information is printed on screen. Defaults to False.

Returns:

The results of the execution. QProgramResults.results() returns a list of dictionary (dict[str, list[Result]]) of measurement results. Each element of the list corresponds to a sequencer. The keys correspond to the buses a measurement were performed upon, and the values are the list of measurement results in chronological order.

Return type:

QProgramResults

compile_circuit(circuit, nshots, *, qubit_mapping=None)

Compiles the circuit / pulse schedule into a set of assembly programs, to be uploaded into the awg buses.

If the program argument is a Circuit, it will first be translated into a PulseSchedule using the transpilation settings of the platform and passed transpile configuration. Then the pulse schedules will be compiled into the assembly programs.

Note

Compile is called during platform.execute(), check its documentation for more information.

The transpilation is performed using the CircuitTranspiler.transpile_circuit() method. Refer to the method’s documentation or Transpilation for more detailed information.

The main stages of this process are: 1. Routing, 2. Canceling Hermitian pairs, 3. Translate to native gates, 4. Correcting Drag phases, 5 Optimize Drag gates, 6. Convert to pulse schedule.

Note

Default steps are only: 3., 4., and 6., since they are always needed.

To do Step 1. set routing=True in transpilation_config (default behavior skips it).

To do Steps 2. and 5. set optimize=True in transpilation_config (default behavior skips it)

Parameters:
  • program (PulseSchedule | Circuit) – Circuit or pulse schedule to compile.

  • num_avg (int) – Number of hardware averages used.

  • repetition_duration (int) – Minimum duration of a single execution.

  • num_bins (int) – Number of bins used.

Returns:

Tuple containing the dictionary of compiled assembly programs (The key is the bus alias (str),

and the value is the assembly compilation (list)), and its corresponding final layout (Initial Re-mapping + SWAPs routing) of the Original Logical Qubits (l_q) in the physical circuit (wires): [l_q in wire 0, l_q in wire 1, …] (None = trivial mapping).

Return type:

tuple[dict, list[int] | None]

Raises:

ValueError – raises value error if the circuit execution time is longer than repetition_duration for some qubit.

draw(qprogram, time_window=None, averages_displayed=False, acquisition_showing=True, bus_mapping=None, calibration=None)

Draw the QProgram using QBlox Compiler whilst adding the knowledge of the platform

Parameters:
  • time_window (int) – Allows the user to stop the plotting after the specified number of ns have been plotted. The plotting might not be the precise number of ns inputted. For example, if the timeout is 100 ns but there is a play operation of 150 ns, the plot will display the data until 150 ns. Defaults to None.

  • averages_displayed (bool) – False means that all loops on the sequencer starting with avg will only loop once, and True shows all iterations. Defaults to False.

  • acquisition_showing (bool) – Allows visualizing the acquisition period on the plot. Defaults to True.

  • bus_mapping (dict[str, str], optional) – A dictionary mapping the buses in the QProgram (keys )to the buses in the platform (values). It is useful for mapping a generic QProgram to a specific experiment. Defaults to None.

Returns:

plotly.graph_objs._figure.Figure

Return type:

plotly object

load_db_manager(db_ini_path=None)

Load Database Manager from an .ini path containing user DB user information or if no path is given it uses ‘~/database.ini’.

Parameters:

db_ini_path (str | None, optional) – Database manager initialization file path. Defaults to None.

Returns:

Database manager class

Return type:

DatabaseManager

db_real_time_saving(shape, loops, experiment_name, qprogram=None, description=None)

Allows for real time saving of results from an experiment.

This class wraps a numpy array and adds a context manager to save results and database metadata on real time while they are acquired by the instruments.

Example usage of this function:

platform = ql.build_platform(runcard=runcard)
platform.connect()
platform.initial_setup()
platform.turn_on_instruments()

db_manager = platform.load_db_manager(db_manager_ini_path)
db_manager.set_sample_and_cooldown(sample=sample, cooldown=cooldown)

(experiment definition)

stream_array = platform.database_saving(
    shape=(len(if_sweep), 2),
    loops={"frequency": if_sweep},
    experiment_name="resonator_spectroscopy",
    qprogram=qprogram,
    description="optional text"
)

with stream_array:
    results = platform.execute_qprogram(qprogram).results
    stream_array[()] = results[readout_bus][0].array.T
Parameters:
  • shape (tuple) – results array shape.

  • loops (dict[str, np.ndarray]) – Dictionary of loops with the name of the loop and the array.

  • experiment_name (str) – Name of the experiment.

  • qprogram (QProgram | None, optional) – Qprogram of the experiment, if there is no Qprogram related to the results it is not mandatory. Defaults to None.

  • description (str | None, optional) – String containing a description or any relevant information about the experiment. Defaults to None.

Returns:

StreamArray class to process and save the data

Return type:

StreamArray

db_save_results(experiment_name, results, loops, qprogram=None, description=None)

Uses the same StreamArray class as for live saving but it saves full chunks of data in the same format as platform.stream_array.

Example usage of this function:

platform = ql.build_platform(runcard=runcard)
platform.connect()
platform.initial_setup()
platform.turn_on_instruments()

db_manager = platform.load_db_manager(db_manager_ini_path)
db_manager.set_sample_and_cooldown(sample=sample, cooldown=cooldown)

results = Create experiment results without live saving, either not needed or incapable (VNA data)
or
results = old results to be saved inside the database

saving_path = platform.save_measurement_results(
    experiment_name="resonator_spectroscopy",
    results = results
    loops={"frequency": if_sweep},
    qprogram=qprogram,
    description="optional text"
)
Parameters:
  • experiment_name (str) – Name of the experiment.

  • results (np.ndarray) – Experiment data.

  • loops (dict[str, np.ndarray]) – Dictionary of loops with the name of the loop and the array.

  • qprogram (QProgram | None, optional) – Qprogram of the experiment, if there is no Qprogram related to the results it is not mandatory. Defaults to None.

  • description (str | None, optional) – String containing a description or any relevant information about the experiment. Defaults to None.