提交 3ef4a040 authored 作者: lamblin's avatar lamblin

Merge pull request #857 from nouiz/shape_tensor_basic2

Shape tensor basic2
......@@ -1888,6 +1888,9 @@ class TensorFromScalar(Op):
out, = out_
out[0] = numpy.asarray(s)
def infer_shape(self, node, in_shapes):
return [()]
def grad(self, inp, grads):
s, = inp
dt, = grads
......@@ -1918,6 +1921,9 @@ class ScalarFromTensor(Op):
out, = out_
out[0] = s.flatten()[0]
def infer_shape(self, node, in_shapes):
return [()]
def grad(self, inp, grads):
s, = inp
dt, = grads
......@@ -2071,6 +2077,9 @@ class Shape(Op):
out, = out_
out[0] = theano._asarray(x.shape, dtype='int64')
def infer_shape(self, node, in_shapes):
return [[len(in_shapes[0])]]
def grad(self, inp, grads):
return [None]
......@@ -2886,6 +2895,10 @@ class Eye(gof.Op):
out, = out_
out[0] = numpy.eye(n, m, k, dtype=self.dtype)
def infer_shape(self, node, in_shapes):
out_shape = [node.inputs[0], node.inputs[1]]
return [out_shape]
def grad(self, inp, grads):
return [None, None, None]
......@@ -3201,6 +3214,7 @@ def prod(input, axis=None, dtype=None, keepdims=False):
class Mean(elemwise.CAReduce):
def __init__(self, axis=None):
elemwise.CAReduce.__init__(self, scal.add, axis)
assert self.axis is None or len(self.axis) == 1
def __str__(self):
if self.axis is not None:
......@@ -3215,7 +3229,14 @@ class Mean(elemwise.CAReduce):
def perform(self, node, inp, out):
input, = inp
output, = out
output[0] = numpy.mean(input, axis=self.axis)
if self.axis is None:
axis = None
else:
axis = self.axis[0]
# numpy.asarray is needed as otherwise we can end up with a
# numpy scalar.
output[0] = numpy.asarray(numpy.mean(input, dtype='float64',
axis=axis))
def c_code(self, node, name, inames, onames, sub):
if self.axis is not None:
......@@ -4285,13 +4306,16 @@ def inc_subtensor(x, y, inplace=False, set_instead_of_inc=False,
elif isinstance(x.owner.op, AdvancedSubtensor1):
real_x = x.owner.inputs[0]
ilist = x.owner.inputs[1]
if set_instead_of_inc:
the_op = AdvancedIncSubtensor1(inplace, set_instead_of_inc=True)
else:
the_op = AdvancedIncSubtensor1(inplace, set_instead_of_inc=False)
the_op = AdvancedIncSubtensor1(inplace,
set_instead_of_inc=set_instead_of_inc)
return the_op(real_x, y, ilist)
elif isinstance(x.owner.op, AdvancedSubtensor):
raise NotImplementedError()
real_x = x.owner.inputs[0]
coordvec_0 = x.owner.inputs[1]
coordvec_1 = x.owner.inputs[2]
the_op = AdvancedIncSubtensor(inplace,
set_instead_of_inc=set_instead_of_inc)
return the_op(real_x, y, coordvec_0, coordvec_1)
else:
raise TypeError('x must be result of a subtensor operation')
......@@ -4645,6 +4669,18 @@ class Split(Op):
outputs[i][0] = x.__getitem__(general_key).copy()
lower_idx = upper_idx
def infer_shape(self, node, in_shapes):
axis = node.inputs[1]
splits = node.inputs[2]
shp_x, shp_axis, shp_splits = in_shapes
out_shapes = []
for i in range(self.len_splits):
temp = as_tensor_variable(shp_x)
temp = set_subtensor(temp[axis], splits[i])
temp = [temp[i] for i in range(len(shp_x))]
out_shapes.append(temp)
return out_shapes
def grad(self, inputs, g_outputs):
"""Join the gradients along the axis that was used to split x."""
_, axis, _ = inputs
......@@ -5333,17 +5369,33 @@ class Reshape(Op):
# Here, we only simplify if the shape (node.inputs[1]) is a constant,
# ideally it would suffice to check that it is always non-negative.
oshape = []
for i in xrange(self.ndim):
default_os_i = theano.tensor.opt.Shape_i(i)(node.outputs[0])
try:
os_i = get_constant_value(node.inputs[1][i]).item()
if os_i == -1:
requ = node.inputs[1]
if isinstance(requ, theano.tensor.TensorConstant):
requ = list(requ.data)
requ_part = [ele for ele in requ if ele != -1]
crit = len(requ) - len(requ_part)
if crit == 1:
missing = numpy.prod(ishapes[0]) / numpy.prod(requ_part)
for i, ele in enumerate(requ):
if ele == -1:
requ[i] = missing
elif crit > 1:
raise ValueError('shape argument to Reshape.perform'
' must have at most one entry equal to -1')
return [requ]
else:
oshape = []
for i in xrange(self.ndim):
default_os_i = theano.tensor.opt.Shape_i(i)(node.outputs[0])
try:
os_i = get_constant_value(node.inputs[1][i]).item()
if os_i == -1:
os_i = default_os_i
except TypeError:
os_i = default_os_i
except TypeError:
os_i = default_os_i
oshape.append(os_i)
return [tuple(oshape)]
oshape.append(os_i)
return [tuple(oshape)]
def c_code_cache_version(self):
return (2,)
......@@ -5433,6 +5485,19 @@ class Flatten(Op):
(numpy.prod(x.shape[outdim - 1:]),))
out[0] = x.reshape(newshape)
def infer_shape(self, node, in_shapes):
in_shp, = in_shapes
part1 = in_shp[:self.outdim - 1]
part2 = in_shp[self.outdim - 1:]
# The if is needed as numpy.prod([]) return a float 1.0
# We do not want to force the other dtype to int32/64.
if len(part2) > 1:
part2 = prod(part2, dtype='int64')
else:
part2 = 1
out_shape = (part1 + (part2,))
return [out_shape]
def grad(self, inp, grads):
x, = inp
g_out, = grads
......@@ -5502,6 +5567,26 @@ class Tile(Op):
if len(out[0].shape) != self.ndim:
raise ValueError('Tile.perform produced incorrect shape')
def infer_shape(self, node, in_shapes):
# Note: in contrast with numpy, it is assumed that x.shape and reps
# have equal length; see also tile function below
# Note: if reps were to be allowed not to be a constant and x.shape
# and reps to be unequal, the following block of code could be used:
## prepend 1 to x.shape if needed
# if self.ndim > x.ndim:
# shp = concatenate(ones(self.ndim - x.ndim), shp)
## prepend 1 to reps if needed
# reps = concatenate(ones(self.ndim - reps.shape[0]), reps)
x, reps = node.inputs
shp = in_shapes[0]
tiled_shp = shp * reps
out_shape = []
for i in range(self.ndim):
out_shape.append(tiled_shp[i])
return [out_shape]
def grad(self, inp, grads):
x, reps = inp
g_out, = grads
......@@ -5514,21 +5599,26 @@ def tile(x, reps, ndim=None):
Tile input array `x` according to `reps`. See the docstring of `numpy.tile`
for details.
Currently, `reps` must be a constant.
Currently, `reps` must be a constant, x.ndim and len(reps) must be equal
and, if specified, 'ndim' must be equal to both.
TODO: expand this.
"""
try:
assert python_all([int(i) == i for i in iter(reps)])
except (TypeError, AssertionError):
raise ValueError("reps argument to tile must be a constant (e.g. "
"tuple, list of integers)")
if len(reps) != x.ndim:
raise ValueError("len(reps) != x.ndim not currently supported")
elif (ndim is not None) and ndim != x.ndim:
raise ValueError("if specified, ndim must be equal to both x.ndim and "
"len(reps)")
if not hasattr(tile, 'op'):
tile.op = {}
try:
assert python_all([int(i) == i for i in iter(reps)])
except (TypeError, AssertionError):
raise ValueError("reps argument to tile must be a constant (e.g. "
"tuple, list of integers)")
if ndim is None:
ndim = len(reps)
......@@ -5781,6 +5871,15 @@ class PermuteRowElements(Op):
self._rec_perform(node, x, y, inverse, outs[0], curdim=0)
def infer_shape(self, node, in_shapes):
shp_x = in_shapes[0]
shp_y = in_shapes[1]
assert len(shp_x) == len(shp_y)
out_shape = []
for i in range(len(shp_x)):
out_shape.append(maximum(shp_x[i], shp_y[i]))
return [out_shape]
def grad(self, inp, grads):
x, y, inverse = inp
gz, = grads
......@@ -6008,6 +6107,8 @@ class AdvancedSubtensor(Op):
def make_node(self, x, *inputs):
x = as_tensor_variable(x)
#FIXME
# Note (9 Jul 2012): what does this 'FIXME' mean? Possibly that the
# current implementation must be generalized? Please specify.
if x.ndim == 2 and len(inputs) == 2:
ind1 = as_tensor_variable(inputs[0])
ind2 = as_tensor_variable(inputs[1])
......@@ -6075,22 +6176,41 @@ class AdvancedSubtensor(Op):
gz, = grads
x = inputs[0]
rest = inputs[1:]
return [AdvancedIncSubtensor()(zeros_like(x), gz,
return [advanced_inc_subtensor(zeros_like(x), gz,
*rest)] + [None] * len(rest)
class AdvancedIncSubtensor(Op):
"""Increments a subtensor using advanced indexing.
:note: We need the numpy.inplace_increment() function currently
numpy's PR 326 to be able to make an inplace version of this
op.
"""
def __eq__(self, other):
return self.__class__ == other.__class__
def __init__(self, inplace=False, set_instead_of_inc=False):
self.inplace = inplace
self.set_instead_of_inc = set_instead_of_inc
#The assert is needed as in the pass the first argument was
#something else that was not used.
assert isinstance(inplace, bool)
if self.inplace:
raise NotImplementedError('In place computation is not'
' implemented')
def __hash__(self):
return hash(self.__class__)
return hash((type(self), self.inplace, self.set_instead_of_inc))
def __eq__(self, other):
return (type(self) == type(other)
and self.inplace == other.inplace
and self.set_instead_of_inc == other.set_instead_of_inc)
def __str__(self):
return self.__class__.__name__
return "%s{%s, %s}" % (self.__class__.__name__,
"inplace=" + str(self.inplace),
" set_instead_of_inc=" + str(self. set_instead_of_inc))
def make_node(self, x, y, *inputs):
x = as_tensor_variable(x)
......@@ -6105,21 +6225,31 @@ class AdvancedIncSubtensor(Op):
[tensor(dtype=x.type.dtype,
broadcastable=x.type.broadcastable)])
raise NotImplementedError(
'Advanced indexing increment of x (of dimension %i) by y'
'Advanced indexing increment/set of x (of dimension %i) by y'
' (of dimension %i) with these argument dimensions (%s) not'
' supported yet'
% (x.ndim, y.ndim,
','.join(str(input.ndim) for input in inputs)))
raise NotImplementedError(
'Advanced indexing increment of x (of dim %i) by y (of dim %i)'
'Advanced indexing increment/set of x (of dim %i) by y (of dim %i)'
' with arguments (%s) not supported yet'
% (x.ndim, y.ndim, ','.join(str(input) for input in inputs)))
def perform(self, node, inputs, out_):
# TODO: 1. opt to make this in place 2. generalize as described in
# AdvancedSubtensor's perform TODO
out, = out_
# TODO: same thing as in AdvancedSubtensor's perform TODO
out[0] = inputs[0].copy()
out[0][inputs[2:]] += inputs[1]
if not self.inplace:
out[0] = inputs[0].copy()
else:
raise NotImplementedError('In place computation is not'
' implemented')
if self.set_instead_of_inc:
out[0][inputs[2:]] = inputs[1]
else:
out[0][inputs[2:]] += inputs[1]
if (numpy.__version__ <= '1.6.1' and
out[0].size != numpy.uint32(out[0].size)):
warnings.warn(
......@@ -6129,6 +6259,9 @@ class AdvancedIncSubtensor(Op):
'out[0] (%s), with shape %s, is not correctly filled.'
% (out[0], out[0].shape))
def infer_shape(self, node, ishapes):
return [ishapes[0]]
def grad(self, inpt, output_gradients):
x, y = inpt[:2]
idxs = inpt[2:]
......@@ -6142,7 +6275,7 @@ class AdvancedIncSubtensor(Op):
return [None]
return self.make_node(eval_points[0], eval_points[1],
*inputs[2:]).outputs
advanced_inc_subtensor = AdvancedIncSubtensor()
#########################
# Linalg : Dot
......@@ -6347,6 +6480,13 @@ pprint.assign(dot, printing.OperatorPrinter(printing.special['middle_dot'],
class TensorDotGrad(Op):
def __init__(self, axes):
self.axes = TensorDot.parse_axes(axes)
if isinstance(self.axes, (tuple, list)) and len(self.axes) == 2:
# The current perform don't implement correctly those cases
for i in range(len(self.axes[0]) - 1):
if self.axes[0][i] > self.axes[0][i + 1]:
raise NotImplementedError()
if self.axes[1][i] > self.axes[1][i + 1]:
raise NotImplementedError()
def __eq__(self, other):
return type(self) == type(other) and self.axes == other.axes
......@@ -6387,6 +6527,11 @@ class TensorDotGrad(Op):
newshapey = numpy.zeros(y.ndim)
newshapey[[newpos for newpos in idy]] = range(y.ndim)
gy[0] = numpy.transpose(_gy, newshapey)
assert gy[0].shape == y.shape
assert gx[0].shape == x.shape
def infer_shape(self, node, in_shapes):
return in_shapes[:2]
tensordot_grad = TensorDotGrad
......@@ -6463,6 +6608,21 @@ class TensorDot(Op):
e.args = e.args + (x.shape, y.shape, self.axes)
raise
def infer_shape(self, node, in_shapes):
shape_x, shape_y = in_shapes
out_shape = []
if isinstance(self.axes, (list, tuple)):
iter = (i for i in range(len(shape_x)) if i not in self.axes[0])
for i in iter:
out_shape.append(shape_x[i])
iter = (i for i in range(len(shape_y)) if i not in self.axes[1])
for i in iter:
out_shape.append(shape_y[i])
else:
out_shape = list(shape_x)[shape_x.ndim - self.axes] + \
list(shape_y)[shape_y.ndim - self.axes, shape_y.ndim]
return [out_shape]
def grad(self, inp, grads):
x, y = inp
gz, = grads
......
......@@ -1546,6 +1546,7 @@ class CAReduceDtype(CAReduce):
# We need to redefine make_node so that, if self.dtype is None,
# we can infer what dtype should be, and create a node from an Op
# of the appropriate dtype.
input = as_tensor_variable(input)
dtype = self._output_dtype(input.dtype)
assert dtype is not None
if dtype == self.dtype:
......
......@@ -360,6 +360,10 @@ class RepeatOp(theano.Op):
repeats = node.inputs[1]
out_shape = list(i0_shapes)
#uint64 shape are not supported.
dtype = None
if repeats.dtype in ['uint8', 'uint16', 'uint32']:
dtype = 'int64'
if self.axis is None:
if repeats.ndim == 0:
if len(i0_shapes) == 0:
......@@ -370,12 +374,12 @@ class RepeatOp(theano.Op):
res = res * d
out_shape = (res * repeats, )
else:
out_shape = [theano.tensor.sum(repeats)]
out_shape = [theano.tensor.sum(repeats, dtype=dtype)]
else:
if repeats.ndim == 0:
out_shape[self.axis] = out_shape[self.axis] * repeats
else:
out_shape[self.axis] = theano.tensor.sum(repeats)
out_shape[self.axis] = theano.tensor.sum(repeats, dtype=dtype)
return [out_shape]
def __str__(self):
......
......@@ -869,7 +869,7 @@ class CrossentropySoftmax1HotWithBiasDx (gof.Op):
# typically we should not need the gradient w.r.t. dy).
y_idx_range = tensor.arange(y_idx.shape[0])
g_dy = tensor.sum(
g_dx * tensor.AdvancedIncSubtensor((y_idx_range, y_idx))(
g_dx * tensor.AdvancedIncSubtensor()(
sm, tensor.fill(dy, -1), y_idx_range, y_idx),
axis=1)
g_sm = dy.dimshuffle(0, 'x') * g_dx
......
......@@ -769,7 +769,8 @@ class T_CrossentropyCategorical1Hot(utt.InferShapeTester):
theano.printing.debugprint(f)
raise
g = theano.function([x, y], T.grad(expr, x), mode=mode)
print_graph(g)
if verbose:
print_graph(g)
try:
ops = [node.op for node in g.maker.fgraph.toposort()]
assert len(ops) == 4
......@@ -829,7 +830,8 @@ class T_CrossentropyCategorical1Hot(utt.InferShapeTester):
finally:
config.warn.sum_div_dimshuffle_bug = backup
print_graph(g)
if verbose:
print_graph(g)
try:
ops = [node.op for node in g.maker.fgraph.toposort()]
assert len(ops) <= 6
......
......@@ -971,6 +971,7 @@ class ShapeFeature(object):
# keep it this way. See #266 for a better long-term fix.
if getattr(d, 'dtype', 'int64') != 'int64':
assert d.dtype in theano.tensor.discrete_dtypes, d.dtype
assert str(d.dtype) != 'uint64'
new_shape += sh[len(new_shape):i + 1]
new_shape[i] = theano.tensor.cast(d, 'int64')
if new_shape:
......
......@@ -36,7 +36,10 @@ from theano.tensor import (_shared, wvector, bvector, autocast_float_as,
get_constant_value, ivector, reshape, scalar_from_tensor, scal,
iscalars, arange, dscalars, fvector, imatrix, numeric_grad,
opt, ComplexError, TensorDot, lvector, true_div, max, min, Split, roll,
tile, patternbroadcast)
tile, patternbroadcast, Eye, Shape, Default, Dot, PermuteRowElements,
ScalarFromTensor, TensorFromScalar, dtensor4, Rebroadcast, Alloc,
dtensor3, SpecifyShape, Mean, IncSubtensor, AdvancedIncSubtensor1,
itensor3, Tile, AdvancedIncSubtensor)
from theano.tests import unittest_tools as utt
from theano.printing import debugprint
......@@ -5165,25 +5168,40 @@ class test_tensordot(unittest.TestCase):
# Test matrix-matrix
amat = matrix()
axes = ((1,),(0,))
c = tensordot(amat, bmat, axes)
f3 = inplace_func([amat,bmat],c)
aval = rand(4,7)
bval = rand(7,9)
self.assertTrue(numpy.allclose(numpy.tensordot(aval,bval,axes),
f3(aval,bval)))
utt.verify_grad(TensorDot(axes), [aval,bval])
for axes, shps in [[((0,), (0,)), [(4, 7), (4, 9)]],
[((0,), (1,)), [(4, 7), (9, 4)]],
[((1,), (0,)), [(4, 7), (7, 9)]],
[((1,), (1,)), [(4, 7), (9, 7)]],
[((0, 1), (0, 1)), [(4, 7), (4, 7)]],
# [((0, 1), (1, 0)), [(4, 7), (7, 4)]],
# [((1, 0), (1, 0)), [(4, 7), (4, 7)]],
# [((1, 0), (0, 1)), [(4, 7), (7, 4)]],
]:
c = tensordot(amat, bmat, axes)
f3 = inplace_func([amat, bmat], c)
aval = rand(*shps[0])
bval = rand(*shps[1])
self.assertTrue(numpy.allclose(numpy.tensordot(aval, bval, axes),
f3(aval, bval)))
utt.verify_grad(TensorDot(axes), [aval, bval])
# Test ndarray-matrix, sum over one dim of matrix
atens = tensor4()
axes = ((2,),(1,))
c = tensordot(atens, bmat, axes)
f4 = inplace_func([atens,bmat],c)
aval = rand(1,2,3,4)
bval = rand(2,3)
self.assertTrue(numpy.allclose(numpy.tensordot(aval,bval,axes),
f4(aval,bval)))
utt.verify_grad(TensorDot(axes), [aval,bval])
for axes, shps in [[((2,), (1,)), [(1, 2, 3, 4), (2, 3)]],
[((0,), (1,)), [(1, 2, 3, 4), (3, 1)]],
[((0,), (0,)), [(1, 2, 3, 4), (1, 3)]],
[((3,), (0,)), [(1, 2, 3, 4), (4, 1)]],
# [((3, 1), (0, 1)), [(1, 2, 3, 4), (4, 2)]],
# [((0, 1), (1, 0)), [(1, 2, 3, 4), (2, 1)]],
# [((3, 1), (1, 0)), [(1, 2, 3, 4), (2, 4)]],
]:
atens = tensor4()
c = tensordot(atens, bmat, axes)
f4 = inplace_func([atens, bmat], c)
aval = rand(*shps[0])
bval = rand(*shps[1])
self.assertTrue(numpy.allclose(numpy.tensordot(aval, bval, axes),
f4(aval, bval)))
utt.verify_grad(TensorDot(axes), [aval, bval])
# Test ndarray-ndarray
atens = tensor4()
......@@ -6060,6 +6078,664 @@ def test_transpose():
assert tensor.transpose(tensor.dmatrix()).name is None
class TestInferShape(utt.InferShapeTester):
def test_infer_shape(self):
# tensordot_grad
admat = dmatrix()
bdmat = dmatrix()
gzdmat = dmatrix()
admat_val = rand(4, 5)
bdmat_val = rand(5, 3)
gzdmat_val = rand(4, 3)
axes = 1
self._compile_and_check([admat, bdmat, gzdmat],
tensordot_grad(axes)(admat, bdmat, gzdmat),
[admat_val, bdmat_val, gzdmat_val], tensordot_grad)
admat_val = rand(5, 4)
bdmat_val = rand(5, 4)
gzdscal = dscalar()
gzdscal_val = rand()
axes = 2
self._compile_and_check([admat, bdmat, gzdscal],
tensordot_grad(axes)(admat, bdmat, gzdscal),
[admat_val, bdmat_val, gzdscal_val], tensordot_grad)
admat_val = rand(4, 5)
bdmat_val = rand(5, 3)
gzdmat_val = rand(4, 3)
axes = ((1, ), (0, ))
self._compile_and_check([admat, bdmat, gzdmat],
tensordot_grad(axes)(admat, bdmat, gzdmat),
[admat_val, bdmat_val, gzdmat_val], tensordot_grad)
axes = ((1, 0))
self._compile_and_check([admat, bdmat, gzdmat],
tensordot_grad(axes)(admat, bdmat, gzdmat),
[admat_val, bdmat_val, gzdmat_val], tensordot_grad)
admat_val = rand(4, 5)
bdmat_val = rand(3, 4)
gzdmat_val = rand(5, 3)
axes = ((0, ), (1, ))
self._compile_and_check([admat, bdmat, gzdmat],
tensordot_grad(axes)(admat, bdmat, gzdmat),
[admat_val, bdmat_val, gzdmat_val], tensordot_grad)
gzdscal = dscalar()
admat_val = rand(5, 4)
bdmat_val = rand(5, 4)
gzdscal_val = rand()
axes = ((0, 1), (0, 1))
self._compile_and_check([admat, bdmat, gzdscal],
tensordot_grad(axes)(admat, bdmat, gzdscal),
[admat_val, bdmat_val, gzdscal_val], tensordot_grad)
# tensordot_grad currently do not support not ordered axes
"""
gzdscal = dscalar()
admat_val = rand(5, 4)
bdmat_val = rand(4, 5)
gzdscal_val = rand()
axes = ((0, 1), (1, 0))
self._compile_and_check([admat, bdmat, gzdscal],
tensordot_grad(axes)(admat, bdmat, gzdscal),
[admat_val, bdmat_val, gzdscal_val], tensordot_grad)
gzdscal = dscalar()
admat_val = rand(5, 4)
bdmat_val = rand(5, 4)
gzdscal_val = rand()
axes = ((1, 0 ), (1, 0))
self._compile_and_check([admat, bdmat, gzdscal],
tensordot_grad(axes)(admat, bdmat, gzdscal),
[admat_val, bdmat_val, gzdscal_val], tensordot_grad)
"""
# tensordot
admat = dmatrix()
bdmat = dmatrix()
admat_val = rand(4, 5)
bdmat_val = rand(5, 3)
axes = 1
self._compile_and_check([admat, bdmat],
[TensorDot(axes)(admat, bdmat)],
[admat_val, bdmat_val], TensorDot)
admat_val = rand(5, 4)
bdmat_val = rand(5, 4)
axes = 2
self._compile_and_check([admat, bdmat],
[TensorDot(axes)(admat, bdmat)],
[admat_val, bdmat_val], TensorDot)
admat_val = rand(4, 5)
bdmat_val = rand(5, 3)
axes = ((1, ), (0, ))
self._compile_and_check([admat, bdmat],
[TensorDot(axes)(admat, bdmat)],
[admat_val, bdmat_val], TensorDot)
axes = ((1, 0))
self._compile_and_check([admat, bdmat],
[TensorDot(axes)(admat, bdmat)],
[admat_val, bdmat_val], TensorDot)
admat_val = rand(4, 5)
bdmat_val = rand(3, 4)
axes = ((0, ), (1, ))
self._compile_and_check([admat, bdmat],
[TensorDot(axes)(admat, bdmat)],
[admat_val, bdmat_val], TensorDot)
axes = ((0, 1))
self._compile_and_check([admat, bdmat],
[TensorDot(axes)(admat, bdmat)],
[admat_val, bdmat_val], TensorDot)
admat_val = rand(5, 4)
bdmat_val = rand(4, 5)
axes = ((1,), (0,))
self._compile_and_check([admat, bdmat],
[TensorDot(axes)(admat, bdmat)],
[admat_val, bdmat_val], TensorDot)
axes = ((0, 1), (1, 0))
self._compile_and_check([admat, bdmat],
[TensorDot(axes)(admat, bdmat)],
[admat_val, bdmat_val], TensorDot)
admat_val = rand(5, 4)
bdmat_val = rand(5, 4)
axes = ((0, 1), (0, 1))
self._compile_and_check([admat, bdmat],
[TensorDot(axes)(admat, bdmat)],
[admat_val, bdmat_val], TensorDot)
admat_val = rand(5, 4)
bdmat_val = rand(4, 5)
axes = ((1, 0), (0, 1))
self._compile_and_check([admat, bdmat],
[TensorDot(axes)(admat, bdmat)],
[admat_val, bdmat_val], TensorDot)
adtens3 = dtensor3()
admat_val = rand(5, 4)
adtens3_val = rand(5, 4, 3)
axes = 2
self._compile_and_check([admat, adtens3],
[TensorDot(axes)(admat, adtens3)],
[admat_val, adtens3_val], TensorDot)
adtens3_val = rand(4, 5, 3)
axes = ((1, 0), (0, 1))
self._compile_and_check([admat, adtens3],
[TensorDot(axes)(admat, adtens3)],
[admat_val, adtens3_val], TensorDot)
adtens3_val = rand(4, 3, 5)
axes = ((1, 0), (0, 2))
self._compile_and_check([admat, adtens3],
[TensorDot(axes)(admat, adtens3)],
[admat_val, adtens3_val], TensorDot)
adtens4 = dtensor4()
admat_val = rand(5, 4)
adtens4_val = rand(5, 4, 3, 2)
axes = 2
self._compile_and_check([admat, adtens4],
[TensorDot(axes)(admat, adtens4)],
[admat_val, adtens4_val], TensorDot)
adtens4_val = rand(4, 3, 2, 5)
axes = ((1, 0), (0, 3))
self._compile_and_check([admat, adtens4],
[TensorDot(axes)(admat, adtens4)],
[admat_val, adtens4_val], TensorDot)
# Flatten
adtens = tensor3()
adtens_val = rand(4, 5, 3)
outdim = 2
self._compile_and_check([adtens],
[Flatten(outdim)(adtens)],
[adtens_val], Flatten)
outdim = 1
self._compile_and_check([adtens],
[Flatten(outdim)(adtens)],
[adtens_val], Flatten)
# Eye
aiscal = iscalar()
biscal = iscalar()
ciscal = iscalar()
self._compile_and_check([aiscal, biscal, ciscal],
[Eye()(aiscal, biscal, ciscal)],
[4, 4, 0], Eye)
self._compile_and_check([aiscal, biscal, ciscal],
[Eye()(aiscal, biscal, ciscal)],
[4, 5, 0], Eye)
self._compile_and_check([aiscal, biscal, ciscal],
[Eye()(aiscal, biscal, ciscal)],
[3, 5, 0], Eye)
# Shape
# 'opt.Makevector' precludes optimizer from disentangling
# elements of shape
self._compile_and_check([adtens],
[Shape()(adtens)],
[adtens_val], (opt.MakeVector, Shape))
# Dot
advec = dvector()
bdvec = dvector()
advec_val = rand(4)
bdvec_val = rand(4)
self._compile_and_check([advec, bdvec],
[Dot()(advec, bdvec)],
[advec_val, bdvec_val],
(Dot, tensor.blas.Gemv, tensor.blas_c.CGemv))
admat_val = rand(4, 5)
bdmat_val = rand(5, 3)
self._compile_and_check([admat, bdmat],
[Dot()(admat, bdmat)],
[admat_val, bdmat_val],
(Dot, tensor.blas.Dot22))
admat_val = rand(5, 4)
self._compile_and_check([admat, advec],
[Dot()(admat, advec)],
[admat_val, advec_val],
(Dot, tensor.blas.Gemv, tensor.blas_c.CGemv))
bdmat_val = rand(4, 5)
self._compile_and_check([advec, bdmat],
[Dot()(advec, bdmat)],
[advec_val, bdmat_val],
(Dot, tensor.blas.Gemv, tensor.blas_c.CGemv))
# Split
aivec = ivector()
adtens_val = rand(4, 10, 3)
aivec_val = [2, 5, 3]
self._compile_and_check([adtens, aiscal, aivec],
[Split(3)(adtens, aiscal, aivec)[0]],
[adtens_val, 1, aivec_val], (Split))
# Join
cdmat = dmatrix()
admat_val = rand(1, 3)
bdmat_val = rand(3, 3)
cdmat_val = rand(4, 3)
aiscal_val = 0
self._compile_and_check([aiscal, admat, bdmat, cdmat],
[Join()(aiscal, admat, bdmat, cdmat)],
[aiscal_val, admat_val, bdmat_val, cdmat_val], Join)
admat_val = rand(4, 1)
bdmat_val = rand(4, 3)
cdmat_val = rand(4, 2)
aiscal_val = 1
self._compile_and_check([aiscal, admat, bdmat, cdmat],
[Join()(aiscal, admat, bdmat, cdmat)],
[aiscal_val, admat_val, bdmat_val, cdmat_val], Join)
# PermuteRowElements
abool = True
rng = numpy.random.RandomState(utt.fetch_seed())
advec_val = rand(5)
aivec_val = rng.permutation(5).astype('int32')
self._compile_and_check([advec, aivec],
[PermuteRowElements()(advec, aivec, abool)],
[advec_val, aivec_val], PermuteRowElements)
admat_val = rand(3, 5)
self._compile_and_check([admat, aivec],
[PermuteRowElements()(admat, aivec, abool)],
[admat_val, aivec_val], PermuteRowElements)
adtens3 = dtensor3()
adtens3_val = rand(3, 2, 5)
self._compile_and_check([adtens3, aivec],
[PermuteRowElements()(adtens3, aivec, abool)],
[adtens3_val, aivec_val], PermuteRowElements)
aimat = imatrix()
perma = rng.permutation(5).astype('int32')
permb = rng.permutation(5).astype('int32')
permc = rng.permutation(5).astype('int32')
aimat_val = numpy.vstack((perma, permb, permc))
admat_val = rand(3, 5)
self._compile_and_check([admat, aimat],
[PermuteRowElements()(admat, aimat, abool)],
[admat_val, aimat_val], PermuteRowElements)
aitens3 = itensor3()
perma = rng.permutation(5).astype('int32')
permb = rng.permutation(5).astype('int32')
permc = rng.permutation(5).astype('int32')
bimat_val = numpy.vstack((perma, permb, permc))
aitens3_val = numpy.empty((2, 3, 5), 'int32')
aitens3_val[0, ::, ::] = aimat_val
aitens3_val[1, ::, ::] = bimat_val
self._compile_and_check([admat, aitens3],
[PermuteRowElements()(admat, aitens3, abool)],
[admat_val, aitens3_val], PermuteRowElements)
# ScalarFromTensor
aiscal = iscalar()
aconst = constant(45)
self._compile_and_check([aiscal],
[TensorFromScalar()(ScalarFromTensor()(aiscal))],
[45], ScalarFromTensor,
excluding=["local_tensor_scalar_tensor"])
# TensorFromScalar
aiscal = scal.float64()
self._compile_and_check([aiscal],
[TensorFromScalar()(aiscal)],
[4.], TensorFromScalar)
# Rebroadcast
adtens4 = dtensor4()
adict = [(0, False), (1, True), (2, False), (3, True)]
adtens4_val = rand(2, 1, 3, 1)
self._compile_and_check([adtens4],
[Rebroadcast(*adict)(adtens4)],
[adtens4_val], Rebroadcast)
adtens4_bro = TensorType('float64', (True, True, True, False))()
bdict = [(0, True), (1, False), (2, False), (3, False)]
adtens4_bro_val = rand(1, 1, 1, 3)
self._compile_and_check([adtens4_bro],
[Rebroadcast(*bdict)(adtens4_bro)],
[adtens4_bro_val], Rebroadcast)
# Alloc
randint = numpy.random.random_integers
adscal = dscalar()
aiscal = lscalar()
biscal = lscalar()
ciscal = lscalar()
discal = lscalar()
adscal_val = rand()
aiscal_val = randint(3, 5, size=())
biscal_val = randint(3, 5, size=())
ciscal_val = randint(3, 5, size=())
discal_val = randint(3, 5, size=())
self._compile_and_check([adscal, aiscal, biscal, ciscal, discal],
[Alloc()(adscal, aiscal, biscal, ciscal, discal)],
[adscal_val, aiscal_val, biscal_val,
ciscal_val, discal_val], Alloc)
# MaxAndArgmax,
adtens3_val = rand(4, 5, 3)
self._compile_and_check([adtens3],
MaxAndArgmax()(adtens3, None),
[adtens3_val], MaxAndArgmax)
self._compile_and_check([adtens3],
MaxAndArgmax()(adtens3, 0),
[adtens3_val], MaxAndArgmax)
self._compile_and_check([adtens3],
MaxAndArgmax()(adtens3, 1),
[adtens3_val], MaxAndArgmax)
self._compile_and_check([adtens3],
MaxAndArgmax()(adtens3, 2),
[adtens3_val], MaxAndArgmax)
self._compile_and_check([adtens3],
MaxAndArgmax()(adtens3, [0, 1, 2]),
[adtens3_val], MaxAndArgmax)
# ARange
self._compile_and_check([aiscal, biscal, ciscal],
[ARange('int64')(aiscal, biscal, ciscal)],
[0, 5, 1], ARange)
self._compile_and_check([aiscal, biscal, ciscal],
[ARange('int64')(aiscal, biscal, ciscal)],
[2, 11, 4], ARange)
self._compile_and_check([aiscal, biscal, ciscal],
[ARange('int64')(aiscal, biscal, ciscal)],
[-5, 1, 1], ARange)
self._compile_and_check([aiscal, biscal, ciscal],
[ARange('int64')(aiscal, biscal, ciscal)],
[10, 2, -2], ARange)
self._compile_and_check([aiscal, biscal, ciscal],
[ARange('int64')(aiscal, biscal, ciscal)],
[10, 2, 2], ARange)
self._compile_and_check([aiscal, biscal, ciscal],
[ARange('int64')(aiscal, biscal, ciscal)],
[0, 0, 1], ARange)
# SpecifyShape
aivec_val = [3, 4, 2, 5]
adtens4_val = rand(*aivec_val)
self._compile_and_check([adtens4, aivec],
[SpecifyShape()(adtens4, aivec)],
[adtens4_val, aivec_val], SpecifyShape)
# Mean
adtens3_val = rand(3, 4, 5)
aiscal_val = 2
self._compile_and_check([adtens3],
[Mean(None)(adtens3)],
[adtens3_val], Mean)
self._compile_and_check([adtens3],
[Mean(aiscal_val)(adtens3)],
[adtens3_val], Mean)
# IncSubtensor
admat = dmatrix()
bdmat = dmatrix()
advec = dvector()
adscal = dscalar()
admat_val = rand(5, 4)
self._compile_and_check([admat, bdmat],
[inc_subtensor(admat[2:4], bdmat)],
[admat_val, [[1, 2, 3, 4]]], IncSubtensor)
self._compile_and_check([admat, advec],
[inc_subtensor(admat[2], advec)],
[admat_val, [1, 2, 3, 4]], IncSubtensor)
self._compile_and_check([admat, adscal],
[inc_subtensor(admat[2, 3], adscal)],
[admat_val, 1], IncSubtensor)
self._compile_and_check([admat, adscal],
[inc_subtensor(admat[1:3, 2], adscal)],
[admat_val, 1], IncSubtensor)
self._compile_and_check([admat, bdmat],
[set_subtensor(admat[2:4], bdmat)],
[admat_val, [[1, 2, 3, 4]]], IncSubtensor)
self._compile_and_check([admat, advec],
[set_subtensor(admat[2], advec)],
[admat_val, [1, 2, 3, 4]], IncSubtensor)
self._compile_and_check([admat, adscal],
[set_subtensor(admat[2, 3], adscal)],
[admat_val, 1], IncSubtensor)
self._compile_and_check([admat, adscal],
[set_subtensor(admat[1:3, 2], adscal)],
[admat_val, 1], IncSubtensor)
bdtens4 = dtensor4()
adtens4_val = rand(3, 4, 2, 5)
self._compile_and_check([adtens4, bdtens4],
[inc_subtensor(adtens4[::, 2:4, ::, ::], bdtens4)],
[adtens4_val, [[[[1, 2, 3, 4, 5]]]]], IncSubtensor)
self._compile_and_check([adtens4, bdmat],
[inc_subtensor(adtens4[2, 2:4, 1, ::], bdmat)],
[adtens4_val, [[1, 2, 3, 4, 5]]], IncSubtensor)
self._compile_and_check([adtens4, advec],
[inc_subtensor(adtens4[0, 1, ::, 4], advec)],
[adtens4_val, [1, 2]], IncSubtensor)
self._compile_and_check([adtens4, adscal],
[inc_subtensor(adtens4[1:3, 1, ::, 2:4], adscal)],
[adtens4_val, 1], IncSubtensor)
self._compile_and_check([adtens4, bdtens4],
[set_subtensor(adtens4[::, 2:4, ::, ::], bdtens4)],
[adtens4_val, [[[[1, 2, 3, 4, 5]]]]], IncSubtensor)
self._compile_and_check([adtens4, bdmat],
[set_subtensor(adtens4[2, 2:4, 1, ::], bdmat)],
[adtens4_val, [[1, 2, 3, 4, 5]]], IncSubtensor)
self._compile_and_check([adtens4, advec],
[set_subtensor(adtens4[0, 1, ::, 4], advec)],
[adtens4_val, [1, 2]], IncSubtensor)
self._compile_and_check([adtens4, adscal],
[set_subtensor(adtens4[1:3, 1, ::, 2:4], adscal)],
[adtens4_val, 1], IncSubtensor)
# AdvancedIncSubtensor1
admat = dmatrix()
bdmat = dmatrix()
advec = dvector()
adscal = dscalar()
admat_val = rand(5, 4)
aivec_val = [2, 3]
self._compile_and_check([admat, bdmat],
[set_subtensor(admat[aivec_val], bdmat)],
[admat_val, [[1, 2, 3, 4]]], AdvancedIncSubtensor1)
aivec_val = [1, 3, 2]
self._compile_and_check([admat, advec],
[set_subtensor(admat[aivec_val], advec)],
[admat_val, [1, 2, 3, 4]], AdvancedIncSubtensor1)
aivec_val = [0, 3, 0]
self._compile_and_check([admat, adscal],
[set_subtensor(admat[aivec_val], adscal)],
[admat_val, 1], AdvancedIncSubtensor1)
bdtens4 = dtensor4()
adtens4_val = rand(4, 3, 2, 5)
aivec_val = [2, 3]
self._compile_and_check([adtens4, bdtens4],
[set_subtensor(adtens4[aivec_val], bdtens4)],
[adtens4_val, [[[[1, 2, 3, 4, 5]]]]],
AdvancedIncSubtensor1)
aivec_val = [1, 3, 2]
self._compile_and_check([adtens4, advec],
[set_subtensor(adtens4[aivec_val], advec)],
[adtens4_val, [1, 2, 3, 4, 5]],
AdvancedIncSubtensor1)
aivec_val = [0, 3, 0]
self._compile_and_check([adtens4, adscal],
[set_subtensor(adtens4[aivec_val], adscal)],
[adtens4_val, 1],
AdvancedIncSubtensor1)
aivec_val = [2, 3]
self._compile_and_check([admat, bdmat],
[inc_subtensor(admat[aivec_val], bdmat)],
[admat_val, [[1, 2, 3, 4], [5, 6, 7, 8]]],
AdvancedIncSubtensor1)
aivec_val = [1, 3, 2]
self._compile_and_check([admat, advec],
[inc_subtensor(admat[aivec_val], advec)],
[admat_val, [1, 2, 3, 4]], AdvancedIncSubtensor1)
aivec_val = [0, 3, 0]
self._compile_and_check([admat, adscal],
[inc_subtensor(admat[aivec_val], adscal)],
[admat_val, 1], AdvancedIncSubtensor1)
bdtens4 = dtensor4()
adtens4_val = rand(4, 3, 2, 5)
aivec_val = [2, 3]
self._compile_and_check([adtens4, bdtens4],
[inc_subtensor(adtens4[aivec_val], bdtens4)],
[adtens4_val, [[[[1, 2, 3, 4, 5]]],
[[[6, 7, 8, 9, 10]]]]],
AdvancedIncSubtensor1)
aivec_val = [1, 2, 1]
self._compile_and_check([adtens4, advec],
[inc_subtensor(adtens4[aivec_val], advec)],
[adtens4_val, [1, 2, 3, 4, 5]],
AdvancedIncSubtensor1)
aivec_val = [0, 3, 0]
self._compile_and_check([adtens4, adscal],
[inc_subtensor(adtens4[aivec_val], adscal)],
[adtens4_val, 2],
AdvancedIncSubtensor1)
# AdvancedIncSubtensor
aivec_val = [1, 3, 2]
bivec_val = [0, 3, 3]
advec_val = [23, 24, 25]
self._compile_and_check([admat, advec],
[set_subtensor(admat[aivec_val, bivec_val], advec)],
[admat_val, advec_val], AdvancedIncSubtensor)
# Reshape
# TODO: generalize infer_shape to account for tensor variable
# (non-constant) input shape
admat = dmatrix()
aivec = ivector()
ndim = 2
admat_val = rand(3, 4)
self._compile_and_check([admat],
[Reshape(ndim)(admat, [4, 3])],
[admat_val], Reshape)
self._compile_and_check([admat],
[Reshape(ndim)(admat, [4, -1])],
[admat_val], Reshape)
# enable when infer_shape is generalized:
# self._compile_and_check([admat, aivec],
# [Reshape(ndim)(admat, aivec)],
# [admat_val, [4, 3]], Reshape)
#
# self._compile_and_check([admat, aivec],
# [Reshape(ndim)(admat, aivec)],
# [admat_val, [4, -1]], Reshape)
adtens4 = dtensor4()
ndim = 4
adtens4_val = rand(2, 4, 3, 5)
self._compile_and_check([adtens4],
[Reshape(ndim)(adtens4, [1, -1, 10, 4])],
[adtens4_val], Reshape)
self._compile_and_check([adtens4],
[Reshape(ndim)(adtens4, [1, 3, 10, 4])],
[adtens4_val], Reshape)
# enable when infer_shape is generalized:
# self._compile_and_check([adtens4, aivec],
# [Reshape(ndim)(adtens4, aivec)],
# [adtens4_val, [1, -1, 10, 4]], Reshape)
#
# self._compile_and_check([adtens4, aivec],
# [Reshape(ndim)(adtens4, aivec)],
# [adtens4_val, [1, 3, 10, 4]], Reshape)
# Tile
advec = dvector()
advec_val = rand(5)
aivec_val = [3]
ndim = 1
self._compile_and_check([advec],
[tile(advec, aivec_val, ndim)],
[advec_val], Tile)
admat = dmatrix()
admat_val = rand(2, 4)
aivec_val = [2, 3]
ndim = None
self._compile_and_check([admat],
[tile(admat, aivec_val)],
[admat_val], Tile)
adtens4 = dtensor4()
adtens4_val = rand(2, 4, 3, 5)
aivec_val = [2, 3, 1, 4]
ndim = 4
self._compile_and_check([adtens4],
[tile(adtens4, aivec_val, ndim)],
[adtens4_val], Tile)
if __name__ == '__main__':
t = TestInferShape('setUp')
t.setUp()
t.test_infer_shape()
"""
if __name__ == '__main__':
if 0:
unittest.main()
......@@ -6069,3 +6745,4 @@ if __name__ == '__main__':
suite = unittest.TestLoader()
suite = suite.loadTestsFromTestCase(testcase)
unittest.TextTestRunner(verbosity=2).run(suite)
"""
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论