127 lines
6.8 KiB
Python
127 lines
6.8 KiB
Python
from sys import getsizeof
|
|
from time import time
|
|
|
|
import numpy as np
|
|
import pyximport
|
|
|
|
from lib_q_computer import Qubit, __0, kron
|
|
|
|
pyximport.install()
|
|
|
|
|
|
def sizeof_fmt(num, suffix='B'):
|
|
for unit in ['', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi']:
|
|
if abs(num) < 1024.0:
|
|
return "%3.1f%s%s" % (num, unit, suffix)
|
|
num /= 1024.0
|
|
return "%.1f%s%s" % (num, 'Yi', suffix)
|
|
|
|
|
|
def run_load_test(N=20):
|
|
"""
|
|
Runs a load test with max N qubits (up to and including N).
|
|
|
|
Expectation is that on a 8GB laptop I should be able to run about 30 qubits using 8-byte numbers.
|
|
|
|
(2**30 * 8 ) / 1024**3 = 8.0
|
|
|
|
Example run output with N=27 on 64GB machine **(without jit, without cython optimizations)**
|
|
|
|
qbits kron_len mem_used mem_per_q getsizeof getsiz/len nbytes nbytes/len time
|
|
2 4 0.0B 0.0B 144.0B 36.0B 32.0B 8.0B 0.0
|
|
3 8 0.0B 0.0B 176.0B 22.0B 64.0B 8.0B 0.0
|
|
4 16 0.0B 0.0B 240.0B 15.0B 128.0B 8.0B 0.0
|
|
5 32 0.0B 0.0B 368.0B 11.5B 256.0B 8.0B 0.0
|
|
6 64 0.0B 0.0B 624.0B 9.8B 512.0B 8.0B 0.0
|
|
7 128 0.0B 0.0B 1.1KiB 8.9B 1.0KiB 8.0B 0.0
|
|
8 256 0.0B 0.0B 2.1KiB 8.4B 2.0KiB 8.0B 0.0
|
|
9 512 312.0KiB 624.0B 4.1KiB 8.2B 4.0KiB 8.0B 0.0
|
|
10 1024 312.0KiB 312.0B 8.1KiB 8.1B 8.0KiB 8.0B 0.0
|
|
11 2048 312.0KiB 156.0B 16.1KiB 8.1B 16.0KiB 8.0B 0.0
|
|
12 4096 816.0KiB 204.0B 32.1KiB 8.0B 32.0KiB 8.0B 0.0
|
|
13 8192 1.2MiB 150.5B 64.1KiB 8.0B 64.0KiB 8.0B 0.01
|
|
14 16384 1.9MiB 123.5B 128.1KiB 8.0B 128.0KiB 8.0B 0.01
|
|
15 32768 3.4MiB 110.1B 256.1KiB 8.0B 256.0KiB 8.0B 0.02
|
|
16 65536 6.5MiB 103.3B 512.1KiB 8.0B 512.0KiB 8.0B 0.04
|
|
17 131072 11.5MiB 91.9B 1.0MiB 8.0B 1.0MiB 8.0B 0.08
|
|
18 262144 22.6MiB 90.2B 2.0MiB 8.0B 2.0MiB 8.0B 0.18
|
|
19 524288 44.7MiB 89.4B 4.0MiB 8.0B 4.0MiB 8.0B 0.32
|
|
20 1048576 88.9MiB 88.9B 8.0MiB 8.0B 8.0MiB 8.0B 0.66
|
|
21 2097152 177.5MiB 88.7B 16.0MiB 8.0B 16.0MiB 8.0B 1.31
|
|
22 4194304 354.5MiB 88.6B 32.0MiB 8.0B 32.0MiB 8.0B 2.67
|
|
23 8388608 676.6MiB 84.6B 64.0MiB 8.0B 64.0MiB 8.0B 5.26
|
|
24 16777216 1.3GiB 84.5B 128.0MiB 8.0B 128.0MiB 8.0B 10.59
|
|
25 33554432 2.6GiB 84.5B 256.0MiB 8.0B 256.0MiB 8.0B 21.3
|
|
26 67108864 5.3GiB 84.5B 512.0MiB 8.0B 512.0MiB 8.0B 41.81
|
|
27 134217728 10.6GiB 84.5B 1.0GiB 8.0B 1.0GiB 8.0B 83.76
|
|
|
|
|
|
TODO: Understand numby.jit magic (look at the results differences > 20qbits, mem usage /10; time /4)
|
|
...
|
|
20 1048576 39.7MiB 39.7B 112.0B 0.0B 8.0MiB 8.0B 0.16
|
|
21 2097152 51.7MiB 25.9B 112.0B 0.0B 16.0MiB 8.0B 0.33
|
|
22 4194304 75.7MiB 18.9B 112.0B 0.0B 32.0MiB 8.0B 0.63
|
|
23 8388608 123.7MiB 15.5B 112.0B 0.0B 64.0MiB 8.0B 1.26
|
|
24 16777216 187.7MiB 11.7B 112.0B 0.0B 128.0MiB 8.0B 2.51
|
|
25 33554432 315.7MiB 9.9B 112.0B 0.0B 256.0MiB 8.0B 5.05
|
|
26 67108864 571.7MiB 8.9B 112.0B 0.0B 512.0MiB 8.0B 10.05
|
|
27 134217728 1.1GiB 8.5B 112.0B 0.0B 1.0GiB 8.0B 19.86
|
|
28 268435456 2.1GiB 8.2B 112.0B 0.0B 2.0GiB 8.0B 40.79
|
|
29 536870912 4.1GiB 8.1B 112.0B 0.0B 4.0GiB 8.0B 81.07
|
|
30 1073741824 8.1GiB 8.1B 112.0B 0.0B 8.0GiB 8.0B 161.68
|
|
...
|
|
Also together with cython optimization (time /4) (but right now it seems to take only doubles):
|
|
...
|
|
20 1048576 23.7MiB 23.7B 8.0MiB 8.0B 8.0MiB 8.0B 0.04
|
|
21 2097152 35.7MiB 17.8B 16.0MiB 8.0B 16.0MiB 8.0B 0.08
|
|
22 4194304 59.7MiB 14.9B 32.0MiB 8.0B 32.0MiB 8.0B 0.15
|
|
23 8388608 107.7MiB 13.5B 64.0MiB 8.0B 64.0MiB 8.0B 0.3
|
|
24 16777216 171.7MiB 10.7B 128.0MiB 8.0B 128.0MiB 8.0B 0.59
|
|
25 33554432 299.7MiB 9.4B 256.0MiB 8.0B 256.0MiB 8.0B 1.18
|
|
26 67108864 555.7MiB 8.7B 512.0MiB 8.0B 512.0MiB 8.0B 2.35
|
|
27 134217728 1.0GiB 8.3B 1.0GiB 8.0B 1.0GiB 8.0B 4.7
|
|
28 268435456 2.0GiB 8.2B 2.0GiB 8.0B 2.0GiB 8.0B 9.52
|
|
29 536870912 4.0GiB 8.1B 4.0GiB 8.0B 4.0GiB 8.0B 19.32
|
|
30 1073741824 8.0GiB 8.0B 8.0GiB 8.0B 8.0GiB 8.0B 37.76
|
|
"""
|
|
_0 = Qubit(__0)
|
|
import os
|
|
import psutil
|
|
import gc
|
|
print("{:>10} {:>10} {:>10} {:>10} {:>10} {:>10} {:>10} {:>10} {:>10}".format(
|
|
"qbits",
|
|
"kron_len",
|
|
"mem_used",
|
|
"mem_per_q",
|
|
"getsizeof",
|
|
"getsiz/len",
|
|
"nbytes",
|
|
"nbytes/len",
|
|
"time"))
|
|
|
|
process = psutil.Process(os.getpid())
|
|
mem_init = process.memory_info().rss
|
|
for i in range(2, N + 1):
|
|
start = time()
|
|
qbits = [_0.matrix_state for _ in range(i)]
|
|
m = kron(qbits)
|
|
len_m = len(m)
|
|
elapsed = time() - start
|
|
mem_b = process.memory_info().rss - mem_init
|
|
print("{:>10} {:>10} {:>10} {:>10} {:>10} {:>10} {:>10} {:>10} {:>10}".format(
|
|
i,
|
|
len(m),
|
|
sizeof_fmt(mem_b),
|
|
sizeof_fmt(mem_b / len_m),
|
|
sizeof_fmt(getsizeof(m)),
|
|
sizeof_fmt(getsizeof(m) / len_m),
|
|
sizeof_fmt(m.nbytes),
|
|
sizeof_fmt(m.nbytes / len_m),
|
|
np.round(elapsed, 2)))
|
|
|
|
gc.collect()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
run_load_test(30)
|