Hardware models

Hardware models are a high-level description of quantum processing units (QPUs). They contain all the information about a QPU that is needed at compile time and runtime, including:

  • Topology: How qubits on the QPU are coupled, and the quality of those couplings.

  • Qubit properties: Properties of the qubits that are required for pulse generation, such as the driving frequency.

  • Resonators: Properties of the resonators that are required for readout.

  • Calibrated pulses: The pulses used to manipulate the state of qubits need to be chosen precisely to have the desired outcome. Calibration routines are run frequently to optimize these values: the hardware model contains these calibration results, such as pulse shape and duration.

  • Error mitigation: Contains the readout benchmarks which can be used in error mitigation strategies.

See LogicalHardwareModel and PhysicalHardwareModel for more details on the properties contained in hardware models.

Hardware model loaders

QAT has a number of lightweight “loaders” for importing hardware models from external calibration files and loading in some default models used for simulators and testing.

Echo models

Let’s get started with loading in a simple model of four qubits on a ring with nearest-neighbour connectivity.

from qat.model.loaders.converted import EchoModelLoader

connectivity = [(0, 1), (1, 2), (2, 3), (3, 0)]
model = EchoModelLoader(qubit_count=4, connectivity=connectivity).load()

The connectivity here is used to express which qubits are coupled. While we write it down here explicitly for demonstration purposes, this is the default connectivity for the EchoModelLoader.

Legacy models

Models from legacy QAT can easily be imported, either as a QuantumHardwareModel (the legacy version of hardware models), or as a Pydantic PhysicalHardwareModel. The import type will depend on its use case. The later was achieved in the previous example, where the EchoModelLoader creates a legacy Echo model and converts it to a Pydantic model.

To load the models as a QuantumHardwareModel, qat.model.loaders has a legacy package, which includes the following loaders:

  • EchoModelLoader: a model traditionally used with “echo engines”.

  • LucyModelLoader: a mock-up hardware model of the legacy OQC Lucy hardware.

  • QiskitModelLoader: a model with specific support for Qiskit’s AerSimulator as a target.

  • RTCSModelLoader: a model with specific support for OQC’s real time chip simulator (RTCS).

  • FileModelLoader: used to load legacy hardware models from file.

For legacy models that do not have a designated loader method, we can manually convert from a legacy to Pydantic hardware model by using the convert_legacy_echo_hw_to_pydantic method.

Loading models from external files

Hardware models can be serialized and saved as a JSON file, allowing them to be shared and stored elsewhere after calibration routines are complete. QAT has some helper methods to build hardware models from calibration files, Let’s start by generating a calibration file that we can use as an example.

1from qat.model.loaders.converted import EchoModelLoader
2
3connectivity = [(0, 1), (1, 2), (2, 3), (3, 0)]
4model = EchoModelLoader(qubit_count=4, connectivity=connectivity).load()
5blob = model.model_dump_json()
6with open("temp.json", "w") as f:
7    f.write(blob)

This file can be loaded using the FileModelLoader.

1from qat.model.loaders.file import FileModelLoader
2
3model = FileModelLoader("temp.json").load()

Building hardware models

The PhysicalHardwareModelBuilder can be used for creating hardware models with a custom topology. The couplings of a QPU are known as the “physical connectivity”: in theory, these might be bidirectional. The “logical connectivity” refers to the connectivity that will be used in compilation. This is useful for a few reasons. Firstly, while couplings are bidirectional in principle, in practice we find that a particular QPU might have a preference for just one direction (that is, we are able to calibrate it better for the given direction). Secondly, some QPUs might have faulty couplings that are known not to perform well. When this is the case, we might want to disable the coupling without throwing away knowledge of the existence of the coupling.

As a simple example, let us build a model that has qubits on a ring with nearest-neighbour couplings, but with random coupling directions.

1from qat.model.builder import PhysicalHardwareModelBuilder
2
3physical_connectivity = {0: {1, 3}, 1: {0, 2}, 2: {1, 3}, 3: {2, 0}}
4logical_connectivity = {0: {1}, 2: {1, 3}, 3: {0}}
5builder = PhysicalHardwareModelBuilder(physical_connectivity, logical_connectivity)
6model = builder.model

Note

Once built, the topology of hardware models (including both the physical and logical topology) is frozen and cannot be changed directly. However, the calibratable properties, such as pulses can be modified, are validated to ensure they are sensible.