Noisy distributed simulation with DNoisy¶
Simulation of quantum circuits on a HPC cluster
This notebook aims at introducing how distributed simulations of noisy quantum processors can be run on a HPC cluster in Distributed Qaptiva. In the current version of Distributed Qaptiva, the only available noisy distributed simulator is DNoisy, a generic simulator based on linear algebra. It can be used to parallelize simulations by distributing the density matrix of the quantum state on several compute nodes, enabling the exact simulation of larger circuits with more qubits.
Note that in the current version of Distributed Qaptiva, DNoisy only supports deterministic simulations: while the DLinAlg simulator represents pure quantum states with state vectors composed of complex amplitudes, the DNoisy deterministic simulator represents the full density matrix of the qubits' state, either in double or single precision. As a result, DNoisy in the deterministic mode is both a noisy QPU and an exact QPU
- Noisy, because it can simulate hardware noise
- Exact, because the quantum state is stored in such a way that its representation does not induce any approximation other than the precision of floating point types
Since we change the representation of the quantum state with $n$ qubits from a state vector (containing $2^n$ complex numbers) to a density matrix (containing $2^n \times 2^n$ complex numbers), the complexity of simulating $n$ noisy qubits using DNoisy is the same as simulating $2n$ perfect qubits using DLinAlg. Hence, this approach demands an amount of memory that grows exponentially with the number of qubits, and quadratically worse than the noiseless simulation using DLinAlg. Each floating-point complex amplitude requires 16 (8) bytes to be stored in double (single) precision, which means that the total memory required to simulate a quantum circuit with $\textrm{nbqbits}$ is $2^{2 \, \textrm{nbqbits} +4}$ ($2^{2 \, \textrm{nbqbits} +3}$) bytes.
For example, a 20 qubits double precision noisy simulation with DNoisy would require $2^{44}$ bytes, which is 16 TiB. Assuming that the compute nodes have at least 256 GiB of memory each, we will then need 64 compute nodes to perform the distributed simulation.
Example simulation
In order to submit a distributed job on a cluster in a SLURM environment, we will follow the steps described below:
- Describe the quantum program and the hardware model in a python script, for example the file qaoa_dnoisy.py in the following cell
- Write a SLURM batch script that may contain options preceded with "#SBATCH", to define the resources to be used on the cluster to run the job
- Submit the SLURM batch script using the sbatch command
- Read the result of the quantum program from the output file generated by the SLURM command
Preparing a python script describing the quantum program and hardware model
The python script that runs a DNoisy distributed simulation ressembles scripts employed with other simulators. In the example below, we demonstrate the preparation of the maximally entangled state $\frac{\ket{0}^{\otimes n} + \ket{1}^{\otimes n}}{\sqrt{2}}$ circuit on noisy quantum hardware that is distributed to one MPI processes. For simplicity, we will create this state on only 8 qubits. However, it is important to note that this simulator is not intended for such small-scale use cases.
Please note that the DNoisy distributed simulator can work with or without SLURM. Under a SLURM environment, it will automatically deduce some options available in the environment as default values if they are not passed explicitly, for instance the number of process and threads to run the simulation on. Without SLURM, it will instead use the mpirun command, and all the options have to be passed by the user to the constructor of the simulator. For all the available options, please refer to the documentation of the DNoisy simulator.
%%writefile ghz_dnoisy.py
import numpy as np
import matplotlib.pyplot as plt
from qat.lang.AQASM import Program, H, CNOT
# Generate the circuit on 8 qbits
nqbits = 8
prog = Program()
qbits = prog.qalloc(nqbits)
prog.apply(H, qbits[0])
for i in range(0, nqbits - 1):
prog.apply(CNOT, [qbits[i], qbits[i + 1]])
circ = prog.to_circ()
Writing ghz_dnoisy.py
The following cell is not required when submitting a real simulation, but it serves as an example to display the circuit in this notebook. It is not submitted to the compute nodes, and will run on the node where the notebook is executed.
%run ghz_dnoisy.py
circ.display()
Then, we need to create a HardwareModel to represent the noisy hardware. Here, we add depolarizing noise after the application of each gate, and add some noise on idle qubits
%%writefile -a ghz_dnoisy.py
from itertools import product
from qat.hardware import HardwareModel, DefaultGatesSpecification
from qat.quops import QuantumChannelKraus, ParametricAmplitudeDamping, ParametricPureDephasing
# Specify appliation time of each gate
gate_times = {
"CNOT": 10,
"H": 2,
}
# Create the GatesSpecification of the hardware, with perfect gates with nonzero application time
gates_spec = DefaultGatesSpecification(gate_times)
# Create an idle noise model, assuming that each qubit experiences the same AD/PD noise.
idle_noise = [ParametricAmplitudeDamping(T_1=200), ParametricPureDephasing(T_phi=100)]
# Instantie a noise model representing a depolarizing noise, to be applyed after application of each perfect gate
# with probability 1%
prob = 0.01
Xmat = np.array([[0, 1], [1, 0]])
Ymat = np.array([[0, -1j], [1j, 0]])
Zmat = np.array([[1, 0], [0, -1]])
kraus_ops = [np.sqrt(1-prob)*np.identity(2),
np.sqrt(prob/3)*Xmat, np.sqrt(prob/3)*Ymat, np.sqrt(prob/3)*Zmat]
noise = QuantumChannelKraus(kraus_ops)
# two-qbit version for the CNOT gate
noise2 = QuantumChannelKraus([np.kron(K1, K2) for K1, K2 in product(noise.kraus_operators,
noise.kraus_operators)])
# for each gate, we specify the noise
# note that the values in this dictionary are lambda functions
# with as many arguments as the gate's number of arguments
gates_noise = {"H": lambda: noise,
"CNOT": lambda: noise2,
}
#Create the hardware model, with gate noise and idle noise
hardware_model = HardwareModel(gates_spec, gates_noise, idle_noise)
Appending to ghz_dnoisy.py
Once the hardware model is defined, we can write the job that must be executed, and define our DNoisy QPU with the correct hardware model
%%writefile -a ghz_dnoisy.py
from qat.qpus import DNoisy
# The nb_processes here is set to 1, so the simulation will only run on a single node
# This argument is optional and the number of reserved nodes in the SLURM environment will be used by default
nb_processes = 1
# The temp_dir argument must be configured to point to a writable temporary directory shared by all the nodes in the cluster
# if the directory containing this Python script does not have write permissions or is not shared
temp_dir = "/tmp/"
qpu = DNoisy(nb_processes=nb_processes, temp_dir=temp_dir, hardware_model=hardware_model)
job = circ.to_job(nbshots=10000)
res = qpu.submit(job)
for sample in res:
print(f"Sampled state {sample.state} with probability {sample.probability} and error {sample.err}")
Appending to ghz_dnoisy.py
Writing the SLURM batch script to define the resources needed to run the job
In the slurm batch script defined in the following cell, the partition in the cluster to run the job on is not specified, so the default partition as designated by the system administrator will be used. However, this can be added through the --partition option. For this example, we will only use a single node, and 64 cpus in the nodes will be used for the simulation. A time limit can be set on the slurm job through the --time option, and it is recommended to do so. Please refer to the official slurm documentation for additional options and examples.
%%file submit.sh
#!/bin/sh
#SBATCH --nodes 1
#SBATCH --ntasks-per-node=1
#SBATCH --cpus-per-task=64
#SBATCH --time 00:03:00
#SBATCH --job-name ghz_dnoisy
#SBATCH --output slurm_output/ghz_dnoisy.out
#SBATCH --error slurm_output/ghz_dnoisy.err
#SBATCH --exclusive
# Load the python3 module to be used on the cluster
# module load python3
echo "Loading the qaptiva-hpc module environment"
module load qaptiva-hpc
# Load other modules if necessary such as openmpi
# module load openmpi
echo "Running the DNoisy simulation"
python3 ghz_dnoisy.py
Writing submit.sh
Submitting the SLURM job on the cluster¶
To submit the simulation job to the compute nodes in the cluster, we simply use the sbatch SLURM command, as shown in the following cell. If we are not in a SLURM environment, we can also use the mpirun command to run the python script, but the resources needed by the simulation job will need to be specified in the command.
%%bash
sbatch --wait --deadline=now+4minutes submit.sh
Submitted batch job 3
Reading the result from the SLURM output file¶
When the simulation job is done, we can read the output file of the SLURM job to retrieve simulation result, or the error file to check if the simulation job is successfully run.
%%bash
cat slurm_output/ghz_dnoisy.out
Loading the qaptiva-hpc module environment Running the DNoisy simulation Sampled state |00000000> wi
th probability 0.4605 and error 0.004984622317283889 Sampled state |00000001> with probability 0.002
6 and error 0.0005092641112364972 Sampled state |00000010> with probability 0.0025 and error 0.00049
93995794892096 Sampled state |00000011> with probability 0.0027 and error 0.0005189392351643681 Samp
led state |00000100> with probability 0.0035 and error 0.0005906012876620731 Sampled state |00000101
> with probability 0.0001 and error 0.0001 Sampled state |00000111> with probability 0.004 and error
0.0006312209153572135 Sampled state |00001000> with probability 0.0024 and error 0.0004893341851888
946 Sampled state |00001011> with probability 0.0005 and error 0.00022356206744392033 Sampled state
|00001111> with probability 0.0044 and error 0.000661897130059557 Sampled state |00010000> with prob
ability 0.0033 and error 0.000573536306077862 Sampled state |00010100> with probability 0.0001 and e
rror 0.0001 Sampled state |00010111> with probability 0.0008 and error 0.00028274369029111855 Sample
d state |00011011> with probability 0.0005 and error 0.00022356206744392033 Sampled state |00011101>
with probability 0.0001 and error 0.0001 Sampled state |00011111> with probability 0.0076 and error
0.0008685041335209604 Sampled state |00100000> with probability 0.0029 and error 0.0005377619536485
258 Sampled state |00100001> with probability 0.0001 and error 0.0001 Sampled state |00100011> with
probability 0.0002 and error 0.00014141428428549925 Sampled state |00100100> with probability 0.0001
and error 0.0001 Sampled state |00100111> with probability 0.0004 and error 0.00019996999474891224
Sampled state |00101011> with probability 0.0002 and error 0.00014141428428549925 Sampled state |001
01111> with probability 0.0027 and error 0.0005189392351643681 Sampled state |00110000> with probabi
lity 0.0001 and error 0.0001 Sampled state |00110011> with probability 0.0001 and error 0.0001 Sampl
ed state |00110101> with probability 0.0001 and error 0.0001 Sampled state |00110111> with probabili
ty 0.0024 and error 0.0004893341851888946 Sampled state |00111000> with probability 0.0003 and error
0.00017318775765030273 Sampled state |00111011> with probability 0.0006 and error 0.000244887723252
31 Sampled state |00111100> with probability 0.0001 and error 0.0001 Sampled state |00111101> with p
robability 0.0001 and error 0.0001 Sampled state |00111110> with probability 0.0002 and error 0.0001
4141428428549925 Sampled state |00111111> with probability 0.0183 and error 0.0013404069042894798 Sa
mpled state |01000000> with probability 0.0042 and error 0.0006467440202914738 Sampled state |010000
11> with probability 0.0001 and error 0.0001 Sampled state |01000100> with probability 0.0001 and er
ror 0.0001 Sampled state |01000111> with probability 0.0001 and error 0.0001 Sampled state |01001011
> with probability 0.0001 and error 0.0001 Sampled state |01001110> with probability 0.0001 and erro
r 0.0001 Sampled state |01001111> with probability 0.0025 and error 0.0004993995794892096 Sampled st
ate |01010000> with probability 0.0001 and error 0.0001 Sampled state |01010011> with probability 0.
0001 and error 0.0001 Sampled state |01010101> with probability 0.0001 and error 0.0001 Sampled stat
e |01010111> with probability 0.0013 and error 0.00036033870788251414 Sampled state |01011011> with
probability 0.0004 and error 0.00019996999474891224 Sampled state |01011100> with probability 0.0001
and error 0.0001 Sampled state |01011101> with probability 0.0001 and error 0.0001 Sampled state |0
1011111> with probability 0.014 and error 0.0011749630010367902 Sampled state |01100000> with probab
ility 0.0007 and error 0.00026449573871724277 Sampled state |01100111> with probability 0.0013 and e
rror 0.00036033870788251414 Sampled state |01101011> with probability 0.0007 and error 0.00026449573
871724277 Sampled state |01101110> with probability 0.0002 and error 0.00014141428428549925 Sampled
state |01101111> with probability 0.0092 and error 0.0009547916855085571 Sampled state |01110000> wi
th probability 0.0006 and error 0.00024488772325231 Sampled state |01110011> with probability 0.0005
and error 0.00022356206744392033 Sampled state |01110100> with probability 0.0001 and error 0.0001
Sampled state |01110111> with probability 0.0063 and error 0.0007912607720346916 Sampled state |0111
1000> with probability 0.0003 and error 0.00017318775765030273 Sampled state |01111010> with probabi
lity 0.0001 and error 0.0001 Sampled state |01111011> with probability 0.0026 and error 0.0005092641
112364972 Sampled state |01111100> with probability 0.0003 and error 0.00017318775765030273 Sampled
state |01111101> with probability 0.0003 and error 0.00017318775765030273 Sampled state |01111110> w
ith probability 0.0006 and error 0.00024488772325231 Sampled state |01111111> with probability 0.061
2 and error 0.0023970879422875384 Sampled state |10000000> with probability 0.0044 and error 0.00066
1897130059557 Sampled state |10000111> with probability 0.0001 and error 0.0001 Sampled state |10001
011> with probability 0.0001 and error 0.0001 Sampled state |10001100> with probability 0.0001 and e
rror 0.0001 Sampled state |10001101> with probability 0.0001 and error 0.0001 Sampled state |1000111
1> with probability 0.0014 and error 0.0003739224275142905 Sampled state |10010000> with probability
0.0004 and error 0.00019996999474891224 Sampled state |10010110> with probability 0.0001 and error
0.0001 Sampled state |10010111> with probability 0.0013 and error 0.00036033870788251414 Sampled sta
te |10011000> with probability 0.0001 and error 0.0001 Sampled state |10011011> with probability 0.0
005 and error 0.00022356206744392033 Sampled state |10011101> with probability 0.0001 and error 0.00
01 Sampled state |10011111> with probability 0.0108 and error 0.0010336550896137592 Sampled state |1
0100000> with probability 0.0007 and error 0.00026449573871724277 Sampled state |10100011> with prob
ability 0.0001 and error 0.0001 Sampled state |10100111> with probability 0.001 and error 0.00031608
541725157126 Sampled state |10101000> with probability 0.0001 and error 0.0001 Sampled state |101010
11> with probability 0.0004 and error 0.00019996999474891224 Sampled state |10101101> with probabili
ty 0.0001 and error 0.0001 Sampled state |10101111> with probability 0.0079 and error 0.000885345911
9114821 Sampled state |10110000> with probability 0.0004 and error 0.00019996999474891224 Sampled st
ate |10110011> with probability 0.0005 and error 0.00022356206744392033 Sampled state |10110110> wit
h probability 0.0001 and error 0.0001 Sampled state |10110111> with probability 0.0053 and error 0.0
007261155034651425 Sampled state |10111000> with probability 0.0002 and error 0.00014141428428549925
Sampled state |10111011> with probability 0.0019 and error 0.00043549737748530665 Sampled state |10
111100> with probability 0.0003 and error 0.00017318775765030273 Sampled state |10111101> with proba
bility 0.0005 and error 0.00022356206744392033 Sampled state |10111110> with probability 0.0004 and
error 0.00019996999474891224 Sampled state |10111111> with probability 0.0462 and error 0.0020992848
067067907 Sampled state |11000000> with probability 0.0031 and error 0.0005559405606633672 Sampled s
tate |11000111> with probability 0.0004 and error 0.00019996999474891224 Sampled state |11001011> wi
th probability 0.0005 and error 0.00022356206744392033 Sampled state |11001111> with probability 0.0
069 and error 0.0008278330331371631 Sampled state |11010000> with probability 0.0003 and error 0.000
17318775765030273 Sampled state |11010011> with probability 0.0003 and error 0.00017318775765030273
Sampled state |11010111> with probability 0.0039 and error 0.0006233120019582315 Sampled state |1101
1000> with probability 0.0003 and error 0.00017318775765030273 Sampled state |11011011> with probabi
lity 0.0021 and error 0.0004577990366916466 Sampled state |11011100> with probability 0.0001 and err
or 0.0001 Sampled state |11011101> with probability 0.0004 and error 0.00019996999474891224 Sampled
state |11011110> with probability 0.0001 and error 0.0001 Sampled state |11011111> with probability
0.0367 and error 0.0018803362907886042 Sampled state |11100000> with probability 0.001 and error 0.0
0031608541725157126 Sampled state |11100011> with probability 0.0003 and error 0.0001731877576503027
3 Sampled state |11100111> with probability 0.0031 and error 0.0005559405606633672 Sampled state |11
101000> with probability 0.0002 and error 0.00014141428428549925 Sampled state |11101011> with proba
bility 0.0014 and error 0.0003739224275142905 Sampled state |11101100> with probability 0.0003 and e
rror 0.00017318775765030273 Sampled state |11101101> with probability 0.0001 and error 0.0001 Sample
d state |11101110> with probability 0.0002 and error 0.00014141428428549925 Sampled state |11101111>
with probability 0.0252 and error 0.0015673996536197834 Sampled state |11110000> with probability 0
.0013 and error 0.00036033870788251414 Sampled state |11110011> with probability 0.0014 and error 0.
0003739224275142905 Sampled state |11110100> with probability 0.0005 and error 0.0002235620674439203
3 Sampled state |11110101> with probability 0.0001 and error 0.0001 Sampled state |11110110> with pr
obability 0.0002 and error 0.00014141428428549925 Sampled state |11110111> with probability 0.0175 a
nd error 0.0013113149715821403 Sampled state |11111000> with probability 0.0011 and error 0.00033149
658972438903 Sampled state |11111001> with probability 0.0001 and error 0.0001 Sampled state |111110
11> with probability 0.009 and error 0.00094445179809236 Sampled state |11111100> with probability 0
.0006 and error 0.00024488772325231 Sampled state |11111101> with probability 0.0011 and error 0.000
33149658972438903 Sampled state |11111110> with probability 0.0016 and error 0.0003996998573900168 S
ampled state |11111111> with probability 0.1601 and error 0.003667171091506563