summaryrefslogtreecommitdiff
path: root/contrib/run_template.py
blob: 50c048462261a2e7161f9af32b112135e3d96e70 (plain)
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
#!/usr/bin/env python

import multiprocessing
import os
import re
import subprocess
import sys

PREFIX = '#TMPLT'

if len(sys.argv) < 3:
    sys.stderr.write('Usage: %s binary <templatized parfile> [number of jobs]\n' % sys.argv[0])
    sys.stderr.write('A templatized parfile starts with a line in the following format:\n')
    sys.stderr.write(PREFIX + ' <varname> value1 value2 ...\n')
    sys.stderr.write('If number of jobs is specified, this number of processes will be executed in parallel.\n')
    sys.exit(0)

if len(sys.argv) >= 4:
    nb_jobs = int(sys.argv[3])
    if nb_jobs <= 0:
        nb_jobs = multiprocessing.cpu_count()
else:
    nb_jobs = 1

with open(sys.argv[2], 'r') as f:
    line = f.readline()
    if not line.startswith(PREFIX):
        sys.stderr.write('The file does not contain a template line.\n')
        sys.exit(1)

    vals = line[len(PREFIX):].split()
    var  = vals.pop(0)
    vals = map(float, vals)

    par = f.read()

    def run_task(val):
        parfile_name = '%s.par' % val
        with open(parfile_name, 'w') as parfile:
            par_expanded = re.sub(r'\$\{(.*?)\}', lambda match: str(eval(match.group(1), {var : val})), par)
            parfile.write(par_expanded)
            parfile.flush()
            os.fsync(parfile.fileno())

        subprocess.call([sys.argv[1], '--', parfile_name])
        os.unlink(parfile_name)

    if nb_jobs > 1:
        pool = multiprocessing.Pool(nb_jobs)
        pool.map(run_task, vals)
    else:
        map(run_task, vals)