提交 9a4fe7f8 authored 作者: Olivier Breuleux's avatar Olivier Breuleux

pulled macro and all references to it

上级 4549f839
......@@ -13,7 +13,6 @@ from elemwise import *
def Env(i, o):
e = gof.Env(i, o)
gof.ExpandMacros().optimize(e)
return e
class _test_DimShuffle(unittest.TestCase):
......
......@@ -540,8 +540,8 @@ def verify_grad(testcase, op, pt, n_tests=1, rng=numpy.random, eps=0.0000001, to
num_grad = gradient.numeric_grad(cost_fn, pt)
#symbolic_grad = exec_grad(cost, tensor_pt,as_tensor(1.0,name='g_cost'))
symbolic_grad = grad.make_node(cost, tensor_pt).outputs
symbolic_grad = grad(cost, tensor_pt,as_tensor(1.0,name='g_cost'))
if 0:
print '-------'
print '----------'
......@@ -899,7 +899,7 @@ class T_subtensor(unittest.TestCase):
n = as_tensor(numpy.random.rand(2,3))
z = scal.constant(0)
t = n[z:,z]
gn = exec_grad(sum(exp(t)), n)
gn = grad(sum(exp(t)), n)
gval = eval_outputs([gn])
s0 = 'array([ 2.05362099, 0. , 0. ])'
s1 = 'array([ 1.55009327, 0. , 0. ])'
......@@ -909,7 +909,7 @@ class T_subtensor(unittest.TestCase):
def test_grad_0d(self):
n = as_tensor(numpy.random.rand(2,3))
t = n[1,0]
gn = exec_grad(sum(exp(t)), n)
gn = grad(sum(exp(t)), n)
gval = eval_outputs([gn])
g0 = repr(gval[0,:])
g1 = repr(gval[1,:])
......@@ -938,7 +938,7 @@ class T_Stack(unittest.TestCase):
a = as_tensor(numpy.array([[1, 2, 3], [4, 5, 6]]))
b = as_tensor(numpy.array([[7, 8, 9]]))
s = vertical_stack(a, b)
ga,gb = exec_grad(sum(vertical_stack(a,b)), [a,b])
ga,gb = grad(sum(vertical_stack(a,b)), [a,b])
gval = eval_outputs([ga, gb])
self.failUnless(numpy.all(gval[0] == 1.0))
......@@ -1672,13 +1672,13 @@ class _test_grad(unittest.TestCase):
"""grad: Test passing a single result param"""
o = _test_grad.O()
a1 = o.make_node()
self.failUnless(o.gval0 is exec_grad(a1.outputs[0], a1.inputs[0]))
self.failUnless(o.gval0 is grad(a1.outputs[0], a1.inputs[0]))
def test_Nparam(self):
"""grad: Test passing multiple result params"""
o = _test_grad.O()
a1 = o.make_node()
g0,g1 = exec_grad(a1.outputs[0], a1.inputs)
g0,g1 = grad(a1.outputs[0], a1.inputs)
self.failUnless(o.gval0 is g0)
self.failUnless(o.gval1 is g1)
......@@ -1686,13 +1686,13 @@ class _test_grad(unittest.TestCase):
"""grad: Test returning a single None from grad"""
o = _test_grad.O()
a1 = o.make_node()
self.failUnless(None is exec_grad(a1.outputs[0], a1.outputs[1]))
self.failUnless(None is exec_grad(a1.outputs[0], 'wtf'))
self.failUnless(None is grad(a1.outputs[0], a1.outputs[1]))
self.failUnless(None is grad(a1.outputs[0], 'wtf'))
def test_NNone_rval(self):
"""grad: Test returning some Nones from grad"""
o = _test_grad.O()
a1 = o.make_node()
g0,g1,g2 = exec_grad(a1.outputs[0], a1.inputs + ['wtf'])
g0,g1,g2 = grad(a1.outputs[0], a1.inputs + ['wtf'])
self.failUnless(o.gval0 is g0)
self.failUnless(o.gval1 is g1)
self.failUnless(None is g2)
......
......@@ -91,10 +91,8 @@ class _test_dimshuffle_lift(unittest.TestCase):
x, y, z = inputs([False]*1, [False]*2, [False]*3)
e = x + y + z
g = Env([x, y, z], [e])
gof.ExpandMacros().optimize(g)
self.failUnless(str(g) == "[add(InplaceDimShuffle{x,0,1}(add(InplaceDimShuffle{x,0}(x), y)), z)]", str(g))
lift_dimshuffle.optimize(g)
gof.ExpandMacros().optimize(g)
self.failUnless(str(g) == "[add(add(InplaceDimShuffle{x,x,0}(x), InplaceDimShuffle{x,0,1}(y)), z)]", str(g))
......
......@@ -104,9 +104,6 @@ class FunctionFactory:
if not isinstance(r, gof.Result):
raise TypeError("All inputs and outputs to FunctionFactory should be Result instances. Received:", type(r), r)
env = std_env(inputs, outputs, disown_inputs = disown_inputs)
gof.ExpandMacros().optimize(env)
#gof.ExpandMacros(lambda node: getattr(node.op, 'level', 0) <= 1).optimize(env)
#gof.ExpandMacros(lambda node: node.op.level == 2).optimize(env)
if None is not optimizer:
optimizer(env)
env.validate()
......
......@@ -2,7 +2,7 @@
import elemwise_cgen as cgen
import numpy
from gof import Op, Macro, Apply
from gof import Op, Apply
import scalar
from scalar import Scalar
import gof
......
......@@ -15,15 +15,14 @@ from link import \
Linker, LocalLinker, PerformLinker, MetaLinker, Profiler
from op import \
Op, Macro, Dispatch
Op
from opt import \
Optimizer, SeqOptimizer, \
MergeOptimizer, MergeOptMerge, \
LocalOptimizer, LocalOptGroup, LocalOpKeyOptGroup, \
ExpandMacro, OpSub, OpRemove, PatternSub, \
NavigatorOptimizer, TopoOptimizer, OpKeyOptimizer, \
ExpandMacros
OpSub, OpRemove, PatternSub, \
NavigatorOptimizer, TopoOptimizer, OpKeyOptimizer
from toolbox import \
Bookkeeper, History, Validator, ReplaceValidate, NodeFinder, PrintListener
......
......@@ -3,7 +3,7 @@ import unittest
from type import Type
from graph import Result, Apply, Constant
from op import Op, Macro
from op import Op
from opt import *
from env import Env
from toolbox import *
......@@ -364,57 +364,6 @@ class _test_MergeOptimizer(unittest.TestCase):
reenter = Exception("Re-Entered")
class LoopyMacro(Macro):
def __init__(self):
self.counter = 0
def make_node(self, x, y):
return Apply(self, [x, y], [MyType()()])
def expand(self, node):
x, y = node.inputs
if self.counter > 0:
raise reenter
self.counter += 1
return [self(y, x)]
def __str__(self):
return "loopy_macro"
class _test_ExpandMacro(unittest.TestCase):
def test_straightforward(self):
class Macro1(Macro):
def make_node(self, x, y):
return Apply(self, [x, y], [MyType()()])
def expand(self, node):
return [op1(y, x)]
def __str__(self):
return "macro"
x, y, z = inputs()
e = Macro1()(x, y)
g = Env([x, y], [e])
ExpandMacros().optimize(g)
assert str(g) == "[Op1(y, x)]"
def test_loopy_1(self):
x, y, z = inputs()
e = LoopyMacro()(x, y)
g = Env([x, y], [e])
TopoOptimizer(ExpandMacro(), ignore_newtrees = True).optimize(g)
assert str(g) == "[loopy_macro(y, x)]"
def test_loopy_2(self):
x, y, z = inputs()
e = LoopyMacro()(x, y)
g = Env([x, y], [e])
try:
TopoOptimizer(ExpandMacro(), ignore_newtrees = False).optimize(g)
self.fail("should not arrive here")
except Exception, e:
if e is not reenter:
raise
if __name__ == '__main__':
unittest.main()
......
......@@ -124,50 +124,3 @@ class Op(utils.object2):
"""
raise utils.AbstractFunctionError()
class Macro(Op):
"""
Abstract Op which does not have an implementation but can be expanded
into a computable graph with its expand() method.
"""
def expand(self, node):
"""
Returns a node representing the expansion of this macro.
"""
raise utils.AbstractFunctionError()
class Dispatch(Macro):
"""
Dispatches inputs to one of a list of candidate ops.
Tries each candidate in order.
"""
def __init__(self, name, candidates):
if not isinstance(name, str):
raise TypeError("name should be a string, not:", name, type(name))
self.candidates = candidates
self.name = name
def __node(self, *inputs):
for candidate in self.candidates:
try:
return candidate.make_node(*inputs)
except:
continue
raise TypeError("No suitable candidate found for %s(%s)" % (self, inputs))
def make_node(self, *inputs):
node = self.__node(*inputs)
node.op = self
return node
def expand(self, node):
return self.__node(*node.inputs)
def __str__(self):
return self.name
......@@ -214,20 +214,6 @@ class LocalOpKeyOptGroup(LocalOptGroup):
return [opt.op_key() for opt in self.opts]
class ExpandMacro(LocalOptimizer):
def __init__(self, filter = None):
if filter is None:
self.filter = lambda node: True
else:
self.filter = filter
def transform(self, node):
if not isinstance(node.op, op.Macro) or not self.filter(node):
return False
return node.op.expand(node)
class OpSub(LocalOptimizer):
"""
Replaces the application of a certain op by the application of
......@@ -561,12 +547,3 @@ class OpKeyOptimizer(NavigatorOptimizer):
def keep_going(exc, nav, repl_pairs):
pass
##############################
### Pre-defined optimizers ###
##############################
def ExpandMacros(filter = None):
return TopoOptimizer(ExpandMacro(filter = filter),
order = 'in_to_out',
ignore_newtrees = False)
......@@ -169,7 +169,6 @@ def make_default_pp():
pp.assign(T.pow, ppow)
pp.assign(T.dot, pdot)
pp.assign(T.Sum(), FunctionPrinter('sum'))
pp.assign(T.grad, FunctionPrinter('d'))
pp.assign(lambda pstate, r: r.owner and isinstance(r.owner.op, T.DimShuffle), DimShufflePrinter())
return pp
......
......@@ -1142,19 +1142,7 @@ gemm = Gemm()
# Gradient
#########################
class Grad(gof.Macro):
level = 2
def make_node(self, cost, wrt):
if not isinstance(wrt, list):
wrt = [wrt]
return Apply(self, [cost] + wrt, [_wrt.type() for _wrt in wrt])
def expand(self, node):
cost, wrt = node.inputs[0], node.inputs[1:]
g = exec_grad(cost, wrt)
return g
grad = Grad()
def exec_grad(cost, wrt, g_cost=None):
def grad(cost, wrt, g_cost=None):
"""
@type cost: L{Result}
@type wrt: L{Result} or list of L{Result}s.
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论