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