cunqa.qpu

Mainly contains the QPU class and the functions to manage the virtual QPUs (vQPUs). The Backend class is dependent on the QPU class in the sense that the former is used to hold the features of the vQPU. Additionally, there are four functions: get_QPUs, qdrop, qraise, and run. We can divide this group of functions into two subgroups:

  • qraise and qdrop, which are adaptations of the qraise and qdrop bash commands to Python, respectively. This allows the use of these commands within the Python workflow.

  • get_QPUs and run, which are responsible for creating the QPU objects corresponding to the vQPUs and for sending quantum tasks to the specified vQPUs, respectively.

class Backend
basis_gates: list[str]

Native gates that the Backend accepts. If others are used, they must be translated into the native gates.

coupling_map: list[list[int]]

Defines the physical connectivity of the qubits, that is, which pairs are connected by two-qubit gates.

custom_instructions: str

Any custom instructions that the Backend has defined.

description: str

Custom description of the Backend itself.

gates: list[str]

Specific gates supported.

n_qubits: int

Number of qubits that form the Backend, which determines the maximal number of qubits supported for a quantum circuit.

name: str

Name assigned to the Backend.

noise_properties_path: str

Path to the noise model json file gathering the noise instructions needed for the simulator.

simulator: str

Name of the simulator that simulates the circuits accordingly to the Backend.

version: str

Version of the Backend.

class QPU(id, backend, device, family, endpoint)

Class that serves as representation of a vQPU for user interaction. This class contains the necessary data for connecting to the vQPU in order to send quantum tasks and obtain the results. This communication is performed through the QPU._qclient attribute, which represents the connection between the Python and the C++ parts of CUNQA.

The initialization of the class is normally done by the get_QPUs function, which loads the id, family and endpoint, and instanciates the backend objects. It could also be manually initialized by the user, but this is not recommended.

Parameters:
  • id (int)

  • backend (Backend)

  • device (dict)

  • family (str)

  • endpoint (str)

id : int

ID string assigned to the object.

backend : Backend

Object that provides the characteristics that the simulator at the vQPU uses to emulate a real device.

family : str

Name of the family to which the corresponding vQPU belongs.

Obtain vQPUs and send jobs

get_QPUs(co_located=False, family=None)

Returns QPU objects corresponding to the vQPUs raised by the user. It will use the two args co_located and family to filter from all the QPUs available.

Parameters:
  • co_located (bool) – if False, filters by the vQPUs available at the local node.

  • family (str) – filters vQPUs by their family name.

Return type:

list[QPU]

run(circuits, qpus, param_values=None, **run_args)

Function responsible of sending circuits to several vQPUs. Each circuit will be sent to each QPU in order, therefore, both lists should be the same size. If they are not, but the number of circuits is less than the numbers of QPUs, the circuit will get executed. In case the number of QPUs is less than the number of circuits an error will be raised. Usage example:

>>> circuit1 = CunqaCircuit(1, id="circuit_1")
>>> circuit2 = CunqaCircuit(1, id="circuit_2")
>>> circuit1.h(0)
>>> circuit1.measure(0,0)
>>> circuit1.send(0, "circuit_2")      # Send bit 0 to circuit_2
>>> circuit2.recv("x", 0, "circuit_1") # Receive bit from circuit_1 and apply a conditional x
>>>
>>> qpus = get_QPUs()
>>>
>>> qjobs = run([circuit1, circuit2], qpus)
>>> results = gather(qjobs)

Note

This method will check if two circuits are related, i.e., if one of them was part of a transformation and the other is the result of a transformation. If this is true and a third circuit tries to communicate with them, an error will be raised. A detailed example can be seen in #TODO.

Parameters:
  • circuits (list[dict | CunqaCircuit | QuantumCircuit] | dict | CunqaCircuit | QuantumCircuit) – circuits to be run.

  • qpus (list[QPU] | QPU) – QPU objects associated to the vQPUs in which the circuits want to be run.

  • param_values (dict | list) – either a list of ordered parameters to assign to the parametrized circuit or a dictionary with keys being the free parameters’ names and its values being its corresponding new values.

  • run_args (Any) – any other run arguments and parameters.

Return type:

list[QJob] | QJob

Commands adapted to Python

qraise(n, t, *, classical_comm=False, quantum_comm=False, simulator=None, backend=None, noise_properties_path=None, no_thermal_relaxation=False, no_readout_error=False, no_gate_error=False, fakeqmio=False, family=None, co_located=True, cores=None, mem_per_qpu=None, n_nodes=None, node_list=None, qpus_per_node=None, partition=None, gpu=False, qmio=False)

Raises vQPUs and returns the family name associated them. This function raises QPUs from the python API, which can also be done from terminal by qraise command.

Parameters:
  • n (int) – number of vQPUs to be raised.

  • t (str) – maximun time that the classical resources will be reserved for the job. Format: ‘D-HH:MM:SS’.

  • classical_comm (bool) – if True, vQPUs will allow classical communications.

  • quantum_comm (bool) – if True, vQPUs will allow quantum communications.

  • simulator (str) – name of the desired simulator to use. Default is Aer.

  • backend (str) – path to a file containing the backend information.

  • noise_properties_path (str) – Path to the noise properties json file, only supported for simulator Aer. Default: None

  • no_thermal_relaxation (bool) – if True, deactivate thermal relaxation in a noisy backend. Default: false

  • no_readout_error (bool) – if True, deactivate readout error in a noisy backend. Default: false

  • no_gate_error (bool) – if True, deactivate gate error in a noisy backend. Default: false

  • fakeqmio (bool) – True for raising n vQPUs with FakeQmio backend. Only available at CESGA.

  • family (str) – name to identify the group of vQPUs raised.

  • co_located (bool) – if True, co-located mode is set, otherwise hpc mode is set. In hpc mode, vQPUs can only be accessed from the node in which they are deployed. In co-located mode, they can be accessed from other nodes.

  • cores (str) – number of cores per vQPU, the total for the SLURM job will be n*cores.

  • mem_per_qpu (str) – memory to allocate for each vQPU in GB, format to use is “XXG”.

  • n_nodes (str) – number of nodes for the SLURM job.

  • node_list (str) – list of nodes in which the vQPUs will be deployed.

  • qpus_per_node (str) – sets the number of vQPUs deployed on each node.

  • partition (str) – partition of the nodes in which the QPUs are going to be executed.

Return type:

str

qdrop(*families)

Same functionality as the qdrop bash command, with the peculiarity that it only takes as argument the vQPU family names (and it does not accept the job ID as the bash command). This is done because the Python version of the qraise bash command returns only the family name.

If no families are provided, all vQPUs deployed by the user will be dropped.

Parameters:

families (str) – family names of the groups of vQPUs to be dropped.