提交 b0de5da7 authored 作者: lamblin's avatar lamblin

Merge pull request #1505 from lamblin/sparse_updates

Sparse updates
......@@ -251,7 +251,7 @@ def sp_zeros_like(x):
# TODO: don't restrict to CSM formats
_, _, indptr, shape = csm_properties(x)
return CSM(format=x.format)(data=numpy.array([], dtype=x.type.dtype),
indices=numpy.array([]),
indices=numpy.array([], dtype='int32'),
indptr=tensor.zeros_like(indptr),
shape=shape)
......@@ -621,12 +621,22 @@ class CSM(gof.Op):
def make_node(self, data, indices, indptr, shape):
data = tensor.as_tensor_variable(data)
if not isinstance(indices, tensor.TensorVariable):
indices = theano._asarray(indices, dtype='int32')
if not isinstance(indptr, tensor.TensorVariable):
indptr = theano._asarray(indptr, dtype='int32')
if not isinstance(shape, tensor.TensorVariable):
shape = theano._asarray(shape, dtype='int32')
if not isinstance(indices, gof.Variable):
indices_ = numpy.asarray(indices)
indices_32 = theano._asarray(indices, dtype='int32')
assert (indices_ == indices_32).all()
indices = indices_32
if not isinstance(indptr, gof.Variable):
indptr_ = numpy.asarray(indptr)
indptr_32 = theano._asarray(indptr, dtype='int32')
assert (indptr_ == indptr_32).all()
indptr = indptr_32
if not isinstance(shape, gof.Variable):
shape_ = numpy.asarray(shape)
shape_32 = theano._asarray(shape, dtype='int32')
assert (shape_ == shape_32).all()
shape = shape_32
indices = tensor.as_tensor_variable(indices)
indptr = tensor.as_tensor_variable(indptr)
shape = tensor.as_tensor_variable(shape)
......
......@@ -876,7 +876,8 @@ def local_csm_grad_c(node):
if node.op == csm_grad(None):
return [csm_grad_c(*node.inputs)]
return False
register_specialize(local_csm_grad_c, 'cxx_only')
#DISABLED AS IT IS BROKEN FOR UNSORTED INDICES!
#register_specialize(local_csm_grad_c, 'cxx_only')
class MulSDCSC(gof.Op):
......
......@@ -857,30 +857,17 @@ class test_csm(unittest.TestCase):
z = tensor.ivector()
s = tensor.ivector()
# Sparse advanced indexing produces unsorted sparse matrices
a = sp_types[format]([[1, 2, 1],
[1, 2, 1],
[1, 2, 1],
[1, 2, 1]],
dtype=dtype)[range(4)]
a = sparse_random_inputs(format, (4, 3), out_dtype=dtype,
unsorted_indices=True)[1][0]
# Make sure it's unsorted
assert not a.has_sorted_indices
a = as_sparse_variable(a)
f = theano.function([x, y, z, s], tensor.grad(tensor.sum(
dense_from_sparse(a * CSM(format)(x, y, z, s))), x))
spmat = sp_types[format](random_lil((4, 3), dtype,
12))[range(4)]
assert not spmat.has_sorted_indices
res = f(spmat.data, spmat.indices, spmat.indptr,
numpy.asarray(spmat.shape, 'int32'))
col1 = sp_types[format]((res, spmat.indices, spmat.indptr),
shape=numpy.asarray(spmat.shape,
'int32'))[:, 1].data
assert numpy.all(col1 == 2)
def my_op(x):
y = tensor.constant(a.indices)
z = tensor.constant(a.indptr)
s = tensor.constant(a.shape)
return tensor.sum(
dense_from_sparse(CSM(format)(x, y, z, s) * a))
verify_grad_sparse(my_op, [a.data])
def test_csm(self):
sp_types = {'csc': sp.csc_matrix,
......@@ -1252,7 +1239,7 @@ class DotTests(utt.InferShapeTester):
fI = I.flatten()
data = tensor.ones_like(fI)
indptr = tensor.arange(data.shape[0] + 1)
indptr = tensor.arange(data.shape[0] + 1, dtype='int32')
m1 = sparse.CSR(data, fI, indptr, (8, size))
m2 = sparse.dot(m1, C)
......
......@@ -37,6 +37,7 @@ def test_local_csm_properties_csm():
def test_local_csm_grad_c():
raise SkipTest("Opt disabled as it don't support unsorted indices")
if not theano.config.cxx:
raise SkipTest("G++ not available, so we need to skip this test.")
data = tensor.vector()
......
......@@ -15,7 +15,7 @@ def _is_sparse(x):
@return: True iff x is a L{scipy.sparse.spmatrix} (and not a
L{numpy.ndarray})
"""
if not isinstance(x, (scipy.sparse.spmatrix, numpy.ndarray)):
if not isinstance(x, (scipy.sparse.spmatrix, numpy.ndarray, tuple, list)):
raise NotImplementedError("this function should only be called on "
"sparse.scipy.sparse.spmatrix or "
"numpy.ndarray, not,", x)
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论