提交 a53ccd27 authored 作者: Frederic Bastien's avatar Frederic Bastien

implemented the c_code for the scalar mod op. It correctly implement the python…

implemented the c_code for the scalar mod op. It correctly implement the python semantic of mod on x86.
上级 8ec730aa
...@@ -752,7 +752,30 @@ class Mod(BinaryScalarOp): ...@@ -752,7 +752,30 @@ class Mod(BinaryScalarOp):
def impl(self, x, y): def impl(self, x, y):
return x % y return x % y
def c_code(self, node, name, (x, y), (z, ), sub): def c_code(self, node, name, (x, y), (z, ), sub):
raise NotImplementedError("Unlike Python, C's modulo returns negative modulo on negative dividend (to implement)") """
We want the result to have the same sign as python, not the other implementaiton of mod.
"""
#raise NotImplementedError("Unlike Python, C's modulo returns negative modulo on negative dividend (to implement)")
return """
if (%(x)s == 0 || %(y)s == 0) {
if (%(y)s == 0) %(z)s = %(x)s %% %(y)s;
%(z)s = 0;
}
//was #if @neg@, I suspect @neg@ to be platform dependant.
//should be true under X86, but could be false for other architecture!
#if 1
else if ((%(x)s > 0) == (%(y)s > 0)) {
%(z)s = %(x)s %% %(y)s;
}
else { /* handled like Python does */
%(z)s = %(x)s %% %(y)s;
if (%(z)s) %(z)s += %(y)s;
}
#else
else
%(z)s = %(x)s %% %(y)s;
#endif
"""%locals()
def grad(self, (x, y), (gz, )): def grad(self, (x, y), (gz, )):
return None, None return None, None
mod = Mod(upcast_out, name = 'mod') mod = Mod(upcast_out, name = 'mod')
......
...@@ -31,6 +31,19 @@ class test_ScalarOps(unittest.TestCase): ...@@ -31,6 +31,19 @@ class test_ScalarOps(unittest.TestCase):
fn = gof.DualLinker().accept(g).make_function() fn = gof.DualLinker().accept(g).make_function()
assert fn(1.0, 2.0) == 1.5 assert fn(1.0, 2.0) == 1.5
def test_mod(self):
"""
We add this test as not all language and C implementation give the same
signe to the result. This check that the c_code of `Mod` is implemented
as Python. That is what we want.
"""
x, y = ints('xy')
fn = gof.DualLinker().accept(Env([x,y], [x%y])).make_function()
for a,b in ((0,1), (1,1), (0,-1), (1,-1), (-1,-1),
(1,2), (-1,2), (1,-2), (-1,-2),
(5,3), (-5,3), (5,-3), (-5,-3)
):
self.failUnless(fn(a,b) == a%b, (a,))
class test_composite(unittest.TestCase): class test_composite(unittest.TestCase):
......
...@@ -874,12 +874,12 @@ class test_fusion(unittest.TestCase): ...@@ -874,12 +874,12 @@ class test_fusion(unittest.TestCase):
(fx+fy+theano.tensor.exp(fz),(fx,fy,fz),(fxv,fyv,fzv),1,fxv+fyv+numpy.exp(fzv),'float32'),#35 (fx+fy+theano.tensor.exp(fz),(fx,fy,fz),(fxv,fyv,fzv),1,fxv+fyv+numpy.exp(fzv),'float32'),#35
(fx-fy-fz,(fx,fy,fz),(fxv,fyv,fzv),1,fxv-fyv-fzv,'float32'), (fx-fy-fz,(fx,fy,fz),(fxv,fyv,fzv),1,fxv-fyv-fzv,'float32'),
(fx-(fy/fz),(fx,fy,fz),(fxv,fyv,fzv),1,fxv-(fyv/fzv),'float32'), (fx-(fy/fz),(fx,fy,fz),(fxv,fyv,fzv),1,fxv-(fyv/fzv),'float32'),
(fx-(fy%fz),(fx,fy,fz),(fxv,fyv,fzv),2,fxv-(fyv%fzv),'float32'),#TODO: c_code not implemented for % (fx-(fy%fz),(fx,fy,fz),(fxv,fyv,fzv),2,fxv-(fyv%fzv),'float32'),
(fx-(fy>fz),(fx,fy,fz),(fxv,fyv,fzv),1,fxv-(fyv>fzv),'float32'), (fx-(fy>fz),(fx,fy,fz),(fxv,fyv,fzv),1,fxv-(fyv>fzv),'float32'),
(fx-(fy>=fz),(fx,fy,fz),(fxv,fyv,fzv),1,fxv-(fyv>=fzv),'float32'), (fx-(fy>=fz),(fx,fy,fz),(fxv,fyv,fzv),1,fxv-(fyv>=fzv),'float32'),#40
(fx-(fy<fz),(fx,fy,fz),(fxv,fyv,fzv),1,fxv-(fyv<fzv),'float32'), (fx-(fy<fz),(fx,fy,fz),(fxv,fyv,fzv),1,fxv-(fyv<fzv),'float32'),
(fx-(fy<=fz),(fx,fy,fz),(fxv,fyv,fzv),1,fxv-(fyv<=fzv),'float32'), (fx-(fy<=fz),(fx,fy,fz),(fxv,fyv,fzv),1,fxv-(fyv<=fzv),'float32'),#TODO: bugged on the gpu
# (fx-(fy==fz),(fx,fy,fz),(fxv,fyv,fzv),1,fxv-(fyv==fzv),'float32'),#TODO: bugged (fx-(fy==fz),(fx,fy,fz),(fxv,fyv,fzv),1,fxv-(fyv==fzv),'float32'),#TODO: bugged
(fx-(fy!=fz),(fx,fy,fz),(fxv,fyv,fzv),1,fxv-(fyv!=fzv),'float32'), (fx-(fy!=fz),(fx,fy,fz),(fxv,fyv,fzv),1,fxv-(fyv!=fzv),'float32'),
(fx-fy+tan(fz),(fx,fy,fz),(fxv,fyv,fzv),1,fxv-fyv+numpy.tan(fzv),'float32'), (fx-fy+tan(fz),(fx,fy,fz),(fxv,fyv,fzv),1,fxv-fyv+numpy.tan(fzv),'float32'),
(fx-fy+tanh(fz),(fx,fy,fz),(fxv,fyv,fzv),1,fxv-fyv+numpy.tanh(fzv),'float32'), (fx-fy+tanh(fz),(fx,fy,fz),(fxv,fyv,fzv),1,fxv-fyv+numpy.tanh(fzv),'float32'),
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论