#!/usr/bin/env python3 import subprocess import time import struct import math import statistics import tempfile import itertools from os import path import tqdm SIMS = [ 'dec_proto_am_ber_top.py', 'dec_proto_am_dc_ber_top.py', 'dec_proto_fm_ber_top.py', ] E12_SERIES = [1.0, 1.2, 1.5, 1.8, 2.2, 2.7, 3.3, 3.9, 4.7, 5.6, 6.8, 8.2] AMPLITUDES_MILLIHERTZ = [ x*y for y in [1, 10, 100] for x in E12_SERIES ] 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)