提交 a6f7beb7 authored 作者: Pascal Lamblin's avatar Pascal Lamblin

Merge pull request #2734 from hojonathanho/tile_symbolic_reps

Accept symbolic `reps` in `tensor.tile`
...@@ -4255,18 +4255,21 @@ def tile(x, reps, ndim=None): ...@@ -4255,18 +4255,21 @@ def tile(x, reps, ndim=None):
Tile input array `x` according to `reps`. See the docstring of `numpy.tile` Tile input array `x` according to `reps`. See the docstring of `numpy.tile`
for details. for details.
Currently, `reps` must be a constant, x.ndim and len(reps) must be equal Currently, x.ndim and len(reps) must be equal, and, if specified, 'ndim'
and, if specified, 'ndim' must be equal to both. must be equal to both.
TODO: expand this. TODO: expand this.
""" """
try: try:
assert python_all([int(i) == i for i in iter(reps)]) iter(reps)
except (TypeError, AssertionError): except TypeError:
raise ValueError("reps argument to tile must be a constant (e.g. " raise ValueError("reps must be iterable")
"tuple, list of integers)") if not numpy.all([isinstance(r, (int, long)) or
if len(reps) != x.ndim: (isinstance(r, TensorVariable) and
r.dtype in ["int8", "int16", "int32", "int64"]) for r in reps]):
raise ValueError("elements of reps must be scalars of integer dtype")
elif len(reps) != x.ndim:
raise ValueError("len(reps) != x.ndim not currently supported") raise ValueError("len(reps) != x.ndim not currently supported")
elif (ndim is not None) and ndim != x.ndim: elif (ndim is not None) and ndim != x.ndim:
raise ValueError("if specified, ndim must be equal to both x.ndim and " raise ValueError("if specified, ndim must be equal to both x.ndim and "
......
...@@ -4838,31 +4838,41 @@ def test_flatten_outdim_invalid(): ...@@ -4838,31 +4838,41 @@ def test_flatten_outdim_invalid():
def test_tile(): def test_tile():
# Test the one-dimensional case. def run_tile(x, x_, reps, use_symbolic_reps):
if use_symbolic_reps:
rep_symbols = [iscalar() for _ in range(len(reps))]
f = function([x] + rep_symbols, tile(x, rep_symbols))
return f(*([x_] + list(reps)))
else:
f = function([x], tile(x, reps))
return f(x_)
rng = numpy.random.RandomState(utt.fetch_seed()) rng = numpy.random.RandomState(utt.fetch_seed())
x = vector()
f = function([x], tile(x, (2,)))
x_ = rng.randn(5).astype(config.floatX)
assert numpy.all(f(x_) == numpy.tile(x_, (2,)))
# Test the two-dimensional case.
x = matrix()
f = function([x], tile(x, (2, 3)))
x_ = rng.randn(2, 4).astype(config.floatX)
assert numpy.all(f(x_) == numpy.tile(x_, (2, 3)))
# Test the three-dimensional case.
x = tensor3()
f = function([x], tile(x, (2, 3, 4)))
x_ = rng.randn(2, 4, 3).astype(config.floatX)
assert numpy.all(f(x_) == numpy.tile(x_, (2, 3, 4)))
# Test the four-dimensional case.
x = tensor4()
f = function([x], tile(x, (2, 3, 4, 6)))
x_ = rng.randn(2, 4, 3, 5).astype(config.floatX)
assert numpy.all(f(x_) == numpy.tile(x_, (2, 3, 4, 6)))
for use_symbolic_reps in [False, True]:
# Test the one-dimensional case.
x = vector()
x_ = rng.randn(5).astype(config.floatX)
assert numpy.all(run_tile(x, x_, (2,), use_symbolic_reps) ==
numpy.tile(x_, (2,)))
# Test the two-dimensional case.
x = matrix()
x_ = rng.randn(2, 4).astype(config.floatX)
assert numpy.all(run_tile(x, x_, (2, 3), use_symbolic_reps) ==
numpy.tile(x_, (2, 3)))
# Test the three-dimensional case.
x = tensor3()
x_ = rng.randn(2, 4, 3).astype(config.floatX)
assert numpy.all(run_tile(x, x_, (2, 3, 4), use_symbolic_reps) ==
numpy.tile(x_, (2, 3, 4)))
# Test the four-dimensional case.
x = tensor4()
x_ = rng.randn(2, 4, 3, 5).astype(config.floatX)
assert numpy.all(run_tile(x, x_, (2, 3, 4, 6), use_symbolic_reps) ==
numpy.tile(x_, (2, 3, 4, 6)))
def test_tile_grad(): def test_tile_grad():
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论