Syntax

SpinQit supports three types of programming syntaxes: native SpinQit Python syntax, OpenQASM 2.0 syntax, and IBM Qiskit Python syntax.

SpinQit Python

SpinQit allows users to define arbitrary quantum circuits. The basic concepts in SpinQit Python syntax are as follows.

Circuit: In SpinQit, each quantum program is a Circuit instance.

Quantum register: A quantum register has a certain number of qubits, and must be allocated by a circuit using allocateQubits. A qubit is represented by the register name and its index.

Classical register: A classical register has a certain number of classical bits, and must be allocated by a circuit using allocateClbits. A classical bit is represented by the register name and its index. A classical bit stores a measurement result in the quantum program, which is used by following if conditions.

Quantum gates: SpinQit defines 22 logic quantum gates (I, H, X, Y, Z, Rx, Ry, Rz, P, T, Td, S, Sd, CX/CNOT, CY, CZ, U, CP, SWAP, CCX, Ph, CSWAP) and two special gates (MEASURE and BARRIER). Specifically, P is the phase shift gate while Ph is the global phase gate.

There is a special gate named StateVector which directly initializes the qubits to a specific state, but this gate is only supported by the torch simulator backend.

Instruction: An instruction consists of a quantum gate, qubits, optional classical bits, and optional rotation radian for rotation gates. SpinQit uses << to add an instruction to a circuit, as shown in the example earlier.

Custom quantum gate: SpinQit provides a gate builder to define a custom quantum gate. The builder builds a gate based on sub-gates. Qubit indexes and optional parameter lambda are defined for each sub-gate. For example, a custom gate can be defined as follows:

plam = lambda params: params[0]
builder = GateBuilder(2)
builder.append(H, [0])
builder.append(CX, [0, 1])
builder.append(Rx, [0], plam)
builder.append(Rx, [0], pi)
g = builder.to_gate()
circ << (g, qreg, pi)

ControlledGate is a class to add a control bit to a base gate and create a new controlled gate.

cswap = ControlledGate(SWAP)
circ << (cswap, (q[0], q[1], q[2]))

Parameter Rotation gates and phase shift gates takes radian parameter constant real number variable variational quantum algorithms

circuit = Circuit()
q=circuit.allocateQubits(qubit_num)
weight = circuit.add_params(shape=(2,)) 
noise = circuit.add_params(shape=(2,)) 

for i in range(qubit_num):
    circuit << (X, q[i])
    circuit << (H, q[i])
    circuit << (Ry, q[i], weight[0])
    circuit << (Rz, q[i], weight[1])
    circuit << (P, q[i], weight[0] + noise[0])
    circuit << (P, q[i], weight[1] + noise[1])

Condition based on measurements: In SpinQit, Circuit has a measure method to measure some of the qubits and store the result into classical bits. This method inserts a special MEASURE gate into the circuit. After the measurement, a gate can be conditionally applied, and the condition is based on the value of classical bits. Such a flow control is also known as cif. A condition in SpinQit is a tuple of a list of classical bits, a comparator string (‘==’, ‘!=’, ‘>’, ‘>=’, ‘<’, ‘<=’), and an integer. The | operator is used to add a condition to an instruction. The usage will be like

circ = Circuit()
q = circ.allocateQubits(2)
c = circ.allocateClbits(2)
circ << (H, q[0])
circ << (X, q[1])
circ.measure(q[0], c[0])
circ << (H, q[1]) | (c, '==', 0)

The MEASURE gate cannot be used in a custom gate or used with cif. Currently, this feature can only be executed by the basic classical simulator.

OpenQASM 2.0

SpinQit supports OpenQASM 2.0. The basic gates allowed in SpinQit include id, x, y, z, h, rx, ry, rz, t, tdg, s, sdg, p, cx, cy, cz, swap, ccx, u, U, CX, measure, and barrier. Other standard gates in OpenQASM can be called by including “qelib1.inc” which is provided by SpinQit and exactly the same with the library file in OpenQASM.

OPENQASM 2.0;
include "qelib1.inc";

gate bell a,b
{
h a;
cx a,b;
}

qreg q[2];
creg c[2];

h q[0];
cx q[0],q[1];
bell q[0],q[1];

IBM Qiskit

SpinQit also supports IBM Qiskit Python interface. The version SpinQit supports is qiskit-0.31.0 (qiskit-terra-0.18.3). We include the qiskit.circuit package and some related packages into SpinQit. Therefore, you can construct a Qiskit QuantumCircuit instance and run it with SpinQit, even without installing Qiskit. Particularly, SpinQit has supported QFT, QPE, and Grover primitives in Qiskit (in spinqit.qiskit.circuit.library) so that you can build up your quantum algorithms based on these primitives. Nevertheless, SpinQit does not include all the Qiskit code. If you want to use the qiskit.algorithm package and run the circuit on SpinQit backends, you still need to install Qiskit.

from spinqit.qiskit.circuit import QuantumCircuit
from spinqit import get_compiler, get_basic_simulator, BasicSimulatorConfig
from math import pi

qc = QuantumCircuit(2)
qc.h(0)
qc.rx(pi, 1)
qc.cx(0, 1)

compiler = get_compiler('qiskit')
simulator = get_basic_simulator()
config = BasicSimulatorConfig()

exe = compiler.compile(qc, 0)
result = simulator.execute(exe, config)
print(result.states)
print(result.counts)