提交 a35991d3 authored 作者: goodfeli's avatar goodfeli

Merge pull request #195 from nouiz/fix_subtensor2

Fix subtensor2
...@@ -2839,7 +2839,7 @@ def ceil_intdiv(a, b): ...@@ -2839,7 +2839,7 @@ def ceil_intdiv(a, b):
# force their upcast to int. # force their upcast to int.
div = int_div(a, b) div = int_div(a, b)
ret = cast(neq(a % b, 0), div.dtype) + div ret = cast(neq(a % b, 0), div.dtype) + div
assert ret.dtype == scal.upcast(a.dtype, b.dtype) assert ret.dtype == scal.upcast(div.owner.inputs[0], div.owner.inputs[1])
return ret return ret
......
...@@ -1795,13 +1795,14 @@ def local_subtensor_of_alloc(node): ...@@ -1795,13 +1795,14 @@ def local_subtensor_of_alloc(node):
# That dimension is removed. # That dimension is removed.
pass pass
else: else:
nw_dims += [(csl.stop - csl.start) // csl.step] nw_dims += [T.ceil_intdiv((csl.stop - csl.start), csl.step)]
nw_val = val[tuple(val_slices)] nw_val = val[tuple(val_slices)]
nw_dims += dims[len(slices):] nw_dims += dims[len(slices):]
rval = T.alloc(nw_val, *nw_dims) rval = T.alloc(nw_val, *nw_dims)
if type(rval) not in (list, tuple): if type(rval) not in (list, tuple):
rval = [rval] rval = [rval]
return rval return rval
......
...@@ -1865,59 +1865,94 @@ class Test_alloc_zero(unittest.TestCase): ...@@ -1865,59 +1865,94 @@ class Test_alloc_zero(unittest.TestCase):
f.maker.env.toposort() ]) f.maker.env.toposort() ])
def test_local_subtensor_alloc0(): def test_local_subtensor_of_alloc():
x = tensor.matrix('x') x = tensor.matrix('x')
y = tensor.vector('y') y = tensor.vector('y')
# The rows of yx are copies of x # The rows of yx are copies of y
yx = tensor.alloc(y, x.shape[0], x.shape[1]) yx = tensor.alloc(y, x.shape[0], x.shape[1])
# Slice of each row # Slice of each row
z_mat = yx[:,3:] z_mat = yx[:, 3:]
assert z_mat.ndim == 2 assert z_mat.ndim == 2
# Only one column # Only one column
z_vec = yx[:,3] z_vec = yx[:, 3]
assert z_vec.ndim == 1 assert z_vec.ndim == 1
f = theano.function([x, y], z_mat)
g = theano.function([x, y], z_vec)
# DebugMode should detect if something goes wrong. # DebugMode should detect if something goes wrong.
xval = numpy.zeros((3,5), dtype=config.floatX) # test shape combination of odd and event shape.
yval = numpy.arange(5, dtype=config.floatX) for shape in [(3, 5), (4, 6), (3, 8), (4, 7)]:
f(xval, yval)
g(xval, yval) xval = numpy.zeros(shape, dtype=config.floatX)
yval = numpy.arange(shape[1], dtype=config.floatX)
for slices in [
# results are vector
(slice(None), 3),
(2, slice(None)),
# results are matrix
(slice(None), slice(3, None)),
(slice(3, None), ),
(slice(3, None), slice(3, None)),
(slice(1, 3), slice(None, -1)),
(slice(None, None, 2)),
(slice(1, None, 2)),
]:
z = yx.__getitem__(slices)
f = theano.function([x, y], z)
val = f(xval, yval)
assert xval.__getitem__(slices).shape == val.shape
def test_local_fill_useless(): def test_local_fill_useless():
m = theano.config.mode #Test opt local_fill_cut
if m == 'FAST_COMPILE':
m = 'FAST_RUN'
x = dvector() x = dvector()
y = dvector() y = dvector()
z = lvector() z = lvector()
m = dmatrix()
x_ = numpy.random.rand(5,)
y_ = numpy.random.rand(5,)
z_ = (numpy.random.rand(5,) * 5).astype("int64")
m_ = numpy.random.rand(5, 5)
# basic case # basic case
f = function([x], T.fill(x,x)*2, mode=m) f = function([x], T.fill(x, x) * 2, mode=mode_opt)
assert [node.op for node in f.maker.env.toposort()] == [T.mul] assert [node.op for node in f.maker.env.toposort()] == [T.mul]
f(x_)
# basic case # basic case
f = function([x,y], T.second(y,x)*2, mode=m) f = function([x, y], T.second(y, x) * 2, mode=mode_opt)
assert [node.op for node in f.maker.env.toposort()] == [T.mul] assert [node.op for node in f.maker.env.toposort()] == [T.mul]
f(x_, y_)
# now with different type # basic case
f = function([x,z], T.fill(z,x)*2, mode=m) f = function([x, y], T.fill(x, y) * 2, mode=mode_opt)
assert [node.op for node in f.maker.env.toposort()] == [T.mul] assert [node.op for node in f.maker.env.toposort()] == [T.mul]
f(x_, y_)
# now cutting out the input ?? # now with different type(cast)
f = function([x,y], T.fill(x,y)*2, mode=m) f = function([x, z], T.fill(z, x) * 2, mode=mode_opt)
assert [node.op for node in f.maker.env.toposort()] == [T.mul] assert [node.op for node in f.maker.env.toposort()] == [T.mul]
f(x_, z_)
# now filll is serving as a cast # now with different type(cast)
f = function([x,y], T.fill(x,y)*2, mode=m) f = function([x, z], T.fill(x, z) * 2, mode=mode_opt)
assert [node.op for node in f.maker.env.toposort()] == [T.mul]
f(x_, z_)
# now cutting out the input ??
f = function([x, y], T.fill(x, y) * 2, mode=mode_opt)
assert [node.op for node in f.maker.env.toposort()] == [T.mul] assert [node.op for node in f.maker.env.toposort()] == [T.mul]
f(x_, y_)
# Test with different number of dimensions
# The fill is not useless, so it should stay
f = function([m, x], T.fill(m, x) * 2, mode=mode_opt)
ops = [node.op.__class__ for node in f.maker.env.toposort()]
assert T.Alloc in ops
f(m_, x_)
class test_shapeoptimizer(unittest.TestCase): class test_shapeoptimizer(unittest.TestCase):
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论