Skip to content

Commit be7487f

Browse files
committed
finish builder code
1 parent e9c5f17 commit be7487f

File tree

3 files changed

+226
-54
lines changed

3 files changed

+226
-54
lines changed

tensorbuilder/builder.py

Lines changed: 162 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,13 @@ def __init__(self, ref=None):
2121
super(Ref, self).__init__()
2222
self.ref = ref
2323

24-
def __call__(self):
24+
def __call__(self, *optional):
2525
return self.ref
2626

27+
def set(self, x):
28+
self.ref = x
29+
return x
30+
2731

2832
class Builder(object):
2933
"""
@@ -98,6 +102,54 @@ def _(builder, g, *args, **kwargs):
98102
g = _compile(g)
99103
return builder._unit(lambda x: g(builder.f(x), *args, **kwargs))
100104

105+
def _2(builder, g, arg1, *args, **kwargs):
106+
"""
107+
"""
108+
g = _compile(g)
109+
110+
def _lambda(x):
111+
arg2 = builder.f(x)
112+
new_args = tuple([arg1, arg2] + list(args))
113+
return g(*new_args, **kwargs)
114+
115+
return builder._unit(_lambda)
116+
117+
def _3(builder, g, arg1, arg2, *args, **kwargs):
118+
"""
119+
"""
120+
g = _compile(g)
121+
122+
def _lambda(x):
123+
arg3 = builder.f(x)
124+
new_args = tuple([arg1, arg2, arg3] + list(args))
125+
return g(*new_args, **kwargs)
126+
127+
return builder._unit(_lambda)
128+
129+
def _4(builder, g, arg1, arg2, arg3, *args, **kwargs):
130+
"""
131+
"""
132+
g = _compile(g)
133+
134+
def _lambda(x):
135+
arg4 = builder.f(x)
136+
new_args = tuple([arg1, arg2, arg3, arg4] + list(args))
137+
return g(*new_args, **kwargs)
138+
139+
return builder._unit(_lambda)
140+
141+
def _5(builder, g, arg1, arg2, arg3, arg4, *args, **kwargs):
142+
"""
143+
"""
144+
g = _compile(g)
145+
146+
def _lambda(x):
147+
arg5 = builder.f(x)
148+
new_args = tuple([arg1, arg2, arg3, arg4, arg5] + list(args))
149+
return g(*new_args, **kwargs)
150+
151+
return builder._unit(_lambda)
152+
101153

102154
def using(builder, x):
103155
"""
@@ -107,15 +159,15 @@ def using(builder, x):
107159
def run(builder):
108160
return builder(None)
109161

110-
def store_on(builder, reference):
111-
def store_ref(x):
112-
reference.ref = x
113-
return x
114-
return builder._(store_ref)
162+
def store(builder, ref):
163+
return builder._(ref.set)
115164

116165
def ref(self):
117166
return Ref()
118167

168+
def identity(self, x):
169+
return x
170+
119171
def pipe(self, x, *ast):
120172
"""
121173
`pipe` takes in a `builder` of type `Builder`, `BuilderTree` or `Object` preferably and an object `ast` which must be part of the domain of the DSL, and compiles `ast` to a function of type `Builder -> Builder` and applies it to the input `builder`. All \*args after `builder` are taken as a tuple, therefore, it makes it easier to define an initial tuple `()` element to define a sequential operation.
@@ -203,7 +255,7 @@ def compile(self, *ast):
203255
return _compile(ast)
204256

205257
@classmethod
206-
def register_method(cls, fn, library_path, alias=None, doc=None):
258+
def register_as_method(cls, fn, library_path, alias=None, doc=None):
207259
"""
208260
This method enables you to register any function `fn` that takes an Applicative as its first argument as a method of the Builder class.
209261
@@ -239,8 +291,16 @@ def register_method(cls, fn, library_path, alias=None, doc=None):
239291

240292
setattr(cls, name, fn)
241293

294+
def register_method(self, library_path, alias=None, doc=None):
295+
def register_decorator(fn):
296+
297+
self.register_as_method(fn, library_path, alias=alias, doc=doc)
298+
299+
return fn
300+
return register_decorator
301+
242302
@classmethod
243-
def register_function_as_method(cls, fn, library_path, alias=None, doc=None):
303+
def register_function(cls, fn, library_path, alias=None, doc=None):
244304
"""
245305
This method enables you to register any function `fn` that takes an object as its first argument as a method of the Builder and Applicative class.
246306
@@ -259,16 +319,107 @@ def register_function_as_method(cls, fn, library_path, alias=None, doc=None):
259319
260320
"""
261321
alias = alias if alias else fn.__name__
262-
method = get_method(fn)
322+
323+
def method(builder, *args, **kwargs):
324+
return builder._(fn, *args, **kwargs)
325+
263326
method.__doc__ = inspect.getdoc(fn)
264327
method.__name__ = alias
265328

266-
cls.register_method(method, library_path, alias=alias, doc=doc)
329+
cls.register_as_method(method, library_path, alias=alias, doc=doc)
330+
331+
@classmethod
332+
def register_function2(cls, fn, library_path, alias=None, doc=None):
333+
"""
334+
"""
335+
alias = alias if alias else fn.__name__
336+
337+
def method(builder, *args, **kwargs):
338+
return builder._2(fn, *args, **kwargs)
339+
340+
method.__doc__ = inspect.getdoc(fn)
341+
method.__name__ = alias
342+
343+
cls.register_as_method(method, library_path, alias=alias, doc=doc)
344+
345+
@classmethod
346+
def register_function3(cls, fn, library_path, alias=None, doc=None):
347+
"""
348+
"""
349+
alias = alias if alias else fn.__name__
350+
351+
def method(builder, *args, **kwargs):
352+
return builder._3(fn, *args, **kwargs)
353+
354+
method.__doc__ = inspect.getdoc(fn)
355+
method.__name__ = alias
356+
357+
cls.register_as_method(method, library_path, alias=alias, doc=doc)
358+
359+
@classmethod
360+
def register_function4(cls, fn, library_path, alias=None, doc=None):
361+
"""
362+
"""
363+
alias = alias if alias else fn.__name__
364+
365+
def method(builder, *args, **kwargs):
366+
return builder._4(fn, *args, **kwargs)
367+
368+
method.__doc__ = inspect.getdoc(fn)
369+
method.__name__ = alias
370+
371+
cls.register_as_method(method, library_path, alias=alias, doc=doc)
372+
373+
@classmethod
374+
def register_function5(cls, fn, library_path, alias=None, doc=None):
375+
"""
376+
"""
377+
alias = alias if alias else fn.__name__
378+
379+
def method(builder, *args, **kwargs):
380+
return builder._5(fn, *args, **kwargs)
381+
382+
method.__doc__ = inspect.getdoc(fn)
383+
method.__name__ = alias
384+
385+
cls.register_as_method(method, library_path, alias=alias, doc=doc)
267386

268387
def register(self, library_path, alias=None, doc=None):
269388
def register_decorator(fn):
270389

271-
self.register_function_as_method(fn, library_path, alias=alias, doc=doc)
390+
self.register_function(fn, library_path, alias=alias, doc=doc)
391+
392+
return fn
393+
return register_decorator
394+
395+
def register2(self, library_path, alias=None, doc=None):
396+
def register_decorator(fn):
397+
398+
self.register_function2(fn, library_path, alias=alias, doc=doc)
399+
400+
return fn
401+
return register_decorator
402+
403+
def register3(self, library_path, alias=None, doc=None):
404+
def register_decorator(fn):
405+
406+
self.register_function3(fn, library_path, alias=alias, doc=doc)
407+
408+
return fn
409+
return register_decorator
410+
411+
def register4(self, library_path, alias=None, doc=None):
412+
def register_decorator(fn):
413+
414+
self.register_function4(fn, library_path, alias=alias, doc=doc)
415+
416+
return fn
417+
return register_decorator
418+
419+
def register5(self, library_path, alias=None, doc=None):
420+
def register_decorator(fn):
421+
422+
self.register_function5(fn, library_path, alias=alias, doc=doc)
272423

273424
return fn
274425
return register_decorator
@@ -279,11 +430,6 @@ def register_decorator(fn):
279430
### FUNCTIONS
280431
#######################
281432

282-
def get_method(fn):
283-
def method(builder, *args, **kwargs):
284-
return builder._(fn, *args, **kwargs)
285-
return method
286-
287433
def _compile(ast):
288434
#if type(ast) is tuple:
289435

tensorbuilder/tests/test_builders.py

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,45 @@
11
import tensorflow as tf
2-
from tensorbuilder import builder
2+
from tensorbuilder import builder, Builder
33
from fn import _
44
# from tensorbuilder import tb
55

66
add2 = _ + 2
77
mul3 = _ * 3
88
get_list = lambda x: [1,2,3]
9+
a2_plus_b_minus_2c = lambda a, b, c: a ** 2 + b - 2*c
910

1011

1112
@builder.register("test.lib")
1213
def add(a, b):
1314
"""Some docs"""
1415
return a + b
1516

17+
@builder.register2("test.lib")
18+
def pow(a, b):
19+
return a ** b
20+
21+
@builder.register_method("test.lib")
22+
def get_function_name(builder):
23+
return builder.f.__name__
24+
1625

1726

1827
class TestBuilder(object):
1928
"""docstring for TestBuilder"""
2029

21-
x = tf.placeholder(tf.float32, shape=[None, 5])
30+
@classmethod
31+
def setup_method(self):
32+
self.x = tf.placeholder(tf.float32, shape=[None, 5])
2233

2334
def test_underscore(self):
2435
assert builder._(add2)(4) == 6
25-
2636
assert builder._(add2)._(mul3)(4) == 18
2737

38+
def test_underscores(self):
39+
assert builder._(a2_plus_b_minus_2c, 2, 4)(3) == 3 # (3)^2 + 2 - 2*4
40+
assert builder._2(a2_plus_b_minus_2c, 2, 4)(3) == -1 # (2)^2 + 3 - 2*4
41+
assert builder._3(a2_plus_b_minus_2c, 2, 4)(3) == 2 # (2)^2 + 4 - 2*3
42+
2843
def test_pipe(self):
2944
assert builder.pipe(4, add2, mul3) == 18
3045

@@ -113,22 +128,67 @@ def test_pipe(self):
113128

114129
assert a == 18 and b == 18 and c == 14
115130

131+
def test_scope(self):
132+
y = builder.ref()
133+
134+
z = builder.pipe(
135+
self.x,
136+
{ tf.name_scope('TEST'):
137+
(
138+
_ * 2,
139+
_ + 4,
140+
builder.store(y)
141+
)
142+
},
143+
_ ** 3
144+
)
145+
146+
assert "TEST/" in y().name
147+
assert "TEST/" not in z.name
148+
116149
def test_register(self):
117150

151+
#register
118152
assert 5 == builder.pipe(
119153
3,
120154
builder.add(2)
121155
)
122156

157+
#register2
158+
assert 8 == builder.pipe(
159+
3,
160+
builder.pow(2)
161+
)
162+
163+
#register_method
164+
assert "_identity" == builder.get_function_name()
165+
123166
def test_using_run(self):
124167
assert 8 == builder.using(3).add(2).add(3).run()
125168

126169
def test_reference(self):
127170
ref = builder.ref()
128171

129-
assert 8 == builder.using(3).add(2).store_on(ref).add(3).run()
172+
assert 8 == builder.using(3).add(2).store(ref).add(3).run()
130173
assert 5 == ref()
131174

175+
def test_ref_props(self):
176+
177+
a = builder.ref()
178+
b = builder.ref()
179+
180+
assert [7, 3, 5] == builder.pipe(
181+
1,
182+
add2, a.set,
183+
add2, b.set,
184+
add2,
185+
[
186+
builder.identity,
187+
a,
188+
b
189+
]
190+
)
191+
132192

133193

134194
#

tensorbuilder/tests/test_dsl.py

Lines changed: 0 additions & 34 deletions
This file was deleted.

0 commit comments

Comments
 (0)