/
ask
executable file
·227 lines (189 loc) · 7.68 KB
/
ask
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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
#!/usr/bin/env python
# Copyright (c) 2011-2012, Universite de Versailles St-Quentin-en-Yvelines
#
# This file is part of ASK. ASK is free software: you can redistribute
# it and/or modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation, version 2.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc., 51
# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import logging
import os
import os.path
import select
import shutil
import subprocess
import sys
from common.configuration import Configuration
from common.util import fatal
VERSION="1.1.0"
###
# Driver Main Loop
#
# Will contain the configuration and logger singletons
C, L = None, None
def call_module(module, params=None):
if params is None:
params = []
L.debug("Calling {0} module".format(module))
# Prepare the command line
# Add the executable
cmd = [C("modules")[module]["executable"]]
# Append configuration file
cmd.append(C("configuration_file"))
# Append the input/output params
cmd += params
cmd = " ".join(cmd)
L.debug(" - cmd : <{0}>".format(cmd))
try:
p = subprocess.Popen(cmd,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE,
bufsize=1,
shell=True)
except OSError:
fatal("Could not execute module {0}\n"
" {1}".format(module, cmd))
eof_stdout, eof_stderr = False, False
while(not(eof_stdout and eof_stderr)):
for fd in select.select([p.stdout, p.stderr], [], [])[0]:
l = fd.readline()
if not l:
if fd == p.stdout:
eof_stdout = True
else:
eof_stderr = True
if fd == p.stderr and l.strip():
L.warning("\t({0}) {1}".format(module, l[:-1]))
elif l.strip():
L.info("\t({0}) {1}".format(module, l[:-1]))
p.wait()
if p.returncode != 0:
if module == "control" and p.returncode == 254:
L.info("Control module decided to stop experiments")
print "Experiments finished normally"
sys.exit(0)
else:
fatal("Module {0} stopped with code {1}"
.format(module, p.returncode), p.returncode)
def driver_loop(args):
""" Main loop of the driver """
L.debug("Starting driver loop")
out_dir = C("output_directory")
iteration = 0
labelled = "{0}/labelled.data".format(out_dir)
# Blank labelled file (needed in replay)
open(labelled, 'w').close()
while(1):
L.debug("**** Starting ITERATION {0} ****".format(iteration))
model = "{0}/model{1:05d}.data".format(out_dir, iteration)
newly_labelled = "{0}/labelled{1:05d}.data".format(out_dir, iteration)
requested = "{0}/requested{1:05d}.data".format(out_dir, iteration)
if not args.replay_only:
if iteration == 0:
# Call bootstrap module to get the initial data
call_module("bootstrap", params=[requested])
if not os.path.exists(requested):
fatal("Bootstrap did not produce points "
"({0} does not exist)".format(requested))
else:
# Ask sampler to request new points
call_module("sampler", params=[labelled, requested])
if not os.path.exists(requested):
fatal("Oracle did not gave back requests "
"({0} does not exist)".format(requested))
# Call source to fulfill the requests
call_module("source", params=[requested, newly_labelled])
if not os.path.exists(newly_labelled):
fatal("Source did not fulfill requests "
"({0} does not exist)".format(newly_labelled))
# Append newly_labelled points to labelled
L.debug("Updating labelled points")
orig = open(newly_labelled, "rb")
dest = open(labelled, "ab")
shutil.copyfileobj(orig, dest)
dest.close()
orig.close()
# Call model module
if not args.skip_model:
call_module("model", params=[labelled, model])
# Call reporter module
if not args.skip_reporter:
call_module("reporter", params=[str(iteration),
labelled,
newly_labelled,
model])
# Call control module (which will decide when to exit this loop)
call_module("control", params=[str(iteration), labelled, model])
iteration += 1
def main():
global C, L
import argparse
parser = argparse.ArgumentParser(
description="Helps choosing sampling points during experiments.")
parser.add_argument(
'--force_overwrite',
action='store_true',
help="If a previous output directory is found its contents"
" will be overwritten")
parser.add_argument(
'--replay_only',
action='store_true',
help="(Must be run over a full previous ask run). Skip bootstrap and"
" sampler modules, but runs previous labels through the model and"
" reporter. This option is useful if one wants to run sampling"
" and analyze results separately.")
parser.add_argument(
'--skip_model',
action='store_true',
help="Skip model module. (WARNING: if the chosen control module"
" relies on the output of the model module, this option"
" fails.)")
parser.add_argument(
'--skip_reporter',
action='store_true',
help="Skip reporter module. (WARNING: if the chosen control module"
" relies on the output of the reporter module, this option"
" fails.)")
parser.add_argument(
'--version',
action='version',
version="ask {}".format(VERSION))
parser.add_argument('configuration',
help="the experiment configuration file")
args = parser.parse_args()
if args.replay_only and args.force_overwrite:
fatal("--force_overwrite and --replay_only are exclusive options.")
# Setup the ASKHOME
os.environ["ASKHOME"] = os.path.dirname(os.path.realpath(__file__))
# Setup PYTHONPATH
if "PYTHONPATH" in os.environ:
os.environ["PYTHONPATH"] += ":" + os.environ["ASKHOME"]
else:
os.environ["PYTHONPATH"] = os.environ["ASKHOME"]
# Read Configuration
C = Configuration(user_configuration=args.configuration,
reload_live_configuration=False,
force_overwrite=args.force_overwrite,
replay_only=args.replay_only)
# Start Logger
print "Logging to {0}".format(C("log.logfile"))
L = logging.getLogger(__name__)
fh = logging.FileHandler(C("log.logfile"))
formatter = logging.Formatter('[%(asctime)s %(levelname)-8s] %(message)s',
datefmt='%H:%M')
fh.setFormatter(formatter)
L.setLevel(eval("logging." + C("log.level")))
fh.setLevel(eval("logging." + C("log.level")))
L.addHandler(fh)
L.debug("Logger started at level {0}".format(C("log.level")))
# Enter driver loop
driver_loop(args)
if __name__ == "__main__":
main()