Qililab

Latest version: v0.28.0

Safety actively analyzes 706267 Python packages for vulnerabilities to keep your Python projects secure.

Scan your dependencies

Page 1 of 10

0.28.0

New features since last release

- Incorporated new check for maximum allowed attenuation in RF modules.

[843](https://github.com/qilimanjaro-tech/qililab/pull/843)

- Updated to latest qblox-instruments version. Changed some deprecated code from the new version and the QcmQrm into the more generic Module class.

[836](https://github.com/qilimanjaro-tech/qililab/pull/836)

- Added empty handlers for Blocks in QProgram compilers

[839](https://github.com/qilimanjaro-tech/qililab/pull/839)

- Support GRES in %%submit_job magic method

[828](https://github.com/qilimanjaro-tech/qililab/pull/828)

- Added intermediate frequency to single input lines on qm. The default is 0 (this prevents some bugs from qua-qm). Now it is possible to use the set_parameter IF and qm.set_frequency for buses with single_input.

[807](https://github.com/qilimanjaro-tech/qililab/pull/807)

- A new `GetParameter` operation has been added to the Experiment class, accessible via the `.get_parameter()` method. This allows users to dynamically retrieve parameters during experiment execution, which is particularly useful when some variables do not have a value at the time of experiment definition but are provided later through external operations. The operation returns a `Variable` that can be used seamlessly within `SetParameter` and `ExecuteQProgram`.

Example:


experiment = Experiment()

Get a parameter's value
amplitude = experiment.get_parameter(bus="drive_q0", parameter=Parameter.AMPLITUDE)

The returned value is of type `Variable`. It's value will be resolved during execution.
It can be used as usual in operations.

Use the variable in a SetOperation.
experiment.set_parameter(bus="drive_q1", parameter=Parameter.AMPLITUDE, value=amplitude)

Use the variable in an ExecuteQProgram with the lambda syntax.
def get_qprogram(amplitude: float, duration: int):
square_wf = Square(amplitude=amplitude, duration=duration)

qp = QProgram()
qp.play(bus="readout", waveform=square_wf)
return qp

experiment.execute_qprogram(lambda: amplitude=amplitude: get_qprogram(amplitude, 2000))


[814](https://github.com/qilimanjaro-tech/qililab/pull/814)

- Added offset set and get for quantum machines (both OPX+ and OPX1000). For hardware loops there is `qp.set_offset(bus: str, offset_path0: float, offset_path1: float | None)` where `offset_path0` is a mandatory field (for flux, drive and readout lines) and `offset_path1` is only used when changing the offset of buses that have to IQ lines (drive and readout). For software loops there is `platform.set_parameter(alias=bus_name, parameter=ql.Parameter.OFFSET_PARAMETER, value=offset_value)`. The possible arguments for `ql.Parameter` are: `DC_OFFSET` (flux lines), `OFFSET_I` (I lines for IQ buses), `OFFSET_Q` (Q lines for IQ buses), `OFFSET_OUT1` (output 1 lines for readout lines), `OFFSET_OUT2` (output 2 lines for readout lines).
[791](https://github.com/qilimanjaro-tech/qililab/pull/791)

- Added the `Ramp` class, which represents a waveform that linearly ramps between two amplitudes over a specified duration.

python
from qililab import Ramp

Create a ramp waveform from amplitude 0.0 to 1.0 over a duration of 100 units
ramp_wf = Ramp(from_amplitude=0.0, to_amplitude=1.0, duration=100)


[816](https://github.com/qilimanjaro-tech/qililab/pull/816)

- Added the `Chained` class, which represents a waveform composed of multiple waveforms chained together in time.

python
from qililab import Ramp, Square, Chained

Create a chained waveform consisting of a ramp up, a square wave, and a ramp down
chained_wf = Chained(
waveforms=[
Ramp(from_amplitude=0.0, to_amplitude=1.0, duration=100),
Square(amplitude=1.0, duration=200),
Ramp(from_amplitude=1.0, to_amplitude=0.0, duration=100),
]
)


[816](https://github.com/qilimanjaro-tech/qililab/pull/816)

- Added `add_block()` and `get_block()` methods to the `Calibration` class. These methods allow users to store a block of operations in a calibration file and later retrieve it. The block can be inserted into a `QProgram` or `Experiment` by calling `insert_block()`.

python
from qililab import QProgram, Calibration

Create a QProgram and add operations
qp = QProgram()
Add operations to qp...

Store the QProgram's body as a block in the calibration file
calibration = Calibration()
calibration.add_block(name="qp_as_block", block=qp.body)

Retrieve the block by its name
calibrated_block = calibration.get_block(name="qp_as_block")

Insert the retrieved block into another QProgram
another_qp = QProgram()
another_qp.insert_block(block=calibrated_block)


[816](https://github.com/qilimanjaro-tech/qililab/pull/816)

- Added routing algorithms to `qililab` in function of the platform connectivity. This is done passing `Qibo` own `Routers` and `Placers` classes,
and can be called from different points of the stack.

The most common way to route, will be automatically through `qililab.execute_circuit.execute()`, or also from `qililab.platform.execute/compile()`. Another way, would be doing the transpilation/routing directly from an instance of the Transpiler, with: `qililab.digital.circuit_transpiler.transpile/route_circuit()` (with this last one, you can route with a different topology from the platform one, if desired, defaults to platform)

Example

python
from qibo import gates
from qibo.models import Circuit
from qibo.transpiler.placer import ReverseTraversal, Trivial
from qibo.transpiler.router import Sabre
from qililab import build_platform
from qililab.circuit_transpiler import CircuitTranspiler

Create circuit:
c = Circuit(5)
c.add(gates.CNOT(1, 0))

From execute_circuit:
With defaults (ReverseTraversal placer and Sabre routing):
probabilities = ql.execute(c, runcard="./runcards/galadriel.yml", placer= Trivial, router = Sabre, routing_iterations: int = 10,)
Changing the placer to Trivial, and changing the number of iterations:
probabilities = ql.execute(c, runcard="./runcards/galadriel.yml",

From the platform:
Create platform:
platform = build_platform(runcard="<path_to_runcard>")
With defaults (ReverseTraversal placer, Sabre routing)
probabilities = platform.execute(c, num_avg: 1000, repetition_duration: 1000)
With non-defaults, and specifying the router with kwargs:
probabilities = platform.execute(c, num_avg: 1000, repetition_duration: 1000, placer= Trivial, router = (Sabre, {"lookahead": 2}), routing_iterations: int = 20))
With a router instance:
router = Sabre(connectivity=None, lookahead=1) No connectivity needed, since it will be overwritten by the platform's one
probabilities = platform.execute(c, num_avg: 1000, repetition_duration: 1000, placer=Trivial, router=router)

Using the transpiler directly:
(If using the routing from this points of the stack, you can route with a different topology from the platform one)
Create transpiler:
transpiler = CircuitTranspiler(platform)
Default Transpilation (ReverseTraversal, Sabre and Platform connectivity):
routed_circ, final_layouts = transpiler.route_circuit([c])
With Non-Default Trivial placer, specifying the kwargs, for the router, and different coupling_map:
routed_circ, final_layouts = transpiler.route_circuit([c], placer=Trivial, router=(Sabre, {"lookahead": 2}, coupling_map=<some_different_topology>))
Or finally, Routing with a concrete Routing instance:
router = Sabre(connectivity=None, lookahead=1) No connectivity needed, since it will be overwritten by the specified in the Transpiler:
routed_circ, final_layouts = transpiler.route_circuit([c], placer=Trivial, router=router, coupling_map=<connectivity_to_use>)


[821](https://github.com/qilimanjaro-tech/qililab/pull/821)

- Added a timeout inside quantum machines to control the `wait_for_all_values` function. The timeout is controlled through the runcard as shown in the example:

yaml
instruments:
- name: quantum_machines_cluster
alias: QMM
...
timeout: 10000 optional timeout in seconds
octaves:
...


[826](https://github.com/qilimanjaro-tech/qililab/pull/826)

- Added `shareable` trigger inside runcard for quantum machines controller. The controller is defined in the runcard following this example:


instruments:
- name: con1
analog_outputs:
- port: 1
offset: 0.0
shareable: True


[844](https://github.com/qilimanjaro-tech/qililab/pull/844)

Improvements

- Legacy linting and formatting tools such as pylint, flake8, isort, bandit, and black have been removed. These have been replaced with Ruff, a more efficient tool that handles both linting and formatting. All configuration settings have been consolidated into the `pyproject.toml` file, simplifying the project's configuration and maintenance. Integration config files like `pre-commit-config.yaml` and `.github/workflows/code_quality.yml` have been updated accordingly. Several rules from Ruff have also been implemented to improve code consistency and quality across the codebase. Additionally, the development dependencies in `dev-requirements.txt` have been updated to their latest versions, ensuring better compatibility and performance. [813](https://github.com/qilimanjaro-tech/qililab/pull/813)

- `platform.execute_experiment()` and the underlying `ExperimentExecutor` can now handle experiments with multiple qprograms and multiple measurements. Parallel loops are also supported in both experiment and qprogram. The structure of the HDF5 results file as well as the functionality of `ExperimentResults` class have been changed accordingly. [796](https://github.com/qilimanjaro-tech/qililab/pull/796)

- Added pulse distorsions in `execute_qprogram` for QBlox in a similar methodology to the distorsions implemented in pulse circuits. The runcard needs to contain the same structure for distorsions as the runcards for circuits and the code will modify the waveforms after compilation (inside `platform.execute_qprogram`).

Example (for Qblox)

yaml
buses:
- alias: readout
...
distortions:
- name: exponential
tau_exponential: 1.
amp: 1.
sampling_rate: 1. Optional. Defaults to 1
norm_factor: 1. Optional. Defaults to 1
auto_norm: True Optional. Defaults to True
- name: bias_tee
tau_bias_tee: 11000
sampling_rate: 1. Optional. Defaults to 1
norm_factor: 1. Optional. Defaults to 1
auto_norm: True Optional. Defaults to True
- name: lfilter
a: []
b: []
norm_factor: 1. Optional. Defaults to 1
auto_norm: True Optional. Defaults to True


[779](https://github.com/qilimanjaro-tech/qililab/pull/779)

- The execution of `QProgram` has been split into two distinct steps: **compilation** and **execution**.

1. **Compilation**: Users can now compile a `QProgram` by calling:

python
platform.compile_qprogram(
qprogram: QProgram,
bus_mapping: dict[str, str] | None = None,
calibration: Calibration | None = None
)


This method can be executed without being connected to any instruments. It returns either a `QbloxCompilationOutput` or a `QuantumMachinesCompilationOutput`, depending on the platform setup.

2. **Execution**: Once the compilation is complete, users can execute the resulting output by calling:

python
platform.execute_compilation_output(
output: QbloxCompilationOutput | QuantumMachinesCompilationOutput,
debug: bool = False
)


If desired, both steps can still be combined into a single call using the existing method:

python
platform.execute_qprogram(
qprogram: QProgram,
bus_mapping: dict[str, str] | None = None,
calibration: Calibration | None = None,
debug: bool = False
)


[817](https://github.com/qilimanjaro-tech/qililab/pull/817)

- Introduced settable attributes `experiment_results_base_path` and `experiment_results_path_format` in the `Platform` class. These attributes determine the directory and file structure for saving experiment results during execution. By default, results are stored within `experiment_results_base_path` following the format `{date}/{time}/{label}.h5`. [819](https://github.com/qilimanjaro-tech/qililab/pull/819)

- Added a `save_plot=True` parameter to the `plotS21()` method of `ExperimentResults`. When enabled (default: True), the plot is automatically saved in the same directory as the experiment results. [819](https://github.com/qilimanjaro-tech/qililab/pull/819)

- Improved the transpiler, by making it more modular, and adding a `gate_cancellation()` stage before the transpilation to natives, this stage can be skipped, together with the old `optimize_transpilation()`, if the flag `optimize=False` is passed. [823](https://github.com/qilimanjaro-tech/qililab/pull/823)

- Split execution of annealing programs into two steps: compilation and execution. [825](https://github.com/qilimanjaro-tech/qililab/pull/825)

- Added a try and except similar to the dataloss error to restart the measurement in case of random timeout issue for quantum machines. This is a temporary fix and will be deleted once the Quantum Machines team fix their issue.

[832](https://github.com/qilimanjaro-tech/qililab/pull/832)

Breaking changes

- Renamed the platform's `execute_anneal_program()` method to `execute_annealing_program()` and updated its parameters. The method now expects `preparation_block` and `measurement_block`, which are strings used to retrieve blocks from the `Calibration`. These blocks are inserted before and after the annealing schedule, respectively.
[816](https://github.com/qilimanjaro-tech/qililab/pull/816)

- **Major reorganization of the library structure and runcard functionality**. Key updates include:

- Removed obsolete instruments, such as VNAs.
- Removed the `drivers` module.
- Simplified the `Qblox` sequencer class hierarchy into two main classes: `QbloxSequencer` and `QbloxADCSequencer`.
- Removed `SystemController` and `ReadoutSystemController`; buses now interface directly with instruments.
- Introduced a new `channels` attribute to the `Bus` class, allowing specification of channels for each associated instrument.
- Removed the `Chip` class and its related runcard settings.
- Eliminated outdated settings, such as instrument firmware.
- Refactored runcard settings into a modular structure with four distinct groups:
- `instruments` and `instrument_controllers` for lab instrument setup.
- `buses` for grouping instrument channels.
- `digital` for digital compilation settings (e.g., Qibo circuits).
- `analog` for analog compilation settings (e.g., annealing programs).

[820](https://github.com/qilimanjaro-tech/qililab/pull/820)

Bug fixes

- Fixed minor type bug in `Platform`. [846](https://github.com/qilimanjaro-tech/qililab/pull/846)

- Fixed minor type bug in `CrosstalkMatrix`. [825](https://github.com/qilimanjaro-tech/qililab/pull/825)

- Fixed typo in ExceptionGroup import statement for python 3.11+ [808](https://github.com/qilimanjaro-tech/qililab/pull/808)

- Fixed serialization/deserialization of lambda functions, mainly used in `experiment.execute_qprogram()` method. The fix depends on the `dill` library which is added as requirement. [815](https://github.com/qilimanjaro-tech/qililab/pull/815)

- Fixed calculation of Arbitrary waveform's envelope when resolution is greater than 1ns. [837](https://github.com/qilimanjaro-tech/qililab/pull/837)

0.27.1

New features since last release

- Introduced the possibility to run multiple shots and averages at the same time for `execute_anneal_program` method.
[797](https://github.com/qilimanjaro-tech/qililab/pull/797)

- Introduced the `Experiment` class, which inherits from `StructuredProgram`. This new class enables the ability to set parameters and execute quantum programs within a structured experiment. Added the `set_parameter` method to allow setting platfform parameters and `execute_qprogram` method to facilitate the execution of quantum programs within the experiment.
[782](https://github.com/qilimanjaro-tech/qililab/pull/782)

- Introduced the `ExperimentExecutor` class to manage and execute quantum experiments within the Qililab framework. This class provides a streamlined way to handle the setup, execution, and results retrieval of experiments.

Temporary Constraints:

- The experiment must contain only one `QProgram`.
- The `QProgram` must contain a single measure operation.
- Parallel loops are not supported.
[790](https://github.com/qilimanjaro-tech/qililab/pull/790)

- Introduced the `platform.execute_experiment()` method for executing experiments. This method simplifies the interaction with the ExperimentExecutor by allowing users to run experiments with a single call.

Example:

Python
Define the QProgram
qp = QProgram()
gain = qp.variable(label='resonator gain', domain=Domain.Voltage)
with qp.for_loop(gain, 0, 10, 1):
qp.set_gain(bus="readout_bus", gain=gain)
qp.measure(bus="readout_bus", waveform=IQPair(I=Square(1.0, 1000), Q=Square(1.0, 1000)), weights=IQPair(I=Square(1.0, 2000), Q=Square(1.0, 2000)))

Define the Experiment
experiment = Experiment()
bias_z = experiment.variable(label='bias_z voltage', domain=Domain.Voltage)
frequency = experiment.variable(label='LO Frequency', domain=Domain.Frequency)
experiment.set_parameter(alias="drive_q0", parameter=Parameter.VOLTAGE, value=0.5)
experiment.set_parameter(alias="drive_q1", parameter=Parameter.VOLTAGE, value=0.5)
experiment.set_parameter(alias="drive_q2", parameter=Parameter.VOLTAGE, value=0.5)
with experiment.for_loop(bias_z, 0.0, 1.0, 0.1):
experiment.set_parameter(alias="readout_bus", parameter=Parameter.VOLTAGE, value=bias_z)
with experiment.for_loop(frequency, 2e9, 8e9, 1e9):
experiment.set_parameter(alias="readout_bus", parameter=Parameter.LO_FREQUENCY, value=frequency)
experiment.execute_qprogram(qp)

Execute the Experiment and display the progress bar.
Results will be streamed to an h5 file. The path of this file is returned from the method.
path = platform.execute_experiment(experiment=experiment, results_path="/tmp/results/")

Load results
results, loops = load_results(path)


[790](https://github.com/qilimanjaro-tech/qililab/pull/790)

- Introduced a robust context manager `platform.session()` for managing platform lifecycle operations. The manager automatically calls `platform.connect()`, `platform.initial_setup()`, and `platform.turn_on_instruments()` to set up the platform environment before experiment execution. It then ensures proper resource cleanup by invoking `platform.turn_off_instruments()` and `platform.disconnect()` after the experiment, even in the event of an error or exception during execution. If multiple exceptions occur during cleanup (e.g., failures in both `turn_off_instruments()` and `disconnect()`), they are aggregated into a single `ExceptionGroup` (Python 3.11+) or a custom exception for earlier Python versions.

Example:

Python
with platform.session():
do stuff...


[792](https://github.com/qilimanjaro-tech/qililab/pull/792)

- Add crosstalk compensation to `AnnealingProgram` workflow. Add methods to `CrosstalkMatrix` to ease crosstalk compensation in the annealing workflow
[775](https://github.com/qilimanjaro-tech/qililab/pull/775)

- Add default measurement to `execute_anneal_program()` method. This method takes now a calibration file and parameters
to add the dispersive measurement at the end of the annealing schedule.
[778](https://github.com/qilimanjaro-tech/qililab/pull/778)

- Added a try/except clause when executing a QProgram on Quantum Machines cluster that controls the execution failing to perform a turning off of the instrument so the \_qm object gets
removed. This, plus setting the close_other_machines=True by default allows to open more than one QuantumMachines VM at the same time to allow more than one experimentalist to work at the same time in the cluster.
[760](https://github.com/qilimanjaro-tech/qililab/pull/760/)

- Added `__str__` method to qprogram. The string is a readable qprogram.
[767](https://github.com/qilimanjaro-tech/qililab/pull/767)

- Added workflow for the execution of annealing programs.

Example:

Python
import qililab as ql

platform = ql.build_platform("examples/runcards/galadriel.yml")
anneal_program_dict = [
{qubit_0": {"sigma_x" : 0, "sigma_y": 0, "sigma_z": 1, "phix":1, "phiz":1},
"qubit_1": {"sigma_x" : 0.1, "sigma_y": 0.1, "sigma_z": 0.1},
"coupler_0_1": {"sigma_x" : 1, "sigma_y": 0.2, "sigma_z": 0.2}
},
{"qubit_0": {"sigma_x" : 0.1, "sigma_y": 0.1, "sigma_z": 1.1},
"qubit_1": {"sigma_x" : 0.2, "sigma_y": 0.2, "sigma_z": 0.2},
"coupler_0_1": {"sigma_x" : 0.9, "sigma_y": 0.1, "sigma_z": 0.1}
},
{"qubit_0": {"sigma_x" : 0.3, "sigma_y": 0.3, "sigma_z": 0.7},
"qubit_1": {"sigma_x" : 0.5, "sigma_y": 0.2, "sigma_z": 0.01},
"coupler_0_1": {"sigma_x" : 0.5, "sigma_y": 0, "sigma_z": -1}
}
]

results = platform.execute_anneal_program(anneal_program_dict=anneal_program_dict, transpiler=lambda delta, epsilon: (delta, epsilon), averages=100_000)


Alternatively, each step of the workflow can be executed separately i.e. the following is equivalent to the above:

python
import qililab as ql

platform = ql.build_platform("examples/runcards/galadriel.yml")
anneal_program_dict = [...] same as in the above example
intialize annealing program class
anneal_program = ql.AnnealingProgram(
platform=platform, anneal_program=anneal_program_dict
)
transpile ising to flux, now flux values can be accessed same as ising coeff values
eg. for phix qubit 0 at t=1ns anneal_program.anneal_program[1]["qubit_0"]["phix"]
anneal_program.transpile(lambda delta, epsilon: (delta, epsilon))
get a dictionary {control_flux: (bus, waveform) from the transpiled fluxes
anneal_waveforms = anneal_program.get_waveforms()
from here on we can create a qprogram to execute the annealing schedule


[767](https://github.com/qilimanjaro-tech/qililab/pull/767)

- Added `CrosstalkMatrix` class to represent and manipulate a crosstalk matrix, where each index corresponds to a bus. The class includes methods for initializing the matrix, getting and setting crosstalk values, and generating string representations of the matrix.

Example:

Python
Create an empty crosstalk matrix
crosstalk_matrix = CrosstalkMatrix()

Add crosstalk values, where the keys are in matrix shape [row][column]
crosstalk_matrix["bus1"]["bus2"] = 0.9
crosstalk_matrix["bus2"]["bus1"] = 0.1

Alternatively, create a matrix from a collection of buses.
All crosstalk values are initialized to 1.0
crosstalk_matrix = CrosstalkMatrix.from_buses({"bus1", "bus2", "bus3"})

Get a formatted string representation of the matrix
bus1 bus2 bus3
bus1 \ 1.0 1.0
bus2 1.0 \ 1.0
bus3 1.0 1.0 \

print(crosstalk_matrix)


- Added the Qblox-specific `set_markers()` method in `QProgram`. This method takes a 4-bit binary mask as input, where `0` means that the associated marker will be open (no signal) and `1` means that the associated marker will be closed (signal). The mapping between bit indexes and markers depends on the Qblox module that the compiled `QProgram` will run on.

Example:

Python
qp = QProgram()
qp.qblox.set_markers(bus='drive_q0', mask='0111')


[747](https://github.com/qilimanjaro-tech/qililab/pull/747)

- Added `set_markers_override_enabled_by_port` and `set_markers_override_value_by_port` methods in `QbloxModule` to set markers through QCoDeS, overriding Q1ASM values.
[747](https://github.com/qilimanjaro-tech/qililab/pull/747)

- Added `from_qprogram` method to the `Counts` class to compute the counts of quantum states obtained from a `QProgram`. The `Counts` object is designed to work for circuits that have only one measurement per bus at the end of the circuit execution. It is the user's responsibility to ensure that this method is used appropriately when it makes sense to compute the state counts for a `QProgram`. Note that probabilities can easily be obtained by calling the `probabilities()` method. See an example below.

Example:

Python
from qililab.result.counts import Counts

qp = QProgram()
Define instructions for QProgram
...
qp_results = platform.execute_qprogram(qp) Platform previously defined
counts_object = Counts.from_qprogram(qp_results)
probs = counts_object.probabilities()


[743](https://github.com/qilimanjaro-tech/qililab/pull/743)

- Added `threshold_rotations` argument to `compile()` method in `QProgram`. This argument allows to use rotation angles on measurement instructions if not specified. Currently used to use the angle rotations specified on the runcard (if any) so the user does not have to explicitly pass it as argument to the measure instruction. Used for classification of results in Quantum Machines's modules. The following example shows how to specify this value on the runcard.

Example:

yaml
buses:
- alias: readout_q0_bus
system_control:
name: readout_system_control
instruments: [QMM]
port: readout_line_q0
distortions: []
instruments:
- name: quantum_machines_cluster
alias: QMM
firmware: ...
elements:
- bus: readout_q0_bus
rf_inputs:
octave: octave1
port: 1
rf_outputs:
octave: octave1
port: 1
time_of_flight: 160
smearing: 0
intermediate_frequency: 10.0e+6
threshold_rotation: 0.5
threshold: 0.03
...


[759](https://github.com/qilimanjaro-tech/qililab/pull/759)

- Added `thresholds` argument to `_execute_qprogram_with_quantum_machines` method in `Platform`. This argument allows to threshold results after the execution of the `QProgram`. It is also a new parameter that can be specified on the runcard for each readout bus. An example of the configuration of this parameter on the runcard can be found above.

[762](https://github.com/qilimanjaro-tech/qililab/pull/762)

- Added `filter` argument inside the qua config file compilation from runcards with qm clusters. This is an optional element for distorsion filters that includes feedforward and feedback, two distorion lists for distorsion compensation and fields in qua config filter. These filters are calibrated and then introduced as compensation for the distorsions of the pulses from external sources such as Bias T. The runcard now might include the new filters (optional):

Example:


instruments:
- name: quantum_machines_cluster
alias: QMM
firmware: 0.7.0
...
controllers:
- name: con1
analog_outputs:
- port: 1
offset: 0.0
filter:
feedforward: [0.1,0.1,0.1]
feedback: [0.1,0.1,0.1]
...


[768](https://github.com/qilimanjaro-tech/qililab/pull/768)

- Added loopbacks in the octave config file for qua following the documentation at https://docs.quantum-machines.co/1.2.0/qm-qua-sdk/docs/Guides/octave/?h=octaves#setting-the-octaves-clock. By default only port 1 of the octave is linked with a local demodulator, to work with the rest of the ports at the back ports must be connected based on the Octave Block Diagram \[https://docs.quantum-machines.co/1.2.0/qm-qua-sdk/docs/Hardware/octave/#octave-block-diagram\]. Where `Synth` is one of the possible 3 synths and `Dmd` is one of the 2 demodulators.

Example:


- name: quantum_machines_cluster
alias: QMM
...
octaves:
- name: octave1
port: 11252
...
loopbacks:
Synth: Synth2 Synth1, Synth2, Synth3
Dmd: Dmd2LO Dmd1LO, Dmd2LO


[770](https://github.com/qilimanjaro-tech/qililab/pull/770)

- Added delay variables to Qblox qprogram implementation. The delays are added in the runcard in nanoseconds and they can be positive or negative scalars (negative delays will make the rest of buses wait). The delay is a wait applied to each iteration of a loop where the bus is present.

Example:


buses:
- alias: readout
...
delay: 100


[793](https://github.com/qilimanjaro-tech/qililab/pull/793)

Improvements

- Improve Crosstalk matrix `from_buses` method so it can be a dictionary of buses and crosstalks coefficients.
\[784\]https://github.com/qilimanjaro-tech/qililab/pull/784

- Now platform.get_parameter works for QM without the need of connecting to the machine.

- Added the option to get the time of flight and smearing information from the QM cluster
[751](https://github.com/qilimanjaro-tech/qililab/pull/751)

- Improved the algorithm determining which markers should be ON during execution of circuits and qprograms. Now, all markers are OFF by default, and only the markers associated with the `outputs` setting of QCM-RF and QRM-RF sequencers are turned on.
[747](https://github.com/qilimanjaro-tech/qililab/pull/747)

- Automatic method to implement the correct `upsampling_mode` when the output mode is selected as `amplified` (fluxes), the `upsampling_mode` is automatically defined as `pulse`. In this mode, the upsampling is optimized to produce cleaner step responses.
[783](https://github.com/qilimanjaro-tech/qililab/pull/783)

- Automatic method for `execute_qprogram` in quantum machines to restart the measurement in case the `StreamProcessingDataLossError` is risen by `qua-qm`, the new feature allows to try again the measurement a number of times equal to the value of `dataloss_tries` (default of three). We can define this value at `execute_qprogram(..., dataloss_tries = N)` and will only do its intended job in case of working with QM.
[788](https://github.com/qilimanjaro-tech/qililab/pull/788)

Breaking changes

- Big code refactor for the `calibration` module/directory, where all `comparisons`, `check_parameters`, `check_data()`,
`check_state()`, `maintain()`, `diagnose()` and other complex unused methods have been deleted, leaving only linear calibration.

Also some other minor improvements like:

- `drift_timeout` is now a single one for the full controller, instead of a different one for each node.
- Notebooks without an export are also accepted now (we will only raise error for multiple exports in a NB).
- Extended/Improved the accepted type for parameters to input/output in notebooks, thorught json serialization.
[746](https://github.com/qilimanjaro-tech/qililab/pull/746)

- Variables in `QProgram` and `Experiment` now require a label.

Python
qp = QProgram()
gain = qp.variable(label="gain", domain=Domain.Voltage)


[790](https://github.com/qilimanjaro-tech/qililab/pull/790)

Deprecations / Removals

- Deleted all the files in `execution` and `experiment` directories (Already obsolete).
[749](https://github.com/qilimanjaro-tech/qililab/pull/749)

Documentation

Bug fixes

- Hotfix to allow to serialise zeros in yaml.
[799](https://github.com/qilimanjaro-tech/qililab/pull/799)

- get_parameter for QM did not work due to the lack of the variable `bus_alias in self.system_control.get_parameter`. The variable has been added to the function and now get parameter does not return a crash.
[751](https://github.com/qilimanjaro-tech/qililab/pull/751)

- set_parameter for intermediate frequency in quantum machines has been adapted for both OPX+ and OPX1000 following the new requirements for OPX1000 with qm-qua job.set_intermediate_frequency.
[764](https://github.com/qilimanjaro-tech/qililab/pull/764)

0.27.0

New features since last release

- Added `Calibration` class to manage calibrated waveforms and weights for QProgram. Included methods to add (`add_waveform`/`add_weights`), check (`has_waveform`/`has_weights`), retrieve (`get_waveform`/`get_weights`), save (`save_to`), and load (`load_from`) calibration data.

Example:

Python
Create a Calibration instance
calibration = Calibration()

Define waveforms and weights
drag_wf = IQPair.DRAG(amplitude=1.0, duration=40, num_sigmas=4.5, drag_coefficient=-2.5)
readout_wf = ql.IQPair(I=ql.Square(amplitude=1.0, duration=200), Q=ql.Square(amplitude=0.0, duration=200))
weights = ql.IQPair(I=ql.Square(amplitude=1.0, duration=200), Q=ql.Square(amplitude=1.0, duration=200))

Add waveforms to the calibration
calibration.add_waveform(bus='drive_q0_bus', name='Xpi', waveform=drag_wf)
calibration.add_waveform(bus='readout_q0_bus', name='Measure', waveform=readout_wf)

Add weights to the calibration
calibration.add_weights(bus='readout_q0_bus', name='optimal_weights', weights=weights)

Save the calibration data to a file
calibration.save_to('calibration_data.yml')

Load the calibration data from a file
loaded_calibration = Calibration.load_from('calibration_data.yml')


The contents of `calibration_data.yml` will be:

YAML
!Calibration
waveforms:
drive_q0_bus:
Xpi: !IQPair
I: &id001 !Gaussian {amplitude: 1.0, duration: 40, num_sigmas: 4.5}
Q: !DragCorrection
drag_coefficient: -2.5
waveform: *id001
readout_q0_bus:
Measure: !IQPair
I: !Square {amplitude: 1.0, duration: 200}
Q: !Square {amplitude: 0.0, duration: 200}
weights:
readout_q0_bus:
optimal_weights: !IQPair
I: !Square {amplitude: 1.0, duration: 200}
Q: !Square {amplitude: 1.0, duration: 200}


Calibrated waveforms and weights can be used in QProgram by providing their name.

Python
qp = QProgram()
qp.play(bus='drive_q0_bus', waveform='Xpi')
qp.measure(bus='readout_q0_bus', waveform='Measure', weights='optimal_weights')


In that case, a `Calibration` instance must be provided when executing the QProgram. (see following changelog entries)

[729](https://github.com/qilimanjaro-tech/qililab/pull/729)
[736](https://github.com/qilimanjaro-tech/qililab/pull/736)

- Introduced `qililab.yaml` namespace that exports a single `YAML` instance for common use throughout qililab. Classes should be registered to this instance with the `yaml.register_class` decorator.

Python
from qililab.yaml import yaml

yaml.register_class
class MyClass:
...


`MyClass` can now be saved to and loaded from a yaml file.

Python
from qililab.yaml import yaml

my_instance = MyClass()

Save to file
with open(file="my_file.yml", mode="w", encoding="utf-8") as stream:
yaml.dump(data=my_instance, stream=stream)

Load from file
with open(file="my_file.yml", mode="r", encoding="utf8") as stream:
loaded_instance = yaml.load(stream)


[729](https://github.com/qilimanjaro-tech/qililab/pull/729)

- Added `serialize()`, `serialize_to()`, `deserialize()`, `deserialize_from()` functions to enable a unified method for serializing and deserializing Qililab classes to and from YAML memory strings and files.

Python
import qililab as ql

qp = QProgram()

Serialize QProgram to a memory string and deserialize from it.
yaml_string = ql.serialize(qp)
deserialized_qprogram = ql.deserialize(yaml_string)

Specify the class for deserialization using the `cls` parameter.
deserialized_qprogram = ql.deserialize(yaml_string, cls=ql.QProgram)

Serialize to and deserialize from a file.
ql.serialize_to(qp, 'qprogram.yml')
deserialized_qprogram = ql.deserialize_from('qprogram.yml', cls=ql.QProgram)


[737](https://github.com/qilimanjaro-tech/qililab/pull/737)

- Added Qblox support for QProgram's `measure` operation. The method can now be used for both Qblox
and Quantum Machines, and the expected behaviour is the same.

Python
readout_pair = IQPair(I=Square(amplitude=1.0, duration=1000), Q=Square(amplitude=0.0, duration=1000))
weights_pair = IQPair(I=Square(amplitude=1.0, duration=2000), Q=Square(amplitude=0.0, duration=2000))
qp = QProgram()

The measure operation has the same behaviour in both vendors.
Time of flight between readout pulse and beginning of acquisition is retrieved from the instrument's settings.
qp.measure(bus="readout_bus", waveform=readout_pair, weights=weights_pair, save_adc=True)


[734](https://github.com/qilimanjaro-tech/qililab/pull/734)
[736](https://github.com/qilimanjaro-tech/qililab/pull/736)
[738](https://github.com/qilimanjaro-tech/qililab/pull/738)

- Update Qibo version to `v.0.2.8`.
[732](https://github.com/qilimanjaro-tech/qililab/pull/732)

Improvements

- Introduced `QProgram.with_bus_mapping` method to remap buses within the QProgram.

Example:

Python
Define the bus mapping
bus_mapping = {"drive": "drive_q0"}

Apply the bus mapping to a QProgram instance
mapped_qprogram = qprogram.with_bus_mapping(bus_mapping=bus_mapping)


[729](https://github.com/qilimanjaro-tech/qililab/pull/729)
[740](https://github.com/qilimanjaro-tech/qililab/pull/740)

- Introduced `QProgram.with_calibration` method to apply calibrated waveforms and weights to the QProgram.

Example:

Python
Load the calibration data from a file
calibration = Calibration.load_from('calibration_data.yml')

Apply the calibration to a QProgram instance
calibrated_qprogram = qprogram.with_calibration(calibration=calibration)


[729](https://github.com/qilimanjaro-tech/qililab/pull/729)
[736](https://github.com/qilimanjaro-tech/qililab/pull/736)

- Extended `Platform.execute_qprogram` method to accept a calibration instance.

Python
Load the calibration data from a file
calibration = Calibration.load_from('calibration_data.yml')

platform.execute_qprogram(qprogram=qprogram, calibration=calibration)


[729](https://github.com/qilimanjaro-tech/qililab/pull/729)

- Added interfaces for Qblox and Quantum Machines to QProgram. The interfaces contain vendor-specific methods and parameters. They can be accessed by `qprogram.qblox` and `qprogram.quantum_machines` properties.

[736](https://github.com/qilimanjaro-tech/qililab/pull/736)

- Added `time_of_flight` setting to Qblox QRM and QRM-RF sequencers.

[738](https://github.com/qilimanjaro-tech/qililab/pull/738)

Breaking changes

- QProgram interface now contains methods and parameters that have common functionality for all hardware vendors. Vendor-specific methods and parameters have been move to their respective interface.

Examples:

Python
Acquire method has been moved to Qblox interface. Instead of running
qp.acquire(bus="readout_q0_bus", weights=weights)
you should run
qp.qblox.acquire(bus="readout_q0_bus", weights=weights)

Play method with `wait_time` parameter has been moved to Qblox interface. Instead of running
qp.play(bus="readout_q0_bus", waveform=waveform, wait_time=40)
you should run
qp.qblox.play(bus="readout_q0_bus", waveform=waveform, wait_time=40)

`disable_autosync` parameter has been moved to Qblox interface. Instead of running
qp = QProgram(disable_autosync=True)
you should run
qp = QProgram()
qp.qblox.disable_autosync = True

Measure method with parameters `rotation` and `demodulation` has been moved to Quantum Machines interface. Instead of running
qp.measure(bus="readout_q0_bus", waveform=waveform, weights=weights, save_adc=True, rotation=np.pi, demodulation=True)
you should run
qp.quantum_machines.measure(bus="readout_q0_bus", waveform=waveform, weights=weights, save_adc=True, rotation=np.pi, demodulation=True)


[736](https://github.com/qilimanjaro-tech/qililab/pull/736)

- `time_of_flight` parameter must be added to Qblox QRM and QRM-RF sequencers's runcard settings.

[738](https://github.com/qilimanjaro-tech/qililab/pull/738)

Deprecations / Removals

- Remove `qiboconnection` dependency from Qililab. It is not a requirement anymore.
[732](https://github.com/qilimanjaro-tech/qililab/pull/732)

- Following the remove of Qiboconnection, `LivePlot` has been removed along with the creation of a `Platform` via API.
[732](https://github.com/qilimanjaro-tech/qililab/pull/732)

- Remove the deprecated `path` argument from `build_platform()`.

[739](https://github.com/qilimanjaro-tech/qililab/pull/739)

0.26.2

New features since last release

- Introduce the Two-Step pulse shape to improve readout
[730](https://github.com/qilimanjaro-tech/qililab/pull/730)

Deprecations / Removals

- Remove qiboconnection_api.block_device() and release_device()
[728](https://github.com/qilimanjaro-tech/qililab/pull/728)

0.26.1

Bug fixes

- Hotfix for the 2readout problem
[720](https://github.com/qilimanjaro-tech/qililab/pull/720)

0.25.1

Bug fixes

- Appended hardcoded Time of Flight
[711](https://github.com/qilimanjaro-tech/qililab/pull/711)

Page 1 of 10

© 2025 Safety CLI Cybersecurity Inc. All Rights Reserved.