def spilu(A, drop_tol=None, fill_factor=None, drop_rule=None, permc_spec=None, diag_pivot_thresh=None, relax=None, panel_size=None, options={}): """Computes the incomplete LU decomposition of a sparse square matrix. Args: A (cupyx.scipy.sparse.spmatrix): Sparse matrix to factorize. drop_tol (float): (For further augments, see :func:`scipy.sparse.linalg.spilu`) fill_factor (float): drop_rule (str): permc_spec (str): diag_pivot_thresh (float): relax (int): panel_size (int): options (dict): Returns: cupyx.scipy.sparse.linalg.SuperLU: Object which has a ``solve`` method. Note: This function computes incomplete LU decomposition of a sparse matrix on the CPU using `scipy.sparse.linalg.spilu` (unless you set ``fill_factor`` to ``1``). Therefore, incomplete LU decomposition is not accelerated on the GPU. On the other hand, the computation of solving linear equations using the ``solve`` method, which this function returns, is performed on the GPU. If you set ``fill_factor`` to ``1``, this function computes incomplete LU decomposition on the GPU, but without fill-in or pivoting. .. seealso:: :func:`scipy.sparse.linalg.spilu` """ if not scipy_available: raise RuntimeError('scipy is not available') if not sparse.isspmatrix(A): raise TypeError('A must be cupyx.scipy.sparse.spmatrix') if A.shape[0] != A.shape[1]: raise ValueError('A must be a square matrix (A.shape: {})' .format(A.shape)) if A.dtype.char not in 'fdFD': raise TypeError('Invalid dtype (actual: {})'.format(A.dtype)) if fill_factor == 1: # Computes ILU(0) on the GPU using cuSparse functions if not sparse.isspmatrix_csr(A): a = A.tocsr() else: a = A.copy() cusparse.csrilu02(a) return CusparseLU(a) a = A.get().tocsc() a_inv = scipy.sparse.linalg.spilu( a, fill_factor=fill_factor, drop_tol=drop_tol, drop_rule=drop_rule, permc_spec=permc_spec, diag_pivot_thresh=diag_pivot_thresh, relax=relax, panel_size=panel_size, options=options) return SuperLU(a_inv)
def test_csrilu02(self, dtype): dtype = numpy.dtype(dtype) a_ref = self._make_matrix(dtype) a = sparse.csr_matrix(a_ref) cusparse.csrilu02(a, level_info=self.level_info) a = a.todense() al = cupy.tril(a, k=-1) al = al + cupy.diag(cupy.ones((self.n, ), dtype=dtype.char.lower())) au = cupy.triu(a) a = al @ au tol = self._tol[dtype.char.lower()] cupy.testing.assert_allclose(a, a_ref, atol=tol, rtol=tol)
def test_invalid_cases(self): dtype = numpy.dtype('d') a_ref = self._make_matrix(dtype) # invalid format a = sparse.csc_matrix(a_ref) with pytest.raises(TypeError): cusparse.csrilu02(a, level_info=self.level_info) # invalid shape a = cupy.ones((self.n, self.n + 1), dtype=dtype) a = sparse.csr_matrix(a) with pytest.raises(ValueError): cusparse.csrilu02(a, level_info=self.level_info) # matrix with zero diagonal element a = a_ref a[-1, -1] = 0 a = sparse.csr_matrix(a) with pytest.raises(ValueError): cusparse.csrilu02(a, level_info=self.level_info) # singular matrix a = a_ref a[1:] = a[0] a = sparse.csr_matrix(a) with pytest.raises(ValueError): cusparse.csrilu02(a, level_info=self.level_info)