rocsparse_spmm Interface Reference#
Sparse matrix dense matrix multiplication. More...
Public Member Functions | |
| integer(kind(rocsparse_status_success)) function | rocsparse_spmm_ (handle, trans_a, trans_b, alpha, mat_a, mat_b, beta, mat_c, compute_type, alg, stage, buffer_size, temp_buffer) |
Detailed Description
Sparse matrix dense matrix multiplication.
rocsparse_spmm multiplies the scalar \(\alpha\) with a sparse \(m \times k\) matrix \(op(A)\), defined in CSR, CSC, COO, BSR, or Blocked ELL storage format, and the dense \(k \times n\) matrix \(op(B)\) and adds the result to the dense \(m \times n\) matrix \(C\) that is multiplied by the scalar \(\beta\), such that
\[ C := \alpha \cdot op(A) \cdot op(B) + \beta \cdot C, \]
with
\[ op(A) = \left\{ \begin{array}{ll} A, & \text{if trans_A == rocsparse_operation_none} \\% A^T, & \text{if trans_A == rocsparse_operation_transpose} \\% A^H, & \text{if trans_A == rocsparse_operation_conjugate_transpose} \end{array} \right. \]
and
\[ op(B) = \left\{ \begin{array}{ll} B, & \text{if trans_B == rocsparse_operation_none} \\% B^T, & \text{if trans_B == rocsparse_operation_transpose} \\% B^H, & \text{if trans_B == rocsparse_operation_conjugate_transpose} \end{array} \right. \]
Both \(B\) and \(C\) can be in row or column order.
rocsparse_spmm requires three stages to complete. First, pass the rocsparse_spmm_stage_buffer_size stage to determine the size of the required temporary storage buffer. Next, allocate this buffer and call rocsparse_spmm again with the rocsparse_spmm_stage_preprocess stage, which will perform analysis on the sparse matrix \(op(A)\). Finally, call rocsparse_spmm with the rocsparse_spmm_stage_compute stage to perform the actual computation. The buffer size, buffer allocation, and preprocess stages only need to be called once for a given sparse matrix \(op(A)\), while the computation stage can be repeatedly used with different \(B\) and \(C\) matrices. After all calls to rocsparse_spmm are complete, the temporary buffer can be deallocated.
As noted above, both \(B\) and \(C\) can be in row or column order (this includes mixing the order so that \(B\) is in row order and \(C\) in column order and vice versa). For best performance, use row order for both \(B\) and \(C\) as this provides the best memory access.
rocsparse_spmm supports multiple different algorithms. These algorithms have different trade-offs depending on the sparsity pattern of the matrix, whether or not the results need to be deterministic, and how many times the sparse-matrix product will be performed.
| CSR Algorithms | Deterministic | Preprocessing | Notes |
|---|---|---|---|
| rocsparse_spmm_alg_csr | Yes | No | Default algorithm. |
| rocsparse_spmm_alg_csr_row_split | Yes | No | Assigns a fixed number of threads per row, regardless of the number of non-zeros in each row. This can perform well when each row in the matrix has roughly the same number of non-zeros. |
| rocsparse_spmm_alg_csr_nnz_split | No | Yes | Distributes work by having each thread block work on a fixed number of non-zeros, regardless of the number of rows that might be involved. This can perform well when the matrix has some rows with few non-zeros and some rows with many non-zeros. |
| rocsparse_spmm_alg_csr_merge_path | No | Yes | Attempts to combine the approaches of row-split and non-zero split by having each block work on a fixed amount of work, which can be either non-zeros or rows. |
| COO Algorithms | Deterministic | Preprocessing | Notes |
|---|---|---|---|
| rocsparse_spmm_alg_coo_segmented | Yes | No | Generally not as fast as the atomic algorithm but is deterministic. |
| rocsparse_spmm_alg_coo_atomic | No | No | Generally the fastest COO algorithm. This is the default algorithm. |
| rocsparse_spmm_alg_coo_segmented_atomic | No | No |
| Blocked ELL Algorithms | Deterministic | Preprocessing | Notes |
|---|---|---|---|
| rocsparse_spmm_alg_bell | Yes | No |
| BSR Algorithms | Deterministic | Preprocessing | Notes |
|---|---|---|---|
| rocsparse_spmm_alg_bsr | Yes | No |
It is also possible to pass rocsparse_spmm_alg_default, which will automatically select from the algorithms listed above based on the sparse matrix format. In the case of CSR or CSC matrices, this will set the algorithm to be rocsparse_spmm_alg_csr. In the case of blocked ELL matrices, this will set the algorithm to be rocsparse_spmm_alg_bell. In the case of BSR matrices, this will set the algorithm to be rocsparse_spmm_alg_bsr, and for COO matrices, it will set the algorithm to be rocsparse_spmm_alg_coo_atomic.
When A is transposed, rocsparse_spmm will revert to using rocsparse_spmm_alg_csr for CSR and CSC formats and rocsparse_spmm_alg_coo_atomic for COO format, regardless of algorithm selected.
rocsparse_spmm supports multiple combinations of data types and compute types. The tables below indicate the currently supported different data types that can be used for for the sparse matrix \(op(A)\) and the dense matrices \(op(B)\) and \(C\) and the compute type for \(\alpha\) and \(\beta\). The advantage of using different data types is to save on memory bandwidth and storage when a user application allows, while performing the actual computation in a higher precision.
- Uniform Precisions:
-
Uniform Precisions A / B / C / compute_type rocsparse_datatype_f32_r rocsparse_datatype_f64_r rocsparse_datatype_f32_c rocsparse_datatype_f64_c
- Mixed precisions:
-
Mixed Precisions A / B C compute_type rocsparse_datatype_i8_r rocsparse_datatype_i32_r rocsparse_datatype_i32_r rocsparse_datatype_i8_r rocsparse_datatype_f32_r rocsparse_datatype_f32_r rocsparse_datatype_f16_r rocsparse_datatype_f32_r rocsparse_datatype_f32_r rocsparse_datatype_f16_r rocsparse_datatype_f16_r rocsparse_datatype_f32_r rocsparse_datatype_bf16_r rocsparse_datatype_f32_r rocsparse_datatype_f32_r rocsparse_datatype_bf16_r rocsparse_datatype_bf16_r rocsparse_datatype_f32_r
rocsparse_spmm supports rocsparse_indextype_i32 and rocsparse_indextype_i64 index precisions for storing the row pointer and column indices arrays of the sparse matrices.
rocsparse_spmm also supports batched computation for CSR and COO matrices. There are three supported batch modes:
\[ C_i = A \times B_i \\% C_i = A_i \times B \\% C_i = A_i \times B_i \]
The batch mode is determined by the batch count and stride passed for each matrix. For example, to use the first batch mode ( \(C_i = A \times B_i\)) with 100 batches for non-transposed \(A\), \(B\), and \(C\), pass:
\[ batch\_count\_A=1 \\% batch\_count\_B=100 \\% batch\_count\_C=100 \\% offsets\_batch\_stride\_A=0 \\% columns\_values\_batch\_stride\_A=0 \\% batch\_stride\_B=k*n \\% batch\_stride\_C=m*n \]
To use the second batch mode ( \(C_i = A_i \times B\)), pass:
\[ batch\_count\_A=100 \\% batch\_count\_B=1 \\% batch\_count\_C=100 \\% offsets\_batch\_stride\_A=m+1 \\% columns\_values\_batch\_stride\_A=nnz \\% batch\_stride\_B=0 \\% batch\_stride\_C=m*n \]
And to use the third batch mode ( \(C_i = A_i \times B_i\)), pass:
\[ batch\_count\_A=100 \\% batch\_count\_B=100 \\% batch\_count\_C=100 \\% offsets\_batch\_stride\_A=m+1 \\% columns\_values\_batch\_stride_A=nnz \\% batch\_stride_B=k*n \\% batch\_stride_C=m*n \]
See the examples below.
- Note
- None of the algorithms above are deterministic when \(A\) is transposed or conjugate transposed.
- All algorithms perform best when using row ordering for the dense \(B\) and \(C\) matrices.
-
The sparse matrix formats currently supported are:
rocsparse_format_coo,rocsparse_format_csr,rocsparse_format_csc,rocsparse_format_bsr, androcsparse_format_bell. - Mixed precisions are only supported for BSR, CSR, CSC, and COO matrix formats.
-
Only the
rocsparse_spmm_stage_buffer_sizestage and therocsparse_spmm_stage_computestage are non-blocking and executed asynchronously with respect to the host. They can return before the actual computation has finished. Therocsparse_spmm_stage_preprocessstage is blocking with respect to the host. -
Currently, only
trans_A==rocsparse_operation_noneis supported for the COO and blocked ELL formats. -
Only the
rocsparse_spmm_stage_buffer_sizestage and therocsparse_spmm_stage_computestage support execution in a hipGraph context. Therocsparse_spmm_stage_preprocessstage does not support hipGraph. - Currently, only CSR, CSC, COO, BSR, and blocked ELL sparse formats are supported.
- Parameters
-
[in] handle - handle to the rocSPARSE library context queue. [in] trans_A - matrix operation type. [in] trans_B - matrix operation type. [in] alpha - scalar \(\alpha\). [in] mat_A - matrix descriptor. [in] mat_B - matrix descriptor. [in] beta - scalar \(\beta\). [in] mat_C - matrix descriptor. [in] compute_type - floating point precision for the SpMM computation. [in] alg - SpMM algorithm for the SpMM computation. [in] stage - SpMM stage for the SpMM computation. [out] buffer_size - number of bytes of the temporary storage buffer. [in] temp_buffer - temporary storage buffer allocated by the user. When the rocsparse_spmm_stage_buffer_sizestage is passed in, the required allocation size (in bytes) is written tobuffer_sizeand function returns without performing the SpMM operation.
- Return values
-
rocsparse_status_success the operation completed successfully. rocsparse_status_invalid_handle the library context was not initialized. rocsparse_status_invalid_pointer alpha,mat_A,mat_B,mat_C,beta, orbuffer_sizepointer is invalid.rocsparse_status_not_implemented trans_A,trans_B,compute_type, oralgis currently not supported.
- Example
- This example performs sparse matrix-dense matrix multiplication, \(C := \alpha \cdot A \cdot B + \beta \cdot C\)
- Example
- An example of the first batch mode ( \(C_i = A \times B_i\)) is provided below.
Member Function/Subroutine Documentation
◆ rocsparse_spmm_()
| integer(kind(rocsparse_status_success)) function hipfort_rocsparse::rocsparse_spmm::rocsparse_spmm_ | ( | type(c_ptr), value | handle, |
| integer(kind(rocsparse_operation_none)), value | trans_a, | ||
| integer(kind(rocsparse_operation_none)), value | trans_b, | ||
| type(c_ptr), value | alpha, | ||
| type(c_ptr), value | mat_a, | ||
| type(c_ptr), value | mat_b, | ||
| type(c_ptr), value | beta, | ||
| type(c_ptr), value | mat_c, | ||
| integer(kind(rocsparse_datatype_f16_r)), value | compute_type, | ||
| integer(kind(rocsparse_spmm_alg_default)), value | alg, | ||
| integer(kind(rocsparse_spmm_stage_buffer_size)), value | stage, | ||
| integer(c_size_t) | buffer_size, | ||
| type(c_ptr), value | temp_buffer | ||
| ) |
The documentation for this interface was generated from the following file: