summaryrefslogtreecommitdiff
path: root/sweep_gr_sims.py
diff options
context:
space:
mode:
Diffstat (limited to 'sweep_gr_sims.py')
-rw-r--r--sweep_gr_sims.py118
1 files changed, 69 insertions, 49 deletions
diff --git a/sweep_gr_sims.py b/sweep_gr_sims.py
index f11ee64..661af56 100644
--- a/sweep_gr_sims.py
+++ b/sweep_gr_sims.py
@@ -2,10 +2,12 @@
import subprocess
import time
import struct
+import random
import math
import statistics
import tempfile
import itertools
+from collections import defaultdict
from os import path
import tqdm
@@ -22,52 +24,70 @@ SIMULATION_DURATION = 30.0 # seconds realtime
MAX_CONCURRENT_PROCESSES = 8
-with tempfile.TemporaryDirectory() as tmpdir:
-
- jobs = list(enumerate(itertools.product(SIMS, AMPLITUDES_MILLIHERTZ)))
- print(f'Will launch {len(jobs)} simulation jobs in {math.ceil(len(jobs)/MAX_CONCURRENT_PROCESSES):.0f} batches of {MAX_CONCURRENT_PROCESSES}')
-
- def start_processes(jobs):
- for i, (sim, ampl_mhz) in jobs:
- berfile = path.join(tmpdir, f'berfile_{i}')
- proc = subprocess.Popen(['/usr/bin/python2', sim,
- '--signal-strength', str(ampl_mhz),
- '--ber-file', berfile],
- stdin=subprocess.PIPE, stdout=subprocess.DEVNULL)
- yield proc, sim, ampl_mhz, berfile
-
- results = { sim: ([], [], []) for sim in SIMS }
- for n, i in enumerate(range(0, len(jobs), MAX_CONCURRENT_PROCESSES)):
- batch = jobs[i:][:MAX_CONCURRENT_PROCESSES]
- print(f'Starting batch {n}... ', end='')
- processes = list(start_processes(batch))
- print('done.')
-
- print('Waiting for simulation:')
- for _ in tqdm.trange(1000):
- time.sleep(SIMULATION_DURATION/1000)
-
- print('Terminating processes...', end='')
- for proc, *_ in processes:
- proc.communicate(b'\n', timeout=10)
-
- for proc, *_ in processes:
- proc.wait(5)
- print('done.')
-
- print('Processing simulation results')
- for _proc, sim, ampl_mhz, berfile in processes:
-
- with open(berfile, 'rb') as f:
- data = f.read()
-
- floats = struct.unpack(f'{len(data)//4}f', data)
- ber = statistics.mean(floats[-256:])
- stdev = statistics.stdev(floats[-256:])
-
- amplitudes, bers, stdevs = results[sim]
- amplitudes.append(ampl_mhz)
- bers.append(ber)
- stdevs.append(stdev)
-
-print(results)
+def run_simulation(
+ duration = SIMULATION_DURATION,
+ simulations = SIMS,
+ forklimit = MAX_CONCURRENT_PROCESSES,
+ amplitudes:'list(millihertz)' = AMPLITUDES_MILLIHERTZ,
+ terminate_timeout:'s' = 5.0,
+ communicate_timeout:'s' = 10.0,
+ repeat_runs = 1,
+ shuffle = False,
+ tqdm = tqdm.tqdm
+ ):
+ with tempfile.TemporaryDirectory() as tmpdir:
+
+ jobs = list(enumerate(itertools.product(simulations, amplitudes * repeat_runs)))
+ if shuffle:
+ random.shuffle(jobs)
+ nchunks = int(math.ceil(len(jobs)/forklimit))
+
+ def start_processes(jobs):
+ for i, (sim, ampl_mhz) in jobs:
+ berfile = path.join(tmpdir, f'berfile_{i}')
+ proc = subprocess.Popen(['/usr/bin/python2', sim,
+ '--signal-strength', str(ampl_mhz),
+ '--ber-file', berfile],
+ stdin=subprocess.PIPE, stdout=subprocess.DEVNULL)
+ yield proc, sim, ampl_mhz, berfile
+
+ results = { sim: defaultdict(lambda: ([], [])) for sim in simulations }
+ with tqdm(total = nchunks * duration, bar_format='{l_bar}{bar}| {elapsed}<{remaining}') as tq:
+ tq.write(f'Will launch {len(jobs)} simulation jobs in {nchunks} batches of {forklimit}')
+ for n, i in enumerate(range(0, len(jobs), forklimit)):
+ batch = jobs[i:][:forklimit]
+ tq.write(f'Starting batch {n+1}/{nchunks}...')
+ processes = list(start_processes(batch))
+ tq.write('done.')
+
+ tq.write('Waiting for simulation:')
+ for _ in range(100):
+ time.sleep(duration/100)
+ tq.update(duration/100)
+
+ tq.write('Terminating processes...')
+ for proc, *_ in processes:
+ proc.communicate(b'\n', timeout=communicate_timeout)
+
+ for proc, *_ in processes:
+ proc.wait(terminate_timeout)
+ tq.write('done.')
+
+ tq.write('Processing simulation results')
+ for _proc, sim, ampl_mhz, berfile in processes:
+
+ with open(berfile, 'rb') as f:
+ data = f.read()
+
+ floats = struct.unpack(f'{len(data)//4}f', data)
+ ber = statistics.mean(floats[-256:])
+ stdev = statistics.stdev(floats[-256:])
+
+ bers, stdevs = results[sim][ampl_mhz]
+ bers.append(ber)
+ stdevs.append(stdev)
+
+ return results
+
+if __name__ == '__main__':
+ print(run_simulation())