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.4603 and error 0.0049844634101925914 Sampled state |00000001> with probability 0.00
23 and error 0.0004790552675787414 Sampled state |00000010> with probability 0.0019 and error 0.0004
3549737748530665 Sampled state |00000011> with probability 0.0026 and error 0.0005092641112364972 Sa
mpled state |00000100> with probability 0.0027 and error 0.0005189392351643681 Sampled state |000001
01> with probability 0.0001 and error 0.0001 Sampled state |00000111> with probability 0.0033 and er
ror 0.000573536306077862 Sampled state |00001000> with probability 0.0031 and error 0.00055594056066
33672 Sampled state |00001011> with probability 0.0007 and error 0.00026449573871724277 Sampled stat
e |00001111> with probability 0.0032 and error 0.0005648078441293809 Sampled state |00010000> with p
robability 0.0023 and error 0.0004790552675787414 Sampled state |00010111> with probability 0.0009 a
nd error 0.00029987996398439146 Sampled state |00011000> with probability 0.0002 and error 0.0001414
1428428549925 Sampled state |00011011> with probability 0.0007 and error 0.00026449573871724277 Samp
led state |00011101> with probability 0.0001 and error 0.0001 Sampled state |00011111> with probabil
ity 0.0062 and error 0.0007849953004713953 Sampled state |00100000> with probability 0.003 and error
0.0005469277036238877 Sampled state |00100111> with probability 0.0004 and error 0.0001999699947489
1224 Sampled state |00101011> with probability 0.0001 and error 0.0001 Sampled state |00101100> with
probability 0.0002 and error 0.00014141428428549925 Sampled state |00101110> with probability 0.000
1 and error 0.0001 Sampled state |00101111> with probability 0.0036 and error 0.0005989489744438992
Sampled state |00110011> with probability 0.0001 and error 0.0001 Sampled state |00110111> with prob
ability 0.0018 and error 0.0004239032547609651 Sampled state |00111000> with probability 0.0001 and
error 0.0001 Sampled state |00111001> with probability 0.0001 and error 0.0001 Sampled state |001110
10> with probability 0.0001 and error 0.0001 Sampled state |00111011> with probability 0.0013 and er
ror 0.00036033870788251414 Sampled state |00111101> with probability 0.0001 and error 0.0001 Sampled
state |00111110> with probability 0.0003 and error 0.00017318775765030273 Sampled state |00111111>
with probability 0.0215 and error 0.0014505121159576206 Sampled state |01000000> with probability 0.
0035 and error 0.0005906012876620731 Sampled state |01000001> with probability 0.0001 and error 0.00
01 Sampled state |01000111> with probability 0.0002 and error 0.00014141428428549925 Sampled state |
01001011> with probability 0.0001 and error 0.0001 Sampled state |01001111> with probability 0.003 a
nd error 0.0005469277036238877 Sampled state |01010000> with probability 0.0002 and error 0.00014141
428428549925 Sampled state |01010011> with probability 0.0002 and error 0.00014141428428549925 Sampl
ed state |01010111> with probability 0.0013 and error 0.00036033870788251414 Sampled state |01011000
> with probability 0.0001 and error 0.0001 Sampled state |01011011> with probability 0.0004 and erro
r 0.00019996999474891224 Sampled state |01011100> with probability 0.0001 and error 0.0001 Sampled s
tate |01011101> with probability 0.0003 and error 0.00017318775765030273 Sampled state |01011111> wi
th probability 0.0136 and error 0.0011582910531539048 Sampled state |01100000> with probability 0.00
03 and error 0.00017318775765030273 Sampled state |01100011> with probability 0.0002 and error 0.000
14141428428549925 Sampled state |01100111> with probability 0.0008 and error 0.00028274369029111855
Sampled state |01101000> with probability 0.0001 and error 0.0001 Sampled state |01101011> with prob
ability 0.0005 and error 0.00022356206744392033 Sampled state |01101101> with probability 0.0001 and
error 0.0001 Sampled state |01101111> with probability 0.0111 and error 0.0010477541595612435 Sampl
ed state |01110000> with probability 0.0005 and error 0.00022356206744392033 Sampled state |01110011
> with probability 0.0008 and error 0.00028274369029111855 Sampled state |01110101> with probability
0.0001 and error 0.0001 Sampled state |01110110> with probability 0.0001 and error 0.0001 Sampled s
tate |01110111> with probability 0.0063 and error 0.0007912607720346916 Sampled state |01111000> wit
h probability 0.0006 and error 0.00024488772325231 Sampled state |01111010> with probability 0.0001
and error 0.0001 Sampled state |01111011> with probability 0.0029 and error 0.0005377619536485258 Sa
mpled state |01111100> with probability 0.0007 and error 0.00026449573871724277 Sampled state |01111
101> with probability 0.0002 and error 0.00014141428428549925 Sampled state |01111110> with probabil
ity 0.0003 and error 0.00017318775765030273 Sampled state |01111111> with probability 0.0599 and err
or 0.002373133408853708 Sampled state |10000000> with probability 0.0058 and error 0.000759403495756
3315 Sampled state |10000010> with probability 0.0001 and error 0.0001 Sampled state |10000011> with
probability 0.0002 and error 0.00014141428428549925 Sampled state |10000100> with probability 0.000
1 and error 0.0001 Sampled state |10000111> with probability 0.0002 and error 0.00014141428428549925
Sampled state |10001011> with probability 0.0001 and error 0.0001 Sampled state |10001101> with pro
bability 0.0002 and error 0.00014141428428549925 Sampled state |10001111> with probability 0.0013 an
d error 0.00036033870788251414 Sampled state |10010000> with probability 0.0002 and error 0.00014141
428428549925 Sampled state |10010101> with probability 0.0001 and error 0.0001 Sampled state |100101
11> with probability 0.0013 and error 0.00036033870788251414 Sampled state |10011000> with probabili
ty 0.0002 and error 0.00014141428428549925 Sampled state |10011011> with probability 0.001 and error
0.00031608541725157126 Sampled state |10011101> with probability 0.0002 and error 0.000141414284285
49925 Sampled state |10011111> with probability 0.0101 and error 0.0009999494936740504 Sampled state
|10100000> with probability 0.0006 and error 0.00024488772325231 Sampled state |10100001> with prob
ability 0.0001 and error 0.0001 Sampled state |10100011> with probability 0.0001 and error 0.0001 Sa
mpled state |10100110> with probability 0.0002 and error 0.00014141428428549925 Sampled state |10100
111> with probability 0.0015 and error 0.00038702710369934015 Sampled state |10101001> with probabil
ity 0.0001 and error 0.0001 Sampled state |10101011> with probability 0.0003 and error 0.00017318775
765030273 Sampled state |10101101> with probability 0.0001 and error 0.0001 Sampled state |10101111>
with probability 0.0089 and error 0.0009392375720347181 Sampled state |10110000> with probability 0
.0004 and error 0.00019996999474891224 Sampled state |10110011> with probability 0.0001 and error 0.
0001 Sampled state |10110100> with probability 0.0001 and error 0.0001 Sampled state |10110110> with
probability 0.0001 and error 0.0001 Sampled state |10110111> with probability 0.005 and error 0.000
7053720684684768 Sampled state |10111000> with probability 0.0002 and error 0.00014141428428549925 S
ampled state |10111010> with probability 0.0001 and error 0.0001 Sampled state |10111011> with proba
bility 0.0022 and error 0.0004685487741904567 Sampled state |10111100> with probability 0.0004 and e
rror 0.00019996999474891224 Sampled state |10111101> with probability 0.0005 and error 0.00022356206
744392033 Sampled state |10111110> with probability 0.0001 and error 0.0001 Sampled state |10111111>
with probability 0.0475 and error 0.0021271641880090675 Sampled state |11000000> with probability 0
.0028 and error 0.000528435354979622 Sampled state |11000011> with probability 0.0001 and error 0.00
01 Sampled state |11000100> with probability 0.0001 and error 0.0001 Sampled state |11000111> with p
robability 0.0011 and error 0.00033149658972438903 Sampled state |11001000> with probability 0.0001
and error 0.0001 Sampled state |11001111> with probability 0.0064 and error 0.000797475765625311 Sam
pled state |11010000> with probability 0.0003 and error 0.00017318775765030273 Sampled state |110100
11> with probability 0.0001 and error 0.0001 Sampled state |11010100> with probability 0.0001 and er
ror 0.0001 Sampled state |11010111> with probability 0.0036 and error 0.0005989489744438992 Sampled
state |11011011> with probability 0.0031 and error 0.0005559405606633672 Sampled state |11011100> wi
th probability 0.0001 and error 0.0001 Sampled state |11011101> with probability 0.0001 and error 0.
0001 Sampled state |11011110> with probability 0.0003 and error 0.00017318775765030273 Sampled state
|11011111> with probability 0.0364 and error 0.001872926796615006 Sampled state |11100000> with pro
bability 0.0018 and error 0.0004239032547609651 Sampled state |11100010> with probability 0.0001 and
error 0.0001 Sampled state |11100011> with probability 0.0002 and error 0.00014141428428549925 Samp
led state |11100100> with probability 0.0001 and error 0.0001 Sampled state |11100111> with probabil
ity 0.0025 and error 0.0004993995794892096 Sampled state |11101000> with probability 0.0001 and erro
r 0.0001 Sampled state |11101011> with probability 0.0016 and error 0.0003996998573900168 Sampled st
ate |11101100> with probability 0.0005 and error 0.00022356206744392033 Sampled state |11101101> wit
h probability 0.0001 and error 0.0001 Sampled state |11101111> with probability 0.0267 and error 0.0
016121324068108392 Sampled state |11110000> with probability 0.001 and error 0.00031608541725157126
Sampled state |11110011> with probability 0.001 and error 0.00031608541725157126 Sampled state |1111
0100> with probability 0.0002 and error 0.00014141428428549925 Sampled state |11110101> with probabi
lity 0.0001 and error 0.0001 Sampled state |11110111> with probability 0.0189 and error 0.0013617872
250996645 Sampled state |11111000> with probability 0.0006 and error 0.00024488772325231 Sampled sta
te |11111010> with probability 0.0001 and error 0.0001 Sampled state |11111011> with probability 0.0
099 and error 0.0009900995049503714 Sampled state |11111100> with probability 0.0007 and error 0.000
26449573871724277 Sampled state |11111101> with probability 0.0006 and error 0.00024488772325231 Sam
pled state |11111110> with probability 0.0012 and error 0.00034621956443661565 Sampled state |111111
11> with probability 0.1555 and error 0.003623987904068236