-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrun
executable file
·115 lines (95 loc) · 3.01 KB
/
run
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#!/usr/bin/env python3
'''
Build binaries for given lattize size and probabilities.
Takes an interval of floating point numbers between 0 and 1 and computes all
floating point numbers in this interval which can be represented by a given
number of bits after the decimal point within that interval.
So, if the parameters '0.0 1.0 2' are given, the numbers 1/4, 1/2 and 3/4 are
computed, which in binary are 0.01, 0.1 and 0.11. Zero is always excluded.
'''
from math import ceil
import os
import sys
import shutil
import signal
import asyncio
if (len(sys.argv) != 6):
print(sys.argv[0], "N pmin pmax maxbits nmeas")
sys.exit()
N = int(sys.argv[1])
L = 256*N
maxbits = int(sys.argv[4])
scaling = 2**maxbits
pmin = max(1, ceil(float(sys.argv[2])*2**maxbits))
pmax = min(2**maxbits - 1, int(float(sys.argv[3])*2**maxbits))
nmeas = int(sys.argv[5])
fmt = '{:0' + str(maxbits) + 'b}'
code = """
use crate::rnd::{{SmallRng,rng}};
pub const N: usize = {};
pub const SIG: &str = "{}";
pub fn rand_p(r: &mut SmallRng) -> u128 {{
let mut res = rng(r);
{}
res
}}
"""
sem_build = asyncio.Semaphore()
sem_run = asyncio.Semaphore(8)
tasks = []
procs = []
def terminate():
print("Terminating")
for task in tasks:
task.cancel()
for proc in procs:
proc.terminate()
async def run(p):
full_sig = fmt.format(p)
sig = full_sig.rstrip('0')
if not os.path.exists(f'bin/{L}/{sig}'):
lines = []
for char in sig[-2::-1]:
op = '|' if char == '1' else '&'
lines.append(f' res {op}= rng(r);')
async with sem_build:
with open('src/generated.rs', 'w') as f:
print(code.format(N, sig, '\n'.join(lines)), file=f)
proc = await asyncio.create_subprocess_exec(
'cargo', 'build', '--release',
stdout=asyncio.subprocess.DEVNULL,
stderr=asyncio.subprocess.DEVNULL,
)
await proc.wait()
os.rename('target/release/ising', f'bin/{L}/{sig}')
async with sem_run:
print(full_sig, p/scaling)
proc = await asyncio.create_subprocess_exec(
f'bin/{L}/{sig}',
str(nmeas),
)
procs.append(proc)
await proc.wait()
procs.remove(proc)
async def main():
loop = asyncio.get_running_loop()
for sig in [signal.SIGINT, signal.SIGTERM]:
loop.add_signal_handler(sig, terminate)
clear = True
if os.path.exists('bin/md5'):
proc = await asyncio.create_subprocess_exec(
'md5sum', '-c', 'bin/md5'
)
clear = await proc.wait() != 0
if clear:
shutil.rmtree('bin')
for f in ['.state', 'result', 'data', 'bin']:
os.makedirs(f'{f}/{L}', exist_ok=True)
proc = await asyncio.create_subprocess_shell(
'md5sum Cargo.toml src/main.rs src/rnd.rs > bin/md5'
)
await proc.wait()
for p in range(pmin, pmax+1):
tasks.append(asyncio.create_task(run(p)))
await asyncio.gather(*tasks, return_exceptions=True)
asyncio.run(main())