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

Merge pull request #3148 from harlouci/props_sparse

Props sparse
...@@ -822,15 +822,11 @@ csm_grad = CSMGrad ...@@ -822,15 +822,11 @@ csm_grad = CSMGrad
class Cast(gof.op.Op): class Cast(gof.op.Op):
# See doc in instance of this Op or function after this class definition. # See doc in instance of this Op or function after this class definition.
__props__ = ("out_type",)
def __init__(self, out_type): def __init__(self, out_type):
self.out_type = out_type self.out_type = out_type
def __eq__(self, other):
return (type(self) == type(other)) and self.out_type == other.out_type
def __hash__(self):
return hash(type(self)) ^ hash(self.out_type)
def make_node(self, x): def make_node(self, x):
x = as_sparse_variable(x) x = as_sparse_variable(x)
assert x.format in ["csr", "csc"] assert x.format in ["csr", "csc"]
...@@ -900,16 +896,11 @@ def cast(variable, dtype): ...@@ -900,16 +896,11 @@ def cast(variable, dtype):
class DenseFromSparse(gof.op.Op): class DenseFromSparse(gof.op.Op):
# See doc in instance of this Op or function after this class definition. # See doc in instance of this Op or function after this class definition.
__props__ = () # We don't put sparse_grad in the props.
def __init__(self, structured=True): def __init__(self, structured=True):
self.sparse_grad = structured self.sparse_grad = structured
def __eq__(self, other):
return ((type(self) == type(other)) and
(self.sparse_grad == other.sparse_grad))
def __hash__(self):
return hash(type(self)) ^ hash(self.sparse_grad)
def __str__(self): def __str__(self):
return "%s{structured_grad=%s}" % ( return "%s{structured_grad=%s}" % (
self.__class__.__name__, self.__class__.__name__,
...@@ -973,14 +964,11 @@ dense_from_sparse = DenseFromSparse() ...@@ -973,14 +964,11 @@ dense_from_sparse = DenseFromSparse()
class SparseFromDense(gof.op.Op): class SparseFromDense(gof.op.Op):
def __init__(self, format):
self.format = format
def __eq__(self, other): __props__ = ()
return type(self) == type(other) and self.format == other.format
def __hash__(self): def __init__(self, format):
return 982374 ^ hash(self.format) ^ hash(DenseFromSparse) self.format = format
def __str__(self): def __str__(self):
return "%s{%s}" % ( return "%s{%s}" % (
...@@ -1036,11 +1024,7 @@ csc_from_dense = SparseFromDense('csc') ...@@ -1036,11 +1024,7 @@ csc_from_dense = SparseFromDense('csc')
# Indexing # Indexing
class GetItemList(gof.op.Op): class GetItemList(gof.op.Op):
def __eq__(self, other): __props__ = ()
return (type(self) == type(other))
def __hash__(self):
return hash(type(self))
def infer_shape(self, node, shapes): def infer_shape(self, node, shapes):
return [(shapes[1][0], shapes[0][1])] return [(shapes[1][0], shapes[0][1])]
...@@ -1068,9 +1052,6 @@ class GetItemList(gof.op.Op): ...@@ -1068,9 +1052,6 @@ class GetItemList(gof.op.Op):
return [GetItemListGrad(self)(x, indices, gout), return [GetItemListGrad(self)(x, indices, gout),
grad_undefined(self, 1, indices, "No gradient for this input")] grad_undefined(self, 1, indices, "No gradient for this input")]
def __str__(self):
return self.__class__.__name__
get_item_list = GetItemList() get_item_list = GetItemList()
"""Select row of sparse matrix, """Select row of sparse matrix,
returning them as a new sparse matrix. returning them as a new sparse matrix.
...@@ -1084,11 +1065,7 @@ returning them as a new sparse matrix. ...@@ -1084,11 +1065,7 @@ returning them as a new sparse matrix.
class GetItemListGrad(gof.op.Op): class GetItemListGrad(gof.op.Op):
def __eq__(self, other): __props__ = ()
return (type(self) == type(other))
def __hash__(self):
return hash(type(self))
def infer_shape(self, node, shapes): def infer_shape(self, node, shapes):
return [(shapes[0])] return [(shapes[0])]
...@@ -1126,19 +1103,12 @@ class GetItemListGrad(gof.op.Op): ...@@ -1126,19 +1103,12 @@ class GetItemListGrad(gof.op.Op):
out[0] = y out[0] = y
def __str__(self):
return self.__class__.__name__
get_item_list_grad = GetItemListGrad() get_item_list_grad = GetItemListGrad()
class GetItem2Lists(gof.op.Op): class GetItem2Lists(gof.op.Op):
def __eq__(self, other): __props__ = ()
return (type(self) == type(other))
def __hash__(self):
return hash(type(self))
def make_node(self, x, ind1, ind2): def make_node(self, x, ind1, ind2):
x = as_sparse_variable(x) x = as_sparse_variable(x)
...@@ -1167,9 +1137,6 @@ class GetItem2Lists(gof.op.Op): ...@@ -1167,9 +1137,6 @@ class GetItem2Lists(gof.op.Op):
grad_undefined(self, 1, ind1, "No gradient for this input"), grad_undefined(self, 1, ind1, "No gradient for this input"),
grad_undefined(self, 1, ind2, "No gradient for this input")] grad_undefined(self, 1, ind2, "No gradient for this input")]
def __str__(self):
return self.__class__.__name__
get_item_2lists = GetItem2Lists() get_item_2lists = GetItem2Lists()
"""Select elements of sparse matrix, returning them in a vector. """Select elements of sparse matrix, returning them in a vector.
...@@ -1184,11 +1151,7 @@ get_item_2lists = GetItem2Lists() ...@@ -1184,11 +1151,7 @@ get_item_2lists = GetItem2Lists()
class GetItem2ListsGrad(gof.op.Op): class GetItem2ListsGrad(gof.op.Op):
def __eq__(self, other): __props__ = ()
return (type(self) == type(other))
def __hash__(self):
return hash(type(self))
def infer_shape(self, node, shapes): def infer_shape(self, node, shapes):
return [(shapes[0])] return [(shapes[0])]
...@@ -1224,19 +1187,13 @@ class GetItem2ListsGrad(gof.op.Op): ...@@ -1224,19 +1187,13 @@ class GetItem2ListsGrad(gof.op.Op):
out[0] = y out[0] = y
def __str__(self):
return self.__class__.__name__
get_item_2lists_grad = GetItem2ListsGrad() get_item_2lists_grad = GetItem2ListsGrad()
class GetItem2d(gof.op.Op): class GetItem2d(gof.op.Op):
# See doc in instance of this Op or function after this class definition. # See doc in instance of this Op or function after this class definition.
def __eq__(self, other):
return (type(self) == type(other))
def __hash__(self): __props__ = ()
return hash(type(self))
# Fred:Too complicated for now. If you need it, look at # Fred:Too complicated for now. If you need it, look at
# the Subtensor.infer_shape. # the Subtensor.infer_shape.
...@@ -1322,9 +1279,6 @@ class GetItem2d(gof.op.Op): ...@@ -1322,9 +1279,6 @@ class GetItem2d(gof.op.Op):
assert _is_sparse(x) assert _is_sparse(x)
out[0] = x[start1:stop1:step1, start2:stop2:step2] out[0] = x[start1:stop1:step1, start2:stop2:step2]
def __str__(self):
return self.__class__.__name__
get_item_2d = GetItem2d() get_item_2d = GetItem2d()
"""Implement a subtensor of sparse variable, returning a """Implement a subtensor of sparse variable, returning a
sparse matrix. sparse matrix.
...@@ -1356,11 +1310,7 @@ when sparse vectors are supported. ...@@ -1356,11 +1310,7 @@ when sparse vectors are supported.
class GetItemScalar(gof.op.Op): class GetItemScalar(gof.op.Op):
# See doc in instance of this Op or function after this class definition. # See doc in instance of this Op or function after this class definition.
def __eq__(self, other): __props__ = ()
return (type(self) == type(other))
def __hash__(self):
return hash(type(self))
def infer_shape(self, node, shapes): def infer_shape(self, node, shapes):
return [()] return [()]
...@@ -1396,9 +1346,6 @@ class GetItemScalar(gof.op.Op): ...@@ -1396,9 +1346,6 @@ class GetItemScalar(gof.op.Op):
assert _is_sparse(x) assert _is_sparse(x)
out[0] = theano._asarray(x[ind1, ind2], x.dtype) out[0] = theano._asarray(x[ind1, ind2], x.dtype)
def __str__(self):
return self.__class__.__name__
get_item_scalar = GetItemScalar() get_item_scalar = GetItemScalar()
"""Implement a subtensor of a sparse variable that takes """Implement a subtensor of a sparse variable that takes
two scalars as index and returns a scalar. two scalars as index and returns a scalar.
...@@ -1422,12 +1369,7 @@ class Transpose(gof.op.Op): ...@@ -1422,12 +1369,7 @@ class Transpose(gof.op.Op):
format_map = {'csr': 'csc', format_map = {'csr': 'csc',
'csc': 'csr'} 'csc': 'csr'}
__props__ = ()
def __eq__(self, other):
return (type(self) == type(other))
def __hash__(self):
return hash(type(self))
def __str__(self): def __str__(self):
return "Sparse" + self.__class__.__name__ return "Sparse" + self.__class__.__name__
...@@ -1471,11 +1413,8 @@ transpose = Transpose() ...@@ -1471,11 +1413,8 @@ transpose = Transpose()
class Neg(gof.op.Op): class Neg(gof.op.Op):
# See doc in instance of this Op or function after this class definition. # See doc in instance of this Op or function after this class definition.
def __eq__(self, other):
return (type(self) == type(other))
def __hash__(self): __props__ = ()
return hash(type(self))
def __str__(self): def __str__(self):
return "Sparse" + self.__class__.__name__ return "Sparse" + self.__class__.__name__
...@@ -1524,11 +1463,7 @@ class ColScaleCSC(gof.op.Op): ...@@ -1524,11 +1463,7 @@ class ColScaleCSC(gof.op.Op):
# :note: The grad implemented is structured. # :note: The grad implemented is structured.
def __eq__(self, other): __props__ = ()
return type(self) == type(other)
def __hash__(self):
return hash(type(self))
def make_node(self, x, s): def make_node(self, x, s):
if x.format != 'csc': if x.format != 'csc':
...@@ -1557,9 +1492,6 @@ class ColScaleCSC(gof.op.Op): ...@@ -1557,9 +1492,6 @@ class ColScaleCSC(gof.op.Op):
def infer_shape(self, node, ins_shapes): def infer_shape(self, node, ins_shapes):
return [ins_shapes[0]] return [ins_shapes[0]]
def __str__(self):
return self.__class__.__name__
class RowScaleCSC(gof.op.Op): class RowScaleCSC(gof.op.Op):
# Scale each row of a sparse matrix by the corresponding element of # Scale each row of a sparse matrix by the corresponding element of
...@@ -1576,12 +1508,7 @@ class RowScaleCSC(gof.op.Op): ...@@ -1576,12 +1508,7 @@ class RowScaleCSC(gof.op.Op):
# :note: The grad implemented is structured. # :note: The grad implemented is structured.
view_map = {0: [0]} view_map = {0: [0]}
__props__ = ()
def __eq__(self, other):
return type(self) == type(other)
def __hash__(self):
return hash(type(self))
def make_node(self, x, s): def make_node(self, x, s):
x = as_sparse_variable(x) x = as_sparse_variable(x)
...@@ -1614,9 +1541,6 @@ class RowScaleCSC(gof.op.Op): ...@@ -1614,9 +1541,6 @@ class RowScaleCSC(gof.op.Op):
def infer_shape(self, node, ins_shapes): def infer_shape(self, node, ins_shapes):
return [ins_shapes[0]] return [ins_shapes[0]]
def __str__(self):
return self.__class__.__name__
def col_scale(x, s): def col_scale(x, s):
"""Scale each columns of a sparse matrix by the corresponding """Scale each columns of a sparse matrix by the corresponding
...@@ -1660,6 +1584,14 @@ def row_scale(x, s): ...@@ -1660,6 +1584,14 @@ def row_scale(x, s):
class SpSum(gof.op.Op): class SpSum(gof.op.Op):
# See doc in instance of this Op or function after this class definition. # See doc in instance of this Op or function after this class definition.
__props__ = ("axis",)
# WARNING: judgement call...
# We are not using the structured in the comparison or hashing
# because it doesn't change the perform method therefore, we
# *do* want Sums with different structured values to be merged
# by the merge optimization and this requires them to compare equal.
def __init__(self, axis=None, sparse_grad=True): def __init__(self, axis=None, sparse_grad=True):
super(SpSum, self).__init__() super(SpSum, self).__init__()
self.axis = axis self.axis = axis
...@@ -1667,22 +1599,6 @@ class SpSum(gof.op.Op): ...@@ -1667,22 +1599,6 @@ class SpSum(gof.op.Op):
if self.axis not in (None, 0, 1): if self.axis not in (None, 0, 1):
raise ValueError('Illegal value for self.axis.') raise ValueError('Illegal value for self.axis.')
def __eq__(self, other):
# WARNING: judgement call...
# We are not using the structured in the comparison or hashing
# because it doesn't change the perform method therefore, we
# *do* want Sums with different structured values to be merged
# by the merge optimization and this requires them to compare equal.
return type(self) == type(other) and self.axis == other.axis
def __hash__(self):
# WARNING: judgement call...
# We are not using the structured in the comparison or hashing
# because it doesn't change the perform method therefore, we
# *do* want Sums with different structured values to be merged
# by the merge optimization and this requires them to compare equal.
return 76324 ^ hash(type(self)) ^ hash(self.axis)
def make_node(self, x): def make_node(self, x):
x = as_sparse_variable(x) x = as_sparse_variable(x)
assert x.format in ["csr", "csc"] assert x.format in ["csr", "csc"]
...@@ -1773,11 +1689,7 @@ def sp_sum(x, axis=None, sparse_grad=False): ...@@ -1773,11 +1689,7 @@ def sp_sum(x, axis=None, sparse_grad=False):
class Diag(gof.op.Op): class Diag(gof.op.Op):
# See doc in instance of this Op or function after this class definition. # See doc in instance of this Op or function after this class definition.
def __eq__(self, other): __props__ = ()
return (type(self) == type(other))
def __hash__(self):
return hash(type(self))
def make_node(self, x): def make_node(self, x):
x = as_sparse_variable(x) x = as_sparse_variable(x)
...@@ -1801,8 +1713,6 @@ class Diag(gof.op.Op): ...@@ -1801,8 +1713,6 @@ class Diag(gof.op.Op):
def infer_shape(self, nodes, shapes): def infer_shape(self, nodes, shapes):
return [(tensor.minimum(*shapes[0]), )] return [(tensor.minimum(*shapes[0]), )]
def __str__(self):
return self.__class__.__name__
diag = Diag() diag = Diag()
"""Extract the diagonal of a square sparse matrix as a dense vector. """Extract the diagonal of a square sparse matrix as a dense vector.
...@@ -1819,11 +1729,8 @@ diag = Diag() ...@@ -1819,11 +1729,8 @@ diag = Diag()
class SquareDiagonal(gof.op.Op): class SquareDiagonal(gof.op.Op):
# See doc in instance of this Op or function after this class definition. # See doc in instance of this Op or function after this class definition.
def __eq__(self, other):
return type(self) == type(other)
def __hash__(self): __props__ = ()
return hash(type(self))
def make_node(self, diag): def make_node(self, diag):
diag = tensor.as_tensor_variable(diag) diag = tensor.as_tensor_variable(diag)
...@@ -1852,8 +1759,6 @@ class SquareDiagonal(gof.op.Op): ...@@ -1852,8 +1759,6 @@ class SquareDiagonal(gof.op.Op):
def infer_shape(self, nodes, shapes): def infer_shape(self, nodes, shapes):
return [(shapes[0][0], shapes[0][0])] return [(shapes[0][0], shapes[0][0])]
def __str__(self):
return self.__class__.__name__
square_diagonal = SquareDiagonal() square_diagonal = SquareDiagonal()
"""Return a square sparse (csc) matrix whose diagonal """Return a square sparse (csc) matrix whose diagonal
is given by the dense vector argument. is given by the dense vector argument.
...@@ -1868,17 +1773,13 @@ is given by the dense vector argument. ...@@ -1868,17 +1773,13 @@ is given by the dense vector argument.
class EnsureSortedIndices(gof.op.Op): class EnsureSortedIndices(gof.op.Op):
# See doc in instance of this Op or function after this class definition. # See doc in instance of this Op or function after this class definition.
__props__ = ("inplace",)
def __init__(self, inplace): def __init__(self, inplace):
self.inplace = inplace self.inplace = inplace
if self.inplace: if self.inplace:
self.view_map = {0: [0]} self.view_map = {0: [0]}
def __eq__(self, other):
return type(self) == type(other)
def __hash__(self):
return hash(type(self))
def make_node(self, x): def make_node(self, x):
x = as_sparse_variable(x) x = as_sparse_variable(x)
assert x.format in ["csr", "csc"] assert x.format in ["csr", "csc"]
...@@ -1941,14 +1842,7 @@ def clean(x): ...@@ -1941,14 +1842,7 @@ def clean(x):
class AddSS(gof.op.Op): class AddSS(gof.op.Op):
# add(sparse, sparse). # add(sparse, sparse).
# see the doc of add() for more detail. # see the doc of add() for more detail.
def __eq__(self, other): __props__ = ()
return (type(self) == type(other))
def __hash__(self):
return hash(type(self))
def __str__(self):
return self.__class__.__name__
def make_node(self, x, y): def make_node(self, x, y):
x, y = map(as_sparse_variable, [x, y]) x, y = map(as_sparse_variable, [x, y])
...@@ -1982,11 +1876,7 @@ add_s_s = AddSS() ...@@ -1982,11 +1876,7 @@ add_s_s = AddSS()
class AddSSData(gof.op.Op): class AddSSData(gof.op.Op):
# See doc in instance of this Op or function after this class definition. # See doc in instance of this Op or function after this class definition.
def __eq__(self, other): __props__ = ()
return (type(self) == type(other))
def __hash__(self):
return hash(type(self))
def make_node(self, x, y): def make_node(self, x, y):
x, y = map(as_sparse_variable, [x, y]) x, y = map(as_sparse_variable, [x, y])
...@@ -2020,8 +1910,6 @@ class AddSSData(gof.op.Op): ...@@ -2020,8 +1910,6 @@ class AddSSData(gof.op.Op):
def infer_shape(self, node, ins_shapes): def infer_shape(self, node, ins_shapes):
return [ins_shapes[0]] return [ins_shapes[0]]
def __str__(self):
return self.__class__.__name__
add_s_s_data = AddSSData() add_s_s_data = AddSSData()
"""Add two sparse matrices assuming they have the same sparsity """Add two sparse matrices assuming they have the same sparsity
pattern. pattern.
...@@ -2041,17 +1929,7 @@ pattern. ...@@ -2041,17 +1929,7 @@ pattern.
class AddSD(gof.op.Op): class AddSD(gof.op.Op):
# add(sparse, sparse). # add(sparse, sparse).
# see the doc of add() for more detail. # see the doc of add() for more detail.
def __init__(self, *args, **kwargs): __props__ = ()
gof.Op.__init__(self, *args, **kwargs)
def __eq__(self, other):
return (type(self) == type(other))
def __hash__(self):
return hash(type(self))
def __str__(self):
return self.__class__.__name__
def make_node(self, x, y): def make_node(self, x, y):
x, y = as_sparse_variable(x), tensor.as_tensor_variable(y) x, y = as_sparse_variable(x), tensor.as_tensor_variable(y)
...@@ -2090,11 +1968,8 @@ add_s_d = AddSD() ...@@ -2090,11 +1968,8 @@ add_s_d = AddSD()
class StructuredAddSV(gof.op.Op): class StructuredAddSV(gof.op.Op):
def __eq__(self, other):
return (type(self) == type(other))
def __hash__(self): __props__ = ()
return hash(type(self))
def make_node(self, x, y): def make_node(self, x, y):
x = as_sparse_variable(x) x = as_sparse_variable(x)
...@@ -2127,8 +2002,6 @@ class StructuredAddSV(gof.op.Op): ...@@ -2127,8 +2002,6 @@ class StructuredAddSV(gof.op.Op):
def infer_shape(self, node, ins_shapes): def infer_shape(self, node, ins_shapes):
return [ins_shapes[0]] return [ins_shapes[0]]
def __str__(self):
return self.__class__.__name__
structured_add_s_v = StructuredAddSV() structured_add_s_v = StructuredAddSV()
"""Structured addition of a sparse matrix and a dense vector. """Structured addition of a sparse matrix and a dense vector.
The elements of the vector are only added to the corresponding The elements of the vector are only added to the corresponding
...@@ -2206,14 +2079,7 @@ def sub(x, y): ...@@ -2206,14 +2079,7 @@ def sub(x, y):
class MulSS(gof.op.Op): class MulSS(gof.op.Op):
# mul(sparse, sparse) # mul(sparse, sparse)
# See the doc of mul() for more detail # See the doc of mul() for more detail
def __eq__(self, other): __props__ = ()
return (type(self) == type(other))
def __hash__(self):
return hash(type(self))
def __str__(self):
return self.__class__.__name__
def make_node(self, x, y): def make_node(self, x, y):
x, y = as_sparse_variable(x), as_sparse_variable(y) x, y = as_sparse_variable(x), as_sparse_variable(y)
...@@ -2249,14 +2115,7 @@ mul_s_s = MulSS() ...@@ -2249,14 +2115,7 @@ mul_s_s = MulSS()
class MulSD(gof.op.Op): class MulSD(gof.op.Op):
# mul(sparse, dense) # mul(sparse, dense)
# See the doc of mul() for more detail # See the doc of mul() for more detail
def __eq__(self, other): __props__ = ()
return (type(self) == type(other))
def __hash__(self):
return hash(type(self))
def __str__(self):
return self.__class__.__name__
def make_node(self, x, y): def make_node(self, x, y):
x, y = as_sparse_variable(x), tensor.as_tensor_variable(y) x, y = as_sparse_variable(x), tensor.as_tensor_variable(y)
...@@ -2344,11 +2203,8 @@ mul_s_d = MulSD() ...@@ -2344,11 +2203,8 @@ mul_s_d = MulSD()
class MulSV(gof.op.Op): class MulSV(gof.op.Op):
def __eq__(self, other):
return (type(self) == type(other))
def __hash__(self): __props__ = ()
return hash(type(self))
def make_node(self, x, y): def make_node(self, x, y):
x = as_sparse_variable(x) x = as_sparse_variable(x)
...@@ -2392,8 +2248,6 @@ class MulSV(gof.op.Op): ...@@ -2392,8 +2248,6 @@ class MulSV(gof.op.Op):
def infer_shape(self, node, ins_shapes): def infer_shape(self, node, ins_shapes):
return [ins_shapes[0]] return [ins_shapes[0]]
def __str__(self):
return self.__class__.__name__
mul_s_v = MulSV() mul_s_v = MulSV()
"""Multiplication of sparse matrix by a broadcasted dense vector element wise. """Multiplication of sparse matrix by a broadcasted dense vector element wise.
...@@ -2459,17 +2313,12 @@ class __ComparisonOpSS(gof.op.Op): ...@@ -2459,17 +2313,12 @@ class __ComparisonOpSS(gof.op.Op):
:return: Comparison(x,y) :return: Comparison(x,y)
""" """
__props__ = ()
# Function to override # Function to override
def comparison(self, x, y): def comparison(self, x, y):
raise NotImplementedError() raise NotImplementedError()
def __eq__(self, other):
return (type(self) == type(other))
def __hash__(self):
return hash(type(self))
def make_node(self, x, y): def make_node(self, x, y):
x = as_sparse_variable(x) x = as_sparse_variable(x)
y = as_sparse_variable(y) y = as_sparse_variable(y)
...@@ -2491,9 +2340,6 @@ class __ComparisonOpSS(gof.op.Op): ...@@ -2491,9 +2340,6 @@ class __ComparisonOpSS(gof.op.Op):
def infer_shape(self, node, ins_shapes): def infer_shape(self, node, ins_shapes):
return [ins_shapes[0]] return [ins_shapes[0]]
def __str__(self):
return self.__class__.__name__
class __ComparisonOpSD(gof.op.Op): class __ComparisonOpSD(gof.op.Op):
""" """
...@@ -2505,17 +2351,12 @@ class __ComparisonOpSD(gof.op.Op): ...@@ -2505,17 +2351,12 @@ class __ComparisonOpSD(gof.op.Op):
:return: Comparison(x,y) :return: Comparison(x,y)
""" """
__props__ = ()
# Function to override # Function to override
def comparison(self, x, y): def comparison(self, x, y):
raise NotImplementedError() raise NotImplementedError()
def __eq__(self, other):
return (type(self) == type(other))
def __hash__(self):
return hash(type(self))
def make_node(self, x, y): def make_node(self, x, y):
x, y = as_sparse_variable(x), tensor.as_tensor_variable(y) x, y = as_sparse_variable(x), tensor.as_tensor_variable(y)
...@@ -2536,9 +2377,6 @@ class __ComparisonOpSD(gof.op.Op): ...@@ -2536,9 +2377,6 @@ class __ComparisonOpSD(gof.op.Op):
def infer_shape(self, node, ins_shapes): def infer_shape(self, node, ins_shapes):
return [ins_shapes[0]] return [ins_shapes[0]]
def __str__(self):
return self.__class__.__name__
def __ComparisonSwitch(SS, SD, DS): def __ComparisonSwitch(SS, SD, DS):
""" """
...@@ -2735,6 +2573,8 @@ ge = __ComparisonSwitch(greater_equal_s_s, greater_equal_s_d, ...@@ -2735,6 +2573,8 @@ ge = __ComparisonSwitch(greater_equal_s_s, greater_equal_s_d,
class HStack(gof.op.Op): class HStack(gof.op.Op):
# See doc in instance of this Op or function after this class definition. # See doc in instance of this Op or function after this class definition.
__props__ = ("format", "dtype")
def __init__(self, format=None, dtype=None): def __init__(self, format=None, dtype=None):
if format is None: if format is None:
self.format = 'csc' self.format = 'csc'
...@@ -2745,14 +2585,6 @@ class HStack(gof.op.Op): ...@@ -2745,14 +2585,6 @@ class HStack(gof.op.Op):
raise ValueError('The output dtype must be specified.') raise ValueError('The output dtype must be specified.')
self.dtype = dtype self.dtype = dtype
def __eq__(self, other):
return (type(self) == type(other) and
self.format == other.format and
self.dtype == other.dtype)
def __hash__(self):
return hash(type(self)) ^ hash(self.format) ^ hash(self.dtype)
def make_node(self, *mat): def make_node(self, *mat):
if not mat: if not mat:
raise ValueError('Cannot join an empty list of sparses.') raise ValueError('Cannot join an empty list of sparses.')
...@@ -2901,18 +2733,13 @@ def vstack(blocks, format=None, dtype=None): ...@@ -2901,18 +2733,13 @@ def vstack(blocks, format=None, dtype=None):
class Remove0(gof.Op): class Remove0(gof.Op):
# See doc in instance of this Op or a function after the class definition. # See doc in instance of this Op or a function after the class definition.
def __init__(self, inplace=False, *args, **kwargs): __props__ = ("inplace",)
gof.Op.__init__(self, *args, **kwargs)
def __init__(self, inplace=False):
self.inplace = inplace self.inplace = inplace
if self.inplace: if self.inplace:
self.destroy_map = {0: [0]} self.destroy_map = {0: [0]}
def __eq__(self, other):
return type(self) == type(other) and self.inplace == other.inplace
def __hash__(self):
return 64153 ^ hash(type(self)) ^ hash(self.inplace)
def __str__(self): def __str__(self):
l = [] l = []
if self.inplace: if self.inplace:
...@@ -3180,22 +3007,15 @@ class TrueDot(gof.op.Op): ...@@ -3180,22 +3007,15 @@ class TrueDot(gof.op.Op):
# TODO # TODO
# Simplify code by splitting into DotSS and DotSD. # Simplify code by splitting into DotSS and DotSD.
__props__ = ()
# The grad_preserves_dense attribute doesn't change the
# execution behavior. To let the optimizer merge nodes with
# different values of this attribute we shouldn't compare it
# here.
def __init__(self, grad_preserves_dense=True): def __init__(self, grad_preserves_dense=True):
self.grad_preserves_dense = grad_preserves_dense self.grad_preserves_dense = grad_preserves_dense
def __eq__(self, other):
# The grad_preserves_dense attribute doesn't change the
# execution behavior. To let the optimizer merge nodes with
# different values of this attribute we shouldn't compare it
# here.
return type(self) == type(other)
def __hash__(self):
return hash(type(self))
def __ne__(self, other):
return not (self == other)
def make_node(self, x, y): def make_node(self, x, y):
# NOTE # NOTE
# Because of trickiness of implementing, # Because of trickiness of implementing,
...@@ -3270,9 +3090,6 @@ class TrueDot(gof.op.Op): ...@@ -3270,9 +3090,6 @@ class TrueDot(gof.op.Op):
def infer_shape(self, node, shapes): def infer_shape(self, node, shapes):
return [(shapes[0][0], shapes[1][1])] return [(shapes[0][0], shapes[1][1])]
def __str__(self):
return self.__class__.__name__
def true_dot(x, y, grad_preserves_dense=True): def true_dot(x, y, grad_preserves_dense=True):
""" """
...@@ -3317,14 +3134,7 @@ def true_dot(x, y, grad_preserves_dense=True): ...@@ -3317,14 +3134,7 @@ def true_dot(x, y, grad_preserves_dense=True):
# Dot # Dot
class StructuredDot(gof.Op): class StructuredDot(gof.Op):
# See doc in instance of this Op or function after this class definition. # See doc in instance of this Op or function after this class definition.
def __eq__(self, other): __props__ = ()
return (type(self) == type(other))
def __hash__(self):
return hash(type(self))
def __str__(self):
return self.__class__.__name__
def make_node(self, a, b): def make_node(self, a, b):
...@@ -3457,15 +3267,7 @@ class StructuredDotGradCSC(gof.Op): ...@@ -3457,15 +3267,7 @@ class StructuredDotGradCSC(gof.Op):
# :note: The grad implemented is structured. # :note: The grad implemented is structured.
# :note: a_* are the corresponding properties of a sparse # :note: a_* are the corresponding properties of a sparse
# matrix in csc format. # matrix in csc format.
__props__ = ()
def __eq__(self, other):
return (type(self) == type(other))
def __hash__(self):
return hash(type(self))
def __str__(self):
return self.__class__.__name__
def make_node(self, a_indices, a_indptr, b, g_ab): def make_node(self, a_indices, a_indptr, b, g_ab):
return gof.Apply(self, [a_indices, a_indptr, b, g_ab], return gof.Apply(self, [a_indices, a_indptr, b, g_ab],
...@@ -3595,15 +3397,7 @@ class StructuredDotGradCSR(gof.Op): ...@@ -3595,15 +3397,7 @@ class StructuredDotGradCSR(gof.Op):
# :note: The grad implemented is structured. # :note: The grad implemented is structured.
# :note: a_* are the corresponding properties of a sparse # :note: a_* are the corresponding properties of a sparse
# matrix in csr format. # matrix in csr format.
__props__ = ()
def __eq__(self, other):
return (type(self) == type(other))
def __hash__(self):
return hash(type(self))
def __str__(self):
return self.__class__.__name__
def make_node(self, a_indices, a_indptr, b, g_ab): def make_node(self, a_indices, a_indptr, b, g_ab):
return gof.Apply(self, [a_indices, a_indptr, b, g_ab], return gof.Apply(self, [a_indices, a_indptr, b, g_ab],
...@@ -3742,11 +3536,7 @@ def structured_dot_grad(sparse_A, dense_B, ga): ...@@ -3742,11 +3536,7 @@ def structured_dot_grad(sparse_A, dense_B, ga):
class SamplingDot(gof.op.Op): class SamplingDot(gof.op.Op):
# See doc in instance of this Op or function after this class definition. # See doc in instance of this Op or function after this class definition.
def __eq__(self, other): __props__ = ()
return type(self) == type(other)
def __hash__(self):
return hash(type(self))
def make_node(self, x, y, p): def make_node(self, x, y, p):
x = tensor.as_tensor_variable(x) x = tensor.as_tensor_variable(x)
...@@ -3790,8 +3580,6 @@ class SamplingDot(gof.op.Op): ...@@ -3790,8 +3580,6 @@ class SamplingDot(gof.op.Op):
def infer_shape(self, node, ins_shapes): def infer_shape(self, node, ins_shapes):
return [ins_shapes[2]] return [ins_shapes[2]]
def __str__(self):
return self.__class__.__name__
sampling_dot = SamplingDot() sampling_dot = SamplingDot()
"""Operand for calculating the dot product dot(`x`, `y`.T) = `z` when you """Operand for calculating the dot product dot(`x`, `y`.T) = `z` when you
only want to calculate a subset of `z`. only want to calculate a subset of `z`.
...@@ -3823,11 +3611,7 @@ than `dot` because SamplingDot requires `x` to be a `m`x`k` matrix while ...@@ -3823,11 +3611,7 @@ than `dot` because SamplingDot requires `x` to be a `m`x`k` matrix while
class Dot(gof.op.Op): class Dot(gof.op.Op):
# See doc in instance of this Op or function after this class definition. # See doc in instance of this Op or function after this class definition.
def __eq__(self, other): __props__ = ()
return type(self) == type(other)
def __hash__(self):
return hash(type(self))
def __str__(self): def __str__(self):
return "Sparse" + self.__class__.__name__ return "Sparse" + self.__class__.__name__
...@@ -3958,12 +3742,7 @@ class Usmm(gof.op.Op): ...@@ -3958,12 +3742,7 @@ class Usmm(gof.op.Op):
# See doc in instance of this Op or function after this class definition. # See doc in instance of this Op or function after this class definition.
# We don't implement the infer_shape as it is # We don't implement the infer_shape as it is
# inserted by optimization only. # inserted by optimization only.
__props__ = ()
def __eq__(self, other):
return type(self) == type(other)
def __hash__(self):
return hash(type(self))
def __str__(self): def __str__(self):
return 'Usmm{no_inplace}' return 'Usmm{no_inplace}'
...@@ -4033,14 +3812,7 @@ usmm = Usmm() ...@@ -4033,14 +3812,7 @@ usmm = Usmm()
class ConstructSparseFromList(gof.Op): class ConstructSparseFromList(gof.Op):
# See doc in instance of this Op or function after this class definition. # See doc in instance of this Op or function after this class definition.
def __hash__(self): __props__ = ()
return hash((type(self)))
def __eq__(self, other):
return (type(self) == type(other))
def __str__(self):
return self.__class__.__name__
def make_node(self, x, values, ilist): def make_node(self, x, values, ilist):
""" """
......
...@@ -65,6 +65,8 @@ class AddSD_ccode(gof.op.Op): ...@@ -65,6 +65,8 @@ class AddSD_ccode(gof.op.Op):
:note: The grad implemented is structured on `x`. :note: The grad implemented is structured on `x`.
""" """
__props__ = ("format", "inplace")
def __init__(self, format, inplace=False, *args, **kwargs): def __init__(self, format, inplace=False, *args, **kwargs):
gof.Op.__init__(self, *args, **kwargs) gof.Op.__init__(self, *args, **kwargs)
# Should we do inplace addition or not ? # Should we do inplace addition or not ?
...@@ -73,14 +75,6 @@ class AddSD_ccode(gof.op.Op): ...@@ -73,14 +75,6 @@ class AddSD_ccode(gof.op.Op):
if self.inplace: if self.inplace:
self.destroy_map = {0: [3]} self.destroy_map = {0: [3]}
def __eq__(self, other):
return (type(self) == type(other) and
self.inplace == other.inplace and
self.format == other.format)
def __hash__(self):
return hash(type(self)) ^ hash(self.inplace) ^ hash(self.format)
def __str__(self): def __str__(self):
inp = '' inp = ''
if self.inplace: if self.inplace:
...@@ -224,15 +218,7 @@ class StructuredDotCSC(gof.Op): ...@@ -224,15 +218,7 @@ class StructuredDotCSC(gof.Op):
:note: The grad implemented is structured. :note: The grad implemented is structured.
:note: This op is used as an optimization for StructuredDot. :note: This op is used as an optimization for StructuredDot.
""" """
__props__ = ()
def __eq__(self, other):
return (type(self) == type(other))
def __hash__(self):
return hash(type(self))
def __str__(self):
return self.__class__.__name__
def make_node(self, a_val, a_ind, a_ptr, a_nrows, b): def make_node(self, a_val, a_ind, a_ptr, a_nrows, b):
dtype_out = scalar.upcast(a_val.type.dtype, b.type.dtype) dtype_out = scalar.upcast(a_val.type.dtype, b.type.dtype)
...@@ -418,15 +404,7 @@ class StructuredDotCSR(gof.Op): ...@@ -418,15 +404,7 @@ class StructuredDotCSR(gof.Op):
:note: The grad implemented is structured. :note: The grad implemented is structured.
:note: This op is used as an optimization for StructuredDot. :note: This op is used as an optimization for StructuredDot.
""" """
__props__ = ()
def __eq__(self, other):
return (type(self) == type(other))
def __hash__(self):
return hash(type(self))
def __str__(self):
return self.__class__.__name__
def make_node(self, a_val, a_ind, a_ptr, b): def make_node(self, a_val, a_ind, a_ptr, b):
self.dtype_out = scalar.upcast(a_val.type.dtype, b.type.dtype) self.dtype_out = scalar.upcast(a_val.type.dtype, b.type.dtype)
...@@ -604,6 +582,7 @@ class UsmmCscDense(gof.Op): ...@@ -604,6 +582,7 @@ class UsmmCscDense(gof.Op):
:note: Optimized version os Usmm when `x` is in csc format and :note: Optimized version os Usmm when `x` is in csc format and
`y` is dense. `y` is dense.
""" """
__props__ = ("inplace",)
def __init__(self, inplace): def __init__(self, inplace):
self.inplace = inplace self.inplace = inplace
...@@ -616,12 +595,6 @@ class UsmmCscDense(gof.Op): ...@@ -616,12 +595,6 @@ class UsmmCscDense(gof.Op):
else: else:
return 'UsmmCscDense{no_inplace}' return 'UsmmCscDense{no_inplace}'
def __eq__(self, other):
return (type(self) == type(other)) and self.inplace == other.inplace
def __hash__(self):
return hash(type(self)) ^ self.inplace
def make_node(self, alpha, x_val, x_ind, x_ptr, x_nrows, y, z): def make_node(self, alpha, x_val, x_ind, x_ptr, x_nrows, y, z):
alpha = tensor.as_tensor_variable(alpha) alpha = tensor.as_tensor_variable(alpha)
x_val = tensor.as_tensor_variable(x_val) x_val = tensor.as_tensor_variable(x_val)
...@@ -890,14 +863,8 @@ register_specialize(local_usmm_csx, 'cxx_only') ...@@ -890,14 +863,8 @@ register_specialize(local_usmm_csx, 'cxx_only')
class CSMGradC(gof.Op): class CSMGradC(gof.Op):
def __eq__(self, other):
return (type(self) == type(other))
def __hash__(self): __props__ = ()
return hash(type(self))
def __str__(self):
return self.__class__.__name__
def make_node(self, a_val, a_ind, a_ptr, a_dim, def make_node(self, a_val, a_ind, a_ptr, a_dim,
b_val, b_ind, b_ptr, b_dim): b_val, b_ind, b_ptr, b_dim):
...@@ -1045,12 +1012,7 @@ class MulSDCSC(gof.Op): ...@@ -1045,12 +1012,7 @@ class MulSDCSC(gof.Op):
cannot be a complex type. cannot be a complex type.
:note: This op is used as an optimization of mul_s_d. :note: This op is used as an optimization of mul_s_d.
""" """
__props__ = ()
def __eq__(self, other):
return (type(self) == type(other))
def __hash__(self):
return hash(type(self))
def make_node(self, a_data, a_indices, a_indptr, b): def make_node(self, a_data, a_indices, a_indptr, b):
assert b.type.ndim == 2 assert b.type.ndim == 2
...@@ -1162,12 +1124,7 @@ class MulSDCSR(gof.Op): ...@@ -1162,12 +1124,7 @@ class MulSDCSR(gof.Op):
cannot be a complex type. cannot be a complex type.
:note: This op is used as an optimization of mul_s_d. :note: This op is used as an optimization of mul_s_d.
""" """
__props__ = ()
def __eq__(self, other):
return (type(self) == type(other))
def __hash__(self):
return hash(type(self))
def make_node(self, a_data, a_indices, a_indptr, b): def make_node(self, a_data, a_indices, a_indptr, b):
assert b.type.ndim == 2 assert b.type.ndim == 2
...@@ -1321,12 +1278,7 @@ class MulSVCSR(gof.Op): ...@@ -1321,12 +1278,7 @@ class MulSVCSR(gof.Op):
cannot be a complex type. cannot be a complex type.
:note: This op is used as an optimization of MulSV. :note: This op is used as an optimization of MulSV.
""" """
__props__ = ()
def __eq__(self, other):
return (type(self) == type(other))
def __hash__(self):
return hash(type(self))
def make_node(self, a_data, a_indices, a_indptr, b): def make_node(self, a_data, a_indices, a_indptr, b):
assert b.type.ndim == 1 assert b.type.ndim == 1
...@@ -1464,12 +1416,7 @@ class StructuredAddSVCSR(gof.Op): ...@@ -1464,12 +1416,7 @@ class StructuredAddSVCSR(gof.Op):
format. format.
:note: This op is used as an optimization for StructuredAddSV. :note: This op is used as an optimization for StructuredAddSV.
""" """
__props__ = ()
def __eq__(self, other):
return (type(self) == type(other))
def __hash__(self):
return hash(type(self))
def make_node(self, a_data, a_indices, a_indptr, b): def make_node(self, a_data, a_indices, a_indptr, b):
b = tensor.as_tensor_variable(b) b = tensor.as_tensor_variable(b)
...@@ -1638,15 +1585,7 @@ class SamplingDotCSR(gof.Op): ...@@ -1638,15 +1585,7 @@ class SamplingDotCSR(gof.Op):
allow mixed dtype. allow mixed dtype.
:note: This op is used as an optimization for SamplingDot. :note: This op is used as an optimization for SamplingDot.
""" """
__props__ = ()
def __eq__(self, other):
return type(self) == type(other)
def __hash__(self):
return hash(type(self))
def __str__(self):
return 'SamplingDot{Csr}'
def make_node(self, x, y, p_data, p_ind, p_ptr, p_ncols): def make_node(self, x, y, p_data, p_ind, p_ptr, p_ncols):
x = tensor.as_tensor_variable(x) x = tensor.as_tensor_variable(x)
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论