예제 #1
0
파일: compressed.py 프로젝트: zivzone/cupy
 def _add(self, other, lhs_negative, rhs_negative):
     if cupy.isscalar(other):
         if other == 0:
             if lhs_negative:
                 return -self
             else:
                 return self.copy()
         else:
             raise NotImplementedError(
                 'adding a nonzero scalar to a sparse matrix is not '
                 'supported')
     elif base.isspmatrix(other):
         alpha = -1 if lhs_negative else 1
         beta = -1 if rhs_negative else 1
         return self._add_sparse(other, alpha, beta)
     elif base.isdense(other):
         if lhs_negative:
             if rhs_negative:
                 return -self.todense() - other
             else:
                 return other - self.todense()
         else:
             if rhs_negative:
                 return self.todense() - other
             else:
                 return self.todense() + other
     else:
         return NotImplemented
예제 #2
0
파일: csc.py 프로젝트: zivzone/cupy
 def __mul__(self, other):
     if cupy.isscalar(other):
         self.sum_duplicates()
         return self._with_data(self.data * other)
     elif cupyx.scipy.sparse.isspmatrix_csr(other):
         self.sum_duplicates()
         other.sum_duplicates()
         return cusparse.csrgemm(self.T, other, transa=True)
     elif isspmatrix_csc(other):
         self.sum_duplicates()
         other.sum_duplicates()
         return cusparse.csrgemm(self.T, other.T, transa=True, transb=True)
     elif cupyx.scipy.sparse.isspmatrix(other):
         return self * other.tocsr()
     elif base.isdense(other):
         if other.ndim == 0:
             self.sum_duplicates()
             return self._with_data(self.data * other)
         elif other.ndim == 1:
             self.sum_duplicates()
             return cusparse.csrmv(self.T,
                                   cupy.asfortranarray(other),
                                   transa=True)
         elif other.ndim == 2:
             self.sum_duplicates()
             return cusparse.csrmm2(self.T,
                                    cupy.asfortranarray(other),
                                    transa=True)
         else:
             raise ValueError('could not interpret dimensions')
     else:
         return NotImplemented
예제 #3
0
파일: csr.py 프로젝트: xuzijian629/cupy
 def __mul__(self, other):
     if cupy.isscalar(other):
         self.sum_duplicates()
         return self._with_data(self.data * other)
     elif isspmatrix_csr(other):
         self.sum_duplicates()
         other.sum_duplicates()
         return cusparse.csrgemm(self, other)
     elif csc.isspmatrix_csc(other):
         self.sum_duplicates()
         other.sum_duplicates()
         return cusparse.csrgemm(self, other.T, transb=True)
     elif base.isspmatrix(other):
         return self * other.tocsr()
     elif base.isdense(other):
         if other.ndim == 0:
             self.sum_duplicates()
             return self._with_data(self.data * other)
         elif other.ndim == 1:
             self.sum_duplicates()
             other = cupy.asfortranarray(other)
             # csrmvEx does not work if nnz == 0
             if self.nnz > 0 and cusparse.csrmvExIsAligned(self, other):
                 return cusparse.csrmvEx(self, other)
             else:
                 return cusparse.csrmv(self, other)
         elif other.ndim == 2:
             self.sum_duplicates()
             return cusparse.csrmm2(self, cupy.asfortranarray(other))
         else:
             raise ValueError('could not interpret dimensions')
     else:
         return NotImplemented
예제 #4
0
파일: csc.py 프로젝트: yoshipon/cupy
 def __mul__(self, other):
     if cupy.isscalar(other):
         self.sum_duplicates()
         return self._with_data(self.data * other)
     elif cupyx.scipy.sparse.isspmatrix_csr(other):
         self.sum_duplicates()
         other.sum_duplicates()
         if cusparse.check_availability('csrgemm'):
             a = self.T
             return cusparse.csrgemm(a, other, transa=True)
         elif cusparse.check_availability('csrgemm2'):
             a = self.tocsr()
             a.sum_duplicates()
             return cusparse.csrgemm2(a, other)
         else:
             raise NotImplementedError
     elif isspmatrix_csc(other):
         self.sum_duplicates()
         other.sum_duplicates()
         if cusparse.check_availability('csrgemm'):
             a = self.T
             b = other.T
             return cusparse.csrgemm(a, b, transa=True, transb=True)
         elif cusparse.check_availability('csrgemm2'):
             a = self.tocsr()
             b = other.tocsr()
             a.sum_duplicates()
             b.sum_duplicates()
             return cusparse.csrgemm2(a, b)
         else:
             raise NotImplementedError
     elif cupyx.scipy.sparse.isspmatrix(other):
         return self * other.tocsr()
     elif base.isdense(other):
         if other.ndim == 0:
             self.sum_duplicates()
             return self._with_data(self.data * other)
         elif other.ndim == 1:
             self.sum_duplicates()
             if cusparse.check_availability('csrmv'):
                 csrmv = cusparse.csrmv
             elif cusparse.check_availability('spmv'):
                 csrmv = cusparse.spmv
             else:
                 raise NotImplementedError
             return csrmv(self.T, cupy.asfortranarray(other), transa=True)
         elif other.ndim == 2:
             self.sum_duplicates()
             if cusparse.check_availability('csrmm2'):
                 csrmm = cusparse.csrmm2
             elif cusparse.check_availability('spmm'):
                 csrmm = cusparse.spmm
             else:
                 raise NotImplementedError
             return csrmm(self.T, cupy.asfortranarray(other), transa=True)
         else:
             raise ValueError('could not interpret dimensions')
     else:
         return NotImplemented
예제 #5
0
    def __init__(self, arg1, shape=None, dtype=None, copy=False):
        if shape is not None and len(shape) != 2:
            raise ValueError(
                'Only two-dimensional sparse arrays are supported.')

        if base.issparse(arg1):
            x = arg1.asformat(self.format)
            data = x.data
            row = x.row
            col = x.col

            if arg1.format != self.format:
                # When formats are differnent, all arrays are already copied
                copy = False

            if shape is None:
                shape = arg1.shape

            self.has_canonical_format = x.has_canonical_format

        elif _util.isshape(arg1):
            m, n = arg1
            m, n = int(m), int(n)
            data = cupy.zeros(0, dtype if dtype else 'd')
            row = cupy.zeros(0, dtype='i')
            col = cupy.zeros(0, dtype='i')
            # shape and copy argument is ignored
            shape = (m, n)
            copy = False

            self.has_canonical_format = True

        elif _scipy_available and scipy.sparse.issparse(arg1):
            # Convert scipy.sparse to cupyx.scipy.sparse
            x = arg1.tocoo()
            data = cupy.array(x.data)
            row = cupy.array(x.row, dtype='i')
            col = cupy.array(x.col, dtype='i')
            copy = False
            if shape is None:
                shape = arg1.shape

            self.has_canonical_format = x.has_canonical_format

        elif isinstance(arg1, tuple) and len(arg1) == 2:
            try:
                data, (row, col) = arg1
            except (TypeError, ValueError):
                raise TypeError('invalid input format')

            if not (base.isdense(data) and data.ndim == 1 and base.isdense(row)
                    and row.ndim == 1 and base.isdense(col) and col.ndim == 1):
                raise ValueError('row, column, and data arrays must be 1-D')
            if not (len(data) == len(row) == len(col)):
                raise ValueError(
                    'row, column, and data array must all be the same length')

            self.has_canonical_format = False

        else:
            # TODO(leofang): support constructing from a dense matrix
            raise TypeError('invalid input format')

        if dtype is None:
            dtype = data.dtype
        else:
            dtype = numpy.dtype(dtype)

        if dtype != 'f' and dtype != 'd' and dtype != 'F' and dtype != 'D':
            raise ValueError('Only float32, float64, complex64 and complex128'
                             ' are supported')

        data = data.astype(dtype, copy=copy)
        row = row.astype('i', copy=copy)
        col = col.astype('i', copy=copy)

        if shape is None:
            if len(row) == 0 or len(col) == 0:
                raise ValueError(
                    'cannot infer dimensions from zero sized index arrays')
            shape = (int(row.max()) + 1, int(col.max()) + 1)

        if len(data) > 0:
            if row.max() >= shape[0]:
                raise ValueError('row index exceeds matrix dimensions')
            if col.max() >= shape[1]:
                raise ValueError('column index exceeds matrix dimensions')
            if row.min() < 0:
                raise ValueError('negative row index found')
            if col.min() < 0:
                raise ValueError('negative column index found')

        sparse_data._data_matrix.__init__(self, data)
        self.row = row
        self.col = col
        if not _util.isshape(shape):
            raise ValueError('invalid shape (must be a 2-tuple of int)')
        self._shape = int(shape[0]), int(shape[1])
예제 #6
0
파일: compressed.py 프로젝트: zivzone/cupy
    def __init__(self, arg1, shape=None, dtype=None, copy=False):
        if shape is not None:
            if not util.isshape(shape):
                raise ValueError('invalid shape (must be a 2-tuple of int)')
            shape = int(shape[0]), int(shape[1])

        if base.issparse(arg1):
            x = arg1.asformat(self.format)
            data = x.data
            indices = x.indices
            indptr = x.indptr

            if arg1.format != self.format:
                # When formats are differnent, all arrays are already copied
                copy = False

            if shape is None:
                shape = arg1.shape

            has_canonical_format = x.has_canonical_format
        elif util.isshape(arg1):
            m, n = arg1
            m, n = int(m), int(n)
            data = basic.zeros(0, dtype if dtype else 'd')
            indices = basic.zeros(0, 'i')
            indptr = basic.zeros(self._swap(m, n)[0] + 1, dtype='i')
            # shape and copy argument is ignored
            shape = (m, n)
            copy = False
            has_canonical_format = True

        elif scipy_available and scipy.sparse.issparse(arg1):
            # Convert scipy.sparse to cupyx.scipy.sparse
            x = arg1.asformat(self.format)
            data = cupy.array(x.data)
            indices = cupy.array(x.indices, dtype='i')
            indptr = cupy.array(x.indptr, dtype='i')
            copy = False

            if shape is None:
                shape = arg1.shape
            has_canonical_format = x.has_canonical_format

        elif isinstance(arg1, tuple) and len(arg1) == 3:
            data, indices, indptr = arg1
            if not (base.isdense(data) and data.ndim == 1 and
                    base.isdense(indices) and indices.ndim == 1 and
                    base.isdense(indptr) and indptr.ndim == 1):
                raise ValueError(
                    'data, indices, and indptr should be 1-D')

            if len(data) != len(indices):
                raise ValueError('indices and data should have the same size')

            has_canonical_format = False

        elif base.isdense(arg1):
            if arg1.ndim > 2:
                raise TypeError('expected dimension <= 2 array or matrix')
            elif arg1.ndim == 1:
                arg1 = arg1[None]
            elif arg1.ndim == 0:
                arg1 = arg1[None, None]
            data, indices, indptr = self._convert_dense(arg1)
            copy = False
            if shape is None:
                shape = arg1.shape

            has_canonical_format = True

        else:
            raise ValueError(
                'Unsupported initializer format')

        if dtype is None:
            dtype = data.dtype
        else:
            dtype = numpy.dtype(dtype)

        if dtype != 'f' and dtype != 'd' and dtype != 'F' and dtype != 'D':
            raise ValueError(
                'Only float32, float64, complex64 and complex128 '
                'are supported')

        data = data.astype(dtype, copy=copy)
        sparse_data._data_matrix.__init__(self, data)

        self.indices = indices.astype('i', copy=copy)
        self.indptr = indptr.astype('i', copy=copy)

        if shape is None:
            shape = self._swap(len(indptr) - 1, int(indices.max()) + 1)

        major, minor = self._swap(*shape)
        if len(indptr) != major + 1:
            raise ValueError('index pointer size (%d) should be (%d)'
                             % (len(indptr), major + 1))

        self._descr = cusparse.MatDescriptor.create()
        self._shape = shape
        self._has_canonical_format = has_canonical_format
예제 #7
0
파일: csr.py 프로젝트: mnicely/cupy
 def __mul__(self, other):
     if cupy.isscalar(other):
         self.sum_duplicates()
         return self._with_data(self.data * other)
     elif isspmatrix_csr(other):
         self.sum_duplicates()
         other.sum_duplicates()
         if cusparse.check_availability('csrgemm2'):
             return cusparse.csrgemm2(self, other)
         elif cusparse.check_availability('csrgemm'):
             return cusparse.csrgemm(self, other)
         else:
             raise NotImplementedError
     elif csc.isspmatrix_csc(other):
         self.sum_duplicates()
         other.sum_duplicates()
         if cusparse.check_availability('csrgemm'):
             return cusparse.csrgemm(self, other.T, transb=True)
         elif cusparse.check_availability('csrgemm2'):
             b = other.tocsr()
             b.sum_duplicates()
             return cusparse.csrgemm2(self, b)
         else:
             raise NotImplementedError
     elif base.isspmatrix(other):
         return self * other.tocsr()
     elif base.isdense(other):
         if other.ndim == 0:
             self.sum_duplicates()
             return self._with_data(self.data * other)
         elif other.ndim == 1:
             self.sum_duplicates()
             other = cupy.asfortranarray(other)
             # csrmvEx does not work if nnz == 0
             if self.nnz > 0 and cusparse.csrmvExIsAligned(self, other):
                 if cupy.cuda.cub_enabled and other.flags.c_contiguous:
                     return device_csrmv(self.shape[0], self.shape[1],
                                         self.nnz, self.data, self.indptr,
                                         self.indices, other)
                 else:
                     return cusparse.csrmvEx(self, other)
             else:
                 if cusparse.check_availability('csrmv'):
                     csrmv = cusparse.csrmv
                 elif cusparse.check_availability('spmv'):
                     csrmv = cusparse.spmv
                 else:
                     raise NotImplementedError
                 return csrmv(self, other)
         elif other.ndim == 2:
             self.sum_duplicates()
             if cusparse.check_availability('csrmm2'):
                 csrmm = cusparse.csrmm2
             elif cusparse.check_availability('spmm'):
                 csrmm = cusparse.spmm
             else:
                 raise NotImplementedError
             return csrmm(self, cupy.asfortranarray(other))
         else:
             raise ValueError('could not interpret dimensions')
     else:
         return NotImplemented
예제 #8
0
 def __mul__(self, other):
     if cupy.isscalar(other):
         self.sum_duplicates()
         return self._with_data(self.data * other)
     elif cupyx.scipy.sparse.isspmatrix_csr(other):
         self.sum_duplicates()
         other.sum_duplicates()
         if cusparse.check_availability('csrgemm') and not runtime.is_hip:
             # trans=True is still buggy as of ROCm 4.2.0
             a = self.T
             return cusparse.csrgemm(a, other, transa=True)
         elif cusparse.check_availability('csrgemm2'):
             a = self.tocsr()
             a.sum_duplicates()
             return cusparse.csrgemm2(a, other)
         else:
             raise NotImplementedError
     elif isspmatrix_csc(other):
         self.sum_duplicates()
         other.sum_duplicates()
         if cusparse.check_availability('csrgemm') and not runtime.is_hip:
             # trans=True is still buggy as of ROCm 4.2.0
             a = self.T
             b = other.T
             return cusparse.csrgemm(a, b, transa=True, transb=True)
         elif cusparse.check_availability('csrgemm2'):
             a = self.tocsr()
             b = other.tocsr()
             a.sum_duplicates()
             b.sum_duplicates()
             return cusparse.csrgemm2(a, b)
         else:
             raise NotImplementedError
     elif cupyx.scipy.sparse.isspmatrix(other):
         return self * other.tocsr()
     elif base.isdense(other):
         if other.ndim == 0:
             self.sum_duplicates()
             return self._with_data(self.data * other)
         elif other.ndim == 1:
             self.sum_duplicates()
             if cusparse.check_availability('csrmv') and not runtime.is_hip:
                 # trans=True is buggy as of ROCm 4.2.0
                 csrmv = cusparse.csrmv
             elif (cusparse.check_availability('spmv')
                   and not runtime.is_hip):
                 # trans=True is buggy as of ROCm 4.2.0
                 # (I got HIPSPARSE_STATUS_INTERNAL_ERROR...)
                 csrmv = cusparse.spmv
             else:
                 raise NotImplementedError
             return csrmv(self.T, cupy.asfortranarray(other), transa=True)
         elif other.ndim == 2:
             self.sum_duplicates()
             if (cusparse.check_availability('csrmm2')
                     and not runtime.is_hip):
                 # trans=True is buggy as of ROCm 4.2.0
                 csrmm = cusparse.csrmm2
             elif cusparse.check_availability('spmm'):
                 csrmm = cusparse.spmm
             else:
                 raise NotImplementedError
             return csrmm(self.T, cupy.asfortranarray(other), transa=True)
         else:
             raise ValueError('could not interpret dimensions')
     else:
         return NotImplemented
예제 #9
0
파일: csr.py 프로젝트: toslunar/cupy
 def __mul__(self, other):
     if cupy.isscalar(other):
         self.sum_duplicates()
         return self._with_data(self.data * other)
     elif isspmatrix_csr(other):
         self.sum_duplicates()
         other.sum_duplicates()
         if cusparse.check_availability('csrgemm2'):
             return cusparse.csrgemm2(self, other)
         elif cusparse.check_availability('csrgemm'):
             return cusparse.csrgemm(self, other)
         else:
             raise NotImplementedError
     elif csc.isspmatrix_csc(other):
         self.sum_duplicates()
         other.sum_duplicates()
         if cusparse.check_availability('csrgemm') and not runtime.is_hip:
             # trans=True is still buggy as of ROCm 4.2.0
             return cusparse.csrgemm(self, other.T, transb=True)
         elif cusparse.check_availability('csrgemm2'):
             b = other.tocsr()
             b.sum_duplicates()
             return cusparse.csrgemm2(self, b)
         else:
             raise NotImplementedError
     elif base.isspmatrix(other):
         return self * other.tocsr()
     elif base.isdense(other):
         if other.ndim == 0:
             self.sum_duplicates()
             return self._with_data(self.data * other)
         elif other.ndim == 1:
             self.sum_duplicates()
             other = cupy.asfortranarray(other)
             # need extra padding to ensure not stepping on the CUB bug,
             # see cupy/cupy#3679 for discussion
             is_cub_safe = (self.indptr.data.mem.size >
                            self.indptr.size * self.indptr.dtype.itemsize)
             # CUB spmv is buggy since CUDA 11.0, see
             # https://github.com/cupy/cupy/issues/3822#issuecomment-782607637
             is_cub_safe &= (cub._get_cuda_build_version() < 11000)
             for accelerator in _accelerator.get_routine_accelerators():
                 if (accelerator == _accelerator.ACCELERATOR_CUB
                         and not runtime.is_hip and is_cub_safe
                         and other.flags.c_contiguous):
                     return cub.device_csrmv(self.shape[0], self.shape[1],
                                             self.nnz, self.data,
                                             self.indptr, self.indices,
                                             other)
             if (cusparse.check_availability('csrmvEx') and self.nnz > 0
                     and cusparse.csrmvExIsAligned(self, other)):
                 # csrmvEx does not work if nnz == 0
                 csrmv = cusparse.csrmvEx
             elif cusparse.check_availability('csrmv'):
                 csrmv = cusparse.csrmv
             elif cusparse.check_availability('spmv'):
                 csrmv = cusparse.spmv
             else:
                 raise NotImplementedError
             return csrmv(self, other)
         elif other.ndim == 2:
             self.sum_duplicates()
             if cusparse.check_availability('csrmm2'):
                 csrmm = cusparse.csrmm2
             elif cusparse.check_availability('spmm'):
                 csrmm = cusparse.spmm
             else:
                 raise NotImplementedError
             return csrmm(self, cupy.asfortranarray(other))
         else:
             raise ValueError('could not interpret dimensions')
     else:
         return NotImplemented