Preconditioner functions

Contents

Preconditioner functions#

This module contains all sparse preconditioners.

The sparse preconditioners describe manipulations on a matrix in sparse format to obtain a sparse preconditioner matrix.

hipsparseXbsrilu02_zeroPivot()#

hipsparseStatus_t hipsparseXbsrilu02_zeroPivot(hipsparseHandle_t handle, bsrilu02Info_t info, int *position)#

hipsparseXbsrilu02_zeroPivot returns HIPSPARSE_STATUS_ZERO_PIVOT, if either a structural or numerical zero has been found during hipsparseXbsrilu02_analysis() or hipsparseXbsrilu02() computation. The first zero pivot \(j\) at \(A_{j,j}\) is stored in position, using same index base as the BSR matrix.

position can be in host or device memory. If no zero pivot has been found, position is set to -1 and HIPSPARSE_STATUS_SUCCESS is returned instead.

Deprecated:

This function is deprecated when using the CUDA backend (CUDA 12.0+) and will be removed in CUDA 13.0. This deprecation does not apply to the ROCm backend.

Note

If a zero pivot is found, position \(=j\) means that either the diagonal block \(A_{j,j}\) is missing (structural zero) or the diagonal block \(A_{j,j}\) is not invertible (numerical zero).

Note

hipsparseXbsrilu02_zeroPivot is a blocking function. It might influence performance negatively.

Parameters:
  • handle[in] handle to the hipsparse library context queue.

  • info[in] structure that holds the information collected during the analysis step.

  • position[inout] pointer to zero pivot \(j\), can be in host or device memory.

Return values:
  • HIPSPARSE_STATUS_SUCCESS – the operation completed successfully.

  • HIPSPARSE_STATUS_NOT_INITIALIZEDhandle is not initialized.

  • HIPSPARSE_STATUS_INVALID_VALUEhandle, info or position is nullptr.

  • HIPSPARSE_STATUS_INTERNAL_ERROR – an internal error occurred.

  • HIPSPARSE_STATUS_ZERO_PIVOT – zero pivot has been found.

hipsparseXbsrilu02_numericBoost()#

hipsparseStatus_t hipsparseSbsrilu02_numericBoost(hipsparseHandle_t handle, bsrilu02Info_t info, int enable_boost, double *tol, float *boost_val)#
hipsparseStatus_t hipsparseDbsrilu02_numericBoost(hipsparseHandle_t handle, bsrilu02Info_t info, int enable_boost, double *tol, double *boost_val)#
hipsparseStatus_t hipsparseCbsrilu02_numericBoost(hipsparseHandle_t handle, bsrilu02Info_t info, int enable_boost, double *tol, hipComplex *boost_val)#
hipsparseStatus_t hipsparseZbsrilu02_numericBoost(hipsparseHandle_t handle, bsrilu02Info_t info, int enable_boost, double *tol, hipDoubleComplex *boost_val)#

hipsparseXbsrilu02_numericBoost enables the user to replace a numerical value in an incomplete LU factorization. tol is used to determine whether a numerical value is replaced by boost_val, such that \(A_{j,j} = \text{boost_val}\) if \(\text{tol} \ge \left|A_{j,j}\right|\).

Deprecated:

This function is deprecated when using the CUDA backend (CUDA 12.0+) and will be removed in CUDA 13.0. This deprecation does not apply to the ROCm backend.

Note

The boost value is enabled by setting enable_boost to 1 or disabled by setting enable_boost to 0.

Note

tol and boost_val can be in host or device memory.

Parameters:
  • handle[in] handle to the hipsparse library context queue.

  • info[in] structure that holds the information collected during the analysis step.

  • enable_boost[in] enable/disable numeric boost.

  • tol[in] tolerance to determine whether a numerical value is replaced or not.

  • boost_val[in] boost value to replace a numerical value.

Return values:
  • HIPSPARSE_STATUS_SUCCESS – the operation completed successfully.

  • HIPSPARSE_STATUS_NOT_INITIALIZEDhandle is not initialized.

  • HIPSPARSE_STATUS_INVALID_VALUEhandle, info, tol or boost_val is nullptr.

  • HIPSPARSE_STATUS_INTERNAL_ERROR – an internal error occurred.

hipsparseXbsrilu02_bufferSize()#

hipsparseStatus_t hipsparseSbsrilu02_bufferSize(hipsparseHandle_t handle, hipsparseDirection_t dirA, int mb, int nnzb, const hipsparseMatDescr_t descrA, float *bsrSortedValA, const int *bsrSortedRowPtrA, const int *bsrSortedColIndA, int blockDim, bsrilu02Info_t info, int *pBufferSizeInBytes)#
hipsparseStatus_t hipsparseDbsrilu02_bufferSize(hipsparseHandle_t handle, hipsparseDirection_t dirA, int mb, int nnzb, const hipsparseMatDescr_t descrA, double *bsrSortedValA, const int *bsrSortedRowPtrA, const int *bsrSortedColIndA, int blockDim, bsrilu02Info_t info, int *pBufferSizeInBytes)#
hipsparseStatus_t hipsparseCbsrilu02_bufferSize(hipsparseHandle_t handle, hipsparseDirection_t dirA, int mb, int nnzb, const hipsparseMatDescr_t descrA, hipComplex *bsrSortedValA, const int *bsrSortedRowPtrA, const int *bsrSortedColIndA, int blockDim, bsrilu02Info_t info, int *pBufferSizeInBytes)#
hipsparseStatus_t hipsparseZbsrilu02_bufferSize(hipsparseHandle_t handle, hipsparseDirection_t dirA, int mb, int nnzb, const hipsparseMatDescr_t descrA, hipDoubleComplex *bsrSortedValA, const int *bsrSortedRowPtrA, const int *bsrSortedColIndA, int blockDim, bsrilu02Info_t info, int *pBufferSizeInBytes)#

hipsparseXbsrilu02_bufferSize returns the size of the temporary storage buffer in bytes that is required by hipsparseXbsrilu02_analysis() and hipsparseXbsrilu02(). The temporary storage buffer must be allocated by the user.

Parameters:
Return values:
  • HIPSPARSE_STATUS_SUCCESS – the operation completed successfully.

  • HIPSPARSE_STATUS_INVALID_VALUEhandle, mb, nnzb, blockDim, descrA, bsrSortedValA, bsrSortedRowPtrA, bsrSortedColIndA, info or pBufferSizeInBytes pointer is invalid.

  • HIPSPARSE_STATUS_INTERNAL_ERROR – an internal error occurred.

  • HIPSPARSE_STATUS_NOT_SUPPORTEDhipsparseMatrixType_t != HIPSPARSE_MATRIX_TYPE_GENERAL.

hipsparseXbsrilu02_analysis()#

hipsparseStatus_t hipsparseSbsrilu02_analysis(hipsparseHandle_t handle, hipsparseDirection_t dirA, int mb, int nnzb, const hipsparseMatDescr_t descrA, float *bsrSortedValA, const int *bsrSortedRowPtrA, const int *bsrSortedColIndA, int blockDim, bsrilu02Info_t info, hipsparseSolvePolicy_t policy, void *pBuffer)#
hipsparseStatus_t hipsparseDbsrilu02_analysis(hipsparseHandle_t handle, hipsparseDirection_t dirA, int mb, int nnzb, const hipsparseMatDescr_t descrA, double *bsrSortedValA, const int *bsrSortedRowPtrA, const int *bsrSortedColIndA, int blockDim, bsrilu02Info_t info, hipsparseSolvePolicy_t policy, void *pBuffer)#
hipsparseStatus_t hipsparseCbsrilu02_analysis(hipsparseHandle_t handle, hipsparseDirection_t dirA, int mb, int nnzb, const hipsparseMatDescr_t descrA, hipComplex *bsrSortedValA, const int *bsrSortedRowPtrA, const int *bsrSortedColIndA, int blockDim, bsrilu02Info_t info, hipsparseSolvePolicy_t policy, void *pBuffer)#
hipsparseStatus_t hipsparseZbsrilu02_analysis(hipsparseHandle_t handle, hipsparseDirection_t dirA, int mb, int nnzb, const hipsparseMatDescr_t descrA, hipDoubleComplex *bsrSortedValA, const int *bsrSortedRowPtrA, const int *bsrSortedColIndA, int blockDim, bsrilu02Info_t info, hipsparseSolvePolicy_t policy, void *pBuffer)#

hipsparseXbsrilu02_analysis performs the analysis step for hipsparseXbsrilu02(). It is expected that this function will be executed only once for a given matrix.

Note

If the matrix sparsity pattern changes, the gathered information will become invalid.

Note

This function is non blocking and executed asynchronously with respect to the host. It may return before the actual computation has finished.

Parameters:
  • handle[in] handle to the hipsparse library context queue.

  • dirA[in] direction that specified whether to count nonzero elements by HIPSPARSE_DIRECTION_ROW or by HIPSPARSE_DIRECTION_COLUMN.

  • mb[in] number of block rows in the sparse BSR matrix.

  • nnzb[in] number of non-zero block entries of the sparse BSR matrix.

  • descrA[in] descriptor of the sparse BSR matrix.

  • bsrSortedValA[in] array of length nnzb*blockDim*blockDim containing the values of the sparse BSR matrix.

  • bsrSortedRowPtrA[in] array of mb+1 elements that point to the start of every block row of the sparse BSR matrix.

  • bsrSortedColIndA[in] array of nnzb elements containing the block column indices of the sparse BSR matrix.

  • blockDim[in] the block dimension of the BSR matrix. Between 1 and m where m=mb*blockDim.

  • info[out] structure that holds the information collected during the analysis step.

  • policy[in] HIPSPARSE_SOLVE_POLICY_NO_LEVEL or HIPSPARSE_SOLVE_POLICY_USE_LEVEL.

  • pBuffer[in] temporary storage buffer allocated by the user.

Return values:
  • HIPSPARSE_STATUS_SUCCESS – the operation completed successfully.

  • HIPSPARSE_STATUS_INVALID_VALUEhandle, mb, nnzb, blockDim, descrA, bsrSortedValA, bsrSortedRowPtrA, bsrSortedColIndA, info or pBuffer pointer is invalid.

  • HIPSPARSE_STATUS_INTERNAL_ERROR – an internal error occurred.

  • HIPSPARSE_STATUS_NOT_SUPPORTEDhipsparseMatrixType_t != HIPSPARSE_MATRIX_TYPE_GENERAL.

hipsparseXbsrilu02()#

hipsparseStatus_t hipsparseSbsrilu02(hipsparseHandle_t handle, hipsparseDirection_t dirA, int mb, int nnzb, const hipsparseMatDescr_t descrA, float *bsrSortedValA_valM, const int *bsrSortedRowPtrA, const int *bsrSortedColIndA, int blockDim, bsrilu02Info_t info, hipsparseSolvePolicy_t policy, void *pBuffer)#
hipsparseStatus_t hipsparseDbsrilu02(hipsparseHandle_t handle, hipsparseDirection_t dirA, int mb, int nnzb, const hipsparseMatDescr_t descrA, double *bsrSortedValA_valM, const int *bsrSortedRowPtrA, const int *bsrSortedColIndA, int blockDim, bsrilu02Info_t info, hipsparseSolvePolicy_t policy, void *pBuffer)#
hipsparseStatus_t hipsparseCbsrilu02(hipsparseHandle_t handle, hipsparseDirection_t dirA, int mb, int nnzb, const hipsparseMatDescr_t descrA, hipComplex *bsrSortedValA_valM, const int *bsrSortedRowPtrA, const int *bsrSortedColIndA, int blockDim, bsrilu02Info_t info, hipsparseSolvePolicy_t policy, void *pBuffer)#
hipsparseStatus_t hipsparseZbsrilu02(hipsparseHandle_t handle, hipsparseDirection_t dirA, int mb, int nnzb, const hipsparseMatDescr_t descrA, hipDoubleComplex *bsrSortedValA_valM, const int *bsrSortedRowPtrA, const int *bsrSortedColIndA, int blockDim, bsrilu02Info_t info, hipsparseSolvePolicy_t policy, void *pBuffer)#

Incomplete LU factorization with 0 fill-ins and no pivoting using BSR storage format.

hipsparseXbsrilu02 computes the incomplete LU factorization with 0 fill-ins and no pivoting of a sparse \(mb \times mb\) BSR matrix \(A\), such that

\[ A \approx LU \]

Computing the above incomplete LU factorization requires three steps to complete. First, the user determines the size of the required temporary storage buffer by calling hipsparseXbsrilu02_bufferSize(). Once this buffer size has been determined, the user allocates the buffer and passes it to hipsparseXbsrilu02_analysis(). This will perform analysis on the sparsity pattern of the matrix. Finally, the user calls hipsparseXbsrilu02 to perform the actual factorization. The calculation of the buffer size and the analysis of the sparse matrix only need to be performed once for a given sparsity pattern while the factorization can be repeatedly applied to multiple matrices having the same sparsity pattern. Once all calls to hipsparseXbsrilu02() are complete, the temporary buffer can be deallocated.

hipsparseXbsrilu02 reports the first zero pivot (either numerical or structural zero). The zero pivot status can be obtained by calling hipsparseXbsrilu02_zeroPivot().

Note

This function is non blocking and executed asynchronously with respect to the host. It may return before the actual computation has finished.

Parameters:
  • handle[in] handle to the hipsparse library context queue.

  • dirA[in] direction that specified whether to count nonzero elements by HIPSPARSE_DIRECTION_ROW or by HIPSPARSE_DIRECTION_COLUMN.

  • mb[in] number of block rows in the sparse BSR matrix.

  • nnzb[in] number of non-zero block entries of the sparse BSR matrix.

  • descrA[in] descriptor of the sparse BSR matrix.

  • bsrSortedValA_valM[inout] array of length nnzb*blockDim*blockDim containing the values of the sparse BSR matrix.

  • bsrSortedRowPtrA[in] array of mb+1 elements that point to the start of every block row of the sparse BSR matrix.

  • bsrSortedColIndA[in] array of nnzb elements containing the block column indices of the sparse BSR matrix.

  • blockDim[in] the block dimension of the BSR matrix. Between 1 and m where m=mb*blockDim.

  • info[in] structure that holds the information collected during the analysis step.

  • policy[in] HIPSPARSE_SOLVE_POLICY_NO_LEVEL or HIPSPARSE_SOLVE_POLICY_USE_LEVEL.

  • pBuffer[in] temporary storage buffer allocated by the user.

Return values:
  • HIPSPARSE_STATUS_SUCCESS – the operation completed successfully.

  • HIPSPARSE_STATUS_INVALID_VALUEhandle, mb, nnzb, blockDim, descrA, bsrSortedValA_valM, bsrSortedRowPtrA or bsrSortedColIndA pointer is invalid.

  • HIPSPARSE_STATUS_ARCH_MISMATCH – the device is not supported.

  • HIPSPARSE_STATUS_INTERNAL_ERROR – an internal error occurred.

  • HIPSPARSE_STATUS_NOT_SUPPORTEDhipsparseMatrixType_t != HIPSPARSE_MATRIX_TYPE_GENERAL.

  1int main(int argc, char* argv[])
  2{
  3    // hipSPARSE handle
  4    hipsparseHandle_t handle;
  5    HIPSPARSE_CHECK(hipsparseCreate(&handle));
  6
  7    // A sample square matrix A (4x4) in BSR format for ILU(0) factorization.
  8    // The 'S' in Sbsrilu02 indicates single precision float.
  9    // We'll use a block size of 1 for simplicity, making it behave like CSR ILU.
 10    // Matrix A:
 11    // ( 1  2  0  0 )
 12    // ( 3  4  5  0 )
 13    // ( 0  6  7  8 )
 14    // ( 0  0  9 10 )
 15
 16    int m    = 4; // Number of rows
 17    int n    = 4; // Number of columns
 18    int bs   = 1; // Block size
 19    int mb   = m / bs; // Number of block rows
 20    int nb   = n / bs; // Number of block columns
 21    int nnzb = 10; // Number of non-zero blocks
 22
 23    // BSR row pointers
 24    std::vector<int> hbsrRowPtr = {0, 2, 5, 8, 10};
 25
 26    // BSR column indices
 27    std::vector<int> hbsrColInd = {0, 1, 0, 1, 2, 1, 2, 3, 2, 3};
 28
 29    // BSR values (single precision float)
 30    std::vector<float> hbsrVal = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f};
 31
 32    // Matrix descriptor
 33    hipsparseMatDescr_t descr;
 34    HIPSPARSE_CHECK(hipsparseCreateMatDescr(&descr));
 35
 36    // Set index base on descriptor
 37    HIPSPARSE_CHECK(hipsparseSetMatIndexBase(descr, HIPSPARSE_INDEX_BASE_ZERO));
 38
 39    // For ILU(0), the L factor often has a unit diagonal.
 40    HIPSPARSE_CHECK(hipsparseSetMatDiagType(descr, HIPSPARSE_DIAG_TYPE_UNIT));
 41
 42    // BSRILU02 info
 43    bsrilu02Info_t info;
 44    HIPSPARSE_CHECK(hipsparseCreateBsrilu02Info(&info));
 45
 46    // Offload data to device
 47    int*   dbsrRowPtr;
 48    int*   dbsrColInd;
 49    float* dbsrVal; // This will store the factorized L and U values
 50
 51    HIP_CHECK(hipMalloc((void**)&dbsrRowPtr, sizeof(int) * (mb + 1)));
 52    HIP_CHECK(hipMalloc((void**)&dbsrColInd, sizeof(int) * nnzb));
 53    HIP_CHECK(hipMalloc((void**)&dbsrVal, sizeof(float) * nnzb * bs * bs));
 54
 55    HIP_CHECK(
 56        hipMemcpy(dbsrRowPtr, hbsrRowPtr.data(), sizeof(int) * (mb + 1), hipMemcpyHostToDevice));
 57    HIP_CHECK(hipMemcpy(dbsrColInd, hbsrColInd.data(), sizeof(int) * nnzb, hipMemcpyHostToDevice));
 58    HIP_CHECK(
 59        hipMemcpy(dbsrVal, hbsrVal.data(), sizeof(float) * nnzb * bs * bs, hipMemcpyHostToDevice));
 60
 61    // 1. Get buffer size
 62    int bufferSize = 0;
 63    HIPSPARSE_CHECK(
 64        hipsparseSbsrilu02_bufferSize(handle,
 65                                      HIPSPARSE_DIRECTION_COLUMN, // Block storage direction
 66                                      mb,
 67                                      nnzb,
 68                                      descr,
 69                                      dbsrVal,
 70                                      dbsrRowPtr,
 71                                      dbsrColInd,
 72                                      bs,
 73                                      info,
 74                                      &bufferSize));
 75
 76    void* dbuffer = nullptr;
 77    HIP_CHECK(hipMalloc((void**)&dbuffer, bufferSize));
 78
 79    // 2. Perform analysis (symbolic factorization)
 80    // This step analyzes the sparsity pattern of A to determine the structure of L and U.
 81    HIPSPARSE_CHECK(
 82        hipsparseSbsrilu02_analysis(handle,
 83                                    HIPSPARSE_DIRECTION_COLUMN,
 84                                    mb,
 85                                    nnzb,
 86                                    descr,
 87                                    dbsrVal,
 88                                    dbsrRowPtr,
 89                                    dbsrColInd,
 90                                    bs,
 91                                    info,
 92                                    HIPSPARSE_SOLVE_POLICY_USE_LEVEL, // Policy for analysis
 93                                    dbuffer));
 94
 95    // 3. Perform factorization (numerical computation)
 96    // This step computes the actual numerical values of L and U, stored in dbsrVal.
 97    HIPSPARSE_CHECK(hipsparseSbsrilu02(handle,
 98                                       HIPSPARSE_DIRECTION_COLUMN,
 99                                       mb,
100                                       nnzb,
101                                       descr,
102                                       dbsrVal,
103                                       dbsrRowPtr,
104                                       dbsrColInd,
105                                       bs,
106                                       info,
107                                       HIPSPARSE_SOLVE_POLICY_USE_LEVEL, // Policy for factorization
108                                       dbuffer));
109
110    // 4. Check for zero pivots
111    // A zero pivot can occur during factorization, indicating a numerical breakdown.
112    int zeroPivot = 0; // -1 if no zero pivot, otherwise the block row index of the first zero pivot
113    HIPSPARSE_CHECK(hipsparseXbsrilu02_zeroPivot(handle, info, &zeroPivot));
114    if(zeroPivot != -1)
115    {
116        printf("Error: Zero pivot detected during ILU0 factorization at block row index %d\n",
117               zeroPivot);
118        // Handle the error (e.g., return, use a different preconditioner, etc.)
119    }
120    else
121    {
122        printf("BSRILU0 factorization completed successfully (no zero pivots detected).\n");
123    }
124
125    // Copy the factorized values (L and U combined) back to host
126    std::vector<float> hbsrVal_result(nnzb * bs * bs);
127    HIP_CHECK(hipMemcpy(
128        hbsrVal_result.data(), dbsrVal, sizeof(float) * nnzb * bs * bs, hipMemcpyDeviceToHost));
129
130    // Print the result (the values of the factorized L and U combined)
131    printf("\nFactorized BSR values (L and U combined):\n");
132    for(int i = 0; i < nnzb * bs * bs; ++i)
133    {
134        printf("val[%d] = %f\n", i, hbsrVal_result[i]);
135    }
136
137    // Clean up
138    HIPSPARSE_CHECK(hipsparseDestroyBsrilu02Info(info));
139    HIPSPARSE_CHECK(hipsparseDestroyMatDescr(descr));
140    HIPSPARSE_CHECK(hipsparseDestroy(handle));
141
142    HIP_CHECK(hipFree(dbsrRowPtr));
143    HIP_CHECK(hipFree(dbsrColInd));
144    HIP_CHECK(hipFree(dbsrVal));
145    HIP_CHECK(hipFree(dbuffer));
146
147    return 0;
148}

hipsparseXcsrilu02_zeroPivot()#

hipsparseStatus_t hipsparseXcsrilu02_zeroPivot(hipsparseHandle_t handle, csrilu02Info_t info, int *position)#

hipsparseXcsrilu02_zeroPivot returns HIPSPARSE_STATUS_ZERO_PIVOT, if either a structural or numerical zero has been found during hipsparseXcsrilu02() computation. The first zero pivot \(j\) at \(A_{j,j}\) is stored in position, using same index base as the CSR matrix.

position can be in host or device memory. If no zero pivot has been found, position is set to -1 and HIPSPARSE_STATUS_SUCCESS is returned instead.

Deprecated:

This function is deprecated when using the CUDA backend (CUDA 12.0+) and will be removed in CUDA 13.0. This deprecation does not apply to the ROCm backend.

Note

hipsparseXcsrilu02_zeroPivot is a blocking function. It might influence performance negatively.

Parameters:
  • handle[in] handle to the hipsparse library context queue.

  • info[in] structure that holds the information collected during the analysis step.

  • position[inout] pointer to zero pivot \(j\), can be in host or device memory.

Return values:
  • HIPSPARSE_STATUS_SUCCESS – the operation completed successfully.

  • HIPSPARSE_STATUS_NOT_INITIALIZEDhandle is not initialized.

  • HIPSPARSE_STATUS_INVALID_VALUEhandle, info or position is nullptr.

  • HIPSPARSE_STATUS_INTERNAL_ERROR – an internal error occurred.

  • HIPSPARSE_STATUS_ZERO_PIVOT – zero pivot has been found.

hipsparseXcsrilu02_numericBoost()#

hipsparseStatus_t hipsparseScsrilu02_numericBoost(hipsparseHandle_t handle, csrilu02Info_t info, int enable_boost, double *tol, float *boost_val)#
hipsparseStatus_t hipsparseDcsrilu02_numericBoost(hipsparseHandle_t handle, csrilu02Info_t info, int enable_boost, double *tol, double *boost_val)#
hipsparseStatus_t hipsparseCcsrilu02_numericBoost(hipsparseHandle_t handle, csrilu02Info_t info, int enable_boost, double *tol, hipComplex *boost_val)#
hipsparseStatus_t hipsparseZcsrilu02_numericBoost(hipsparseHandle_t handle, csrilu02Info_t info, int enable_boost, double *tol, hipDoubleComplex *boost_val)#

hipsparseXcsrilu02_numericBoost enables the user to replace a numerical value in an incomplete LU factorization. tol is used to determine whether a numerical value is replaced by boost_val, such that \(A_{j,j} = \text{boost_val}\) if \(\text{tol} \ge \left|A_{j,j}\right|\).

Deprecated:

This function is deprecated when using the CUDA backend (CUDA 12.0+) and will be removed in CUDA 13.0. This deprecation does not apply to the ROCm backend.

Note

The boost value is enabled by setting enable_boost to 1 or disabled by setting enable_boost to 0.

Note

tol and boost_val can be in host or device memory.

Parameters:
  • handle[in] handle to the hipsparse library context queue.

  • info[in] structure that holds the information collected during the analysis step.

  • enable_boost[in] enable/disable numeric boost.

  • tol[in] tolerance to determine whether a numerical value is replaced or not.

  • boost_val[in] boost value to replace a numerical value.

Return values:
  • HIPSPARSE_STATUS_SUCCESS – the operation completed successfully.

  • HIPSPARSE_STATUS_NOT_INITIALIZEDhandle is not initialized.

  • HIPSPARSE_STATUS_INVALID_VALUEhandle, info, tol or boost_val is nullptr.

  • HIPSPARSE_STATUS_INTERNAL_ERROR – an internal error occurred.

hipsparseXcsrilu02_bufferSize()#

hipsparseStatus_t hipsparseScsrilu02_bufferSize(hipsparseHandle_t handle, int m, int nnz, const hipsparseMatDescr_t descrA, float *csrSortedValA, const int *csrSortedRowPtrA, const int *csrSortedColIndA, csrilu02Info_t info, int *pBufferSizeInBytes)#
hipsparseStatus_t hipsparseDcsrilu02_bufferSize(hipsparseHandle_t handle, int m, int nnz, const hipsparseMatDescr_t descrA, double *csrSortedValA, const int *csrSortedRowPtrA, const int *csrSortedColIndA, csrilu02Info_t info, int *pBufferSizeInBytes)#
hipsparseStatus_t hipsparseCcsrilu02_bufferSize(hipsparseHandle_t handle, int m, int nnz, const hipsparseMatDescr_t descrA, hipComplex *csrSortedValA, const int *csrSortedRowPtrA, const int *csrSortedColIndA, csrilu02Info_t info, int *pBufferSizeInBytes)#
hipsparseStatus_t hipsparseZcsrilu02_bufferSize(hipsparseHandle_t handle, int m, int nnz, const hipsparseMatDescr_t descrA, hipDoubleComplex *csrSortedValA, const int *csrSortedRowPtrA, const int *csrSortedColIndA, csrilu02Info_t info, int *pBufferSizeInBytes)#

hipsparseXcsrilu02_bufferSize returns the size of the temporary storage buffer in bytes that is required by hipsparseXcsrilu02_analysis() and hipsparseXcsrilu02(). The temporary storage buffer must be allocated by the user.

Parameters:
  • handle[in] handle to the hipsparse library context queue.

  • m[in] number of rows of the sparse CSR matrix.

  • nnz[in] number of non-zero entries of the sparse CSR matrix.

  • descrA[in] descriptor of the sparse CSR matrix.

  • csrSortedValA[in] array of nnz elements of the sparse CSR matrix.

  • csrSortedRowPtrA[in] array of m+1 elements that point to the start of every row of the sparse CSR matrix.

  • csrSortedColIndA[in] array of nnz elements containing the column indices of the sparse CSR matrix.

  • info[out] structure that holds the information collected during the analysis step.

  • pBufferSizeInBytes[out] number of bytes of the temporary storage buffer required by hipsparseXcsrilu02_analysis() and hipsparseXcsrilu02().

Return values:
  • HIPSPARSE_STATUS_SUCCESS – the operation completed successfully.

  • HIPSPARSE_STATUS_INVALID_VALUEhandle, m, nnz, descrA, csrSortedValA, csrSortedRowPtrA, csrSortedColIndA, info or pBufferSizeInBytes pointer is invalid.

  • HIPSPARSE_STATUS_INTERNAL_ERROR – an internal error occurred.

hipsparseXcsrilu02_bufferSizeExt()#

hipsparseStatus_t hipsparseScsrilu02_bufferSizeExt(hipsparseHandle_t handle, int m, int nnz, const hipsparseMatDescr_t descrA, float *csrSortedValA, const int *csrSortedRowPtrA, const int *csrSortedColIndA, csrilu02Info_t info, size_t *pBufferSizeInBytes)#
hipsparseStatus_t hipsparseDcsrilu02_bufferSizeExt(hipsparseHandle_t handle, int m, int nnz, const hipsparseMatDescr_t descrA, double *csrSortedValA, const int *csrSortedRowPtrA, const int *csrSortedColIndA, csrilu02Info_t info, size_t *pBufferSizeInBytes)#
hipsparseStatus_t hipsparseCcsrilu02_bufferSizeExt(hipsparseHandle_t handle, int m, int nnz, const hipsparseMatDescr_t descrA, hipComplex *csrSortedValA, const int *csrSortedRowPtrA, const int *csrSortedColIndA, csrilu02Info_t info, size_t *pBufferSizeInBytes)#
hipsparseStatus_t hipsparseZcsrilu02_bufferSizeExt(hipsparseHandle_t handle, int m, int nnz, const hipsparseMatDescr_t descrA, hipDoubleComplex *csrSortedValA, const int *csrSortedRowPtrA, const int *csrSortedColIndA, csrilu02Info_t info, size_t *pBufferSizeInBytes)#

hipsparseXcsrilu02_bufferSizeExt returns the size of the temporary storage buffer in bytes that is required by hipsparseXcsrilu02_analysis() and hipsparseXcsrilu02(). The temporary storage buffer must be allocated by the user.

Parameters:
  • handle[in] handle to the hipsparse library context queue.

  • m[in] number of rows of the sparse CSR matrix.

  • nnz[in] number of non-zero entries of the sparse CSR matrix.

  • descrA[in] descriptor of the sparse CSR matrix.

  • csrSortedValA[in] array of nnz elements of the sparse CSR matrix.

  • csrSortedRowPtrA[in] array of m+1 elements that point to the start of every row of the sparse CSR matrix.

  • csrSortedColIndA[in] array of nnz elements containing the column indices of the sparse CSR matrix.

  • info[out] structure that holds the information collected during the analysis step.

  • pBufferSizeInBytes[out] number of bytes of the temporary storage buffer required by hipsparseXcsrilu02_analysis() and hipsparseXcsrilu02().

Return values:
  • HIPSPARSE_STATUS_SUCCESS – the operation completed successfully.

  • HIPSPARSE_STATUS_INVALID_VALUEhandle, m, nnz, descrA, csrSortedValA, csrSortedRowPtrA, csrSortedColIndA, info or pBufferSizeInBytes pointer is invalid.

  • HIPSPARSE_STATUS_INTERNAL_ERROR – an internal error occurred.

hipsparseXcsrilu02_analysis()#

hipsparseStatus_t hipsparseScsrilu02_analysis(hipsparseHandle_t handle, int m, int nnz, const hipsparseMatDescr_t descrA, const float *csrSortedValA, const int *csrSortedRowPtrA, const int *csrSortedColIndA, csrilu02Info_t info, hipsparseSolvePolicy_t policy, void *pBuffer)#
hipsparseStatus_t hipsparseDcsrilu02_analysis(hipsparseHandle_t handle, int m, int nnz, const hipsparseMatDescr_t descrA, const double *csrSortedValA, const int *csrSortedRowPtrA, const int *csrSortedColIndA, csrilu02Info_t info, hipsparseSolvePolicy_t policy, void *pBuffer)#
hipsparseStatus_t hipsparseCcsrilu02_analysis(hipsparseHandle_t handle, int m, int nnz, const hipsparseMatDescr_t descrA, const hipComplex *csrSortedValA, const int *csrSortedRowPtrA, const int *csrSortedColIndA, csrilu02Info_t info, hipsparseSolvePolicy_t policy, void *pBuffer)#
hipsparseStatus_t hipsparseZcsrilu02_analysis(hipsparseHandle_t handle, int m, int nnz, const hipsparseMatDescr_t descrA, const hipDoubleComplex *csrSortedValA, const int *csrSortedRowPtrA, const int *csrSortedColIndA, csrilu02Info_t info, hipsparseSolvePolicy_t policy, void *pBuffer)#

hipsparseXcsrilu02_analysis performs the analysis step for hipsparseXcsrilu02(). It is expected that this function will be executed only once for a given matrix and particular operation type.

Note

If the matrix sparsity pattern changes, the gathered information will become invalid.

Note

This function is non blocking and executed asynchronously with respect to the host. It may return before the actual computation has finished.

Parameters:
  • handle[in] handle to the hipsparse library context queue.

  • m[in] number of rows of the sparse CSR matrix.

  • nnz[in] number of non-zero entries of the sparse CSR matrix.

  • descrA[in] descriptor of the sparse CSR matrix.

  • csrSortedValA[in] array of nnz elements of the sparse CSR matrix.

  • csrSortedRowPtrA[in] array of m+1 elements that point to the start of every row of the sparse CSR matrix.

  • csrSortedColIndA[in] array of nnz elements containing the column indices of the sparse CSR matrix.

  • info[out] structure that holds the information collected during the analysis step.

  • policy[in] HIPSPARSE_SOLVE_POLICY_NO_LEVEL or HIPSPARSE_SOLVE_POLICY_USE_LEVEL.

  • pBuffer[in] temporary storage buffer allocated by the user.

Return values:
  • HIPSPARSE_STATUS_SUCCESS – the operation completed successfully.

  • HIPSPARSE_STATUS_INVALID_VALUEhandle, m, nnz, descrA, csrSortedValA, csrSortedRowPtrA, csrSortedColIndA, info or pBuffer pointer is invalid.

  • HIPSPARSE_STATUS_INTERNAL_ERROR – an internal error occurred.

hipsparseXcsrilu02()#

hipsparseStatus_t hipsparseScsrilu02(hipsparseHandle_t handle, int m, int nnz, const hipsparseMatDescr_t descrA, float *csrSortedValA_valM, const int *csrSortedRowPtrA, const int *csrSortedColIndA, csrilu02Info_t info, hipsparseSolvePolicy_t policy, void *pBuffer)#
hipsparseStatus_t hipsparseDcsrilu02(hipsparseHandle_t handle, int m, int nnz, const hipsparseMatDescr_t descrA, double *csrSortedValA_valM, const int *csrSortedRowPtrA, const int *csrSortedColIndA, csrilu02Info_t info, hipsparseSolvePolicy_t policy, void *pBuffer)#
hipsparseStatus_t hipsparseCcsrilu02(hipsparseHandle_t handle, int m, int nnz, const hipsparseMatDescr_t descrA, hipComplex *csrSortedValA_valM, const int *csrSortedRowPtrA, const int *csrSortedColIndA, csrilu02Info_t info, hipsparseSolvePolicy_t policy, void *pBuffer)#
hipsparseStatus_t hipsparseZcsrilu02(hipsparseHandle_t handle, int m, int nnz, const hipsparseMatDescr_t descrA, hipDoubleComplex *csrSortedValA_valM, const int *csrSortedRowPtrA, const int *csrSortedColIndA, csrilu02Info_t info, hipsparseSolvePolicy_t policy, void *pBuffer)#

Incomplete LU factorization with 0 fill-ins and no pivoting using CSR storage format.

hipsparseXcsrilu02 computes the incomplete LU factorization with 0 fill-ins and no pivoting of a sparse \(m \times m\) CSR matrix \(A\), such that

\[ A \approx LU \]
where the lower triangular matrix \(L\) and the upper triangular matrix \(U\) are computed using:
\[\begin{split} \begin{array}{ll} L_{ij} = \frac{1}{U_{jj}}(A_{ij} - \sum_{k=0}^{j-1}L_{ik} \times U_{kj}), & \text{if i > j} \\ U_{ij} = (A_{ij} - \sum_{k=0}^{j-1}L_{ik} \times U_{kj}), & \text{if i <= j} \end{array} \end{split}\]
for each entry found in the CSR matrix \(A\).

Computing the above incomplete \(LU\) factorization requires three steps to complete. First, the user determines the size of the required temporary storage buffer by calling hipsparseXcsrilu02_bufferSize(). Once this buffer size has been determined, the user allocates the buffer and passes it to hipsparseXcsrilu02_analysis(). This will perform analysis on the sparsity pattern of the matrix. Finally, the user calls hipsparseScsrilu02, hipsparseDcsrilu02, hipsparseCcsrilu02, or hipsparseZcsrilu02 to perform the actual factorization. The calculation of the buffer size and the analysis of the sparse matrix only need to be performed once for a given sparsity pattern while the factorization can be repeatedly applied to multiple matrices having the same sparsity pattern. Once all calls to hipsparseXcsrilu02() are complete, the temporary buffer can be deallocated.

When computing the \(LU\) factorization, it is possible that \(U_{jj} == 0\) which would result in a division by zero. This could occur from either \(A_{jj}\) not existing in the sparse CSR matrix (referred to as a structural zero) or because \(A_{ij} - \sum_{k=0}^{j-1}L_{ik} \times U_{kj} == 0\) (referred to as a numerical zero). For example, running the \(LU\) factorization on the following matrix:

\[\begin{split} \begin{bmatrix} 2 & 1 & 0 \\ 1 & 2 & 1 \\ 0 & 1 & 2 \end{bmatrix} \end{split}\]
results in a successful \(LU\) factorization, however running with the matrix:
\[\begin{split} \begin{bmatrix} 2 & 1 & 0 \\ 1 & 1/2 & 1 \\ 0 & 1 & 2 \end{bmatrix} \end{split}\]
results in a numerical zero because:
\[\begin{split} \begin{array}{ll} U_{00} &= 2 \\ U_{01} &= 1 \\ L_{10} &= \frac{1}{2} \\ U_{11} &= \frac{1}{2} - \frac{1}{2} &= 0 \end{array} \end{split}\]
The user can detect the presence of a structural zero by calling hipsparseXcsrilu02_zeroPivot() after hipsparseXcsrilu02_analysis() and/or the presence of a structural or numerical zero by calling hipsparseXcsrilu02_zeroPivot() after hipsparseXcsrilu02(). In both cases, hipsparseXcsrilu02_zeroPivot() will report the first zero pivot (either numerical or structural) found. See example below. The user can also set the diagonal type to be \(1\) using hipsparseSetMatDiagType() which will interpret the matrix \(A\) as having ones on its diagonal (even if no nonzero exists in the sparsity pattern).

hipsparseXcsrilu02 computes the \(LU\) factorization inplace meaning that the values array csrSortedValA_valM of the \(A\) matrix is overwritten with the \(L\) matrix stored in the strictly lower triangular part of \(A\) and the \(U\) matrix stored in the upper part of \(A\):

\[\begin{split} \begin{align} \begin{bmatrix} a_{00} & a_{01} & a_{02} \\ a_{10} & a_{11} & a_{12} \\ a_{20} & a_{21} & a_{22} \end{bmatrix} \rightarrow \begin{bmatrix} u_{00} & u_{01} & u_{02} \\ l_{10} & u_{11} & u_{12} \\ l_{20} & l_{21} & u_{22} \end{bmatrix} \end{align} \end{split}\]
The row pointer array csrSortedRowPtrA and the column indices array csrSortedColIndA remain the same for \(A\) and \(LU\) as the incomplete factorization does not generate new nonzeros in \(LU\) which do not already exist in \(A\).

The performance of computing \(LU\) factorization with hipSPARSE greatly depends on the sparisty pattern the the matrix \(A\) as this is what determines the amount of parallelism available.

Note

The sparse CSR matrix has to be sorted. This can be achieved by calling hipsparseXcsrsort().

Note

This function is non blocking and executed asynchronously with respect to the host. It may return before the actual computation has finished.

Parameters:
  • handle[in] handle to the hipsparse library context queue.

  • m[in] number of rows of the sparse CSR matrix.

  • nnz[in] number of non-zero entries of the sparse CSR matrix.

  • descrA[in] descriptor of the sparse CSR matrix.

  • csrSortedValA_valM[inout] array of nnz elements of the sparse CSR matrix.

  • csrSortedRowPtrA[in] array of m+1 elements that point to the start of every row of the sparse CSR matrix.

  • csrSortedColIndA[in] array of nnz elements containing the column indices of the sparse CSR matrix.

  • info[in] structure that holds the information collected during the analysis step.

  • policy[in] HIPSPARSE_SOLVE_POLICY_NO_LEVEL or HIPSPARSE_SOLVE_POLICY_USE_LEVEL.

  • pBuffer[in] temporary storage buffer allocated by the user.

Return values:
  • HIPSPARSE_STATUS_SUCCESS – the operation completed successfully.

  • HIPSPARSE_STATUS_INVALID_VALUEhandle, m, nnz, descrA, csrSortedValA_valM, csrSortedRowPtrA or csrSortedColIndA pointer is invalid.

  • HIPSPARSE_STATUS_ARCH_MISMATCH – the device is not supported.

  • HIPSPARSE_STATUS_INTERNAL_ERROR – an internal error occurred.

  1int main(int argc, char* argv[])
  2{
  3    // hipSPARSE handle
  4    hipsparseHandle_t handle;
  5    HIPSPARSE_CHECK(hipsparseCreate(&handle));
  6
  7    // A sample square matrix A (4x4) in CSR format for ILU(0) factorization.
  8    // The 'S' in Scsrilu02 indicates single precision float.
  9    // Matrix A:
 10    // ( 1  2  0  0 )
 11    // ( 3  4  5  0 )
 12    // ( 0  6  7  8 )
 13    // ( 0  0  9 10 )
 14
 15    int m   = 4; // Number of rows
 16    int n   = 4; // Number of columns (equal to m for ILU)
 17    int nnz = 10; // Number of non-zero elements
 18
 19    // CSR row pointers
 20    std::vector<int> hcsrRowPtr = {0, 2, 5, 8, 10};
 21
 22    // CSR column indices
 23    std::vector<int> hcsrColInd = {0, 1, 0, 1, 2, 1, 2, 3, 2, 3};
 24
 25    // CSR values
 26    std::vector<float> hcsrVal = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f};
 27
 28    // Matrix descriptor
 29    hipsparseMatDescr_t descr;
 30    HIPSPARSE_CHECK(hipsparseCreateMatDescr(&descr));
 31
 32    // Set index base on descriptor
 33    HIPSPARSE_CHECK(hipsparseSetMatIndexBase(descr, HIPSPARSE_INDEX_BASE_ZERO));
 34
 35    // For incomplete LU, the L factor often has a unit diagonal.
 36    HIPSPARSE_CHECK(hipsparseSetMatDiagType(descr, HIPSPARSE_DIAG_TYPE_UNIT));
 37
 38    // CSRILU02 info (for incomplete LU factorization)
 39    csrilu02Info_t info;
 40    HIPSPARSE_CHECK(hipsparseCreateCsrilu02Info(&info));
 41
 42    // Offload data to device
 43    int*   dcsrRowPtr;
 44    int*   dcsrColInd;
 45    float* dcsrVal; // This will store the factorized L and U values
 46
 47    HIP_CHECK(hipMalloc((void**)&dcsrRowPtr, sizeof(int) * (m + 1)));
 48    HIP_CHECK(hipMalloc((void**)&dcsrColInd, sizeof(int) * nnz));
 49    HIP_CHECK(
 50        hipMalloc((void**)&dcsrVal,
 51                  sizeof(float) * nnz)); // Note: Same size as input, values will be overwritten
 52
 53    HIP_CHECK(
 54        hipMemcpy(dcsrRowPtr, hcsrRowPtr.data(), sizeof(int) * (m + 1), hipMemcpyHostToDevice));
 55    HIP_CHECK(hipMemcpy(dcsrColInd, hcsrColInd.data(), sizeof(int) * nnz, hipMemcpyHostToDevice));
 56    HIP_CHECK(hipMemcpy(dcsrVal, hcsrVal.data(), sizeof(float) * nnz, hipMemcpyHostToDevice));
 57
 58    // 1. Get buffer size
 59    int bufferSize = 0;
 60    HIPSPARSE_CHECK(hipsparseScsrilu02_bufferSize(
 61        handle, m, nnz, descr, dcsrVal, dcsrRowPtr, dcsrColInd, info, &bufferSize));
 62
 63    void* dbuffer = nullptr;
 64    HIP_CHECK(hipMalloc((void**)&dbuffer, bufferSize));
 65
 66    // 2. Perform analysis (symbolic factorization)
 67    // This step analyzes the sparsity pattern of A to determine the structure of L and U.
 68    HIPSPARSE_CHECK(
 69        hipsparseScsrilu02_analysis(handle,
 70                                    m,
 71                                    nnz,
 72                                    descr,
 73                                    dcsrVal,
 74                                    dcsrRowPtr,
 75                                    dcsrColInd,
 76                                    info,
 77                                    HIPSPARSE_SOLVE_POLICY_USE_LEVEL, // Policy for analysis
 78                                    dbuffer));
 79
 80    // 3. Perform factorization (numerical computation)
 81    // This step computes the actual numerical values of L and U, stored in dcsrVal.
 82    HIPSPARSE_CHECK(hipsparseScsrilu02(handle,
 83                                       m,
 84                                       nnz,
 85                                       descr,
 86                                       dcsrVal,
 87                                       dcsrRowPtr,
 88                                       dcsrColInd,
 89                                       info,
 90                                       HIPSPARSE_SOLVE_POLICY_USE_LEVEL, // Policy for factorization
 91                                       dbuffer));
 92
 93    // 4. Check for zero pivots
 94    // A zero pivot can occur during factorization, indicating a numerical breakdown.
 95    int zeroPivot = 0; // -1 if no zero pivot, otherwise the row index of the first zero pivot
 96    HIPSPARSE_CHECK(hipsparseXcsrilu02_zeroPivot(handle, info, &zeroPivot));
 97    if(zeroPivot != -1)
 98    {
 99        printf("Error: Zero pivot detected during ILU0 factorization at row index %d\n", zeroPivot);
100        // Depending on your application, you might want to handle this error
101        // or switch to a different preconditioner.
102    }
103    else
104    {
105        printf("CSRILU0 factorization completed successfully (no zero pivots detected).\n");
106    }
107
108    // Copy the factorized values (L and U combined) back to host
109    std::vector<float> hcsrVal_result(nnz);
110    HIP_CHECK(
111        hipMemcpy(hcsrVal_result.data(), dcsrVal, sizeof(float) * nnz, hipMemcpyDeviceToHost));
112
113    // Print the result (the values of the factorized L and U combined)
114    printf("\nFactorized CSR values (L and U combined):\n");
115    for(int i = 0; i < nnz; ++i)
116    {
117        printf("val[%d] = %f\n", i, hcsrVal_result[i]);
118    }
119
120    // Clean up
121    HIPSPARSE_CHECK(hipsparseDestroyCsrilu02Info(info));
122    HIPSPARSE_CHECK(hipsparseDestroyMatDescr(descr));
123    HIPSPARSE_CHECK(hipsparseDestroy(handle));
124
125    HIP_CHECK(hipFree(dcsrRowPtr));
126    HIP_CHECK(hipFree(dcsrColInd));
127    HIP_CHECK(hipFree(dcsrVal));
128    HIP_CHECK(hipFree(dbuffer));
129
130    return 0;
131}

hipsparseXbsric02_zeroPivot()#

hipsparseStatus_t hipsparseXbsric02_zeroPivot(hipsparseHandle_t handle, bsric02Info_t info, int *position)#

hipsparseXbsric02_zeroPivot returns HIPSPARSE_STATUS_ZERO_PIVOT, if either a structural or numerical zero has been found during hipsparseXbsric02_analysis() or hipsparseXbsric02() computation. The first zero pivot \(j\) at \(A_{j,j}\) is stored in position, using same index base as the BSR matrix.

position can be in host or device memory. If no zero pivot has been found, position is set to -1 and HIPSPARSE_STATUS_SUCCESS is returned instead.

Deprecated:

This function is deprecated when using the CUDA backend (CUDA 12.0+) and will be removed in CUDA 13.0. This deprecation does not apply to the ROCm backend.

Note

If a zero pivot is found, position=j means that either the diagonal block A(j,j) is missing (structural zero) or the diagonal block A(j,j) is not positive definite (numerical zero).

Note

hipsparseXbsric02_zeroPivot is a blocking function. It might influence performance negatively.

Parameters:
  • handle[in] handle to the hipsparse library context queue.

  • info[in] structure that holds the information collected during the analysis step.

  • position[inout] pointer to zero pivot \(j\), can be in host or device memory.

Return values:
  • HIPSPARSE_STATUS_SUCCESS – the operation completed successfully.

  • HIPSPARSE_STATUS_NOT_INITIALIZEDhandle is not initialized.

  • HIPSPARSE_STATUS_INVALID_VALUEhandle, info or position is nullptr.

  • HIPSPARSE_STATUS_INTERNAL_ERROR – an internal error occurred.

  • HIPSPARSE_STATUS_ZERO_PIVOT – zero pivot has been found.

hipsparseXbsric02_bufferSize()#

hipsparseStatus_t hipsparseSbsric02_bufferSize(hipsparseHandle_t handle, hipsparseDirection_t dirA, int mb, int nnzb, const hipsparseMatDescr_t descrA, float *bsrValA, const int *bsrRowPtrA, const int *bsrColIndA, int blockDim, bsric02Info_t info, int *pBufferSizeInBytes)#
hipsparseStatus_t hipsparseDbsric02_bufferSize(hipsparseHandle_t handle, hipsparseDirection_t dirA, int mb, int nnzb, const hipsparseMatDescr_t descrA, double *bsrValA, const int *bsrRowPtrA, const int *bsrColIndA, int blockDim, bsric02Info_t info, int *pBufferSizeInBytes)#
hipsparseStatus_t hipsparseCbsric02_bufferSize(hipsparseHandle_t handle, hipsparseDirection_t dirA, int mb, int nnzb, const hipsparseMatDescr_t descrA, hipComplex *bsrValA, const int *bsrRowPtrA, const int *bsrColIndA, int blockDim, bsric02Info_t info, int *pBufferSizeInBytes)#
hipsparseStatus_t hipsparseZbsric02_bufferSize(hipsparseHandle_t handle, hipsparseDirection_t dirA, int mb, int nnzb, const hipsparseMatDescr_t descrA, hipDoubleComplex *bsrValA, const int *bsrRowPtrA, const int *bsrColIndA, int blockDim, bsric02Info_t info, int *pBufferSizeInBytes)#

hipsparseXbsric02_bufferSize returns the size of the temporary storage buffer in bytes that is required by hipsparseXbsric02_analysis() and hipsparseXbsric02(). The temporary storage buffer must be allocated by the user.

Parameters:
  • handle[in] handle to the hipsparse library context queue.

  • dirA[in] direction that specifies whether to count nonzero elements by HIPSPARSE_DIRECTION_ROW or by HIPSPARSE_DIRECTION_COLUMN.

  • mb[in] number of block rows in the sparse BSR matrix. Must be non-negative.

  • nnzb[in] number of non-zero block entries of the sparse BSR matrix. Must be non-negative.

  • descrA[in] descriptor of the sparse BSR matrix.

  • bsrValA[in] array of length nnzb*blockDim*blockDim containing the values of the sparse BSR matrix.

  • bsrRowPtrA[in] array of mb+1 elements that point to the start of every block row of the sparse BSR matrix.

  • bsrColIndA[in] array of nnzb elements containing the block column indices of the sparse BSR matrix.

  • blockDim[in] the block dimension of the BSR matrix. Must be positive. Between 1 and m where m=mb*blockDim.

  • info[out] structure that holds the information collected during the analysis step.

  • pBufferSizeInBytes[out] number of bytes of the temporary storage buffer required by hipsparseSbsric02_analysis(), hipsparseDbsric02_analysis(), hipsparseCbsric02_analysis(), hipsparseZbsric02_analysis(), hipsparseSbsric02(), hipsparseDbsric02(), hipsparseCbsric02() and hipsparseZbsric02().

Return values:
  • HIPSPARSE_STATUS_SUCCESS – the operation completed successfully.

  • HIPSPARSE_STATUS_NOT_INITIALIZEDhandle is not initialized.

  • HIPSPARSE_STATUS_INVALID_VALUEhandle, descrA, bsrValA, bsrRowPtrA, bsrColIndA, info or pBufferSizeInBytes is nullptr, mb or nnzb is negative, or blockDim is invalid.

  • HIPSPARSE_STATUS_INTERNAL_ERROR – an internal error occurred.

  • HIPSPARSE_STATUS_NOT_SUPPORTEDhipsparseMatrixType_t != HIPSPARSE_MATRIX_TYPE_GENERAL.

hipsparseXbsric02_analysis()#

hipsparseStatus_t hipsparseSbsric02_analysis(hipsparseHandle_t handle, hipsparseDirection_t dirA, int mb, int nnzb, const hipsparseMatDescr_t descrA, const float *bsrValA, const int *bsrRowPtrA, const int *bsrColIndA, int blockDim, bsric02Info_t info, hipsparseSolvePolicy_t policy, void *pBuffer)#
hipsparseStatus_t hipsparseDbsric02_analysis(hipsparseHandle_t handle, hipsparseDirection_t dirA, int mb, int nnzb, const hipsparseMatDescr_t descrA, const double *bsrValA, const int *bsrRowPtrA, const int *bsrColIndA, int blockDim, bsric02Info_t info, hipsparseSolvePolicy_t policy, void *pBuffer)#
hipsparseStatus_t hipsparseCbsric02_analysis(hipsparseHandle_t handle, hipsparseDirection_t dirA, int mb, int nnzb, const hipsparseMatDescr_t descrA, const hipComplex *bsrValA, const int *bsrRowPtrA, const int *bsrColIndA, int blockDim, bsric02Info_t info, hipsparseSolvePolicy_t policy, void *pBuffer)#
hipsparseStatus_t hipsparseZbsric02_analysis(hipsparseHandle_t handle, hipsparseDirection_t dirA, int mb, int nnzb, const hipsparseMatDescr_t descrA, const hipDoubleComplex *bsrValA, const int *bsrRowPtrA, const int *bsrColIndA, int blockDim, bsric02Info_t info, hipsparseSolvePolicy_t policy, void *pBuffer)#

hipsparseXbsric02_analysis performs the analysis step for hipsparseXbsric02(). It is expected that this function will be executed only once for a given matrix and particular operation type.

Note

If the matrix sparsity pattern changes, the gathered information will become invalid.

Note

This function is non blocking and executed asynchronously with respect to the host. It may return before the actual computation has finished.

Parameters:
  • handle[in] handle to the hipsparse library context queue.

  • dirA[in] direction that specified whether to count nonzero elements by HIPSPARSE_DIRECTION_ROW or by HIPSPARSE_DIRECTION_COLUMN.

  • mb[in] number of block rows in the sparse BSR matrix.

  • nnzb[in] number of non-zero block entries of the sparse BSR matrix.

  • descrA[in] descriptor of the sparse BSR matrix.

  • bsrValA[in] array of length nnzb*blockDim*blockDim containing the values of the sparse BSR matrix.

  • bsrRowPtrA[in] array of mb+1 elements that point to the start of every block row of the sparse BSR matrix.

  • bsrColIndA[in] array of nnzb elements containing the block column indices of the sparse BSR matrix.

  • blockDim[in] the block dimension of the BSR matrix. Between 1 and m where m=mb*blockDim.

  • info[out] structure that holds the information collected during the analysis step.

  • policy[in] HIPSPARSE_SOLVE_POLICY_NO_LEVEL or HIPSPARSE_SOLVE_POLICY_USE_LEVEL.

  • pBuffer[in] temporary storage buffer allocated by the user.

Return values:
  • HIPSPARSE_STATUS_SUCCESS – the operation completed successfully.

  • HIPSPARSE_STATUS_INVALID_VALUEhandle, mb, nnzb, blockDim, descrA, bsrValA, bsrRowPtrA, bsrColIndA, info or pBuffer pointer is invalid.

  • HIPSPARSE_STATUS_INTERNAL_ERROR – an internal error occurred.

  • HIPSPARSE_STATUS_NOT_SUPPORTEDhipsparseMatrixType_t != HIPSPARSE_MATRIX_TYPE_GENERAL.

hipsparseXbsric02()#

hipsparseStatus_t hipsparseSbsric02(hipsparseHandle_t handle, hipsparseDirection_t dirA, int mb, int nnzb, const hipsparseMatDescr_t descrA, float *bsrValA, const int *bsrRowPtrA, const int *bsrColIndA, int blockDim, bsric02Info_t info, hipsparseSolvePolicy_t policy, void *pBuffer)#
hipsparseStatus_t hipsparseDbsric02(hipsparseHandle_t handle, hipsparseDirection_t dirA, int mb, int nnzb, const hipsparseMatDescr_t descrA, double *bsrValA, const int *bsrRowPtrA, const int *bsrColIndA, int blockDim, bsric02Info_t info, hipsparseSolvePolicy_t policy, void *pBuffer)#
hipsparseStatus_t hipsparseCbsric02(hipsparseHandle_t handle, hipsparseDirection_t dirA, int mb, int nnzb, const hipsparseMatDescr_t descrA, hipComplex *bsrValA, const int *bsrRowPtrA, const int *bsrColIndA, int blockDim, bsric02Info_t info, hipsparseSolvePolicy_t policy, void *pBuffer)#
hipsparseStatus_t hipsparseZbsric02(hipsparseHandle_t handle, hipsparseDirection_t dirA, int mb, int nnzb, const hipsparseMatDescr_t descrA, hipDoubleComplex *bsrValA, const int *bsrRowPtrA, const int *bsrColIndA, int blockDim, bsric02Info_t info, hipsparseSolvePolicy_t policy, void *pBuffer)#

Incomplete Cholesky factorization with 0 fill-ins and no pivoting using BSR storage format.

hipsparseXbsric02 computes the incomplete Cholesky factorization with 0 fill-ins and no pivoting of a sparse \(mb \times mb\) BSR matrix \(A\), such that

\[ A \approx LL^T \]

Computing the above incomplete Cholesky factorization requires three steps to complete. First, the user determines the size of the required temporary storage buffer by calling hipsparseXbsric02_bufferSize(). Once this buffer size has been determined, the user allocates the buffer and passes it to hipsparseXbsric02_analysis(). This will perform analysis on the sparsity pattern of the matrix. Finally, the user calls hipsparseXbsric02 to perform the actual factorization. The calculation of the buffer size and the analysis of the sparse matrix only need to be performed once for a given sparsity pattern while the factorization can be repeatedly applied to multiple matrices having the same sparsity pattern. Once all calls to hipsparseXbsric02 are complete, the temporary buffer can be deallocated.

hipsparseXbsric02 requires a user allocated temporary buffer. Its size is returned by hipsparseXbsric02_bufferSize(). Furthermore, analysis meta data is required. It can be obtained by hipsparseXbsric02_analysis(). hipsparseXbsric02 reports the first zero pivot (either numerical or structural zero). The zero pivot status can be obtained by calling hipsparseXbsric02_zeroPivot().

hipsparseXbsric02 reports the first zero pivot (either numerical or structural zero). The zero pivot status can be obtained by calling hipsparseXbsric02_zeroPivot().

Note

This function is non blocking and executed asynchronously with respect to the host. It may return before the actual computation has finished.

Parameters:
  • handle[in] handle to the hipsparse library context queue.

  • dirA[in] direction that specified whether to count nonzero elements by HIPSPARSE_DIRECTION_ROW or by HIPSPARSE_DIRECTION_COLUMN.

  • mb[in] number of block rows in the sparse BSR matrix.

  • nnzb[in] number of non-zero block entries of the sparse BSR matrix.

  • descrA[in] descriptor of the sparse BSR matrix.

  • bsrValA[inout] array of length nnzb*blockDim*blockDim containing the values of the sparse BSR matrix.

  • bsrRowPtrA[in] array of mb+1 elements that point to the start of every block row of the sparse BSR matrix.

  • bsrColIndA[in] array of nnzb elements containing the block column indices of the sparse BSR matrix.

  • blockDim[in] the block dimension of the BSR matrix. Between 1 and m where m=mb*blockDim.

  • info[in] structure that holds the information collected during the analysis step.

  • policy[in] HIPSPARSE_SOLVE_POLICY_NO_LEVEL or HIPSPARSE_SOLVE_POLICY_USE_LEVEL.

  • pBuffer[in] temporary storage buffer allocated by the user.

Return values:
  • HIPSPARSE_STATUS_SUCCESS – the operation completed successfully.

  • HIPSPARSE_STATUS_INVALID_VALUEhandle, mb, nnzb, blockDim, descrA, bsrValA, bsrRowPtrA, or bsrColIndA pointer is invalid.

  • HIPSPARSE_STATUS_ARCH_MISMATCH – the device is not supported.

  • HIPSPARSE_STATUS_INTERNAL_ERROR – an internal error occurred.

  • HIPSPARSE_STATUS_NOT_SUPPORTEDhipsparseMatrixType_t != HIPSPARSE_MATRIX_TYPE_GENERAL.

  1int main(int argc, char* argv[])
  2{
  3    // hipSPARSE handle
  4    hipsparseHandle_t handle;
  5    HIPSPARSE_CHECK(hipsparseCreate(&handle));
  6
  7    // A sample symmetric positive definite matrix A (4x4)
  8    // with a block size of 1. This example effectively uses BSR format
  9    // for a CSR-like matrix.
 10    // Matrix A:
 11    // ( 4  1  0  0 )
 12    // ( 1  5  2  0 )
 13    // ( 0  2  3  1 )
 14    // ( 0  0  1  2 )
 15
 16    const int m    = 4; // Number of rows
 17    const int n    = 4; // Number of columns
 18    const int bs   = 1; // Block size
 19    const int mb   = m / bs; // Number of block rows
 20    const int nb   = n / bs; // Number of block columns
 21    const int nnzb = 10; // Number of non-zero blocks
 22
 23    // BSR row pointers
 24    std::vector<int> hbsrRowPtr = {0, 2, 5, 8, 10};
 25
 26    // BSR column indices
 27    std::vector<int> hbsrColInd = {0, 1, 0, 1, 2, 1, 2, 3, 2, 3};
 28
 29    // BSR values (single precision float for 'S'bsric02)
 30    // Values are stored column-major within each block, but with bs=1, this is simple.
 31    // The values correspond to the upper triangular part of the matrix.
 32    std::vector<float> hbsrVal = {4.0f, 1.0f, 1.0f, 5.0f, 2.0f, 2.0f, 3.0f, 1.0f, 1.0f, 2.0f};
 33
 34    // Matrix descriptor
 35    hipsparseMatDescr_t descr;
 36    HIPSPARSE_CHECK(hipsparseCreateMatDescr(&descr));
 37
 38    // Set index base on descriptor
 39    HIPSPARSE_CHECK(hipsparseSetMatIndexBase(descr, HIPSPARSE_INDEX_BASE_ZERO));
 40
 41    // Set fill mode to lower and diagonal type to unit (required for IC02)
 42    HIPSPARSE_CHECK(hipsparseSetMatFillMode(descr, HIPSPARSE_FILL_MODE_LOWER));
 43    HIPSPARSE_CHECK(hipsparseSetMatDiagType(descr, HIPSPARSE_DIAG_TYPE_UNIT));
 44
 45    // BSRIC02 info
 46    bsric02Info_t info;
 47    HIPSPARSE_CHECK(hipsparseCreateBsric02Info(&info));
 48
 49    // Offload data to device
 50    int*   dbsrRowPtr;
 51    int*   dbsrColInd;
 52    float* dbsrVal;
 53
 54    HIP_CHECK(hipMalloc((void**)&dbsrRowPtr, sizeof(int) * (mb + 1)));
 55    HIP_CHECK(hipMalloc((void**)&dbsrColInd, sizeof(int) * nnzb));
 56    HIP_CHECK(hipMalloc((void**)&dbsrVal, sizeof(float) * nnzb * bs * bs));
 57
 58    HIP_CHECK(
 59        hipMemcpy(dbsrRowPtr, hbsrRowPtr.data(), sizeof(int) * (mb + 1), hipMemcpyHostToDevice));
 60    HIP_CHECK(hipMemcpy(dbsrColInd, hbsrColInd.data(), sizeof(int) * nnzb, hipMemcpyHostToDevice));
 61    HIP_CHECK(
 62        hipMemcpy(dbsrVal, hbsrVal.data(), sizeof(float) * nnzb * bs * bs, hipMemcpyHostToDevice));
 63
 64    // 1. Get buffer size
 65    int bufferSize = 0;
 66    HIPSPARSE_CHECK(hipsparseSbsric02_bufferSize(handle,
 67                                                 HIPSPARSE_DIRECTION_COLUMN,
 68                                                 mb,
 69                                                 nnzb,
 70                                                 descr,
 71                                                 dbsrVal,
 72                                                 dbsrRowPtr,
 73                                                 dbsrColInd,
 74                                                 bs,
 75                                                 info,
 76                                                 &bufferSize));
 77
 78    void* dbuffer = nullptr;
 79    HIP_CHECK(hipMalloc((void**)&dbuffer, bufferSize));
 80
 81    // 2. Perform analysis (symbolic factorization)
 82    HIPSPARSE_CHECK(hipsparseSbsric02_analysis(handle,
 83                                               HIPSPARSE_DIRECTION_COLUMN,
 84                                               mb,
 85                                               nnzb,
 86                                               descr,
 87                                               dbsrVal,
 88                                               dbsrRowPtr,
 89                                               dbsrColInd,
 90                                               bs,
 91                                               info,
 92                                               HIPSPARSE_SOLVE_POLICY_USE_LEVEL,
 93                                               dbuffer));
 94
 95    // 3. Perform factorization (numerical computation)
 96    HIPSPARSE_CHECK(hipsparseSbsric02(handle,
 97                                      HIPSPARSE_DIRECTION_COLUMN,
 98                                      mb,
 99                                      nnzb,
100                                      descr,
101                                      dbsrVal,
102                                      dbsrRowPtr,
103                                      dbsrColInd,
104                                      bs,
105                                      info,
106                                      HIPSPARSE_SOLVE_POLICY_USE_LEVEL,
107                                      dbuffer));
108
109    // 4. Check for zero pivots
110    int zeroPivot = 0;
111    HIPSPARSE_CHECK(hipsparseXbsric02_zeroPivot(handle, info, &zeroPivot));
112    if(zeroPivot != -1)
113    {
114        printf("Error: Zero pivot detected at index %d\n", zeroPivot);
115        // Handle error, e.g., by returning an error code
116    }
117
118    // Copy the factorized values back to host
119    std::vector<float> hbsrVal_result(nnzb * bs * bs);
120    HIP_CHECK(hipMemcpy(
121        hbsrVal_result.data(), dbsrVal, sizeof(float) * nnzb * bs * bs, hipMemcpyDeviceToHost));
122
123    // Print the result (the values of the factorized matrix)
124    printf("Successfully computed incomplete Cholesky factorization.\n");
125    printf("Factorized BSR values:\n");
126    for(int i = 0; i < nnzb * bs * bs; ++i)
127    {
128        printf("val[%d] = %f\n", i, hbsrVal_result[i]);
129    }
130
131    // Clean up
132    HIPSPARSE_CHECK(hipsparseDestroyBsric02Info(info));
133    HIPSPARSE_CHECK(hipsparseDestroyMatDescr(descr));
134    HIPSPARSE_CHECK(hipsparseDestroy(handle));
135
136    HIP_CHECK(hipFree(dbsrRowPtr));
137    HIP_CHECK(hipFree(dbsrColInd));
138    HIP_CHECK(hipFree(dbsrVal));
139    HIP_CHECK(hipFree(dbuffer));
140
141    return 0;
142}

hipsparseXcsric02_zeroPivot()#

hipsparseStatus_t hipsparseXcsric02_zeroPivot(hipsparseHandle_t handle, csric02Info_t info, int *position)#

hipsparseXcsric02_zeroPivot returns HIPSPARSE_STATUS_ZERO_PIVOT, if either a structural or numerical zero has been found during hipsparseXcsric02_analysis() or hipsparseXcsric02() computation. The first zero pivot \(j\) at \(A_{j,j}\) is stored in position, using same index base as the CSR matrix.

position can be in host or device memory. If no zero pivot has been found, position is set to -1 and HIPSPARSE_STATUS_SUCCESS is returned instead.

Deprecated:

This function is deprecated when using the CUDA backend (CUDA 12.0+) and will be removed in CUDA 13.0. This deprecation does not apply to the ROCm backend.

Note

hipsparseXcsric02_zeroPivot is a blocking function. It might influence performance negatively.

Parameters:
  • handle[in] handle to the hipsparse library context queue.

  • info[in] structure that holds the information collected during the analysis step.

  • position[inout] pointer to zero pivot \(j\), can be in host or device memory.

Return values:
  • HIPSPARSE_STATUS_SUCCESS – the operation completed successfully.

  • HIPSPARSE_STATUS_NOT_INITIALIZEDhandle is not initialized.

  • HIPSPARSE_STATUS_INVALID_VALUEhandle, info or position is nullptr.

  • HIPSPARSE_STATUS_INTERNAL_ERROR – an internal error occurred.

  • HIPSPARSE_STATUS_ZERO_PIVOT – zero pivot has been found.

hipsparseXcsric02_bufferSize()#

hipsparseStatus_t hipsparseScsric02_bufferSize(hipsparseHandle_t handle, int m, int nnz, const hipsparseMatDescr_t descrA, float *csrSortedValA, const int *csrSortedRowPtrA, const int *csrSortedColIndA, csric02Info_t info, int *pBufferSizeInBytes)#
hipsparseStatus_t hipsparseDcsric02_bufferSize(hipsparseHandle_t handle, int m, int nnz, const hipsparseMatDescr_t descrA, double *csrSortedValA, const int *csrSortedRowPtrA, const int *csrSortedColIndA, csric02Info_t info, int *pBufferSizeInBytes)#
hipsparseStatus_t hipsparseCcsric02_bufferSize(hipsparseHandle_t handle, int m, int nnz, const hipsparseMatDescr_t descrA, hipComplex *csrSortedValA, const int *csrSortedRowPtrA, const int *csrSortedColIndA, csric02Info_t info, int *pBufferSizeInBytes)#
hipsparseStatus_t hipsparseZcsric02_bufferSize(hipsparseHandle_t handle, int m, int nnz, const hipsparseMatDescr_t descrA, hipDoubleComplex *csrSortedValA, const int *csrSortedRowPtrA, const int *csrSortedColIndA, csric02Info_t info, int *pBufferSizeInBytes)#

hipsparseXcsric02_bufferSize returns the size of the temporary storage buffer in bytes that is required by hipsparseXcsric02_analysis() and hipsparseXcsric02(). The temporary storage buffer must be allocated by the user.

Parameters:
  • handle[in] handle to the hipsparse library context queue.

  • m[in] number of rows of the sparse CSR matrix.

  • nnz[in] number of non-zero entries of the sparse CSR matrix.

  • descrA[in] descriptor of the sparse CSR matrix.

  • csrSortedValA[in] array of nnz elements of the sparse CSR matrix.

  • csrSortedRowPtrA[in] array of m+1 elements that point to the start of every row of the sparse CSR matrix.

  • csrSortedColIndA[in] array of nnz elements containing the column indices of the sparse CSR matrix.

  • info[out] structure that holds the information collected during the analysis step.

  • pBufferSizeInBytes[out] number of bytes of the temporary storage buffer required by hipsparseXcsric02_analysis() and hipsparseXcsric02().

Return values:
  • HIPSPARSE_STATUS_SUCCESS – the operation completed successfully.

  • HIPSPARSE_STATUS_INVALID_VALUEhandle, m, nnz, descrA, csrSortedValA, csrSortedRowPtrA, csrSortedColIndA, info or pBufferSizeInBytes pointer is invalid.

  • HIPSPARSE_STATUS_INTERNAL_ERROR – an internal error occurred.

  • HIPSPARSE_STATUS_NOT_SUPPORTEDhipsparseMatrixType_t != HIPSPARSE_MATRIX_TYPE_GENERAL.

hipsparseXcsric02_bufferSizeExt()#

hipsparseStatus_t hipsparseScsric02_bufferSizeExt(hipsparseHandle_t handle, int m, int nnz, const hipsparseMatDescr_t descrA, float *csrSortedValA, const int *csrSortedRowPtrA, const int *csrSortedColIndA, csric02Info_t info, size_t *pBufferSizeInBytes)#
hipsparseStatus_t hipsparseDcsric02_bufferSizeExt(hipsparseHandle_t handle, int m, int nnz, const hipsparseMatDescr_t descrA, double *csrSortedValA, const int *csrSortedRowPtrA, const int *csrSortedColIndA, csric02Info_t info, size_t *pBufferSizeInBytes)#
hipsparseStatus_t hipsparseCcsric02_bufferSizeExt(hipsparseHandle_t handle, int m, int nnz, const hipsparseMatDescr_t descrA, hipComplex *csrSortedValA, const int *csrSortedRowPtrA, const int *csrSortedColIndA, csric02Info_t info, size_t *pBufferSizeInBytes)#
hipsparseStatus_t hipsparseZcsric02_bufferSizeExt(hipsparseHandle_t handle, int m, int nnz, const hipsparseMatDescr_t descrA, hipDoubleComplex *csrSortedValA, const int *csrSortedRowPtrA, const int *csrSortedColIndA, csric02Info_t info, size_t *pBufferSizeInBytes)#

hipsparseXcsric02_bufferSizeExt returns the size of the temporary storage buffer in bytes that is required by hipsparseXcsric02_analysis() and hipsparseXcsric02(). The temporary storage buffer must be allocated by the user.

Parameters:
  • handle[in] handle to the hipsparse library context queue.

  • m[in] number of rows of the sparse CSR matrix.

  • nnz[in] number of non-zero entries of the sparse CSR matrix.

  • descrA[in] descriptor of the sparse CSR matrix.

  • csrSortedValA[in] array of nnz elements of the sparse CSR matrix.

  • csrSortedRowPtrA[in] array of m+1 elements that point to the start of every row of the sparse CSR matrix.

  • csrSortedColIndA[in] array of nnz elements containing the column indices of the sparse CSR matrix.

  • info[out] structure that holds the information collected during the analysis step.

  • pBufferSizeInBytes[out] number of bytes of the temporary storage buffer required by hipsparseXcsric02_analysis() and hipsparseXcsric02().

Return values:
  • HIPSPARSE_STATUS_SUCCESS – the operation completed successfully.

  • HIPSPARSE_STATUS_INVALID_VALUEhandle, m, nnz, descrA, csrSortedValA, csrSortedRowPtrA, csrSortedColIndA, info or pBufferSizeInBytes pointer is invalid.

  • HIPSPARSE_STATUS_INTERNAL_ERROR – an internal error occurred.

  • HIPSPARSE_STATUS_NOT_SUPPORTEDhipsparseMatrixType_t != HIPSPARSE_MATRIX_TYPE_GENERAL.

hipsparseXcsric02_analysis()#

hipsparseStatus_t hipsparseScsric02_analysis(hipsparseHandle_t handle, int m, int nnz, const hipsparseMatDescr_t descrA, const float *csrSortedValA, const int *csrSortedRowPtrA, const int *csrSortedColIndA, csric02Info_t info, hipsparseSolvePolicy_t policy, void *pBuffer)#
hipsparseStatus_t hipsparseDcsric02_analysis(hipsparseHandle_t handle, int m, int nnz, const hipsparseMatDescr_t descrA, const double *csrSortedValA, const int *csrSortedRowPtrA, const int *csrSortedColIndA, csric02Info_t info, hipsparseSolvePolicy_t policy, void *pBuffer)#
hipsparseStatus_t hipsparseCcsric02_analysis(hipsparseHandle_t handle, int m, int nnz, const hipsparseMatDescr_t descrA, const hipComplex *csrSortedValA, const int *csrSortedRowPtrA, const int *csrSortedColIndA, csric02Info_t info, hipsparseSolvePolicy_t policy, void *pBuffer)#
hipsparseStatus_t hipsparseZcsric02_analysis(hipsparseHandle_t handle, int m, int nnz, const hipsparseMatDescr_t descrA, const hipDoubleComplex *csrSortedValA, const int *csrSortedRowPtrA, const int *csrSortedColIndA, csric02Info_t info, hipsparseSolvePolicy_t policy, void *pBuffer)#

hipsparseXcsric02_analysis performs the analysis step for hipsparseXcsric02().

Note

If the matrix sparsity pattern changes, the gathered information will become invalid.

Note

This function is non blocking and executed asynchronously with respect to the host. It may return before the actual computation has finished.

Parameters:
  • handle[in] handle to the hipsparse library context queue.

  • m[in] number of rows of the sparse CSR matrix.

  • nnz[in] number of non-zero entries of the sparse CSR matrix.

  • descrA[in] descriptor of the sparse CSR matrix.

  • csrSortedValA[in] array of nnz elements of the sparse CSR matrix.

  • csrSortedRowPtrA[in] array of m+1 elements that point to the start of every row of the sparse CSR matrix.

  • csrSortedColIndA[in] array of nnz elements containing the column indices of the sparse CSR matrix.

  • info[out] structure that holds the information collected during the analysis step.

  • policy[in] HIPSPARSE_SOLVE_POLICY_NO_LEVEL or HIPSPARSE_SOLVE_POLICY_USE_LEVEL.

  • pBuffer[in] temporary storage buffer allocated by the user.

Return values:
  • HIPSPARSE_STATUS_SUCCESS – the operation completed successfully.

  • HIPSPARSE_STATUS_INVALID_VALUEhandle, m, nnz, descrA, csrSortedValA, csrSortedRowPtrA, csrSortedColIndA, info or pBuffer pointer is invalid.

  • HIPSPARSE_STATUS_INTERNAL_ERROR – an internal error occurred.

  • HIPSPARSE_STATUS_NOT_SUPPORTEDhipsparseMatrixType_t != HIPSPARSE_MATRIX_TYPE_GENERAL.

hipsparseXcsric02()#

hipsparseStatus_t hipsparseScsric02(hipsparseHandle_t handle, int m, int nnz, const hipsparseMatDescr_t descrA, float *csrSortedValA_valM, const int *csrSortedRowPtrA, const int *csrSortedColIndA, csric02Info_t info, hipsparseSolvePolicy_t policy, void *pBuffer)#
hipsparseStatus_t hipsparseDcsric02(hipsparseHandle_t handle, int m, int nnz, const hipsparseMatDescr_t descrA, double *csrSortedValA_valM, const int *csrSortedRowPtrA, const int *csrSortedColIndA, csric02Info_t info, hipsparseSolvePolicy_t policy, void *pBuffer)#
hipsparseStatus_t hipsparseCcsric02(hipsparseHandle_t handle, int m, int nnz, const hipsparseMatDescr_t descrA, hipComplex *csrSortedValA_valM, const int *csrSortedRowPtrA, const int *csrSortedColIndA, csric02Info_t info, hipsparseSolvePolicy_t policy, void *pBuffer)#
hipsparseStatus_t hipsparseZcsric02(hipsparseHandle_t handle, int m, int nnz, const hipsparseMatDescr_t descrA, hipDoubleComplex *csrSortedValA_valM, const int *csrSortedRowPtrA, const int *csrSortedColIndA, csric02Info_t info, hipsparseSolvePolicy_t policy, void *pBuffer)#

Incomplete Cholesky factorization with 0 fill-ins and no pivoting using CSR storage format.

hipsparseXcsric02 computes the incomplete Cholesky factorization with 0 fill-ins and no pivoting of a sparse \(m \times m\) CSR matrix \(A\), such that

\[ A \approx LL^T \]
where the lower triangular matrix \(L\) is computed using:
\[\begin{split} L_{ij} = \left\{ \begin{array}{ll} \sqrt{A_{jj} - \sum_{k=0}^{j-1}(L_{jk})^{2}}, & \text{if i == j} \\ \frac{1}{L_{jj}}(A_{jj} - \sum_{k=0}^{j-1}L_{ik} \times L_{jk}), & \text{if i > j} \end{array} \right. \end{split}\]
for each entry found in the CSR matrix \(A\).

Computing the above incomplete Cholesky factorization requires three steps to complete. First, the user determines the size of the required temporary storage buffer by calling hipsparseXcsric02_bufferSize(). Once this buffer size has been determined, the user allocates the buffer and passes it to hipsparseXcsric02_analysis(). This will perform analysis on the sparsity pattern of the matrix. Finally, the user calls hipsparseScsric02, hipsparseDcsric02, hipsparseCcsric02, or hipsparseZcsric02 to perform the actual factorization. The calculation of the buffer size and the analysis of the sparse matrix only need to be performed once for a given sparsity pattern while the factorization can be repeatedly applied to multiple matrices having the same sparsity pattern. Once all calls to hipsparseXcsric02() are complete, the temporary buffer can be deallocated.

When computing the Cholesky factorization, it is possible that \(L_{jj} == 0\) which would result in a division by zero. This could occur from either \(A_{jj}\) not existing in the sparse CSR matrix (referred to as a structural zero) or because \(A_{jj} - \sum_{k=0}^{j-1}(L_{jk})^{2} == 0\) (referred to as a numerical zero). For example, running the Cholesky factorization on the following matrix:

\[\begin{split} \begin{bmatrix} 2 & 1 & 0 \\ 1 & 2 & 1 \\ 0 & 1 & 2 \end{bmatrix} \end{split}\]
results in a successful Cholesky factorization, however running with the matrix:
\[\begin{split} \begin{bmatrix} 2 & 1 & 0 \\ 1 & 1/2 & 1 \\ 0 & 1 & 2 \end{bmatrix} \end{split}\]
results in a numerical zero because:
\[\begin{split} \begin{array}{ll} L_{00} &= \sqrt{2} \\ L_{10} &= \frac{1}{\sqrt{2}} \\ L_{11} &= \sqrt{\frac{1}{2} - (\frac{1}{\sqrt{2}})^2} &= 0 \end{array} \end{split}\]
The user can detect the presence of a structural zero by calling hipsparseXcsric02_zeroPivot() after hipsparseXcsric02_analysis() and/or the presence of a structural or numerical zero by calling hipsparseXcsric02_zeroPivot() after hipsparseXcsric02():
hipsparseDcsric02(handle,
                  m,
                  nnz,
                  descrM,
                  csrVal,
                  csrRowPtr,
                  csrColInd,
                  info,
                  HIPSPARSE_SOLVE_POLICY_USE_LEVEL,
                  buffer);

// Check for zero pivot
if(CUSPARSE_STATUS_ZERO_PIVOT == hipsparseXcsric02_zeroPivot(handle, info, &position))
{
    printf("L has structural and/or numerical zero at L(%d,%d)\n", position, position);
}
In both cases, hipsparseXcsric02_zeroPivot() will report the first zero pivot (either numerical or structural) found. See full example below. The user can also set the diagonal type to be \(1\) using hipsparseSetMatDiagType() which will interpret the matrix \(A\) as having ones on its diagonal (even if no nonzero exists in the sparsity pattern).

hipsparseXcsric02 computes the Cholesky factorization inplace meaning that the values array csrSortedValA_valM of the \(A\) matrix is overwritten with the \(L\) matrix stored in the lower triangular part of \(A\):

\[\begin{split} \begin{align} \begin{bmatrix} a_{00} & a_{01} & a_{02} \\ a_{10} & a_{11} & a_{12} \\ a_{20} & a_{21} & a_{22} \end{bmatrix} \rightarrow \begin{bmatrix} l_{00} & a_{01} & a_{02} \\ l_{10} & l_{11} & a_{12} \\ l_{20} & l_{21} & l_{22} \end{bmatrix} \end{align} \end{split}\]
The row pointer array csrSortedRowPtrA and the column indices array csrSortedColIndA remain the same for \(A\) and the output as the incomplete factorization does not generate new nonzeros in the output which do not already exist in \(A\).

The performance of computing Cholesky factorization with hipSPARSE greatly depends on the sparisty pattern the the matrix \(A\) as this is what determines the amount of parallelism available.

Note

The sparse CSR matrix has to be sorted. This can be achieved by calling hipsparseXcsrsort().

Note

This function is non blocking and executed asynchronously with respect to the host. It may return before the actual computation has finished.

Parameters:
  • handle[in] handle to the hipsparse library context queue.

  • m[in] number of rows of the sparse CSR matrix.

  • nnz[in] number of non-zero entries of the sparse CSR matrix.

  • descrA[in] descriptor of the sparse CSR matrix.

  • csrSortedValA_valM[inout] array of nnz elements of the sparse CSR matrix.

  • csrSortedRowPtrA[in] array of m+1 elements that point to the start of every row of the sparse CSR matrix.

  • csrSortedColIndA[in] array of nnz elements containing the column indices of the sparse CSR matrix.

  • info[in] structure that holds the information collected during the analysis step.

  • policy[in] HIPSPARSE_SOLVE_POLICY_NO_LEVEL or HIPSPARSE_SOLVE_POLICY_USE_LEVEL.

  • pBuffer[in] temporary storage buffer allocated by the user.

Return values:
  • HIPSPARSE_STATUS_SUCCESS – the operation completed successfully.

  • HIPSPARSE_STATUS_INVALID_VALUEhandle, m, nnz, descrA, csrSortedValA_valM, csrSortedRowPtrA or csrSortedColIndA pointer is invalid.

  • HIPSPARSE_STATUS_ARCH_MISMATCH – the device is not supported.

  • HIPSPARSE_STATUS_INTERNAL_ERROR – an internal error occurred.

  • HIPSPARSE_STATUS_NOT_SUPPORTEDhipsparseMatrixType_t != HIPSPARSE_MATRIX_TYPE_GENERAL.

  1int main(int argc, char* argv[])
  2{
  3    // hipSPARSE handle
  4    hipsparseHandle_t handle;
  5    HIPSPARSE_CHECK(hipsparseCreate(&handle));
  6
  7    // A sample symmetric positive definite matrix A (4x4) in CSR format.
  8    // The 'S' in Scsric02 indicates single precision float.
  9    // Matrix A:
 10    // ( 4  1  0  0 )
 11    // ( 1  5  2  0 )
 12    // ( 0  2  3  1 )
 13    // ( 0  0  1  2 )
 14    // This matrix is symmetric. For IC02, we typically provide the full matrix
 15    // or just the lower/upper part if using `HIPSPARSE_MATRIX_TYPE_SYMMETRIC`
 16    // with the descriptor. Here, we provide elements for both lower and upper parts
 17    // for simplicity, but the factorization will operate on the implicitly
 18    // symmetric matrix and produce the lower triangular factor L.
 19
 20    int m   = 4; // Number of rows
 21    int n   = 4; // Number of columns (equal to m for Cholesky)
 22    int nnz = 10; // Number of non-zero elements (counting only one side for symmetric)
 23
 24    // CSR row pointers
 25    std::vector<int> hcsrRowPtr = {0, 2, 5, 8, 10};
 26
 27    // CSR column indices
 28    // These indices correspond to the non-zero values used below.
 29    // For a symmetric matrix A, we implicitly work with A_lower.
 30    // The output will be L.
 31    std::vector<int> hcsrColInd = {0, 1, 0, 1, 2, 1, 2, 3, 2, 3};
 32
 33    // CSR values (single precision float for 'S'csric02)
 34    // The factorization computes the lower triangular L factor.
 35    // The input values represent the entries of A that correspond to the non-zero pattern.
 36    std::vector<float> hcsrVal = {4.0f, 1.0f, 1.0f, 5.0f, 2.0f, 2.0f, 3.0f, 1.0f, 1.0f, 2.0f};
 37
 38    // Matrix descriptor
 39    hipsparseMatDescr_t descr;
 40    HIPSPARSE_CHECK(hipsparseCreateMatDescr(&descr));
 41
 42    // Set index base on descriptor
 43    HIPSPARSE_CHECK(hipsparseSetMatIndexBase(descr, HIPSPARSE_INDEX_BASE_ZERO));
 44
 45    // For incomplete Cholesky, the L factor is computed.
 46    // L is lower triangular with a unit diagonal.
 47    HIPSPARSE_CHECK(hipsparseSetMatFillMode(descr, HIPSPARSE_FILL_MODE_LOWER));
 48    HIPSPARSE_CHECK(hipsparseSetMatDiagType(descr, HIPSPARSE_DIAG_TYPE_UNIT));
 49    // Optionally set matrix type to symmetric if only storing one triangle of A
 50    // HIPSPARSE_CHECK(hipsparseSetMatType(descr, HIPSPARSE_MATRIX_TYPE_SYMMETRIC));
 51
 52    // CSRIC02 info
 53    csric02Info_t info;
 54    HIPSPARSE_CHECK(hipsparseCreateCsric02Info(&info));
 55
 56    // Offload data to device
 57    int*   dcsrRowPtr;
 58    int*   dcsrColInd;
 59    float* dcsrVal; // This will store the factorized L values
 60
 61    HIP_CHECK(hipMalloc((void**)&dcsrRowPtr, sizeof(int) * (m + 1)));
 62    HIP_CHECK(hipMalloc((void**)&dcsrColInd, sizeof(int) * nnz));
 63    HIP_CHECK(
 64        hipMalloc((void**)&dcsrVal,
 65                  sizeof(float) * nnz)); // Note: Same size as input, values will be overwritten
 66
 67    HIP_CHECK(
 68        hipMemcpy(dcsrRowPtr, hcsrRowPtr.data(), sizeof(int) * (m + 1), hipMemcpyHostToDevice));
 69    HIP_CHECK(hipMemcpy(dcsrColInd, hcsrColInd.data(), sizeof(int) * nnz, hipMemcpyHostToDevice));
 70    HIP_CHECK(hipMemcpy(dcsrVal, hcsrVal.data(), sizeof(float) * nnz, hipMemcpyHostToDevice));
 71
 72    // 1. Get buffer size
 73    int bufferSize = 0;
 74    HIPSPARSE_CHECK(hipsparseScsric02_bufferSize(
 75        handle, m, nnz, descr, dcsrVal, dcsrRowPtr, dcsrColInd, info, &bufferSize));
 76
 77    void* dbuffer = nullptr;
 78    HIP_CHECK(hipMalloc((void**)&dbuffer, bufferSize));
 79
 80    // 2. Perform analysis (symbolic factorization)
 81    // This step analyzes the sparsity pattern of A to determine the structure of L.
 82    HIPSPARSE_CHECK(
 83        hipsparseScsric02_analysis(handle,
 84                                   m,
 85                                   nnz,
 86                                   descr,
 87                                   dcsrVal,
 88                                   dcsrRowPtr,
 89                                   dcsrColInd,
 90                                   info,
 91                                   HIPSPARSE_SOLVE_POLICY_USE_LEVEL, // Policy for analysis
 92                                   dbuffer));
 93
 94    // 3. Perform factorization (numerical computation)
 95    // This step computes the actual numerical values of L, stored in dcsrVal.
 96    HIPSPARSE_CHECK(hipsparseScsric02(handle,
 97                                      m,
 98                                      nnz,
 99                                      descr,
100                                      dcsrVal,
101                                      dcsrRowPtr,
102                                      dcsrColInd,
103                                      info,
104                                      HIPSPARSE_SOLVE_POLICY_USE_LEVEL, // Policy for factorization
105                                      dbuffer));
106
107    // 4. Check for zero pivots
108    // A zero pivot can occur during factorization, indicating a numerical breakdown.
109    int zeroPivot = 0; // -1 if no zero pivot, otherwise the row index of the first zero pivot
110    HIPSPARSE_CHECK(hipsparseXcsric02_zeroPivot(handle, info, &zeroPivot));
111    if(zeroPivot != -1)
112    {
113        printf("Error: Zero pivot detected during IC02 factorization at row index %d\n", zeroPivot);
114        // Depending on your application, you might want to handle this error
115        // or switch to a different preconditioner.
116    }
117    else
118    {
119        printf("CSRIC02 factorization completed successfully (no zero pivots detected).\n");
120    }
121
122    // Copy the factorized values (L) back to host
123    std::vector<float> hcsrVal_result(nnz);
124    HIP_CHECK(
125        hipMemcpy(hcsrVal_result.data(), dcsrVal, sizeof(float) * nnz, hipMemcpyDeviceToHost));
126
127    // Print the result (the values of the factorized L)
128    printf("\nFactorized CSR values (L factor):\n");
129    for(int i = 0; i < nnz; ++i)
130    {
131        printf("val[%d] = %f\n", i, hcsrVal_result[i]);
132    }
133
134    // Clean up
135    HIPSPARSE_CHECK(hipsparseDestroyCsric02Info(info));
136    HIPSPARSE_CHECK(hipsparseDestroyMatDescr(descr));
137    HIPSPARSE_CHECK(hipsparseDestroy(handle));
138
139    HIP_CHECK(hipFree(dcsrRowPtr));
140    HIP_CHECK(hipFree(dcsrColInd));
141    HIP_CHECK(hipFree(dcsrVal));
142    HIP_CHECK(hipFree(dbuffer));
143
144    return 0;
145}

hipsparseXgtsv2_bufferSizeExt()#

hipsparseStatus_t hipsparseSgtsv2_bufferSizeExt(hipsparseHandle_t handle, int m, int n, const float *dl, const float *d, const float *du, const float *B, int ldb, size_t *pBufferSizeInBytes)#
hipsparseStatus_t hipsparseDgtsv2_bufferSizeExt(hipsparseHandle_t handle, int m, int n, const double *dl, const double *d, const double *du, const double *B, int ldb, size_t *pBufferSizeInBytes)#
hipsparseStatus_t hipsparseCgtsv2_bufferSizeExt(hipsparseHandle_t handle, int m, int n, const hipComplex *dl, const hipComplex *d, const hipComplex *du, const hipComplex *B, int ldb, size_t *pBufferSizeInBytes)#
hipsparseStatus_t hipsparseZgtsv2_bufferSizeExt(hipsparseHandle_t handle, int m, int n, const hipDoubleComplex *dl, const hipDoubleComplex *d, const hipDoubleComplex *du, const hipDoubleComplex *B, int ldb, size_t *pBufferSizeInBytes)#

hipsparseSgtsv2_bufferSizeExt returns the size of the temporary storage buffer that is required by hipsparseXgtsv2(). The temporary storage buffer must be allocated by the user.

Note

This function is non blocking and executed asynchronously with respect to the host. It may return before the actual computation has finished.

Note

This routine supports execution in a hipGraph context.

Parameters:
  • handle[in] handle to the hipsparse library context queue.

  • m[in] size of the tri-diagonal linear system. Must be at least 2.

  • n[in] number of columns in the dense matrix B. Must be non-negative.

  • dl[in] lower diagonal of tri-diagonal system. First entry must be zero.

  • d[in] main diagonal of tri-diagonal system.

  • du[in] upper diagonal of tri-diagonal system. Last entry must be zero.

  • B[in] dense matrix of size ( ldb, n ).

  • ldb[in] leading dimension of B. Must satisfy ldb >= max(1, m).

  • pBufferSizeInBytes[out] number of bytes of the temporary storage buffer required by hipsparseXgtsv2().

Return values:
  • HIPSPARSE_STATUS_SUCCESS – the operation completed successfully.

  • HIPSPARSE_STATUS_NOT_INITIALIZEDhandle is not initialized.

  • HIPSPARSE_STATUS_INVALID_VALUEhandle, dl, d, du, B or pBufferSizeInBytes is nullptr, m is less than 2 or n is negative, or ldb is invalid.

  • HIPSPARSE_STATUS_INTERNAL_ERROR – an internal error occurred.

hipsparseXgtsv2()#

hipsparseStatus_t hipsparseSgtsv2(hipsparseHandle_t handle, int m, int n, const float *dl, const float *d, const float *du, float *B, int ldb, void *pBuffer)#
hipsparseStatus_t hipsparseDgtsv2(hipsparseHandle_t handle, int m, int n, const double *dl, const double *d, const double *du, double *B, int ldb, void *pBuffer)#
hipsparseStatus_t hipsparseCgtsv2(hipsparseHandle_t handle, int m, int n, const hipComplex *dl, const hipComplex *d, const hipComplex *du, hipComplex *B, int ldb, void *pBuffer)#
hipsparseStatus_t hipsparseZgtsv2(hipsparseHandle_t handle, int m, int n, const hipDoubleComplex *dl, const hipDoubleComplex *d, const hipDoubleComplex *du, hipDoubleComplex *B, int ldb, void *pBuffer)#

Tridiagonal solver with pivoting.

hipsparseXgtsv2 solves a tridiagonal system for multiple right hand sides using pivoting

\[ T*B = B \]
where \(T\) is a sparse tridiagonal matrix and \(B\) is a dense \(ldb \times n\) matrix storing the right-hand side vectors in column order. The tridiagonal matrix \(T\) is defined by three vectors: dl for the lower diagonal, d for the main diagonal and du for the upper diagonal.

Solving the tridiagonal system involves two steps. First, the user calls hipsparseXgtsv2_bufferSizeExt() in order to determine the size of the required temporary storage buffer. Once determined, the user allocates this buffer and passes it to hipsparseXgtsv2() to perform the actual solve. The \(B\) dense matrix, which initially stores the n right-hand side vectors, is overwritten with the n solution vectors after the call to hipsparseXgtsv2().

Note

This function is non blocking and executed asynchronously with respect to the host. It may return before the actual computation has finished.

Note

This routine supports execution in a hipGraph context.

Parameters:
  • handle[in] handle to the hipSPARSE library context queue.

  • m[in] size of the tri-diagonal linear system (must be >= 2).

  • n[in] number of columns in the dense matrix B.

  • dl[in] lower diagonal of tri-diagonal system. First entry must be zero.

  • d[in] main diagonal of tri-diagonal system.

  • du[in] upper diagonal of tri-diagonal system. Last entry must be zero.

  • B[inout] Dense matrix of size ( ldb, n ).

  • ldb[in] Leading dimension of B. Must satisfy ldb >= max(1, m).

  • pBuffer[in] temporary storage buffer allocated by the user.

Return values:
  • HIPSPARSE_STATUS_SUCCESS – the operation completed successfully.

  • HIPSPARSE_STATUS_INVALID_VALUEhandle, m, n, ldb, dl, d, du, B or pBuffer pointer is invalid.

  • HIPSPARSE_STATUS_INTERNAL_ERROR – an internal error occurred.

 1int main(int argc, char* argv[])
 2{
 3    // Size of square tridiagonal matrix
 4    int m = 5;
 5
 6    // Number of columns in right-hand side (column ordered) matrix
 7    int n = 3;
 8
 9    // Leading dimension of right-hand side (column ordered) matrix
10    int ldb = m;
11
12    // Host tri-diagonal matrix
13    // 2 3 0 0 0
14    // 2 4 2 0 0
15    // 0 1 1 1 0
16    // 0 0 1 3 1
17    // 0 0 0 1 4
18    std::vector<float> hdl = {0.0f, 2.0f, 1.0f, 1.0f, 1.0f};
19    std::vector<float> hd  = {2.0f, 4.0f, 1.0f, 3.0f, 4.0f};
20    std::vector<float> hdu = {3.0f, 2.0f, 1.0f, 1.0f, 0.0f};
21
22    // Host right-hand side column vectors
23    std::vector<float> hB(ldb * n, 2.0f);
24
25    float* ddl = nullptr;
26    float* dd  = nullptr;
27    float* ddu = nullptr;
28    float* dB  = nullptr;
29    HIP_CHECK(hipMalloc((void**)&ddl, sizeof(float) * m));
30    HIP_CHECK(hipMalloc((void**)&dd, sizeof(float) * m));
31    HIP_CHECK(hipMalloc((void**)&ddu, sizeof(float) * m));
32    HIP_CHECK(hipMalloc((void**)&dB, sizeof(float) * ldb * n));
33
34    HIP_CHECK(hipMemcpy(ddl, hdl.data(), sizeof(float) * m, hipMemcpyHostToDevice));
35    HIP_CHECK(hipMemcpy(dd, hd.data(), sizeof(float) * m, hipMemcpyHostToDevice));
36    HIP_CHECK(hipMemcpy(ddu, hdu.data(), sizeof(float) * m, hipMemcpyHostToDevice));
37    HIP_CHECK(hipMemcpy(dB, hB.data(), sizeof(float) * ldb * n, hipMemcpyHostToDevice));
38
39    // hipSPARSE handle
40    hipsparseHandle_t handle;
41    HIPSPARSE_CHECK(hipsparseCreate(&handle));
42
43    // 1. Get buffer size
44    size_t bufferSize = 0;
45    HIPSPARSE_CHECK(
46        hipsparseSgtsv2_bufferSizeExt(handle, m, m, ddl, dd, ddu, dB, ldb, &bufferSize));
47
48    void* dbuffer = nullptr;
49    HIP_CHECK(hipMalloc((void**)&dbuffer, bufferSize));
50
51    // 2. Perform tridiagonal solve with pivoting
52    // The solution is computed and stored in the dB vector.
53    HIPSPARSE_CHECK(hipsparseSgtsv2(handle, m, m, ddl, dd, ddu, dB, ldb, dbuffer));
54
55    // Copy solution back to host from dB
56    HIP_CHECK(hipMemcpy(hB.data(), dB, sizeof(float) * m, hipMemcpyDeviceToHost));
57
58    // Print the solution
59    printf("Solution for the tridiagonal system:\n");
60    for(int i = 0; i < m; ++i)
61    {
62        printf("  x[%d] = %f\n", i, hB[i]);
63    }
64
65    // Clean up
66    HIP_CHECK(hipFree(ddl));
67    HIP_CHECK(hipFree(dd));
68    HIP_CHECK(hipFree(ddu));
69    HIP_CHECK(hipFree(dB));
70    HIP_CHECK(hipFree(dbuffer));
71
72    HIPSPARSE_CHECK(hipsparseDestroy(handle));
73
74    return 0;
75}

hipsparseXgtsv2_nopivot_bufferSizeExt()#

hipsparseStatus_t hipsparseSgtsv2_nopivot_bufferSizeExt(hipsparseHandle_t handle, int m, int n, const float *dl, const float *d, const float *du, const float *B, int ldb, size_t *pBufferSizeInBytes)#
hipsparseStatus_t hipsparseDgtsv2_nopivot_bufferSizeExt(hipsparseHandle_t handle, int m, int n, const double *dl, const double *d, const double *du, const double *B, int ldb, size_t *pBufferSizeInBytes)#
hipsparseStatus_t hipsparseCgtsv2_nopivot_bufferSizeExt(hipsparseHandle_t handle, int m, int n, const hipComplex *dl, const hipComplex *d, const hipComplex *du, const hipComplex *B, int ldb, size_t *pBufferSizeInBytes)#
hipsparseStatus_t hipsparseZgtsv2_nopivot_bufferSizeExt(hipsparseHandle_t handle, int m, int n, const hipDoubleComplex *dl, const hipDoubleComplex *d, const hipDoubleComplex *du, const hipDoubleComplex *B, int ldb, size_t *pBufferSizeInBytes)#

hipsparseXgtsv2_nopivot_bufferSizeExt returns the size of the temporary storage buffer in bytes that is required by hipsparseXgtsv2_nopivot(). The temporary storage buffer must be allocated by the user.

Parameters:
  • handle[in] handle to the hipsparse library context queue.

  • m[in] size of the tri-diagonal linear system. Must be >= 2.

  • n[in] number of columns in the dense matrix B. Must be non-negative.

  • dl[in] lower diagonal of tri-diagonal system. First entry must be zero.

  • d[in] main diagonal of tri-diagonal system.

  • du[in] upper diagonal of tri-diagonal system. Last entry must be zero.

  • B[in] Dense matrix of size ( ldb, n ).

  • ldb[in] Leading dimension of B. Must satisfy ldb >= max(1, m).

  • pBufferSizeInBytes[out] number of bytes of the temporary storage buffer required by hipsparseSgtsv2_nopivot “hipsparseXgtsv2_nopivot()”.

Return values:
  • HIPSPARSE_STATUS_SUCCESS – the operation completed successfully.

  • HIPSPARSE_STATUS_NOT_INITIALIZEDhandle is not initialized.

  • HIPSPARSE_STATUS_INVALID_VALUEhandle, dl, d, du, B or pBufferSizeInBytes is nullptr, m is less than 2 or n is negative, or ldb is invalid.

  • HIPSPARSE_STATUS_INTERNAL_ERROR – an internal error occurred.

hipsparseXgtsv2_nopivot()#

hipsparseStatus_t hipsparseSgtsv2_nopivot(hipsparseHandle_t handle, int m, int n, const float *dl, const float *d, const float *du, float *B, int ldb, void *pBuffer)#
hipsparseStatus_t hipsparseDgtsv2_nopivot(hipsparseHandle_t handle, int m, int n, const double *dl, const double *d, const double *du, double *B, int ldb, void *pBuffer)#
hipsparseStatus_t hipsparseCgtsv2_nopivot(hipsparseHandle_t handle, int m, int n, const hipComplex *dl, const hipComplex *d, const hipComplex *du, hipComplex *B, int ldb, void *pBuffer)#
hipsparseStatus_t hipsparseZgtsv2_nopivot(hipsparseHandle_t handle, int m, int n, const hipDoubleComplex *dl, const hipDoubleComplex *d, const hipDoubleComplex *du, hipDoubleComplex *B, int ldb, void *pBuffer)#

Tridiagonal solver (no pivoting)

hipsparseXgtsv2_nopivot solves a tridiagonal linear system for multiple right-hand sides without pivoting

\[ T*B = B \]
where \(T\) is a sparse tridiagonal matrix and \(B\) is a dense \(ldb \times n\) matrix storing the right-hand side vectors in column order. The tridiagonal matrix \(T\) is defined by three vectors: dl for the lower diagonal, d for the main diagonal and du for the upper diagonal.

Solving the tridiagonal system with multiple right-hand sides without pivoting involves two steps. First, the user calls hipsparseXgtsv2_nopivot_bufferSizeExt() in order to determine the size of the required temporary storage buffer. Once determined, the user allocates this buffer and passes it to hipsparseXgtsv2_nopivot() to perform the actual solve. The \(B\) dense matrix, which initially stores the n right-hand side vectors, is overwritten with the n solution vectors after the call to hipsparseXgtsv2_nopivot().

Note

This function is non blocking and executed asynchronously with respect to the host. It may return before the actual computation has finished.

Parameters:
  • handle[in] handle to the hipsparse library context queue.

  • m[in] size of the tri-diagonal linear system (must be >= 2).

  • n[in] number of columns in the dense matrix B.

  • dl[in] lower diagonal of tri-diagonal system. First entry must be zero.

  • d[in] main diagonal of tri-diagonal system.

  • du[in] upper diagonal of tri-diagonal system. Last entry must be zero.

  • B[inout] Dense matrix of size ( ldb, n ).

  • ldb[in] Leading dimension of B. Must satisfy ldb >= max(1, m).

  • pBuffer[in] temporary storage buffer allocated by the user.

Return values:
  • HIPSPARSE_STATUS_SUCCESS – the operation completed successfully.

  • HIPSPARSE_STATUS_INVALID_VALUEhandle, m, n, ldb, dl, d, du, B or pBuffer pointer is invalid.

  • HIPSPARSE_STATUS_INTERNAL_ERROR – an internal error occurred.

 1int main(int argc, char* argv[])
 2{
 3    // hipSPARSE handle
 4    hipsparseHandle_t handle;
 5    HIPSPARSE_CHECK(hipsparseCreate(&handle));
 6
 7    // Size of square tridiagonal matrix
 8    int m = 5;
 9
10    // Number of columns in right-hand side (column ordered) matrix
11    int n = 3;
12
13    // Leading dimension of right-hand side (column ordered) matrix
14    int ldb = m;
15
16    // Host tri-diagonal matrix
17    //  2 -1  0  0  0
18    // -1  2 -1  0  0
19    //  0 -1  2 -1  0
20    //  0  0 -1  2 -1
21    //  0  0  0 -1  2
22    std::vector<float> hdl = {0.0f, -1.0f, -1.0f, -1.0f, -1.0f};
23    std::vector<float> hd  = {2.0f, 2.0f, 2.0f, 2.0f, 2.0f};
24    std::vector<float> hdu = {-1.0f, -1.0f, -1.0f, -1.0f, 0.0f};
25
26    // Host right-hand side column vectors
27    std::vector<float> hB(ldb * n, 1.0f);
28
29    float* ddl = nullptr;
30    float* dd  = nullptr;
31    float* ddu = nullptr;
32    float* dB  = nullptr;
33    HIP_CHECK(hipMalloc((void**)&ddl, sizeof(float) * m));
34    HIP_CHECK(hipMalloc((void**)&dd, sizeof(float) * m));
35    HIP_CHECK(hipMalloc((void**)&ddu, sizeof(float) * m));
36    HIP_CHECK(hipMalloc((void**)&dB, sizeof(float) * ldb * n));
37
38    HIP_CHECK(hipMemcpy(ddl, hdl.data(), sizeof(float) * m, hipMemcpyHostToDevice));
39    HIP_CHECK(hipMemcpy(dd, hd.data(), sizeof(float) * m, hipMemcpyHostToDevice));
40    HIP_CHECK(hipMemcpy(ddu, hdu.data(), sizeof(float) * m, hipMemcpyHostToDevice));
41    HIP_CHECK(hipMemcpy(dB, hB.data(), sizeof(float) * ldb * n, hipMemcpyHostToDevice));
42
43    // Obtain required buffer size
44    size_t bufferSize;
45    HIPSPARSE_CHECK(
46        hipsparseSgtsv2_nopivot_bufferSizeExt(handle, m, n, ddl, dd, ddu, dB, ldb, &bufferSize));
47
48    void* dbuffer;
49    HIP_CHECK(hipMalloc(&dbuffer, bufferSize));
50
51    HIPSPARSE_CHECK(hipsparseSgtsv2_nopivot(handle, m, n, ddl, dd, ddu, dB, ldb, dbuffer));
52
53    // Copy right-hand side to host
54    HIP_CHECK(hipMemcpy(hB.data(), dB, sizeof(float) * ldb * n, hipMemcpyDeviceToHost));
55
56    // Print the solution
57    printf("Solution for the tridiagonal system:\n");
58    for(int i = 0; i < m; ++i)
59    {
60        printf("  x[%d] = %f\n", i, hB[i]);
61    }
62
63    // Clean up
64    HIP_CHECK(hipFree(ddl));
65    HIP_CHECK(hipFree(dd));
66    HIP_CHECK(hipFree(ddu));
67    HIP_CHECK(hipFree(dB));
68    HIP_CHECK(hipFree(dbuffer));
69
70    HIPSPARSE_CHECK(hipsparseDestroy(handle));
71
72    return 0;
73}

hipsparseXgtsv2StridedBatch_bufferSizeExt()#

hipsparseStatus_t hipsparseSgtsv2StridedBatch_bufferSizeExt(hipsparseHandle_t handle, int m, const float *dl, const float *d, const float *du, const float *x, int batchCount, int batchStride, size_t *pBufferSizeInBytes)#
hipsparseStatus_t hipsparseDgtsv2StridedBatch_bufferSizeExt(hipsparseHandle_t handle, int m, const double *dl, const double *d, const double *du, const double *x, int batchCount, int batchStride, size_t *pBufferSizeInBytes)#
hipsparseStatus_t hipsparseCgtsv2StridedBatch_bufferSizeExt(hipsparseHandle_t handle, int m, const hipComplex *dl, const hipComplex *d, const hipComplex *du, const hipComplex *x, int batchCount, int batchStride, size_t *pBufferSizeInBytes)#
hipsparseStatus_t hipsparseZgtsv2StridedBatch_bufferSizeExt(hipsparseHandle_t handle, int m, const hipDoubleComplex *dl, const hipDoubleComplex *d, const hipDoubleComplex *du, const hipDoubleComplex *x, int batchCount, int batchStride, size_t *pBufferSizeInBytes)#

hipsparseXgtsv2StridedBatch_bufferSizeExt returns the size of the temporary storage buffer in bytes that is required by hipsparseXgtsv2StridedBatch(). The temporary storage buffer must be allocated by the user.

Parameters:
  • handle[in] handle to the hipsparse library context queue.

  • m[in] size of the tri-diagonal linear system.

  • dl[in] lower diagonal of tri-diagonal system where the ith system lower diagonal starts at dl+batchStride*i.

  • d[in] main diagonal of tri-diagonal system where the ith system diagonal starts at d+batchStride*i.

  • du[in] upper diagonal of tri-diagonal system where the ith system upper diagonal starts at du+batchStride*i.

  • x[inout] Dense array of righthand-sides where the ith righthand-side starts at x+batchStride*i.

  • batchCount[in] The number of systems to solve.

  • batchStride[in] The number of elements that separate each system. Must satisfy batchStride >= m.

  • pBufferSizeInBytes[out] number of bytes of the temporary storage buffer required by hipsparseSgtsv2StridedBatch “hipsparseXgtsv2StridedBatch()”.

Return values:
  • HIPSPARSE_STATUS_SUCCESS – the operation completed successfully.

  • HIPSPARSE_STATUS_INVALID_VALUEhandle, m, batchCount, batchStride, dl, d, du, x or pBufferSizeInBytes pointer is invalid.

  • HIPSPARSE_STATUS_INTERNAL_ERROR – an internal error occurred.

hipsparseXgtsv2StridedBatch()#

hipsparseStatus_t hipsparseSgtsv2StridedBatch(hipsparseHandle_t handle, int m, const float *dl, const float *d, const float *du, float *x, int batchCount, int batchStride, void *pBuffer)#
hipsparseStatus_t hipsparseDgtsv2StridedBatch(hipsparseHandle_t handle, int m, const double *dl, const double *d, const double *du, double *x, int batchCount, int batchStride, void *pBuffer)#
hipsparseStatus_t hipsparseCgtsv2StridedBatch(hipsparseHandle_t handle, int m, const hipComplex *dl, const hipComplex *d, const hipComplex *du, hipComplex *x, int batchCount, int batchStride, void *pBuffer)#
hipsparseStatus_t hipsparseZgtsv2StridedBatch(hipsparseHandle_t handle, int m, const hipDoubleComplex *dl, const hipDoubleComplex *d, const hipDoubleComplex *du, hipDoubleComplex *x, int batchCount, int batchStride, void *pBuffer)#

Strided Batch tridiagonal solver (no pivoting)

hipsparseXgtsv2StridedBatch solves a batched tridiagonal linear system

\[ T^{i}*x^{i} = x^{i} \]
where for each batch \(i=0\ldots\) batchCount, \(T^{i}\) is a sparse tridiagonal matrix and \(x^{i}\) is a dense right-hand side vector. All of the tridiagonal matrices, \(T^{i}\), are packed one after the other into three vectors: dl for the lower diagonals, d for the main diagonals and du for the upper diagonals. See below for a description of what this strided memory pattern looks like.

Solving the batched tridiagonal system involves two steps. First, the user calls hipsparseXgtsv2StridedBatch_bufferSizeExt() in order to determine the size of the required temporary storage buffer. Once determined, the user allocates this buffer and passes it to hipsparseXgtsv2StridedBatch() to perform the actual solve. The \(x^{i}\) vectors, which initially stores the right-hand side values, are overwritten with the solution after the call to hipsparseXgtsv2StridedBatch().

The strided batch routines write each batch matrix one after the other in memory. For example, consider the following batch matrices:

\[\begin{split} \begin{bmatrix} t^{0}_{00} & t^{0}_{01} & 0 \\ t^{0}_{10} & t^{0}_{11} & t^{0}_{12} \\ 0 & t^{0}_{21} & t^{0}_{22} \end{bmatrix} \begin{bmatrix} t^{1}_{00} & t^{1}_{01} & 0 \\ t^{1}_{10} & t^{1}_{11} & t^{1}_{12} \\ 0 & t^{1}_{21} & t^{1}_{22} \end{bmatrix} \begin{bmatrix} t^{2}_{00} & t^{2}_{01} & 0 \\ t^{2}_{10} & t^{2}_{11} & t^{2}_{12} \\ 0 & t^{2}_{21} & t^{2}_{22} \end{bmatrix} \end{split}\]

In strided format, the upper, lower, and diagonal arrays would look like:

\[\begin{split} \begin{align} \text{lower} &= \begin{bmatrix} 0 & t^{0}_{10} & t^{0}_{21} & 0 & t^{1}_{10} & t^{1}_{21} & 0 & t^{2}_{10} & t^{2}_{21} \end{bmatrix} \\ \text{diagonal} &= \begin{bmatrix} t^{0}_{00} & t^{0}_{11} & t^{0}_{22} & t^{1}_{00} & t^{1}_{11} & t^{1}_{22} & t^{2}_{00} & t^{2}_{11} & t^{2}_{22} \end{bmatrix} \\ \text{upper} &= \begin{bmatrix} t^{0}_{01} & t^{0}_{12} & 0 & t^{1}_{01} & t^{1}_{12} & 0 & t^{2}_{01} & t^{2}_{12} & 0 \end{bmatrix} \\ \end{align} \end{split}\]
For the lower array, for each batch i, the i*batchStride entries are zero and for the upper array the i*batchStride+batchStride-1 entries are zero.

Note

This function is non blocking and executed asynchronously with respect to the host. It may return before the actual computation has finished.

Parameters:
  • handle[in] handle to the hipsparse library context queue.

  • m[in] size of the tri-diagonal linear system (must be >= 2).

  • dl[in] lower diagonal of tri-diagonal system. First entry must be zero.

  • d[in] main diagonal of tri-diagonal system.

  • du[in] upper diagonal of tri-diagonal system. Last entry must be zero.

  • x[inout] Dense array of righthand-sides where the ith righthand-side starts at x+batchStride*i.

  • batchCount[in] The number of systems to solve.

  • batchStride[in] The number of elements that separate each system. Must satisfy batchStride >= m.

  • pBuffer[in] temporary storage buffer allocated by the user.

Return values:
  • HIPSPARSE_STATUS_SUCCESS – the operation completed successfully.

  • HIPSPARSE_STATUS_INVALID_VALUEhandle, m, batchCount, batchStride, dl, d, du, x or pBuffer pointer is invalid.

  • HIPSPARSE_STATUS_INTERNAL_ERROR – an internal error occurred.

hipsparseXgtsvInterleavedBatch_bufferSizeExt()#

hipsparseStatus_t hipsparseSgtsvInterleavedBatch_bufferSizeExt(hipsparseHandle_t handle, int algo, int m, const float *dl, const float *d, const float *du, const float *x, int batchCount, size_t *pBufferSizeInBytes)#
hipsparseStatus_t hipsparseDgtsvInterleavedBatch_bufferSizeExt(hipsparseHandle_t handle, int algo, int m, const double *dl, const double *d, const double *du, const double *x, int batchCount, size_t *pBufferSizeInBytes)#
hipsparseStatus_t hipsparseCgtsvInterleavedBatch_bufferSizeExt(hipsparseHandle_t handle, int algo, int m, const hipComplex *dl, const hipComplex *d, const hipComplex *du, const hipComplex *x, int batchCount, size_t *pBufferSizeInBytes)#
hipsparseStatus_t hipsparseZgtsvInterleavedBatch_bufferSizeExt(hipsparseHandle_t handle, int algo, int m, const hipDoubleComplex *dl, const hipDoubleComplex *d, const hipDoubleComplex *du, const hipDoubleComplex *x, int batchCount, size_t *pBufferSizeInBytes)#

hipsparseXgtsvInterleavedBatch_bufferSizeExt returns the size of the temporary storage buffer in bytes that is required by hipsparseXgtsvInterleavedBatch(). The temporary storage buffer must be allocated by the user.

Parameters:
  • handle[in] handle to the hipsparse library context queue.

  • algo[in] Algorithm to use when solving tridiagonal systems. Options are thomas ( algo=0 ), LU ( algo=1 ), or QR ( algo=2 ). Thomas algorithm is the fastest but is not stable while LU and QR are slower but are stable.

  • m[in] size of the tri-diagonal linear system.

  • dl[in] lower diagonal of tri-diagonal system. The first element of the lower diagonal must be zero.

  • d[in] main diagonal of tri-diagonal system.

  • du[in] upper diagonal of tri-diagonal system. The last element of the upper diagonal must be zero.

  • x[inout] Dense array of righthand-sides with dimension batchCount by m.

  • batchCount[in] The number of systems to solve.

  • pBufferSizeInBytes[out] number of bytes of the temporary storage buffer required by hipsparseSgtsvInterleavedBatch().

Return values:
  • HIPSPARSE_STATUS_SUCCESS – the operation completed successfully.

  • HIPSPARSE_STATUS_INVALID_VALUEhandle, m, batchCount, dl, d, du, x or pBufferSizeInBytes pointer is invalid.

  • HIPSPARSE_STATUS_INTERNAL_ERROR – an internal error occurred.

hipsparseXgtsvInterleavedBatch()#

hipsparseStatus_t hipsparseSgtsvInterleavedBatch(hipsparseHandle_t handle, int algo, int m, float *dl, float *d, float *du, float *x, int batchCount, void *pBuffer)#
hipsparseStatus_t hipsparseDgtsvInterleavedBatch(hipsparseHandle_t handle, int algo, int m, double *dl, double *d, double *du, double *x, int batchCount, void *pBuffer)#
hipsparseStatus_t hipsparseCgtsvInterleavedBatch(hipsparseHandle_t handle, int algo, int m, hipComplex *dl, hipComplex *d, hipComplex *du, hipComplex *x, int batchCount, void *pBuffer)#
hipsparseStatus_t hipsparseZgtsvInterleavedBatch(hipsparseHandle_t handle, int algo, int m, hipDoubleComplex *dl, hipDoubleComplex *d, hipDoubleComplex *du, hipDoubleComplex *x, int batchCount, void *pBuffer)#

Interleaved Batch tridiagonal solver.

hipsparseXgtsvInterleavedBatch solves a batched tridiagonal linear system

\[ T^{i}*x^{i} = x^{i} \]
where for each batch \(i=0\ldots\) batchCount, \(T^{i}\) is a sparse tridiagonal matrix and \(x^{i}\) is a dense right-hand side vector. All of the tridiagonal matrices, \(T^{i}\), are packed in an interleaved fashion into three vectors: dl for the lower diagonals, d for the main diagonals and du for the upper diagonals. See below for a description of what this interleaved memory pattern looks like.

Solving the batched tridiagonal system involves two steps. First, the user calls hipsparseXgtsvInterleavedBatch_bufferSizeExt() in order to determine the size of the required temporary storage buffer. Once determined, the user allocates this buffer and passes it to hipsparseXgtsvInterleavedBatch() to perform the actual solve. The \(x^{i}\) vectors, which initially stores the right-hand side values, are overwritten with the solution after the call to hipsparseXgtsvInterleavedBatch().

The user can specify different algorithms for hipsparseXgtsvInterleavedBatch to use. Options are thomas ( algo=0 ), LU ( algo=1 ), or QR ( algo=2 ).

Unlike the strided batch routines which write each batch matrix one after the other in memory, the interleaved routines write the batch matrices such that each element from each matrix is written consecutively one after the other. For example, consider the following batch matrices:

\[\begin{split} \begin{bmatrix} t^{0}_{00} & t^{0}_{01} & 0 \\ t^{0}_{10} & t^{0}_{11} & t^{0}_{12} \\ 0 & t^{0}_{21} & t^{0}_{22} \end{bmatrix} \begin{bmatrix} t^{1}_{00} & t^{1}_{01} & 0 \\ t^{1}_{10} & t^{1}_{11} & t^{1}_{12} \\ 0 & t^{1}_{21} & t^{1}_{22} \end{bmatrix} \begin{bmatrix} t^{2}_{00} & t^{2}_{01} & 0 \\ t^{2}_{10} & t^{2}_{11} & t^{2}_{12} \\ 0 & t^{2}_{21} & t^{2}_{22} \end{bmatrix} \end{split}\]

In interleaved format, the upper, lower, and diagonal arrays would look like:

\[\begin{split} \begin{align} \text{lower} &= \begin{bmatrix} 0 & 0 & 0 & t^{0}_{10} & t^{1}_{10} & t^{1}_{10} & t^{0}_{21} & t^{1}_{21} & t^{2}_{21} \end{bmatrix} \\ \text{diagonal} &= \begin{bmatrix} t^{0}_{00} & t^{1}_{00} & t^{2}_{00} & t^{0}_{11} & t^{1}_{11} & t^{2}_{11} & t^{0}_{22} & t^{1}_{22} & t^{2}_{22} \end{bmatrix} \\ \text{upper} &= \begin{bmatrix} t^{0}_{01} & t^{1}_{01} & t^{2}_{01} & t^{0}_{12} & t^{1}_{12} & t^{2}_{12} & 0 & 0 & 0 \end{bmatrix} \\ \end{align} \end{split}\]
For the lower array, the first batchCount entries are zero and for the upper array the last batchCount entries are zero.

Note

This function is non blocking and executed asynchronously with respect to the host. It may return before the actual computation has finished.

Parameters:
  • handle[in] handle to the hipsparse library context queue.

  • algo[in] Algorithm to use when solving tridiagonal systems. Options are thomas ( algo=0 ), LU ( algo=1 ), or QR ( algo=2 ). Thomas algorithm is the fastest but is not stable while LU and QR are slower but are stable.

  • m[in] size of the tri-diagonal linear system.

  • dl[inout] lower diagonal of tri-diagonal system. The first element of the lower diagonal must be zero.

  • d[inout] main diagonal of tri-diagonal system.

  • du[inout] upper diagonal of tri-diagonal system. The last element of the upper diagonal must be zero.

  • x[inout] Dense array of righthand-sides with dimension batchCount by m.

  • batchCount[in] The number of systems to solve.

  • pBuffer[in] temporary storage buffer allocated by the user.

Return values:
  • HIPSPARSE_STATUS_SUCCESS – the operation completed successfully.

  • HIPSPARSE_STATUS_INVALID_VALUEhandle, m, batchCount, dl, d, du, x or pBuffer pointer is invalid.

  • HIPSPARSE_STATUS_INTERNAL_ERROR – an internal error occurred.

  1int main(int argc, char* argv[])
  2{
  3    // hipSPARSE handle
  4    hipsparseHandle_t handle;
  5    HIPSPARSE_CHECK(hipsparseCreate(&handle));
  6
  7    // Size of each square tridiagonal matrix
  8    int m = 6;
  9
 10    // Number of batches
 11    int batchCount = 4;
 12
 13    // Can be Thomas algorithm (0), LU (1), or QR (2)
 14    int algo = 1;
 15
 16    // Host tridiagonal matrix
 17    std::vector<float> hdl(m * batchCount);
 18    std::vector<float> hd(m * batchCount);
 19    std::vector<float> hdu(m * batchCount);
 20
 21    // Solve multiple tridiagonal matrix systems by interleaving matrices for better memory access:
 22    //
 23    //      4 2 0 0 0 0        5 3 0 0 0 0        6 4 0 0 0 0        7 5 0 0 0 0
 24    //      2 4 2 0 0 0        3 5 3 0 0 0        4 6 4 0 0 0        5 7 5 0 0 0
 25    // A1 = 0 2 4 2 0 0   A2 = 0 3 5 3 0 0   A3 = 0 4 6 4 0 0   A4 = 0 5 7 5 0 0
 26    //      0 0 2 4 2 0        0 0 3 5 3 0        0 0 4 6 4 0        0 0 5 7 5 0
 27    //      0 0 0 2 4 2        0 0 0 3 5 3        0 0 0 4 6 4        0 0 0 5 7 5
 28    //      0 0 0 0 2 4        0 0 0 0 3 5        0 0 0 0 4 6        0 0 0 0 5 7
 29    //
 30    // hdl = 0 0 0 0 2 3 4 5 2 3 4 5 2 3 4 5 2 3 4 5 2 3 4 5
 31    // hd  = 4 5 6 7 4 5 6 7 4 5 6 7 4 5 6 7 4 5 6 7 4 5 6 7
 32    // hdu = 2 3 4 5 2 3 4 5 2 3 4 5 2 3 4 5 2 3 4 5 0 0 0 0
 33    for(int b = 0; b < batchCount; ++b)
 34    {
 35        for(int i = 0; i < m; ++i)
 36        {
 37            hdl[batchCount * i + b] = 2 + b;
 38            hd[batchCount * i + b]  = 4 + b;
 39            hdu[batchCount * i + b] = 2 + b;
 40        }
 41
 42        hdl[batchCount * 0 + b]       = 0.0f;
 43        hdu[batchCount * (m - 1) + b] = 0.0f;
 44    }
 45
 46    // Host dense rhs
 47    std::vector<float> hx(m * batchCount);
 48
 49    for(int b = 0; b < batchCount; ++b)
 50    {
 51        for(int i = 0; i < m; ++i)
 52        {
 53            hx[batchCount * i + b] = static_cast<float>(b + 1);
 54        }
 55    }
 56
 57    float* ddl = nullptr;
 58    float* dd  = nullptr;
 59    float* ddu = nullptr;
 60    float* dx  = nullptr;
 61    HIP_CHECK(hipMalloc((void**)&ddl, sizeof(float) * m * batchCount));
 62    HIP_CHECK(hipMalloc((void**)&dd, sizeof(float) * m * batchCount));
 63    HIP_CHECK(hipMalloc((void**)&ddu, sizeof(float) * m * batchCount));
 64    HIP_CHECK(hipMalloc((void**)&dx, sizeof(float) * m * batchCount));
 65
 66    HIP_CHECK(hipMemcpy(ddl, hdl.data(), sizeof(float) * m * batchCount, hipMemcpyHostToDevice));
 67    HIP_CHECK(hipMemcpy(dd, hd.data(), sizeof(float) * m * batchCount, hipMemcpyHostToDevice));
 68    HIP_CHECK(hipMemcpy(ddu, hdu.data(), sizeof(float) * m * batchCount, hipMemcpyHostToDevice));
 69    HIP_CHECK(hipMemcpy(dx, hx.data(), sizeof(float) * m * batchCount, hipMemcpyHostToDevice));
 70
 71    // 1. Get buffer size
 72    size_t bufferSize = 0;
 73    HIPSPARSE_CHECK(hipsparseSgtsvInterleavedBatch_bufferSizeExt(
 74        handle, algo, m, ddl, dd, ddu, dx, batchCount, &bufferSize));
 75
 76    void* dbuffer = nullptr;
 77    HIP_CHECK(hipMalloc((void**)&dbuffer, bufferSize));
 78
 79    // 2. Perform batched tridiagonal solve
 80    HIPSPARSE_CHECK(
 81        hipsparseSgtsvInterleavedBatch(handle, algo, m, ddl, dd, ddu, dx, batchCount, dbuffer));
 82
 83    // Copy solution back to host
 84    HIP_CHECK(hipMemcpy(hx.data(), dx, sizeof(float) * m * batchCount, hipMemcpyDeviceToHost));
 85
 86    // Print the solutions
 87    printf("Solutions for batched tridiagonal systems:\n");
 88    for(int b = 0; b < batchCount; ++b)
 89    {
 90        printf("  Batch %d:\n", b);
 91        for(int i = 0; i < m; ++i)
 92        {
 93            printf("    x[%d] = %f\n", i, hx[i * batchCount + b]);
 94        }
 95    }
 96
 97    // Clean up
 98    HIP_CHECK(hipFree(ddl));
 99    HIP_CHECK(hipFree(dd));
100    HIP_CHECK(hipFree(ddu));
101    HIP_CHECK(hipFree(dx));
102    HIP_CHECK(hipFree(dbuffer));
103
104    HIPSPARSE_CHECK(hipsparseDestroy(handle));
105
106    return 0;
107}

hipsparseXgpsvInterleavedBatch_bufferSizeExt()#

hipsparseStatus_t hipsparseSgpsvInterleavedBatch_bufferSizeExt(hipsparseHandle_t handle, int algo, int m, const float *ds, const float *dl, const float *d, const float *du, const float *dw, const float *x, int batchCount, size_t *pBufferSizeInBytes)#
hipsparseStatus_t hipsparseDgpsvInterleavedBatch_bufferSizeExt(hipsparseHandle_t handle, int algo, int m, const double *ds, const double *dl, const double *d, const double *du, const double *dw, const double *x, int batchCount, size_t *pBufferSizeInBytes)#
hipsparseStatus_t hipsparseCgpsvInterleavedBatch_bufferSizeExt(hipsparseHandle_t handle, int algo, int m, const hipComplex *ds, const hipComplex *dl, const hipComplex *d, const hipComplex *du, const hipComplex *dw, const hipComplex *x, int batchCount, size_t *pBufferSizeInBytes)#
hipsparseStatus_t hipsparseZgpsvInterleavedBatch_bufferSizeExt(hipsparseHandle_t handle, int algo, int m, const hipDoubleComplex *ds, const hipDoubleComplex *dl, const hipDoubleComplex *d, const hipDoubleComplex *du, const hipDoubleComplex *dw, const hipDoubleComplex *x, int batchCount, size_t *pBufferSizeInBytes)#

hipsparseXgpsvInterleavedBatch_bufferSizeExt returns the size of the temporary storage buffer in bytes that is required by hipsparseXgpsvInterleavedBatch(). The temporary storage buffer must be allocated by the user.

Parameters:
  • handle[in] handle to the hipsparse library context queue.

  • algo[in] algorithm to solve the linear system.

  • m[in] size of the pentadiagonal linear system.

  • ds[in] lower diagonal (distance 2) of pentadiagonal system. First two entries must be zero.

  • dl[in] lower diagonal of pentadiagonal system. First entry must be zero.

  • d[in] main diagonal of pentadiagonal system.

  • du[in] upper diagonal of pentadiagonal system. Last entry must be zero.

  • dw[in] upper diagonal (distance 2) of pentadiagonal system. Last two entries must be zero.

  • x[in] Dense array of right-hand-sides with dimension batchCount by m.

  • batchCount[in] The number of systems to solve.

  • pBufferSizeInBytes[out] Number of bytes of the temporary storage buffer required.

Return values:
  • HIPSPARSE_STATUS_SUCCESS – the operation completed successfully.

  • HIPSPARSE_STATUS_INVALID_VALUEhandle, m, alg, batchCount, ds, dl, d, du, dw, x or pBufferSizeInBytes pointer is invalid.

  • HIPSPARSE_STATUS_INTERNAL_ERROR – an internal error occurred.

hipsparseXgpsvInterleavedBatch()#

hipsparseStatus_t hipsparseSgpsvInterleavedBatch(hipsparseHandle_t handle, int algo, int m, float *ds, float *dl, float *d, float *du, float *dw, float *x, int batchCount, void *pBuffer)#
hipsparseStatus_t hipsparseDgpsvInterleavedBatch(hipsparseHandle_t handle, int algo, int m, double *ds, double *dl, double *d, double *du, double *dw, double *x, int batchCount, void *pBuffer)#
hipsparseStatus_t hipsparseCgpsvInterleavedBatch(hipsparseHandle_t handle, int algo, int m, hipComplex *ds, hipComplex *dl, hipComplex *d, hipComplex *du, hipComplex *dw, hipComplex *x, int batchCount, void *pBuffer)#
hipsparseStatus_t hipsparseZgpsvInterleavedBatch(hipsparseHandle_t handle, int algo, int m, hipDoubleComplex *ds, hipDoubleComplex *dl, hipDoubleComplex *d, hipDoubleComplex *du, hipDoubleComplex *dw, hipDoubleComplex *x, int batchCount, void *pBuffer)#

Interleaved Batch pentadiagonal solver.

hipsparseXgpsvInterleavedBatch solves a batch of pentadiagonal linear systems

\[ P^{i}*x^{i} = x^{i} \]
where for each batch \(i=0\ldots\) batchCount, \(P^{i}\) is a sparse pentadiagonal matrix and \(x^{i}\) is a dense right-hand side vector. All of the pentadiagonal matrices, \(P^{i}\), are packed in an interleaved fashion into five vectors: ds for the lowest diagonals, dl for the lower diagonals, d for the main diagonals, du for the upper diagonals, and dw for the highest digaonals. See below for a description of what this interleaved memory pattern looks like.

Solving the batched pentadiagonal system involves two steps. First, the user calls hipsparseSgpsvInterleavedBatch_bufferSizeExt() in order to determine the size of the required temporary storage buffer. Once determined, the user allocates this buffer and passes it to hipsparseXgpsvInterleavedBatch() to perform the actual solve. The \(x^{i}\) vectors, which initially stores the right-hand side values, are overwritten with the solution after the call to hipsparseXgpsvInterleavedBatch().

Unlike the strided batch routines which write each batch matrix one after the other in memory, the interleaved routines write the batch matrices such that each element from each matrix is written consecutively one after the other. For example, consider the following batch matrices:

\[\begin{split} \begin{bmatrix} t^{0}_{00} & t^{0}_{01} & t^{0}_{02} \\ t^{0}_{10} & t^{0}_{11} & t^{0}_{12} \\ t^{0}_{20} & t^{0}_{21} & t^{0}_{22} \end{bmatrix} \begin{bmatrix} t^{1}_{00} & t^{1}_{01} & t^{1}_{02} \\ t^{1}_{10} & t^{1}_{11} & t^{1}_{12} \\ t^{1}_{20} & t^{1}_{21} & t^{1}_{22} \end{bmatrix} \begin{bmatrix} t^{2}_{00} & t^{2}_{01} & t^{2}_{02} \\ t^{2}_{10} & t^{2}_{11} & t^{2}_{12} \\ t^{2}_{20} & t^{2}_{21} & t^{2}_{22} \end{bmatrix} \end{split}\]

In interleaved format, the highest, higher, lowest, lower, and diagonal arrays would look like:

\[\begin{split} \begin{align} \text{lowest} &= \begin{bmatrix} 0 & 0 & 0 & 0 & 0 & 0 & t^{0}_{20} & t^{1}_{20} & t^{2}_{20} \end{bmatrix} \\ \text{lower} &= \begin{bmatrix} 0 & 0 & 0 & t^{0}_{10} & t^{1}_{10} & t^{1}_{10} & t^{0}_{21} & t^{1}_{21} & t^{2}_{21} \end{bmatrix} \\ \text{diagonal} &= \begin{bmatrix} t^{0}_{00} & t^{1}_{00} & t^{2}_{00} & t^{0}_{11} & t^{1}_{11} & t^{2}_{11} & t^{0}_{22} & t^{1}_{22} & t^{2}_{22} \end{bmatrix} \\ \text{higher} &= \begin{bmatrix} t^{0}_{01} & t^{1}_{01} & t^{2}_{01} & t^{0}_{12} & t^{1}_{12} & t^{2}_{12} & 0 & 0 & 0 \end{bmatrix} \\ \text{highest} &= \begin{bmatrix} t^{0}_{02} & t^{1}_{02} & t^{2}_{02} & 0 & 0 & 0 & 0 & 0 & 0 \end{bmatrix} \\ \end{align} \end{split}\]
For the lowest array, the first 2*batchCount entries are zero, for the lower array, the first batchCount entries are zero, for the upper array the last batchCount entries are zero, and for the highest array, the last 2*batchCount entries are zero.

Note

This function is non blocking and executed asynchronously with respect to the host. It may return before the actual computation has finished.

Parameters:
  • handle[in] handle to the hipsparse library context queue.

  • algo[in] algorithm to solve the linear system.

  • m[in] size of the pentadiagonal linear system.

  • ds[inout] lower diagonal (distance 2) of pentadiagonal system. First two entries must be zero.

  • dl[inout] lower diagonal of pentadiagonal system. First entry must be zero.

  • d[inout] main diagonal of pentadiagonal system.

  • du[inout] upper diagonal of pentadiagonal system. Last entry must be zero.

  • dw[inout] upper diagonal (distance 2) of pentadiagonal system. Last two entries must be zero.

  • x[inout] Dense array of right-hand-sides with dimension batchCount by m.

  • batchCount[in] The number of systems to solve.

  • pBuffer[in] Temporary storage buffer allocated by the user.

Return values:
  • HIPSPARSE_STATUS_SUCCESS – the operation completed successfully.

  • HIPSPARSE_STATUS_INVALID_VALUEhandle, m, alg, batchCount, ds, dl, d, du, dw, x or pBuffer pointer is invalid.

  • HIPSPARSE_STATUS_INTERNAL_ERROR – an internal error occurred.