comparison doc/v2_planning/plugin_JB.py @ 1203:865936d8221b

v2planning plugin_JB - removed VM for clarity
author James Bergstra <bergstrj@iro.umontreal.ca>
date Mon, 20 Sep 2010 21:33:45 -0400
parents acfd5e747a75
children cbe1fb32686c
comparison
equal deleted inserted replaced
1202:7fff3d5c7694 1203:865936d8221b
15 train_pca = SEQ([ 15 train_pca = SEQ([
16 BUFFER_REPEAT(pca_batchsize, CALL(dataset.next)), 16 BUFFER_REPEAT(pca_batchsize, CALL(dataset.next)),
17 FILT(pca.analyze)]) 17 FILT(pca.analyze)])
18 18
19 # run the program 19 # run the program
20 VirtualMachine(train_pca).run() 20 train_pca.run()
21 21
22 The CALL, SEQ, FILT, and BUFFER_REPEAT are control-flow elements. The control-flow elements I 22 The CALL, SEQ, FILT, and BUFFER_REPEAT are control-flow elements. The control-flow elements I
23 defined so far are: 23 defined so far are:
24 24
25 - CALL - a basic statement, just calls a python function 25 - CALL - a basic statement, just calls a python function
36 and realizes all of them. 36 and realizes all of them.
37 The advantages of this approach are: 37 The advantages of this approach are:
38 38
39 - algorithms (including partially run ones) are COPYABLE, and SERIALIZABLE 39 - algorithms (including partially run ones) are COPYABLE, and SERIALIZABLE
40 40
41 - algorithms can be executed without seizing control of the python process (the VM is an 41 - algorithms can be executed without seizing control of the python process (the run()
42 iterator) so your main loop (aka alternate VM implementation) can be checking for network 42 method does this, but if you look inside it you'll see it's a simple for loop)
43 or filesystem events related to job management 43
44 - it is easy to execute an algorithm step by step in a main loop that also checks for
45 network or filesystem events related to e.g. job management.
44 46
45 - the library can provide learning algorithms via control-flow templates, and the user can 47 - the library can provide learning algorithms via control-flow templates, and the user can
46 edit them (with search/replace calls) to include HOOKS, and DIAGNOSTIC plug-in 48 edit them (with search/replace calls) to include HOOKS, and DIAGNOSTIC plug-in
47 functionality 49 functionality
48 50
67 __copyright__ = 'TODO' 69 __copyright__ = 'TODO'
68 70
69 import copy, sys, cPickle 71 import copy, sys, cPickle
70 import numpy 72 import numpy
71 73
72 ###################################################
73 # Virtual Machine for executing programs
74
75 class VirtualMachine(object):
76 def __init__(self, prog):
77 self.prog = prog
78 self.started = False
79 self.finished=False
80 def __iter__(self):
81 assert not self.started
82 self.prog.start(None)
83 self.started = True
84 return self
85 def next(self):
86 if self.finished:
87 raise StopIteration()
88 r = self.prog.step()
89 if r is INCOMPLETE:
90 return r
91 else:
92 self.finished=True
93 return r
94 def run(self,n_steps=float('inf')):
95 i = 0
96 for r in self:
97 i += 1
98 if i > n_steps:
99 break
100 return r
101
102
103 #################################################### 74 ####################################################
104 # CONTROL-FLOW CONSTRUCTS 75 # CONTROL-FLOW CONSTRUCTS
105 76
106 class INCOMPLETE: 77 class INCOMPLETE:
107 """Return value for Element.step""" 78 """Return value for Element.step"""
108 79
109 class ELEMENT(object): 80 class ELEMENT(object):
110 """ 81 """
111 every execution block has a driver 82 Base class for control flow elements (e.g. CALL, REPEAT, etc.)
83
84 The design is that every element has a driver, that is another element, or the iterator
85 implementation in the ELEMENT class.
112 86
113 the driver calls start when entering a new control element 87 the driver calls start when entering a new control element
114 - this would be called once per e.g. outer loop iteration 88 - this would be called once per e.g. outer loop iteration
115 89
116 the driver calls step to advance the control element 90 the driver calls step to advance the control element
117 - which returns INCOMPLETE 91 - which returns INCOMPLETE
118 - which returns any other object to indicate completion 92 - which returns any other object to indicate completion
119 """ 93 """
120 94
95 # subclasses should override these methods:
121 def start(self, arg): 96 def start(self, arg):
122 pass 97 pass
123 def step(self): 98 def step(self):
124 pass 99 pass
100
101 # subclasses should typically not override these:
102 def run(self, arg=None, n_steps=float('inf')):
103 self.start(arg)
104 i = 0
105 r = self.step()
106 while r is INCOMPLETE:
107 i += 1
108 #TODO make sure there is not an off-by-one error
109 if i > n_steps:
110 break
111 r = self.step()
112 return r
113
125 114
126 class BUFFER_REPEAT(ELEMENT): 115 class BUFFER_REPEAT(ELEMENT):
127 """ 116 """
128 Accumulate a number of return values into one list / array. 117 Accumulate a number of return values into one list / array.
129 118
221 class REPEAT(ELEMENT): 210 class REPEAT(ELEMENT):
222 def __init__(self, N, elements, pass_rvals=False): 211 def __init__(self, N, elements, pass_rvals=False):
223 self.N = N 212 self.N = N
224 self.elements = elements 213 self.elements = elements
225 self.pass_rvals = pass_rvals 214 self.pass_rvals = pass_rvals
215
226 #TODO: check for N being callable 216 #TODO: check for N being callable
227 def start(self, arg): 217 def start(self, arg):
228 self.n = 0 #loop iteration 218 self.n = 0 #loop iteration
229 self.idx = 0 #element idx 219 self.idx = 0 #element idx
230 self.finished = False 220 self.finished = False
367 def f(a): 357 def f(a):
368 print l 358 print l
369 l[0] += a 359 l[0] += a
370 return l[0] 360 return l[0]
371 361
372 print VirtualMachine(WEAVE([ 362 print WEAVE([
373 BUFFER_REPEAT(3,CALL(f,1)), 363 BUFFER_REPEAT(3,CALL(f,1)),
374 BUFFER_REPEAT(5,CALL(f,1)), 364 BUFFER_REPEAT(5,CALL(f,1)),
375 ])).run() 365 ]).run()
376 366
377 def main(): 367 def main():
378 # create components 368 # create components
379 dataset = Dataset(numpy.random.RandomState(123).randn(13,1)) 369 dataset = Dataset(numpy.random.RandomState(123).randn(13,1))
380 pca = PCA_Analysis() 370 pca = PCA_Analysis()
432 print >> sys.stderr, "pickling doesnt work, but it can be fixed I think" 422 print >> sys.stderr, "pickling doesnt work, but it can be fixed I think"
433 423
434 pkg = pkg2 424 pkg = pkg2
435 425
436 # running a program updates the variables in its package, but not the other package 426 # running a program updates the variables in its package, but not the other package
437 VirtualMachine(pkg['prog']).run() 427 pkg['prog'].run()
438 print pkg['kf'].scores 428 print pkg['kf'].scores
439 429
440 430
441 if __name__ == '__main__': 431 if __name__ == '__main__':
442 sys.exit(main()) 432 sys.exit(main())