-
Notifications
You must be signed in to change notification settings - Fork 1
/
paramsweep.py
executable file
·154 lines (121 loc) · 3.96 KB
/
paramsweep.py
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#!/usr/bin/python
import re, sys, shlex, argparse, fcntl, time
from subprocess import Popen, PIPE
from os import listdir, makedirs, unlink
from os.path import isfile, isdir, join, getmtime, exists
from math import ceil
import numpy as np
port_start = 8000
def_number = 20
nice = 19
binary = "./bin/Release/evolution-1.0.1"
data_path = "../data/exp/"
settings_folder = "./settings/"
settings_file_ending = ".setting"
ansi_escape = re.compile(r'\x1b[^m]*m')
def write_locked(fname, op, line):
fout = open(fname, op)
while True:
try:
fcntl.flock(fout, fcntl.LOCK_EX | fcntl.LOCK_NB)
break
except IOError as e:
# raise on unrelated IOErrors
if e.errno != errno.EAGAIN:
raise
else:
time.sleep(0.25)
fout.write(line)
fout.flush()
fcntl.flock(fout, fcntl.LOCK_UN)
fout.close()
def check_binary():
if isfile(binary):
print("Binary is: {0}".format(binary))
else:
print("Could not find evolution binary {0}".format(binary))
def execute_command(command):
args = shlex.split(command)
proc = Popen(args, stdout=PIPE, stderr=PIPE)
out, err = proc.communicate()
exitcode = proc.returncode
return exitcode, out, err
def override_settings(filename, setlist = ()):
if setlist:
with open(filename, "r") as f:
data = f.read().format(*setlist)
newfile = filename+".tmp"
write_locked(newfile, "w+", data)
return newfile
else:
return filename
def conduct(robot, experiment, port, num, dry, add_settings = ()):
expname = "{0}/{2}_{0}_{1}".format(robot, experiment, num)
if isdir(data_path+expname):
print(" + {0} DONE. SKIPPED.".format(expname))
return False
else:
print(" > {0}".format(expname)),
setting = "{0}{1}/{2}{3}".format(settings_folder, robot, experiment, settings_file_ending)
if not dry:
setting = override_settings(setting, add_settings)
command = "nice -n {4} {0} -n {1} -s {2} -p {3} -b"\
.format(binary, expname, setting, port, nice)
if not exists(data_path+robot):
makedirs(data_path+robot)
if not dry:
output_path = "{0}{1}/".format(data_path, expname)
try:
exitcode, out, err = execute_command(command)
with open(output_path + "stdout.txt", "w") as out_file:
out_file.write(ansi_escape.sub('', out))
with open(output_path + "stderr.txt", "w") as err_file:
err_file.write(ansi_escape.sub('', err))
except:
print("ERROR")
if exitcode==0:
print("OK.")
return True
else:
print("FAILED. Code {0}".format(exitcode))
return False
else:
print(command)
return False
def tail(filename):
with open(filename, "rb") as f:
first = f.readline() # Read the first line.
f.seek(-2, 2) # Jump to the second last byte.
while f.read(1) != b"\n": # Until EOL is found...
f.seek(-2, 1) # ...jump back the read byte plus one more.
last = f.readline() # Read last line.
return last
def main():
global port_start
parser = argparse.ArgumentParser()
parser.add_argument('-r', '--robot' , required=True)
parser.add_argument('-p', '--port' , default=port_start)
parser.add_argument('-d', '--dry' , action='store_true')
parser.add_argument('-n', '--number', default=def_number)
parser.add_argument('-m', '--meta' , default=0.5)
args = parser.parse_args()
robot = str(args.robot)
port_start = int(args.port)
check_binary()
experiment = "31_p_0fw_e_param_sweep"
idx = 0
me = args.meta
for ps in np.linspace(5, 100, num=args.number):
for mr in [round(x,10) for x in np.logspace(-3, 0, num=args.number)]:
print("Conducting with mutation rate {0} and popsize {1} and meta {2}".format(mr,int(ps),me))
res = conduct(robot, experiment, port_start, idx, args.dry, add_settings=(int(ps),mr,me))
port_start += 1 if port_start != 8089 else 2
# get fitness
if args.dry:
continue
if res:
line = "{0} {1} {2}".format(int(ps),mr,tail(data_path+robot+"/"+str(idx)+"_"+robot+"_"+experiment+"/evolution.log"))
write_locked("results.log", "a+", line)
idx += 1
print("\n____\nDONE.\n")
if __name__ == "__main__": main()