SOQCS Benchmark
In this example various random circuits of N photons and 2N channels are generated. The N photons are assigned one by one to be initialized in the first N channels. The amplitude to find out those photons in the same configuration at the output is calculated. The calculation of this amplitude implies the calculation of a single permanent. The time required to calculate this permanent with different methods is registered and plotted as function of the number of photons and channels. The permanent is calculated using the the Balasubramanian–Bax–Franklin–Glynn formula “Glynn”, the Ryser formula “Ryser” or the Ryser formula making use of parallelization in the way suggested in ref. [1] “Ryser 10”. In the last case 10 processor cores are used.
[1] P.H. Lundow, K. Markström, Efficient computation of permanents, with applications to Boson sampling and random matrices, Journal of Computational Physics, Volume 455, 2022,110990.
[1]:
import soqcs # SOQCS Library
import time # Time measurement library
Set up simulation constant and create the simulator.
[2]:
# Configuration constants
minnph = 10 # Minimum number of photons
maxnph = 20 # Maximum number of photons
chf = 2 # Channels by photon
# Create the simulator
sim = soqcs.simulator(1)
The next piece of code performs the benchmark for the different methods mentioned above. Random circuits are generated to calculate these benchmarks from minph photons to maxnph photon doubling the number of channels with respect the number of photons.
[3]:
print(" nph nch Glynn Ryser Ryser10")
for nph in range (minnph,maxnph+1):
nch=chf*nph;
# Build circuit
example = soqcs.qodev(nph,nch)
for j in range (0,nph):
example.add_photons(1,j)
example.random_circuit()
for j in range (0,nch):
example.detector(j)
# Set-up inital state
inputst=example.input()
# List of output amplitudes to be calcualted
olist=example.input()
# Set-up circuit
circuit=example.circuit()
# Simulate Glynn
start = time.time()
output=sim.run_st(inputst,circuit,2,st_list=olist);
end = time.time()
tglynn=(end-start)*1000
# Simulate Ryser 1
start = time.time()
output=sim.run_st(inputst,circuit,4,nthreads=1,st_list=olist);
end = time.time()
tryser=(end-start)*1000
# Simulate Ryser 10
start = time.time()
output=sim.run_st(inputst,circuit,4,nthreads=10,st_list=olist);
end = time.time()
tryser10=(end-start)*1000
# Print results
print("{:5d}".format(nph),"{:5d}".format(nch),"{:8.2f}".format(tglynn),"{:8.2f}".format(tryser),"{:8.2f}".format(tryser10))
nph nch Glynn Ryser Ryser10
10 20 0.07 1.14 0.04
11 22 0.17 0.11 0.03
12 24 0.35 0.21 0.04
13 26 0.69 0.44 0.07
14 28 1.38 0.88 0.13
15 30 2.90 1.87 0.25
16 32 5.81 3.53 0.49
17 34 11.45 6.82 0.90
18 36 22.04 14.43 1.94
19 38 46.05 36.39 7.57
20 40 112.97 104.44 13.10
THIS CODE IS PART OF SOQCS
Copyright: Copyright © 2023 National University of Ireland Maynooth, Maynooth University. All rights reserved. The contents and use of this document and the related code are subject to the licence terms detailed in LICENCE.txt