def test_lu_factor_reconstruction(self, dtype): m, n = self.shape A = testing.shaped_random(self.shape, cupy, dtype=dtype) lu, piv = cupyx.scipy.linalg.lu_factor(A) # extract ``L`` and ``U`` from ``lu`` L = cupy.tril(lu, k=-1) cupy.fill_diagonal(L, 1.) L = L[:, :m] U = cupy.triu(lu) U = U[:n, :] # check output shapes assert lu.shape == (m, n) assert L.shape == (m, min(m, n)) assert U.shape == (min(m, n), n) assert piv.shape == (min(m, n),) # apply pivot (on CPU since slaswp is not available in cupy) piv = cupy.asnumpy(piv) rows = numpy.arange(m) for i, row in enumerate(piv): if i != row: rows[i], rows[row] = rows[row], rows[i] PA = A[rows] # check that reconstruction is close to original LU = L.dot(U) cupy.testing.assert_allclose(LU, PA, atol=1e-5)
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 _potrf_batched(a): """Batched Cholesky decomposition. Decompose a given array of two-dimensional square matrices into ``L * L.T``, where ``L`` is a lower-triangular matrix and ``.T`` is a conjugate transpose operator. Args: a (cupy.ndarray): The input array of matrices with dimension ``(..., N, N)`` Returns: cupy.ndarray: The lower-triangular matrix. """ if not check_availability('potrfBatched'): raise RuntimeError('potrfBatched is not available') if a.dtype.char == 'f' or a.dtype.char == 'd': dtype = a.dtype.char else: dtype = numpy.promote_types(a.dtype.char, 'f').char if dtype == 'f': potrfBatched = cusolver.spotrfBatched elif dtype == 'd': potrfBatched = cusolver.dpotrfBatched elif dtype == 'F': potrfBatched = cusolver.cpotrfBatched else: # dtype == 'D': potrfBatched = cusolver.zpotrfBatched x = a.astype(dtype, order='C', copy=True) xp = cupy.core._mat_ptrs(x) n = x.shape[-1] ldx = x.strides[-2] // x.dtype.itemsize handle = device.get_cusolver_handle() batch_size = internal.prod(x.shape[:-2]) dev_info = cupy.empty(batch_size, dtype=numpy.int32) potrfBatched( handle, cublas.CUBLAS_FILL_MODE_UPPER, n, xp.data.ptr, ldx, dev_info.data.ptr, batch_size) cupy.linalg._util._check_cusolver_dev_info_if_synchronization_allowed( potrfBatched, dev_info) return cupy.tril(x)
def test_gmres(): all_x = [] msgs = [] try: import cupy as cp slippy.CUDA = True n = 6 a = cp.tril(cp.ones((n, n))) b = cp.ones(n) x0 = b * 0 x, failed = gmres(lambda y: cp.dot(a, y), x0, b, 4, n, 1e-6, override_cuda=False) assert not failed, "GPU gmres iterations failed to converge" all_x.append(cp.asnumpy(x)) msgs.append("GPU gmres iterations converged to incorrect result") except ImportError: pass n = 6 a = np.tril(np.ones((n, n))) b = np.ones(n) x0 = b * 0 x, failed = gmres(lambda y: np.dot(a, y), x0, b, 4, n, 1e-6, override_cuda=True) assert not failed, "CPU gmres iterations failed to converge" all_x.append(x) msgs.append("CPU gmres iterations converged to incorrect result") x_true = x0 * 0 x_true[0] = 1 for x, msg in zip(all_x, msgs): npt.assert_allclose(x, x_true, atol=3e-6, err_msg=msg)
def time_tril_l10x10(self): np.tril(self.l10x10)
finally: runtime.setDevice(prev_device) def tril(x: Array, /, *, k: int = 0) -> Array: """ Array API compatible wrapper for :py:func:`np.tril <numpy.tril>`. See its docstring for more information. """ from ._array_object import Array if x.ndim < 2: # Note: Unlike np.tril, x must be at least 2-D raise ValueError("x must be at least 2-dimensional for tril") return Array._new(np.tril(x._array, k=k)) def triu(x: Array, /, *, k: int = 0) -> Array: """ Array API compatible wrapper for :py:func:`np.triu <numpy.triu>`. See its docstring for more information. """ from ._array_object import Array if x.ndim < 2: # Note: Unlike np.triu, x must be at least 2-D raise ValueError("x must be at least 2-dimensional for triu") return Array._new(np.triu(x._array, k=k))