Backend

SpinQit has five different types of backends: a basic classical simulator, a simulator based on PyTorch, local quantum computers from SpinQ, the SpinQ cloud, and a QASM-based backend.

Basic Simulator

The basic simulator is a local classical simulator based on CPU. It supports measure and cif in the quantum circuit, but does not support autograd and parallel processing.

The code below shows how to use the basic classical simulator to run a quantum program. The configuration methods of BasicSimulatorConfig are also listed below.

engine = get_basic_simulator()
config = BasicSimulatorConfig()
config.configure_shots(1024)
result = engine.execute(exe, config)
class spinqit.backend.BasicSimulatorConfig

Method

Description

configure_shots(shots)

Configure the total number of shots so that the count of each possible binary reading is calculated in the result.

configure_measure_qubits(mqubits)

Configure the subset of qubits to measure so that only the result about these qubits will be measured.

Each kind of backend in SpinQit has a get_value_and_grad_fn method that returns the evaluation result of an input quantum circuit and the corresponding grad function. This method is used by the QLayer interface of SpinQit which will be introduced later. This method has two important parameters, measure_op and grad_method, which specify the measurement in the evaluation and the type of grad function respectively.

The basic SpinQ simulator backend supports two types of gradient methods, parameter shift (“param_shift”) and adjoint differentiation (“adjoint_differentiation”). The two grad methods can work with only the measure_op of “expval” which means expected value.

Torch Simulator

SpinQit includes another simulator based on PyTorch. This torch simulator supports autograd, and executes a quantum simulation in parallel on multiple CPU cores.

The code example shows how to use the torch simulator. The configuration methods of TorchSimulatorConfig are also listed below.

engine = get_torch_simulator()
config = TorchSimulatorConfig()
config.configure_num_thread(4)
result = engine.execute(exe, config)
class spinqit.backend.TorchSimulatorConfig

Method

Description

configure_shots(shots)

Configure the total number of shots so that the count of each possible binary reading is calculated in the result.

configure_measure_qubits(mqubits)

Configure the subset of qubits to measure so that only the result about these qubits will be measured.

configure_num_thread(n_threads)

Configure the number of threads to run the simulation.

The torch simulator backend supports two types of gradient methods, parameter shift (“param_shift”) and back propagation (“backprop”). Parameter shift can work with only the measure_op of “expval”, while back propagation supports “expval” and “state”. Here “state” refers to the result of state vector.

Local Quantum Computer

To use a local quantum computer from SpinQ, you first need to get the network information and register an account on the machine. Here Triangulum GUI is used as an example. For instructions on how to use other models, please contact our sales team.

TriangulumIP.png

TriangulumRegister.png

The code example shows how to use a local quantum computer backend in SpinQit. The configuration methods of NMRConfig are listed below.

engine = get_nmr()
config = NMRConfig()
config.configure_ip("192.168.137.1")
config.configure_port(55444)
config.configure_account("user9", "123456")
config.configure_task("task2", "Bell")
result = engine.execute(exe, config)
class spinqit.backend.NMRConfig

Method

Description

configure_shots(shots)

Configure the total number of shots so that the count of each possible binary reading is calculated in the result.

configure_ip(addr)

Configure the ip address of the quantum computer.

configure_port(port)

Configure the port number of the quantum computer.

configure_account(username, password)

Configure the username and password that registered on the quantum computer.

configure_task(task_name, task_desc)

Configure the task name and description.

The local quantum computer backend supports only parameter shift (“param_shift”). Parameter shift can work with only the measure_op of “expval”.

Cloud

In order to use the SpinQ cloud, you have to first register and add a public SSH key on https://cloud.spinq.cn. Please refer to the documentation online about the SpinQ cloud https://cloud.spinq.cn/#/docs. Username and key information are required to use the cloud backend. SSH.PNG SpinQ provides multiple platforms with different number of qubits on the SpinQ cloud. The cloud backend has a get_platform method, and this method can provide a platform instance from “gemini_vp”, “triangulum_vp”, “superconductor_vp”. These platforms have 2, 3 and 8 qubits respectively and support only quantum programs with fewer qubits. The result from the cloud backend contains only a probability distribution. The data type of the result is a dictionary. The keys in the dictionary are binary measurements. The values in the dictionary are the corresponding probabilities.

class spinqit.backend.CloudConfig

Method

Description

configure_shots(shots)

Configure the total number of shots so that the count of each possible binary reading is calculated in the result.

configure_ip(addr)

Configure the ip address of the quantum computer.

configure_port(port)

Configure the port number of the quantum computer.

configure_account(username, password)

Configure the username and password that registered on the quantum computer.

configure_task(task_name, task_desc)

Configure the task name and description.

The following example shows how to use the cloud backend and login using your SSH key.

username = "username"
keyfile = "/path/to/.ssh/id_rsa"

backend = get_spinq_cloud(username, keyfile)

gemini = backend.get_platform("gemini_vp")
print("gemini has " + str(gemini.machine_count) + " active machines.")

if gemini.available():
    comp = get_compiler("native")
    circ = Circuit()
    ...
    ir = comp.compile(circ, 0)
    config = SpinQCloudConfig()
    config.configure_platform('gemini_vp')
    config.configure_shots(1024)
    config.configure_task('newapitest1', 'newapi')

    res = backend.execute(ir, config)
else:
    print("No machine available for this platform.")

The cloud backend supports only parameter shift (“param_shift”). Parameter shift can work with only the measure_op of “expval”.

QASM

SpinQit can convert its intermediate representation to OpenQASM codes in the form of string so that any third-party platform which suports OpenQASM can be used to execute codes written in SpinQit. The QASM backend is initialized using a handle function which can run OpenQASM codes. The result format of this backend depends on the actual execution platform. It would be better to convert the third-party results to the result formats of SpinQit in the handle. SpinQit provides a QiskitQasmResult class to process Qiskit results.

The following example shows how to define a handle for the QASM backend to use Qiskit 0.31.0 to execute a quantum circuit.

from qiskit import QuantumCircuit
from qiskit import execute
from qiskit import Aer
from spinqit import get_qasm_backend, QasmConfig, QiskitQasmResult

def qiskit_fn(qasm, shots=1024, *args, **kwargs):
    qc = QuantumCircuit.from_qasm_str(qasm)
    simulator = Aer.get_backend('statevector_simulator')
    result = execute(qc, simulator, *args, **kwargs).result()
    print(result.get_statevector())
    qiskit_result = QiskitQasmResult()
    qiskit_result.set_result(result.get_statevector(), shots)
    return qiskit_result

...

exe = compiler.compile(circuit, 0)
config = QasmConfig()
engine = get_qasm_backend(qiskit_fn)
states = engine.execute(exe, config).states

The configuration methods of QasmConfig are listed below.

class spinqit.backend.QasmConfig

Method

Description

configure_shots(shots)

Configure the total number of shots so that the count of each possible binary reading is calculated in the result.

configure_measure_qubits(mqubits)

Configure the subset of qubits to measure so that only the result about these qubits will be measured.

This QASM backend supports parameter shift (“param_shift”). It also supports adjoint differentiation (“adjoint_differentiation”) if the external QASM engine can return the state vector. The two grad methods can work with only the measure_op of “expval”.