提交 a384448e authored 作者: Frédéric Bastien's avatar Frédéric Bastien

Merge pull request #3160 from harlouci/props_tensor

Props tensor
......@@ -22,7 +22,6 @@ from theano.tensor.type_other import NoneConst
from theano import scalar as scal
from functools import partial
from six import integer_types
from theano.gof.utils import hashtype
from theano import compile, printing
from theano.printing import pprint, min_informative_str
# For history
......@@ -1002,6 +1001,9 @@ _scal_elemwise = _scal_elemwise_with_nfunc(None, None, None)
#########################
class TensorFromScalar(Op):
__props__ = ()
def make_node(self, s):
assert isinstance(s.type, scal.Scalar)
return Apply(self,
......@@ -1033,18 +1035,12 @@ class TensorFromScalar(Op):
raise NotImplementedError("grad not implemented for complex dtypes")
def __str__(self):
return self.__class__.__name__
tensor_from_scalar = TensorFromScalar()
class ScalarFromTensor(Op):
def __eq__(self, other):
return type(self) == type(other)
def __hash__(self):
return hash(type(self))
__props__ = ()
def make_node(self, t):
assert isinstance(t.type, TensorType)
......@@ -1072,9 +1068,6 @@ class ScalarFromTensor(Op):
return [None]
return self.make_node(*eval_points).outputs
def __str__(self):
return self.__class__.__name__
def c_code(self, node, name, inputs, outputs, sub):
x, = inputs
z, = outputs
......@@ -1197,12 +1190,7 @@ class MaxAndArgmax(Op):
nin = 2 # tensor, axis
nout = 2 # max val, max idx
E_axis = 'invalid axis'
def __eq__(self, other):
return type(self) == type(other)
def __hash__(self):
return hash(type(self))
__props__ = ()
def make_node(self, x, axis=None):
x = _as_tensor_variable(x)
......@@ -1424,10 +1412,6 @@ class MaxAndArgmax(Op):
g_x = eq(xmax_pad, x) * g_max_pad
return g_x, axis_grad
def __str__(self):
return self.__class__.__name__
_max_and_argmax = MaxAndArgmax()
......@@ -2330,6 +2314,9 @@ def nonzero_values(a):
class Tri(gof.Op):
__props__ = ("dtype",)
def __init__(self, dtype=None):
if dtype is None:
dtype = config.floatX
......@@ -2356,12 +2343,6 @@ class Tri(gof.Op):
def grad(self, inp, grads):
return [grad_undefined(self, i, inp[i]) for i in xrange(3)]
def __eq__(self, other):
return type(self) == type(other) and self.dtype == other.dtype
def __hash__(self):
return hash(self.dtype) ^ hash(type(self))
def tri(N, M=None, k=0, dtype=None):
"""
......@@ -2438,6 +2419,9 @@ def triu(m, k=0):
class Eye(gof.Op):
__props__ = ("dtype", )
def __init__(self, dtype=None):
if dtype is None:
dtype = config.floatX
......@@ -2467,12 +2451,6 @@ class Eye(gof.Op):
def grad(self, inp, grads):
return [grad_undefined(self, i, inp[i]) for i in xrange(3)]
def __eq__(self, other):
return type(self) == type(other) and self.dtype == other.dtype
def __hash__(self):
return hash(self.dtype) ^ hash(type(self))
def eye(n, m=None, k=0, dtype=None):
"""Return a 2-D array with ones on the diagonal and zeros elsewhere.
......@@ -2990,6 +2968,7 @@ class Default(gof.Op):
have exactly the same type.
"""
view_map = {0: [0]}
__props__ = ()
def make_node(self, x, default):
x, default = as_tensor_variable(x), as_tensor_variable(default)
......@@ -3283,20 +3262,14 @@ class Split(Op):
"""A Split instance will have this many outputs, and require that
the splits argument to `perform` have exactly this many elements.
"""
__props__ = ("len_splits",)
def __init__(self, len_splits):
self.len_splits = int(len_splits)
def __eq__(self, other):
return (type(self) == type(other) and
self.len_splits == other.len_splits)
def __str__(self):
return self.__class__.__name__ + "{%s}" % self.len_splits
def __hash__(self):
return hash(Split) ^ self.len_splits
def make_node(self, x, axis, splits):
"""WRITEME"""
x = as_tensor_variable(x)
......@@ -3510,15 +3483,7 @@ class Join(Op):
join(0, x, u) # WRONG: joined tensors must have the same rank
"""
check_input = False
def __eq__(self, other):
return type(self) == type(other)
def __hash__(self):
return hash(type(self))
def __str__(self):
return '%s' % (self.__class__.__name__)
__props__ = ()
def make_node(self, *axis_and_tensors):
"""
......@@ -3979,19 +3944,13 @@ class Reshape(Op):
_f16_ok = True
check_input = False
__props__ = ("ndim",)
# name does not participate because it doesn't affect computations
def __init__(self, ndim, name=None):
self.ndim = ndim
self.name = name
def __eq__(self, other):
# .name does not participate because it doesn't affect computations
return (type(other) is type(self)) and (other.ndim == self.ndim)
def __hash__(self):
# .name does not participate because it doesn't affect computations
return hash(type(self)) ^ hash(self.ndim)
def __str__(self):
return '%s{%s}' % (self.__class__.__name__, self.ndim)
......@@ -4180,16 +4139,11 @@ class Flatten(Op):
view_map = {0: [0]}
check_input = False
__props__ = ("outdim",)
def __init__(self, outdim=1):
self.outdim = int(outdim)
def __eq__(self, other):
return type(self) == type(other) and self.outdim == other.outdim
def __hash__(self):
return hashtype(self) ^ hash(self.outdim)
def __str__(self):
return '%s{%s}' % (self.__class__.__name__, self.outdim)
......@@ -4364,15 +4318,11 @@ class Tile(Op):
:see: `numpy.tile
<http://docs.scipy.org/doc/numpy/reference/generated/numpy.tile.html>`_
"""
__props__ = ("ndim",)
def __init__(self, ndim):
self.ndim = ndim
def __eq__(self, other):
return (type(other) is Tile) and (other.ndim == self.ndim)
def __hash__(self):
return hash(Tile) ^ hash(self.ndim)
def __str__(self):
return self.__class__.__name__ + "{ndim=%d}" % self.ndim
......@@ -4473,19 +4423,11 @@ class ARange(Op):
Parameters and behaviour are the same as numpy.arange().
"""
__props__ = ("dtype",)
def __init__(self, dtype):
self.dtype = dtype
def __eq__(self, other):
return type(self) == type(other) and self.dtype == other.dtype
def __hash__(self):
return hash(self.dtype)
def __str__(self):
return self.__class__.__name__
def make_node(self, start, stop, step):
start, stop, step = map(as_tensor_variable, (start, stop, step))
assert start.ndim == 0
......@@ -4641,6 +4583,7 @@ class _nd_grid(object):
>>> b[1].eval()
array([[0, 1, 2, 3]], dtype=int8)
"""
def __init__(self, sparse=False):
self.sparse = sparse
......@@ -4701,6 +4644,7 @@ class PermuteRowElements(Op):
If the "inverse" argument is True, the Op will perform the inverse
permutation instead.
"""
__props__ = ()
def make_node(self, x, y, inverse):
x = as_tensor_variable(x)
......@@ -4908,12 +4852,7 @@ class Dot(Op):
tensor.blas)
"""
def __eq__(self, other):
return type(self) == type(other)
def __hash__(self):
return hash(type(self))
__props__ = ()
# the rationale for Dot22 is related to getting GEMM Ops into the
# graph. See Dot22 in tensor.blas for details.
......@@ -5377,6 +5316,7 @@ class Diagonal(Op):
:return: A vector representing the diagonal elements.
"""
__props__ = ("offset", "axis1", "axis2")
def __init__(self, offset=0, axis1=0, axis2=1):
if numpy_diagonal_return_view:
......@@ -5385,16 +5325,6 @@ class Diagonal(Op):
self.axis1 = axis1
self.axis2 = axis2
def __eq__(self, other):
return (type(self) == type(other) and
self.offset == other.offset and
self.axis1 == other.axis1 and
self.axis2 == other.axis2)
def __hash__(self):
return (hash(type(self)) ^ hash(self.offset) ^
hash(self.axis1) ^ hash(self.axis2))
def make_node(self, x):
x = as_tensor_variable(x)
assert x.ndim >= 2
......@@ -5428,9 +5358,6 @@ class Diagonal(Op):
out_shape.append(diag_size)
return [tuple(out_shape)]
def __str__(self):
return self.__class__.__name__
def diagonal(a, offset=0, axis1=0, axis2=1):
if (offset, axis1, axis2) == (0, 0, 1):
......@@ -5440,11 +5367,7 @@ def diagonal(a, offset=0, axis1=0, axis2=1):
class Diag(Op):
def __eq__(self, other):
return type(self) == type(other)
def __hash__(self):
return hash(type(self))
__props__ = ()
def make_node(self, diag):
diag = as_tensor_variable(diag)
......@@ -5464,9 +5387,6 @@ class Diag(Op):
def infer_shape(self, nodes, shapes):
return [(shapes[0][0],) * 2]
def __str__(self):
return self.__class__.__name__
def diag(v, k=0):
if v.ndim == 1:
......
......@@ -360,23 +360,19 @@ class Gemv(Op):
alpha, beta are scalars
output is a vector that can be inplace on y
"""
__props__ = ("inplace",)
def __init__(self, inplace):
self.inplace = inplace
if inplace:
self.destroy_map = {0: [0]}
def __eq__(self, other):
return type(self) == type(other) and self.inplace == other.inplace
def __str__(self):
if self.inplace:
return '%s{inplace}' % self.__class__.__name__
else:
return '%s{no_inplace}' % self.__class__.__name__
def __hash__(self):
return hash(type(self)) ^ hash(self.inplace)
def make_node(self, y, alpha, A, x, beta):
y = T.as_tensor_variable(y)
x = T.as_tensor_variable(x)
......@@ -453,18 +449,13 @@ class Ger(Op):
:TODO: Create better classes ScipyGer and CGer that inherit from this class
and override the make_thunk() method to use Scipy and C respectively.
"""
__props__ = ("destructive",)
def __init__(self, destructive):
self.destructive = destructive
if destructive:
self.destroy_map = {0: [0]}
def __eq__(self, other):
return (type(self) == type(other) and
self.destructive == other.destructive)
def __hash__(self):
return hash(type(self)) ^ hash(self.destructive)
def __str__(self):
if self.destructive:
return '%s{destructive}' % self.__class__.__name__
......@@ -611,14 +602,7 @@ class GemmRelated(Op):
This class provides a kind of templated gemm Op.
"""
def __eq__(self, other):
return (type(self) == type(other))
def __hash__(self):
return hash(type(self))
def __str__(self):
return self.__class__.__name__
__props__ = ()
def c_support_code(self):
# return cblas_header_text()
......
......@@ -98,7 +98,6 @@ class DimShuffle(Op):
Adding, subtracting dimensions can be done with reshape.
"""
_f16_ok = True
check_input = False
def __init__(self, input_broadcastable, new_order, inplace=False):
......
......@@ -65,6 +65,7 @@ cpu_contiguous = CpuContiguous()
class CumsumOp(theano.Op):
# See function cumsum for docstring
__props__ = ("axis",)
def __init__(self, axis=None):
......@@ -182,6 +183,7 @@ def cumsum(x, axis=None):
class CumprodOp(theano.Op):
# See function cumprod for docstring
__props__ = ("axis",)
def __init__(self, axis=None):
......@@ -344,9 +346,6 @@ class DiffOp(theano.Op):
out_shape[self.axis] = out_shape[self.axis] - self.n
return [out_shape]
def __str__(self):
return self.__class__.__name__
def diff(x, n=1, axis=-1):
"""Calculate the n-th order discrete difference along given axis.
......@@ -462,9 +461,6 @@ class BinCountOp(theano.Op):
m = basic.maximum(m, self.minlength)
return [[m]]
def __str__(self):
return self.__class__.__name__
def bincount(x, weights=None, minlength=None, assert_nonneg=False):
"""Count number of occurrences of each value in array of ints.
......@@ -670,9 +666,6 @@ class RepeatOp(theano.Op):
out_shape[self.axis] = theano.tensor.sum(repeats, dtype=dtype)
return [out_shape]
def __str__(self):
return self.__class__.__name__
def repeat(x, repeats, axis=None):
"""Repeat elements of an array.
......@@ -739,9 +732,6 @@ class Bartlett(gof.Op):
# See function bartlett for docstring
__props__ = ()
def __str__(self):
return self.__class__.__name__
def make_node(self, M):
M = tensor.as_tensor_variable(M)
if M.ndim != 0:
......@@ -797,9 +787,6 @@ class FillDiagonal(gof.Op):
# See function fill_diagonal for docstring
__props__ = ()
def __str__(self):
return self.__class__.__name__
def infer_shape(self, node, in_shapes):
return [in_shapes[0]]
......@@ -881,9 +868,6 @@ class FillDiagonalOffset(gof.Op):
# See function fill_diagonal_offset for docstring
__props__ = ()
def __str__(self):
return self.__class__.__name__
def infer_shape(self, node, in_shapes):
return [in_shapes[0]]
......
......@@ -34,15 +34,7 @@ class Fourier(gof.Op):
input points, A[(n-1)/2] contains the largest positive frequency, while
A[(n+1)/2] contains the largest negative frequency.
"""
def __eq__(self, other):
return type(self) == type(other)
def __hash__(self):
return hash(self.__class__)
def __str__(self):
return self.__class__.__name__
__props__ = ()
def make_node(self, a, n, axis):
a = tensor.as_tensor_variable(a)
......
......@@ -18,6 +18,8 @@ class LoadFromDisk(Op):
@note: Non-differentiable.
"""
__props__ = ("dtype", "broadcastable", "mmap_mode")
def __init__(self, dtype, broadcastable, mmap_mode=None):
self.dtype = numpy.dtype(dtype) # turn "float64" into numpy.float64
self.broadcastable = broadcastable
......@@ -25,13 +27,6 @@ class LoadFromDisk(Op):
raise ValueError("The only supported values for mmap_mode "
"are None and 'c', got %s" % mmap_mode)
self.mmap_mode = mmap_mode
self._info = (dtype, broadcastable, mmap_mode)
def __eq__(self, other):
return (type(self) == type(other) and self._info == other._info)
def __hash__(self):
return hash((type(self),) + self._info)
def make_node(self, path):
if isinstance(path, str):
......@@ -50,7 +45,8 @@ class LoadFromDisk(Op):
out[0][0] = result
def __str__(self):
return "Load{dtype: %s, broadcastable: %s, mmep: %s}" % self._info
return ("Load{dtype: %s, broadcastable: %s, mmep: %s}" %
(self.dtype, self.broadcastable, self.mmap_mode))
def load(path, dtype, broadcastable, mmap_mode=None):
......@@ -103,6 +99,7 @@ class MPIRecv(Op):
@note: Non-differentiable.
"""
__props__ = ("source", "tag", "shape", "dtype")
def __init__(self, source, tag, shape, dtype):
self.source = source
......@@ -110,13 +107,6 @@ class MPIRecv(Op):
self.shape = shape
self.dtype = numpy.dtype(dtype) # turn "float64" into numpy.float64
self.broadcastable = (False,) * len(shape)
self._info = (source, tag, shape, dtype)
def __eq__(self, other):
return (type(self) == type(other) and self._info == other._info)
def __hash__(self):
return hash((type(self),) + self._info)
def make_node(self):
return gof.Apply(self, [], [theano.Variable(Generic()),
......@@ -132,7 +122,8 @@ class MPIRecv(Op):
out[1][0] = data
def __str__(self):
return "MPIRecv{source: %d, tag: %d, shape: %s, dtype: %s}" % self._info
return ("MPIRecv{source: %d, tag: %d, shape: %s, dtype: %s}" %
(self.source, self.tag, self.shape, self.dtype))
def infer_shape(self, node, shapes):
return [None, self.shape]
......@@ -150,16 +141,11 @@ class MPIRecvWait(Op):
@note: Non-differentiable.
"""
__props__ = ("tag",)
def __init__(self, tag):
self.tag = tag
def __eq__(self, other):
return type(self) == type(other) and self.tag == other.tag
def __hash__(self):
return hash((type(self), self.tag))
def make_node(self, request, data):
return gof.Apply(self, [request, data],
[tensor(data.dtype,
......@@ -174,9 +160,6 @@ class MPIRecvWait(Op):
out[0][0] = data
def __str__(self):
return "MPIRecvWait"
def infer_shape(self, node, shapes):
return [shapes[1]]
......@@ -193,17 +176,11 @@ class MPISend(Op):
@note: Non-differentiable.
"""
__props__ = ("dest", "tag")
def __init__(self, dest, tag):
self.dest = dest
self.tag = tag
self._info = (dest, tag)
def __eq__(self, other):
return (type(self) == type(other) and self._info == other._info)
def __hash__(self):
return hash((type(self),) + self._info)
def make_node(self, data):
return gof.Apply(self, [data],
......@@ -220,7 +197,7 @@ class MPISend(Op):
out[1][0] = data
def __str__(self):
return "MPISend{dest: %d, tag: %d}" % self._info
return "MPISend{dest: %d, tag: %d}" % (self.dest, self.tag)
class MPISendWait(Op):
......@@ -233,15 +210,11 @@ class MPISendWait(Op):
@note: Non-differentiable.
"""
__props__ = ("tag",)
def __init__(self, tag):
self.tag = tag
def __eq__(self, other):
return type(self) == type(other) and self.tag == other.tag
def __hash__(self):
return hash((type(self), self.tag))
def make_node(self, request, data):
return gof.Apply(self, [request, data],
[theano.Variable(Generic())])
......@@ -251,9 +224,6 @@ class MPISendWait(Op):
request.wait()
out[0][0] = True
def __str__(self):
return "MPISendWait"
def isend(var, dest, tag):
"""
......
......@@ -136,11 +136,8 @@ class AllocDiag(Op):
"""
Allocates a square matrix with the given vector as its diagonal.
"""
def __eq__(self, other):
return type(self) == type(other)
def __hash__(self):
return hash(type(self))
__props__ = ()
def make_node(self, _x):
x = as_tensor_variable(_x)
......@@ -170,17 +167,13 @@ class ExtractDiag(Op):
:note: work on the GPU.
"""
__props__ = ("view",)
def __init__(self, view=False):
self.view = view
if self.view:
self.view_map = {0: [0]}
def __eq__(self, other):
return type(self) == type(other) and self.view == other.view
def __hash__(self):
return hash(type(self)) ^ hash(self.view)
def make_node(self, _x):
if not isinstance(_x, theano.Variable):
x = as_tensor_variable(_x)
......@@ -262,6 +255,9 @@ class Det(Op):
"""Matrix determinant
Input should be a square matrix
"""
__props__ = ()
def make_node(self, x):
x = as_tensor_variable(x)
assert x.ndim == 2
......@@ -640,14 +636,8 @@ def svd(a, full_matrices=1, compute_uv=1):
class lstsq(Op):
def __eq__(self, other):
return type(self) == type(other)
def __hash__(self):
return hash(type(self))
def __str__(self):
return self.__class__.__name__
__props__ = ()
def make_node(self, x, y, rcond):
x = theano.tensor.as_tensor_variable(x)
......
......@@ -651,14 +651,11 @@ class MakeVector(T.Op):
into the graph. Should work with 0 inputs. The constant_folding
optimization will remove it.
"""
def __init__(self, dtype='int64'):
self.dtype = dtype
def __eq__(self, other):
return type(self) == type(other) and self.dtype == other.dtype
__props__ = ("dtype",)
def __hash__(self):
return hash(type(self)) ^ hash(self.dtype)
def __init__(self, dtype='int64'):
self.dtype = dtype
def make_node(self, *inputs):
inputs = list(map(T.as_tensor_variable, inputs))
......@@ -688,9 +685,6 @@ class MakeVector(T.Op):
otype = T.TensorType(broadcastable=(bcastable,), dtype=dtype)
return T.Apply(self, inputs, [otype()])
def __str__(self):
return self.__class__.__name__
def perform(self, node, inputs, out_):
out, = out_
# not calling theano._asarray as optimization
......
......@@ -102,6 +102,7 @@ class RandomFunction(gof.Op):
"""Op that draws random numbers from a numpy.random.RandomState object
"""
__props__ = ("fn", "outtype", "inplace", "ndim_added")
def __init__(self, fn, outtype, inplace=False, ndim_added=0):
"""
......@@ -129,17 +130,6 @@ class RandomFunction(gof.Op):
"""
self.__setstate__([fn, outtype, inplace, ndim_added])
def __eq__(self, other):
return type(self) == type(other) \
and self.fn == other.fn\
and self.outtype == other.outtype\
and self.inplace == other.inplace\
and self.ndim_added == other.ndim_added
def __hash__(self):
return (hash(type(self)) ^ hash(self.fn) ^ hash(self.outtype) ^
hash(self.inplace) ^ hash(self.ndim_added))
def __getstate__(self):
return self.state
......
......@@ -339,6 +339,8 @@ class Expm(Op):
"""Compute the matrix exponential of a square array
"""
__props__ = ()
def make_node(self, A):
assert imported_scipy, (
"Scipy not available. Scipy is needed for the Expm op")
......@@ -366,6 +368,8 @@ class ExpmGrad(Op):
"""Gradient of the matrix exponential of a square array.
"""
__props__ = ()
def make_node(self, A, gw):
assert imported_scipy, (
"Scipy not available. Scipy is needed for the Expm op")
......
......@@ -7,17 +7,13 @@ class SortOp(theano.Op):
"""
This class is a wrapper for numpy sort function
"""
__props__ = ("kind", "order")
def __init__(self, kind, order=None):
self.kind = kind
self.order = order
def __eq__(self, other):
return (type(self) == type(other) and self.order == other.order and
self.kind == other.kind)
def __hash__(self):
return hash(type(self)) ^ hash(self.order) ^ hash(self.kind)
def __str__(self):
return self.__class__.__name__ + "{%s, %s}" % (self.kind,
str(self.order))
......@@ -132,18 +128,13 @@ class ArgSortOp(theano.Op):
"""
This class is a wrapper for numpy argsort function
"""
__props__ = ("kind", "order")
def __init__(self, kind, order=None):
self.kind = kind
self.order = order
def __eq__(self, other):
return (type(self) == type(other) and
self.order == other.order and
self.kind == other.kind)
def __hash__(self):
return hash(type(self)) ^ hash(self.order) ^ hash(self.kind)
def __str__(self):
return (self.__class__.__name__ +
"{%s, %s}" % (self.kind, str(self.order)))
......
......@@ -292,6 +292,7 @@ class Subtensor(Op):
check_input = False
view_map = {0: [0]}
_f16_ok = True
__props__ = ("idx_list",)
@staticmethod
def collapse(idxs, cond):
......@@ -567,9 +568,6 @@ class Subtensor(Op):
return rval
def __eq__(self, other):
return type(self) == type(other) and self.idx_list == other.idx_list
def __hash__(self):
# TODO: optimize by cache this hash value
msg = []
......@@ -1174,6 +1172,7 @@ class IncSubtensor(Op):
"""
check_input = False
__props__ = ("idx_list", "inplace", "set_instead_of_inc")
def __init__(self, idx_list, inplace=False, set_instead_of_inc=False,
destroyhandler_tolerate_aliased=None):
......@@ -1187,12 +1186,6 @@ class IncSubtensor(Op):
destroyhandler_tolerate_aliased)
self.set_instead_of_inc = set_instead_of_inc
def __eq__(self, other):
return (type(self) == type(other) and
self.idx_list == other.idx_list and
self.inplace == other.inplace and
self.set_instead_of_inc == other.set_instead_of_inc)
def __hash__(self):
msg = []
for entry in self.idx_list:
......@@ -2033,15 +2026,7 @@ class AdvancedSubtensor(Op):
# Should be used by __getitem__ and __getslice__, as follow:
# AdvancedSubtensor()(self, *args),
# if args contains and advanced indexing pattern
def __eq__(self, other):
return self.__class__ == other.__class__
def __hash__(self):
return hash(self.__class__)
def __str__(self):
return self.__class__.__name__
__props__ = ()
def make_node(self, x, *index):
x = theano.tensor.as_tensor_variable(x)
......@@ -2116,6 +2101,7 @@ class AdvancedIncSubtensor(Op):
op.
"""
__props__ = ("inplace", "set_instead_of_inc")
def __init__(self, inplace=False, set_instead_of_inc=False):
self.inplace = inplace
......@@ -2129,14 +2115,6 @@ class AdvancedIncSubtensor(Op):
self.allow_legacy_perform = False
def __hash__(self):
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 "%s{%s, %s}" % (self.__class__.__name__,
"inplace=" + str(self.inplace),
......
......@@ -21,6 +21,9 @@ def as_int_none_variable(x):
class MakeSlice(Op):
__props__ = ()
def make_node(self, slc, stop=None, step=None):
# We need to accept and handle in make_node inputs the node
# inputs to allow redoing a new op elsewhere in the graph by
......@@ -39,15 +42,6 @@ class MakeSlice(Op):
out, = out_
out[0] = slice(*inp)
def __str__(self):
return self.__class__.__name__
def __eq__(self, other):
return type(self) == type(other)
def __hash__(self):
return hash(type(self))
def grad(self, inputs, grads):
return [DisconnectedType()() for i in inputs]
......
......@@ -342,7 +342,7 @@ def test_scan_debugprint2():
| |Subtensor{int64} [@J] ''
| |Shape [@K] ''
| | |Subtensor{int64::} [@L] ''
| | |ARange [@M] ''
| | |ARange{dtype='int16'} [@M] ''
| | | |TensorConstant{0} [@N]
| | | |TensorConstant{10000} [@O]
| | | |TensorConstant{1} [@P]
......@@ -425,7 +425,7 @@ def test_scan_debugprint3():
| |Subtensor{int64} [@J] ''
| |Shape [@K] ''
| | |Subtensor{int64::} [@L] ''
| | |ARange [@M] ''
| | |ARange{dtype='int8'} [@M] ''
| | | |TensorConstant{0} [@N]
| | | |TensorConstant{10} [@O]
| | | |TensorConstant{1} [@P]
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论