Mercurial > pylearn
annotate doc/v2_planning/arch_src/checkpoint_JB.py @ 1340:04b988fb00b6
Reply to Razvan
author | Olivier Delalleau <delallea@iro> |
---|---|
date | Thu, 21 Oct 2010 16:18:52 -0400 |
parents | 09ad2a4f663c |
children |
rev | line source |
---|---|
1336
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
1 import copy as copy_module |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
2 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
3 #TODO: use logging.info to report cache hits/ misses |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
4 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
5 CO_VARARGS = 0x0004 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
6 CO_VARKEYWORDS = 0x0008 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
7 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
8 class mem_db(dict): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
9 # A key->document dictionary. |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
10 # A "document" is itself a dictionary. |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
11 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
12 # A "document" can be a small or large object, but it cannot be partially retrieved. |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
13 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
14 # This simple data structure is used in pylearn to cache intermediate reults between |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
15 # several process invocations. |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
16 pass |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
17 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
18 class UNSPECIFIED(object): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
19 pass |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
20 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
21 class CtrlObj(object): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
22 """ |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
23 Job control API. |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
24 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
25 This interface makes it easier to break a logical program into pieces that can be |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
26 executed by several different processes, either serially or in parallel. |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
27 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
28 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
29 The base class provides decorators to simplify some common cache patterns: |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
30 - cache_pickle to cache arbitrary return values using the pickle mechanism |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
31 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
32 - cache_dict to cache dict return values directly using the document db |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
33 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
34 - cache_numpy to cache [single] numpy ndarray rvals in a way that supports memmapping of |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
35 large arrays. |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
36 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
37 Authors are encouraged to use these when they apply, but should feel free to implement |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
38 other cache logic when these standard ones are lacking using the CtorlObj.get() and |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
39 CtorlObj.set() methods. |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
40 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
41 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
42 """ |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
43 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
44 def __init__(self, rootdir, db, autosync): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
45 self.db = db |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
46 self.r_lookup = {} |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
47 self.autosync=autosync |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
48 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
49 def get(self, key, default_val=UNSPECIFIED, copy=True): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
50 # Default to return a COPY because a self.set() is required to make a change persistent. |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
51 # Inplace changes that the CtrlObj does not know about (via self.set()) will not be saved. |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
52 try: |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
53 val = self.db[key] |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
54 except: |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
55 if default_val is not UNSPECIFIED: |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
56 # return default_val, but do not add it to the r_lookup object |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
57 # since looking up that key in the future would not retrieve default_val |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
58 return default_val |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
59 else: |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
60 raise |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
61 if copy: |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
62 rval = copy_module.deepcopy(val) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
63 else: |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
64 rval = val |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
65 self.r_lookup[id(rval)] = key |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
66 return rval |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
67 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
68 def get_key(self, val): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
69 """Return the key that retrieved `val`. |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
70 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
71 This is useful for specifying cache keys for unhashable (e.g. numpy) objects that |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
72 happen to be stored in the db. |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
73 """ |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
74 return self.r_lookup[id(val)] |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
75 def set(self, key, val): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
76 vv = dict(val) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
77 if self.db.get(key, None) not in (val, None): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
78 del_keys = [k for (k,v) in self.r_lookup.iteritems() if v == key] |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
79 for k in del_keys: |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
80 del self.r_lookup[k] |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
81 self.db[key] = vv |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
82 def delete(self, key): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
83 del_keys = [k for (k,v) in self.r_lookup.iteritems() if v == key] |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
84 for k in del_keys: |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
85 del self.r_lookup[k] |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
86 del self.db[key] |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
87 def checkpoint(self): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
88 """Potentially pass control to another greenlet/tasklet that could potentially |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
89 serialize this (calling) greenlet/tasklet using cPickle. |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
90 """ |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
91 pass |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
92 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
93 def sync(self, pull=True, push=True): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
94 """Synchronise local changes with a master version (if applicable). |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
95 """ |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
96 pass |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
97 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
98 def open(self, filename): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
99 """Return a file-handle to a file that can be synced with a server""" |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
100 #todo - save references / proxies of the file objects returned here |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
101 # and sync them with a server if they are closed |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
102 return open(os.path.join(self.rootdir, filename)) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
103 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
104 def open_unique(self, mode='wb', prefix='uniq_', suffix=''): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
105 #TODO: use the standard lib algo for this if you can find it. |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
106 if suffix: |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
107 template = prefix+'%06i.'+suffix |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
108 else: |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
109 template = prefix+'%06i' |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
110 while True: |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
111 fname = template%numpy.random.randint(999999) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
112 path = os.path.join(self.rootdir, fname) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
113 try: |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
114 open(path).close() |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
115 except IOError: #file not found |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
116 return open(path, mode=mode), path |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
117 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
118 def memory_ctrl_obj(): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
119 return CtrlObj(db=dict()) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
120 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
121 def directory_ctrl_obj(path, **kwargs): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
122 raise NotImplementedError() |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
123 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
124 def mongo_ctrl_obj(connection_args, **kwargs): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
125 raise NotImplementedError() |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
126 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
127 def couchdb_ctrl_obj(connection_args, **kwargs): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
128 raise NotImplementedError() |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
129 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
130 def jobman_ctrl_obj(connection_args, **kwargs): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
131 raise NotImplementedError() |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
132 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
133 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
134 def _default_values(f): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
135 """Return a dictionary param -> default value of function `f`'s parameters""" |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
136 default_dict = {} |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
137 func_defaults = f.func_defaults |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
138 if func_defaults: |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
139 first_default_pos = f.func_code.co_argcount-len(f.func_defaults) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
140 params_with_defaults = f.func_code.co_varnames[first_default_pos:f.func_code.co_argcount] |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
141 rval = dict(zip(params_with_defaults, f.func_defaults)) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
142 else: |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
143 rval = {} |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
144 return rval |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
145 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
146 def test_default_values(): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
147 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
148 def f(a): pass |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
149 assert _default_values(f) == {} |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
150 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
151 def f(a, b=1): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
152 aa = 5 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
153 assert _default_values(f) == dict(b=1) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
154 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
155 def f(a, b=1, c=2, *args, **kwargs): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
156 e = b+c |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
157 return e |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
158 assert _default_values(f) == dict(b=1, c=2) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
159 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
160 def _arg_assignment(f, args, kwargs): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
161 # make a dictionary from args and kwargs that contains all the arguments to f and their |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
162 # values |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
163 assignment = dict() |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
164 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
165 params = f.func_code.co_varnames[:f.func_code.co_argcount] #CORRECT? |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
166 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
167 f_accepts_varargs = f.func_code.co_flags & CO_VARARGS |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
168 f_accepts_kwargs = f.func_code.co_flags & CO_VARKEYWORDS |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
169 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
170 if f_accepts_varargs: |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
171 raise NotImplementedError() |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
172 if f_accepts_kwargs: |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
173 raise NotImplementedError() |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
174 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
175 # first add positional arguments |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
176 #TODO: what if f accepts a '*args' or similar? |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
177 assert len(args) <= f.func_code.co_argcount |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
178 for i, a in enumerate(args): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
179 assignment[f.func_code.co_varnames[i]] = a # CORRECT?? |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
180 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
181 # next add kw arguments |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
182 for k,v in kwargs.iteritems(): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
183 if k in assignment: |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
184 #TODO: match Python error |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
185 raise TypeError('duplicate argument provided for parameter', k) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
186 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
187 if (not f_accepts_kwargs) and (k not in params): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
188 #TODO: match Python error |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
189 raise TypeError('invalid keyword argument', k) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
190 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
191 assignment[k] = v |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
192 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
193 # finally add default arguments for any remaining parameters |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
194 for k,v in _default_values(f).iteritems(): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
195 if k in assignment: |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
196 pass # this argument has [already] been specified |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
197 else: |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
198 assignment[k] = v |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
199 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
200 # TODO |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
201 # check that the assignment covers all parameters without default values |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
202 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
203 # TODO |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
204 # check that the assignment includes no extra variables if f does not accept a '**' |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
205 # parameter. |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
206 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
207 return assignment |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
208 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
209 def test_arg_assignment(): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
210 #TODO: check cases that should cause errors |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
211 # - doubly-specified arguments, |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
212 # - insufficient arguments |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
213 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
214 def f():pass |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
215 assert _arg_assignment(f, (), {}) == {} |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
216 def f(a):pass |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
217 assert _arg_assignment(f, (1,), {}) == {'a':1} |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
218 def f(a):pass |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
219 assert _arg_assignment(f, (), {'a':1}) == {'a':1} |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
220 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
221 def f(a=1):pass |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
222 assert _arg_assignment(f, (), {}) == {'a':1} |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
223 def f(a=1):pass |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
224 assert _arg_assignment(f, (2,), {}) == {'a':2} |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
225 def f(a=1):pass |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
226 assert _arg_assignment(f, (), {'a':2}) == {'a':2} |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
227 def f(a=1):pass |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
228 assert _arg_assignment(f, (), {'a':2}) == {'a':2} |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
229 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
230 def f(b, a=1): pass |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
231 assert _arg_assignment(f, (3,4), {}) == {'b':3, 'a':4} |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
232 def f(b, a=1): pass |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
233 assert _arg_assignment(f, (3,), {'a':4}) == {'b':3, 'a':4} |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
234 def f(b, a=1): pass |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
235 assert _arg_assignment(f, (), {'b':3,'a':4}) == {'b':3, 'a':4} |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
236 def f(b, a=1): pass |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
237 assert _arg_assignment(f, (), {'b':3}) == {'b':3, 'a':1} |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
238 def f(b, a=1): a0=6 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
239 assert _arg_assignment(f, (2,), {}) == {'b':2, 'a':1} |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
240 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
241 if 0: |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
242 def test_arg_assignment_w_varargs(): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
243 def f(b, c=1, *a, **kw): z=5 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
244 assert _arg_assignment(f, (3,), {}) == {'b':3, 'c':1, 'a':(), 'kw':{}} |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
245 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
246 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
247 class CtrlObjCacheWrapper(object): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
248 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
249 @classmethod |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
250 def decorate(cls, *args, **kwargs): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
251 self = cls(*args, **kwargs) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
252 def rval(f): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
253 self.f = f |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
254 return rval |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
255 def parse_args(self, args, kwargs): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
256 """Return key, f_args, f_kwargs, by removing ctrl-cache related flags. |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
257 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
258 The key is None or a hashable pair that identifies all the arguments to the function. |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
259 """ |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
260 ctrl_args = dict( |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
261 ctrl = None, |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
262 ctrl_ignore_cache=False, |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
263 ctrl_force_shallow_recompute=False, |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
264 ctrl_force_deep_recompute=False, |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
265 ) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
266 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
267 # remove the ctrl and ctrl_* arguments |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
268 # because they are not meant to be passed to 'f' |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
269 ctrl_kwds = [(k,v) for (k,v) in kwargs.iteritems() |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
270 if k.startswith('ctrl')] |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
271 ctrl_args.update(dict(ctrl_kwds)) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
272 f_kwds = [(k,v) for (k,v) in kwargs.iteritems() |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
273 if not k.startswith('ctrl')] |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
274 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
275 # assignment is a dictionary with a complete specification of the effective arguments to f |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
276 # including default values, varargs, and varkwargs. |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
277 assignment = _arg_assignment(self.f, args, dict(f_kwds)) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
278 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
279 assignment_items = assignment.items() |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
280 assignment_items.sort() #canonical ordering for parameters |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
281 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
282 # replace argument values with explicitly provided keys |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
283 assignment_key = [(k, kwargs.get('ctrl_key_%s'%k, v)) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
284 for (k,v) in assignment_items] |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
285 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
286 rval_key = ('fn_cache', self.f, tuple(assignment_key)) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
287 try: |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
288 hash(rval_key) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
289 except: |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
290 rval_key = None |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
291 return rval_key, assignment, {}, ctrl_args |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
292 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
293 def __doc__(self): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
294 #TODO: Add documentation from self.f |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
295 return """ |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
296 Optional magic kwargs: |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
297 ctrl - use this handle for cache/checkpointing |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
298 ctrl_key_%(paramname)s - specify a key to use for a cache lookup of this parameter |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
299 ctrl_ignore_cache - completely ignore the cache (but checkpointing can still work) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
300 ctrl_force_shallow_recompute - refresh the cache (but not of sub-calls) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
301 ctrl_force_deep_recompute - recursively refresh the cache |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
302 ctrl_nocopy - skip the usual copy of a cached return value |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
303 """ |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
304 def __call__(self, *args, **kwargs): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
305 # N.B. |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
306 # ctrl_force_deep_recompute |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
307 # can work by inspecting the call stack |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
308 # if any parent frame has a special variable set (e.g. _child_frame_ctrl_force_deep_recompute) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
309 # then it means this is a ctrl_force_deep_recompute too. |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
310 key, f_args, f_kwargs, ctrl_args = self.parse_args(args, kwargs) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
311 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
312 ctrl = ctrl_args['ctrl'] |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
313 if ctrl is None or ctrl_args['ctrl_ignore_cache']: |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
314 return self.f(*f_args, **f_kwargs) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
315 if key: |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
316 try: |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
317 return self.get_cached_val(ctrl, key) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
318 except KeyError: |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
319 pass |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
320 f_rval = self.f(*f_args, **f_kwargs) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
321 if key: |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
322 f_rval = self.cache_val(ctrl, key, f_rval) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
323 return f_rval |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
324 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
325 def get_cached_val(self, ctrl, key): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
326 return ctrl.get(key) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
327 def cache_val(self, ctrl, key, val): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
328 ctrl.set(key, val) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
329 return val |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
330 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
331 class NumpyCacheCtrl(CtrlObjCacheWrapper): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
332 def get_cached_val(self, ctrl, key): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
333 filename = ctrl.get(key)['npy_filename'] |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
334 return numpy.load(filename) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
335 def cache_val(self, ctrl, key, val): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
336 try: |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
337 filename = ctrl.get(key) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
338 except KeyError: |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
339 handle, filename = ctrl.open_uniq() |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
340 handle.close() |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
341 ctrl.set(key, dict(npy_filename=filename)) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
342 numpy.save(filename, val) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
343 return val |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
344 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
345 class PickleCacheCtrl(CtrlObjCacheWrapper): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
346 def __init__(self, protocol=0, **kwargs): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
347 self.protocol=protocol |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
348 super(PickleCacheCtrl, self).__init__(**kwargs) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
349 def get_cached_val(self, ctrl, key): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
350 return cPickle.loads(ctrl.get(key)['cPickle_str']) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
351 def cache_val(self, ctrl, key, val): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
352 ctrl.set(key, dict(cPickle_str=cPickle.dumps(val))) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
353 return val |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
354 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
355 @NumpyCacheCtrl.decorate() |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
356 def get_raw_data(rows, cols, seed=67273): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
357 return numpy.random.RandomState(seed).randn(rows, cols) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
358 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
359 @NumpyCacheCtrl.decorate() |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
360 def get_whitened_dataset(X, pca, max_components=5): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
361 return X[:,:max_components] |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
362 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
363 @PickleCacheCtrl.decorate(protocol=-1) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
364 def get_pca(X, max_components=100): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
365 return dict( |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
366 mean=0, |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
367 eigvals=numpy.ones(X.shape[1]), |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
368 eigvecs=numpy.identity(X.shape[1]) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
369 ) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
370 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
371 @PickleCacheCtrl.decorate(protocol=-1) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
372 def train_mean_var_model(data, ctrl): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
373 mean = numpy.zeros(data.shape[1]) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
374 meansq = numpy.zeros(data.shape[1]) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
375 for i in xrange(data.shape[0]): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
376 alpha = 1.0 / (i+1) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
377 mean += (1-alpha) * mean + data[i] * alpha |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
378 meansq += (1-alpha) * meansq + (data[i]**2) * alpha |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
379 ctrl.checkpoint() |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
380 return (mean, meansq) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
381 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
382 def test_run_experiment(): |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
383 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
384 # Could use db, or filesystem, or both, etc. |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
385 # There would be generic ones, but the experimenter should be very aware of what is being |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
386 # cached where, when, and how. This is how results are stored and retrieved after all. |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
387 # Cluster-friendly jobs should not use local files directly, but should store cached |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
388 # computations and results to such a database. |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
389 # Different jobs should avoid using the same keys in the database because coordinating |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
390 # writes is difficult, and conflicts will inevitably arise. |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
391 ctrl = memory_ctrl_obj() |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
392 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
393 raw_data = get_raw_data(ctrl=ctrl) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
394 raw_data_key = ctrl.get_key(raw_data) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
395 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
396 pca = get_pca(raw_data, max_components=30, ctrl=ctrl) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
397 whitened_data = get_whitened_dataset(raw_data, pca, ctrl=ctrl) |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
398 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
399 mean_var = train_mean_var_model( |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
400 data=whitened_data+66, |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
401 ctrl=ctrl, |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
402 ctrl_key_data=whitened_data) #tell that the temporary is tied to whitened_data |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
403 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
404 mean, var = mean_var |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
405 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
406 #TODO: Test that the cache actually worked!! |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
407 |
09ad2a4f663c
adding new idea to arch_src
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff
changeset
|
408 |