提交 3a5e8260 authored 作者: Frederic Bastien's avatar Frederic Bastien

a test where we generate an Elemwise composite with a mod that don't compile and…

a test where we generate an Elemwise composite with a mod that don't compile and commit the fix at the same time.
上级 526689e5
...@@ -953,7 +953,11 @@ class Mod(BinaryScalarOp): ...@@ -953,7 +953,11 @@ class Mod(BinaryScalarOp):
def impl(self, x, y): def impl(self, x, y):
return x % y return x % y
def c_code_cache_version(self): def c_code_cache_version(self):
return (4,) return (5,)
def c_support_code(self):
#We use a macro as python use % as a special string caractere.
return "#define THEANO_MACRO_MOD(x,y) (x % y)"
def c_code(self, node, name, (x, y), (z, ), sub): def c_code(self, node, name, (x, y), (z, ), sub):
""" """
...@@ -962,10 +966,10 @@ class Mod(BinaryScalarOp): ...@@ -962,10 +966,10 @@ class Mod(BinaryScalarOp):
#raise NotImplementedError("Unlike Python, C's modulo returns negative modulo on negative dividend (to implement)") #raise NotImplementedError("Unlike Python, C's modulo returns negative modulo on negative dividend (to implement)")
t = node.inputs[0].type.upcast(*[ i.type for i in node.inputs[1:]]) t = node.inputs[0].type.upcast(*[ i.type for i in node.inputs[1:]])
if t in int_types or t in ['uint8','int8','uint16','int16','uint32','int32','uint64','int64']: if t in int_types or t in ['uint8','int8','uint16','int16','uint32','int32','uint64','int64']:
x_mod_y = "(%(x)s %% %(y)s)"%locals() x_mod_y = "THEANO_MACRO_MOD(%(x)s, %(y)s)"%locals()
x_mod_ymm = "(-%(x)s %% -%(y)s)"%locals() x_mod_ymm = "THEANO_MACRO_MOD(-%(x)s, -%(y)s)"%locals()
x_mod_ypm = "(%(x)s %% -%(y)s)"%locals() x_mod_ypm = "THEANO_MACRO_MOD(%(x)s, -%(y)s)"%locals()
x_mod_ymp = "(-%(x)s %% %(y)s)"%locals() x_mod_ymp = "THEANO_MACRO_MOD(-%(x)s, %(y)s)"%locals()
elif t in float_types or t in ['float32','float64']: elif t in float_types or t in ['float32','float64']:
x_mod_y = "fmod(%(x)s,%(y)s)"%locals() x_mod_y = "fmod(%(x)s,%(y)s)"%locals()
x_mod_ymm = "fmod(-%(x)s,-%(y)s)"%locals() x_mod_ymm = "fmod(-%(x)s,-%(y)s)"%locals()
...@@ -1773,6 +1777,15 @@ class Composite(ScalarOp): ...@@ -1773,6 +1777,15 @@ class Composite(ScalarOp):
def c_code_cache_version(self): def c_code_cache_version(self):
return (1,)+tuple([x.op.c_code_cache_version() for x in self.env.toposort()]) return (1,)+tuple([x.op.c_code_cache_version() for x in self.env.toposort()])
def c_support_code(self):
str = ""
for node in self.env.toposort():
try:
str += node.op.c_support_code()+"\n"
except gof.utils.MethodNotDefined:
pass
return str
def __eq__(self, other): def __eq__(self, other):
if self is other: return True if self is other: return True
if not isinstance(other, self.__class__): return False if not isinstance(other, self.__class__): return False
......
...@@ -2676,6 +2676,21 @@ def test_mod(): ...@@ -2676,6 +2676,21 @@ def test_mod():
): ):
assert fn(a,b) == a%b, (a,) assert fn(a,b) == a%b, (a,)
def test_mod_compile():
"""
This test generate an Elemwise of Composite as:
Elemwise{Composite{Composite{Composite{Composite{mod,EQ},Switch},mul},add}}
The c_code generated is not compiling as of 30 June 2010. I fix the compilation in the same commit.
"""
x = tensor.vector()
y = tensor.vector()
shape = x.shape
out = tensor.switch(tensor.eq(3%x.shape[0],0),y,y[:-1])
f = theano.function([x,y],out)
if __name__ == '__main__': if __name__ == '__main__':
if 1: if 1:
unittest.main() unittest.main()
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论