Computing on the Dynex Neuromorphic Platform: IBM Qiskit 4-Qubit Full Adder Circuit

Dynex [DNX]
10 min readSep 25, 2023

Computing on Quantum or neuromorphic systems is fundamentally different than using traditional hardware and is a very active area of research with new algorithms surfacing almost on a weekly basis. In this article we will use the Dynex SDK (beta) and the Dynex-Qiskit (alpha) Package to construct an 4-qubit full adder circuit with IBM Qiskit which we will then execute on the Dynex Neuromorphic Platform (instead using IBM-Q). This example is just one of multiple possibilities to work with quamtum gate circuits. However, it can be easily adopted to other use cases.

Recent advances in quantum hardware have resulted in the first systems becoming publicly available. On one hand, gate-based quantum computers have been designed, such as the IBM Q, Rigetti’s Aspen, or IonQ’s systems using using superconducting transmons or ion tubes. On the other hand, adibiatic quantum computing and neuromorphic computing has emerged as another possibility to leverage physics inspired computations. It was shown that adiabatic quantum computing can solve the same problems as gate-based (universal) quantum computing given at least two degrees of freedom for 2-local Hamiltonian [3,4,5]. The Dynex Neuromorphic platform supports a 2-local Ising Hamiltonian with a single degree of freedom, which is why it is believed to only solve a subset of the problems that can be expressed by gate-based (universal) quantum machines. In 2014, Warren outlined how a set of universal quantum gates could be realized in adiabatic form using D-Wave’s annealing abstraction [1]. This is demonstrated, among others, for C-NOT, Toffoli (CC-NOT), Swap and C-Swap (Fredkin) gates in a {0, 1} base of qubit states, and for the Hadamard gate in a two-vector {|0i, |1i} base.

The Dynex Qiskit Package allows to execute IBM Qiskit programs and circuits on the Dynex Neuromorphic platform. Thanks to groundbreaking research from Richard H. Warren [1], it is possible to directly translate Qiskit quantum circuits into Dynex Neuromorphic chips. The concept behind is a direct translation of Qiskit objects, but instead of running on IBM Q, the circuits are executed on the Dynex platform.

Requirements

To construct our 4-qubit full adder circuit we need to install the Qiskit package as well as the Dynex SDK package:

pip install qiskit
pip install dynex

In addition, we need to download the Dynex Qiskit Package:

git clone https://github.com/dynexcoin/Dynex-Qiskit.git

We will also need to configure the Dynex SDK as explained in the Dynex SDK Wiki installation instructions. With this setup, we are ready to build our quantum gate circuit.

What is a Qubit?

A qubit (or quantum bit) is the quantum mechanical analogue of a classical bit. In classical computing the information is encoded in bits, where each bit can have the value zero or one. In quantum computing the information is encoded in qubits. A qubit is a two-level quantum system where the two basis qubit states are usually written as ∣0⟩∣0⟩ and ∣1⟩∣1⟩. A qubit can be in state ∣0⟩∣0⟩, ∣1⟩∣1⟩ or (unlike a classical bit) in a linear combination of both states. The name of this phenomenon is superposition.

The basis states are located at opposite points on the Bloch sphere. Note that a pure qubit state can be expressed as a point on the surface of the Bloch sphere and therefore can be described by two angles. In general, the polar angle θ (theta) (angle with respect to positive z-axis), and azimuthal angle φ (phi) (counter-clock wise angle of rotation in the xy-plane from the positive x-axis) are used in quantum physics.

For more information see https://en.wikipedia.org/wiki/Bloch_sphere.

Creating a Quantum Circuit

In IBM Qiskit, a typical quantum circuit is being built based on the following components:

QuantumRegister

A Quantum Register is a system of many Qubits. A Quantum Register can be created in Qiskit by using the QuantumRegister class and passing it the number of Qubits required in the Quantum Register.

  • Collection of qubits
  • Indexed to reference an individual qubit with q[0]

ClassicalRegister

A Classical Register is a system of many bits. Bits in classical registers are used for storing the measured values of Qubits in Quantum Registers. A Classical Register can be created in Qiskit by using the ClassicalRegister class and passing it the number of bits required in the Classical Register.

  • Collection of bits
  • Used as the receiver of measurements on qubits

QuantumCircuit

A Quantum Circuit consists of Quantum Register and Classical Registers which are used for measuring the states of Quantum Register. Once the Quantum Circuit is created, it is possible to perform various operations on the Qubits as well as measuring them. A Quantum Register can be created in Qiskit by using the QuantumCircuit class and passing it the Quantum Register and Classical Register.

  • starts with a set of registers
  • Gates specifying registers/qubits are added as arguments

Imports

To execute IBM Qiskit circuits on the Dynex Neuromorphic platform instead of IBM-Q, we simply pre-annotate the imports with ‘dynexsdk’:

from dynexsdk.qiskit import QuantumRegister, ClassicalRegister
from dynexsdk.qiskit import QuantumCircuit, execute

We want to design a 4-qubit full adder circuit. It is the quantum equivalent of a Full Adder which is a logic circuit used by classical computers to implement additions.

We first define the QuantumRegisters for A,B for the inputs as well as S for the resulting sum and C for the carries:

n = 4
a = QuantumRegister(n)
b = QuantumRegister(n)

C = QuantumRegister(n)
S = QuantumRegister(n)

We will also need ClassicalRegisters for the carries:

ac = ClassicalRegister(n)
bc = ClassicalRegister(n)
Cc = ClassicalRegister(n)
Sc = ClassicalRegister(n)

With these definitions, we can construct the circuit:

circuit = QuantumCircuit(a, b, C, S, ac, bc, Cc, Sc)

For calculating the sum, we need to define CNOT and Toffoli gates accordingly:

circuit.ccx(a[n-1], b[n-1], C[n-1])
circuit.cx(a[n-1], S[n-1])
circuit.cx(b[n-1], S[n-1])

for i in range(1,n):
circuit.ccx(a[n-1-i],b[n-1-i],C[n-1-i])
circuit.ccx(b[n-1-i],C[n-1-(i-1)],C[n-1-i])
circuit.ccx(a[n-1-i],C[n-1-(i-1)],C[n-1-i])
circuit.cx(a[n-1-i], S[n-1-i])
circuit.cx(b[n-1-i], S[n-1-i])
circuit.cx(C[n-1-(i-1)], S[n-1-i])

Lastly, we also want to measure the sum and the carry:

circuit.measure(C, Cc)
circuit.measure(S, Sc)

We can visualize our 4-qubit full adder circuit which shows us the qubits, gate connections and 8 measuring points:

4-Qubit Full Adder Quantum Circuit

As we are using the Qiskit Dynex Package, the circuit creation also prints us some status information:

=========================================
IBM Qiskit on Dynex Neuromorphic Platform
=========================================
[DYNEX] Dynex SDK version: 0.1.5
[DYNEX] Annealer Graph initialised

Running the IBM Qiskit Quantum Circuit on the Dynex Neuromorphic Platform

Instead of executing the circuit on the IBM-Q quantum computer, we use the Dynex Neuromorphic Computing Platform. The Dynex Qiskit Package automatically translates quantum programs (Qiskit based) from a subset of common gates to an adibiatic representation, which is used by adibiatic quantum computers and by the Dynex Neuromorphic platform. Adiabatic computing with two degrees of freedom of 2-local Hamiltonians has been theoretically shown to be equivalent to the gate model of universal quantum computing. The Dynex Qiskit Package translates quantum gate circuits comprised of a subset of common gates expressed as an IBM Qiskit program to single-degree 2-local Ising Hamiltonians, which are subsequently embedded on the Dynex Neuromomorphic platform. These gate elements are placed in the chimera graph and augmented by constraints that enforce inter-gate logical relationships, resulting in an annealer embedding that completely characterizes the overall gate circuit.

The translation process can be summarized as followed:

  1. Construct equivalent QUBO
  • Each gate -> QUBO (Quadratic unconstrained binary optimization model)
  • Compose QUBOs into single Hamiltonian

2. Find embedding

  • In 16x16 bi-partite graphs (K4,4) sparsely connected as Chimera
  • Project per-gate QUBO -> bi-partite unit graph K4,4
  • Connect constraints b/w QUBOs of units graphs -> “wires”

3. In Python: Transform IBM Qiskit program

  • Replace gates
  • Run, but instead of IBM Q exec., sample on the Dynex Neuromorphic sampler

Further details about the conversion can be found in [1] and [2]. We run the execution of the quantum circuit with the following command by specifying ‘dynex’ as the sampler and setting the number of reads (num_reads) to 50,000 and the annealing time (annealing_time) to 1,000. For a simple circuit like this, these values are more than appropriate:

qubits_measured, qubits_unmeasured = execute(
circuit,
sampler='dynex',
mainnet=True,
num_reads=50000,
annealing_time=1000,
logging=False,
constrain_measured_qubits=True,
constraint_strength = 10
)

During the circuit execution, we receive the following information:

[DYNEX] Qiskit circuit qubits: 17
[DYNEX] Embedding has been built:
number of qubits: 310
number of couplers: 419
number of non-gate couplers: 201
[DYNEX] INFO: q2_0 was constrained to be 0 (contrain_measured_qubits=True)
[DYNEX] INFO: q2_1 was constrained to be 0 (contrain_measured_qubits=True)
[DYNEX] INFO: q2_2 was constrained to be 0 (contrain_measured_qubits=True)
[DYNEX] INFO: q2_3 was constrained to be 0 (contrain_measured_qubits=True)
[DYNEX] INFO: q3_0 was constrained to be 0 (contrain_measured_qubits=True)
[DYNEX] INFO: q3_1 was constrained to be 0 (contrain_measured_qubits=True)
[DYNEX] INFO: q3_2 was constrained to be 0 (contrain_measured_qubits=True)
[DYNEX] INFO: q3_3 was constrained to be 0 (contrain_measured_qubits=True)
[ÐYNEX] BQM gnerated
number of variables: 310
number of qubit biases: 310
number of coupler_strengths: 419
[DYNEX] Running Qiskit Circuit on the Dynex Neuromorphic Platform...
[DYNEX] Sampling completed. Result:
32 35 36 39 44 47 52 55 60 63 65 67 68 69 71 76 77 80 ... 1125 energy num_oc.
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... 0 0.0 1
['BINARY', 1 rows, 1 samples, 310 variables]
[DYNEX] Found ground state (energy): 0.0
[DYNEX] [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

We can observe that the original quantum gate circuit, which was consisting of 17 qubits (including auxiliary qubits), was converted into an embedding consisting of 310 qubits on the Dynex Neuromorphic platform, which is a factor of ~18. This is fairly in line with the theoretical upper bound of 32.

Given an n-gate quantum circuit (in our case specified as a Qiskit program), a translation to an adiabatic form is provided in no more than 32n adiabatic qubits on its QUBO/Ising representation. The factor is comprised of 8 qubits for the K4,4 representation of a gate, the remaining 24 qubits are used as wiring to the left and below that gate-equivalent K4,4 graph. Notice that an increase by 32X still increases the capabilities by mapping to the Dynex platform dramatically, and problems can often be mapped more efficiently.

We can also inspect the created Chimera graph by opening the file `chimera_graph.txt’ which is automatically generated during the execution:

The ‘execute’ function returns us the values for the measured and unmeasured qubits respectively:

print('measured:',qubits_measured)
print('unmeasured:',qubits_unmeasured)

measured: {'q2_0': 0, 'q2_1': 0, 'q2_2': 0, 'q2_3': 0, 'q3_0': 0, 'q3_1': 0, 'q3_2': 0, 'q3_3': 0}
unmeasured: {'q0_0': 0, 'q0_1': 0, 'q0_2': 0, 'q0_3': 0, 'q1_0': 0, 'q1_1': 0, 'q1_2': 0, 'q1_3': 0}

Verification of the Results

Albeit it is clear from the reads above that the results are correct, we can also programmatically extract and reconstruct the values. According to our circuit definition, the qubit values for our ‘sum’ can be found in the first 4 qubits of the measured results:

# sum (first n qubits of measured)
cnt = 0;
bin_sum = "";
for q in qubits_measured:
if cnt < n:
bin_sum += str(qubits_measured[q])
cnt += 1

Equally, the values for ‘a’ and ‘b’ are returned in the unmeasured results:

# input A (first n qubits of unmeasured)
# input B (last n qubits of unmeasured)
cnt = 0;
bin_a = "";
bin_b = "";
for q in qubits_measured:
if cnt < n:
bin_a += str(qubits_measured[q])
else:
bin_b += str(qubits_measured[q])
cnt += 1

We can then define a simple function to calculate the sum of ‘a’ and ‘b’ to verify the found ‘sum’:

# Calculating binary sum by using bin() and int()
binary_sum = lambda a,b : bin(int(a, 2) + int(b, 2))
get_bin = lambda x, n: format(x, 'b').zfill(n)
bin_sum_calc = get_bin(int(binary_sum(bin_a, bin_b)[2:]),n)

print('A =', bin_a);
print('B =', bin_b);
print('SUM =', bin_sum)
print('Correct result?',bin_sum == bin_sum_calc)

A = 0000
B = 0000
SUM = 0000
Correct result? True

Which unsurprisingly is correct.

We hoped you enjoyed reading this article. The code used in this article is also available on our GitHub repository as a Jupyter Notebook. If you want to learn more, visit the Dynex SDK Wiki or browse our Dynex SDK ReadTheDocs. You can also get in touch with us on one of our channels.

Further Reading

References

[1] Warren, Richard. (2014). Gates for Adiabatic Quantum Computing.

[2] Regan, Malcolm & Eastwood, Brody & Nagabhiru, Mahita & Mueller, Frank. (2019). Automatically Translating Quantum Programs from a Subset of Common Gates to an Adiabatic Representation. 10.1007/978–3–030–21500–2_9.

[3] Aharonov, D., van Dam, W., Kempe, J., Landau, Z., Lloyd, S., Regev, O.: Adiabatic quantum computation is equivalent to standard quantum computation. SIAM J. Comput. 37(1), 166–194 (Apr 2007). https://doi.org/10.1137/S0097539705447323, http://dx.doi.org/10.1137/S0097539705447323

[4] Bacon, D., Flammia, S.T., Crosswhite, G.M.: Adiabatic quantum transistors (2012). https://doi.org/10.1103/PhysRevX.3.021015

[5] Dorit Aharonov, Wim van Dam, J.K.Z.L.S.L.O.R.: Adiabatic quantum computation is equivalent to standard quantum computation. ArXiv e-prints (May 2004), https://arxiv.org/abs/quant-ph/0405098

--

--

Dynex [DNX]

Dynex is a next-generation platform for neuromorphic computing based on a groundbreaking flexible blockchain protocol.