# HG changeset patch # User James Bergstra # Date 1285032825 14400 # Node ID 865936d8221b04e11d567c77462c04473533953b # Parent 7fff3d5c769494dde8b7e6af1273e93710646978 v2planning plugin_JB - removed VM for clarity diff -r 7fff3d5c7694 -r 865936d8221b doc/v2_planning/plugin_JB.py --- a/doc/v2_planning/plugin_JB.py Mon Sep 20 20:35:03 2010 -0400 +++ b/doc/v2_planning/plugin_JB.py Mon Sep 20 21:33:45 2010 -0400 @@ -17,7 +17,7 @@ FILT(pca.analyze)]) # run the program - VirtualMachine(train_pca).run() + train_pca.run() The CALL, SEQ, FILT, and BUFFER_REPEAT are control-flow elements. The control-flow elements I defined so far are: @@ -38,9 +38,11 @@ - algorithms (including partially run ones) are COPYABLE, and SERIALIZABLE - - algorithms can be executed without seizing control of the python process (the VM is an - iterator) so your main loop (aka alternate VM implementation) can be checking for network - or filesystem events related to job management + - algorithms can be executed without seizing control of the python process (the run() + method does this, but if you look inside it you'll see it's a simple for loop) + + - it is easy to execute an algorithm step by step in a main loop that also checks for + network or filesystem events related to e.g. job management. - the library can provide learning algorithms via control-flow templates, and the user can edit them (with search/replace calls) to include HOOKS, and DIAGNOSTIC plug-in @@ -69,37 +71,6 @@ import copy, sys, cPickle import numpy -################################################### -# Virtual Machine for executing programs - -class VirtualMachine(object): - def __init__(self, prog): - self.prog = prog - self.started = False - self.finished=False - def __iter__(self): - assert not self.started - self.prog.start(None) - self.started = True - return self - def next(self): - if self.finished: - raise StopIteration() - r = self.prog.step() - if r is INCOMPLETE: - return r - else: - self.finished=True - return r - def run(self,n_steps=float('inf')): - i = 0 - for r in self: - i += 1 - if i > n_steps: - break - return r - - #################################################### # CONTROL-FLOW CONSTRUCTS @@ -108,7 +79,10 @@ class ELEMENT(object): """ - every execution block has a driver + Base class for control flow elements (e.g. CALL, REPEAT, etc.) + + The design is that every element has a driver, that is another element, or the iterator + implementation in the ELEMENT class. the driver calls start when entering a new control element - this would be called once per e.g. outer loop iteration @@ -118,11 +92,26 @@ - which returns any other object to indicate completion """ + # subclasses should override these methods: def start(self, arg): pass def step(self): pass + # subclasses should typically not override these: + def run(self, arg=None, n_steps=float('inf')): + self.start(arg) + i = 0 + r = self.step() + while r is INCOMPLETE: + i += 1 + #TODO make sure there is not an off-by-one error + if i > n_steps: + break + r = self.step() + return r + + class BUFFER_REPEAT(ELEMENT): """ Accumulate a number of return values into one list / array. @@ -223,6 +212,7 @@ self.N = N self.elements = elements self.pass_rvals = pass_rvals + #TODO: check for N being callable def start(self, arg): self.n = 0 #loop iteration @@ -369,10 +359,10 @@ l[0] += a return l[0] - print VirtualMachine(WEAVE([ + print WEAVE([ BUFFER_REPEAT(3,CALL(f,1)), BUFFER_REPEAT(5,CALL(f,1)), - ])).run() + ]).run() def main(): # create components @@ -434,7 +424,7 @@ pkg = pkg2 # running a program updates the variables in its package, but not the other package - VirtualMachine(pkg['prog']).run() + pkg['prog'].run() print pkg['kf'].scores