Skip to main content
`Ctrl`+`K`

# Bitwise reproducibility

Some routines do not produce deterministic results from run to run. This is typically the case when HIP atomics are used. This page catalogues the run-to-run reproducibility of each routine.

## Sparse level 1 functions

Function name | yes | no
--- | --- | ---
`rocsparse_Xaxpyi()` | x |
`rocsparse_Xdoti()` | x |
`rocsparse_Xdotci()` | x |
`rocsparse_Xgthr()` | x |
`rocsparse_Xgthrz()` | x |
`rocsparse_Xroti()` | x |
`rocsparse_Xsctr()` | x |

## Sparse level 2 functions

Function name | yes | no
--- | --- | ---
`rocsparse_Xbsrmv_analysis()` | x |
`rocsparse_bsrmv_clear()` | x |
`rocsparse_Xbsrmv()` | x |
`rocsparse_Xbsrxmv()` | x |
`rocsparse_Xbsrsv_buffer_size()` | x |
`rocsparse_Xbsrsv_analysis()` |  | x
`rocsparse_bsrsv_zero_pivot()` | x |
`rocsparse_bsrsv_clear()` | x |
`rocsparse_Xbsrsv_solve()` |  | x
`rocsparse_Xcsrmv_analysis()` | x |
`rocsparse_csrmv_clear()` | x |
`rocsparse_Xcsrsv_buffer_size()` | x |
`rocsparse_Xcsrsv_analysis()` |  | x
`rocsparse_csrsv_zero_pivot()` | x |
`rocsparse_csrsv_clear()` | x |
`rocsparse_Xcsrsv_solve()` |  | x
`rocsparse_Xcsritsv_buffer_size()` | x |
`rocsparse_Xcsritsv_analysis()` |  | x
`rocsparse_csritsv_zero_pivot()` | x |
`rocsparse_csritsv_clear()` | x |
`rocsparse_Xcsritsv_solve()` |  | x
`rocsparse_Xcsritsv_solve_ex()` |  | x
`rocsparse_Xgemvi_buffer_size()` | x |
`rocsparse_Xgemvi()` | x |

The reproducibility of `rocsparse_Xbsrmv()`, `rocsparse_Xbsrxmv()`, `rocsparse_Xcoomv()`, `rocsparse_Xcsrmv()`, `rocsparse_Xellmv()`, `rocsparse_Xhybmv()`, and `rocsparse_Xgebsrmv()` is more complicated, depending on whether A is transposed or not. See the chart below to determine whether these routines are deterministic.

Routine | A non-transpose | A transpose
--- | --- | ---
Yes | No | Yes | No
rocsparse_Xbsrmv | x |  | N/A | N/A
rocsparse_Xbsrxmv | x |  | N/A | N/A
rocsparse_Xcoomv | x |  |  | x
rocsparse_Xcsrmv | x |  |  | x
rocsparse_Xcsrmv (info != NULL) |  | x |  | x
rocsparse_Xellmv | x |  |  | x
rocsparse_Xhybmv | x |  |  | x
rocsparse_Xgebsrmv | x |  | N/A | N/A

## Sparse level 3 functions

Function name | yes | no
--- | --- | ---
`rocsparse_Xcsrsm_buffer_size()` | x |
`rocsparse_Xcsrsm_analysis()` |  | x
`rocsparse_csrsm_zero_pivot()` | x |
`rocsparse_csrsm_clear()` | x |
`rocsparse_Xcsrsm_solve()` |  | x
`rocsparse_Xbsrsm_buffer_size()` | x |
`rocsparse_Xbsrsm_analysis()` |  | x
`rocsparse_bsrsm_zero_pivot()` | x |
`rocsparse_bsrsm_clear()` | x |
`rocsparse_Xbsrsm_solve()` |  | x
`rocsparse_Xgemmi()` | x |

The reproducibility of `rocsparse_Xbsrmm()`, `rocsparse_Xgebsrmm()`, and `rocsparse_Xcsrmm()` is more complicated, depending on whether A is transposed or not. See the chart below to determine whether these routines are deterministic.

Routine | A non-transpose | A transpose
--- | --- | ---
Yes | No | Yes | No
rocsparse_Xbsrmm | x |  | N/A | N/A
rocsparse_Xgebsrmm | x |  | N/A | N/A
rocsparse_Xcsrmm | x |  |  | x

## Sparse extra functions

Function name | yes | no
--- | --- | ---
`rocsparse_bsrgeam_nnzb()` | x |
`rocsparse_Xbsrgeam()` | x |
`rocsparse_Xbsrgemm_buffer_size()` | x |
`rocsparse_bsrgemm_nnzb()` | x |
`rocsparse_Xbsrgemm()` | x |
`rocsparse_csrgeam_nnz()` | x |
`rocsparse_Xcsrgeam()` | x |
`rocsparse_Xcsrgemm_buffer_size()` | x |
`rocsparse_csrgemm_nnz()` |  | x
`rocsparse_csrgemm_symbolic()` |  | x
`rocsparse_Xcsrgemm()` |  | x
`rocsparse_Xcsrgemm_numeric()` |  | x

## Preconditioner functions

Function name | yes | no
--- | --- | ---
`rocsparse_Xbsric0_buffer_size()` | x |
`rocsparse_Xbsric0_analysis()` |  | x
`rocsparse_bsric0_zero_pivot()` | x |
`rocsparse_bsric0_clear()` | x |
`rocsparse_Xbsric0()` |  | x
`rocsparse_Xbsrilu0_buffer_size()` | x |
`rocsparse_Xbsrilu0_analysis()` |  | x
`rocsparse_bsrilu0_zero_pivot()` | x |
`rocsparse_Xbsrilu0_numeric_boost()` |  | x
`rocsparse_bsrilu0_clear()` | x |
`rocsparse_Xbsrilu0()` |  | x
`rocsparse_Xcsric0_buffer_size()` | x |
`rocsparse_Xcsric0_analysis()` |  | x
`rocsparse_csric0_zero_pivot()` | x |
`rocsparse_csric0_clear()` | x |
`rocsparse_Xcsric0()` |  | x
`rocsparse_Xcsrilu0_buffer_size()` | x |
`rocsparse_Xcsrilu0_numeric_boost()` |  | x
`rocsparse_Xcsrilu0_analysis()` |  | x
`rocsparse_csrilu0_zero_pivot()` | x |
`rocsparse_csrilu0_clear()` | x |
`rocsparse_Xcsrilu0()` |  | x
`rocsparse_csritilu0_buffer_size()` | x |
`rocsparse_csritilu0_preprocess()` |  | x
`rocsparse_Xcsritilu0_compute()` |  | x
`rocsparse_Xcsritilu0_compute_ex()` |  | x
`rocsparse_Xcsritilu0_history()` |  | x
`rocsparse_Xgtsv_buffer_size()` | x |
`rocsparse_Xgtsv()` | x |
`rocsparse_Xgtsv_no_pivot_buffer_size()` | x |
`rocsparse_Xgtsv_no_pivot()` | x |
`rocsparse_Xgtsv_no_pivot_strided_batch_buffer_size()` | x |
`rocsparse_Xgtsv_no_pivot_strided_batch()` | x |
`rocsparse_Xgtsv_interleaved_batch_buffer_size()` | x |
`rocsparse_Xgtsv_interleaved_batch()` | x |
`rocsparse_Xgpsv_interleaved_batch_buffer_size()` | x |
`rocsparse_Xgpsv_interleaved_batch()` | x |

## Conversion functions

Function name | yes | no
--- | --- | ---
`rocsparse_csr2coo()` | x |
`rocsparse_csr2csc_buffer_size()` | x |
`rocsparse_Xcsr2csc()` | x |
`rocsparse_Xgebsr2gebsc_buffer_size()` | x |
`rocsparse_Xgebsr2gebsc()` | x |
`rocsparse_csr2ell_width()` | x |
`rocsparse_Xcsr2ell()` | x |
`rocsparse_Xcsr2hyb()` | x |
`rocsparse_csr2bsr_nnz()` | x |
`rocsparse_Xcsr2bsr()` | x |
`rocsparse_csr2gebsr_nnz()` | x |
`rocsparse_Xcsr2gebsr_buffer_size()` | x |
`rocsparse_Xcsr2gebsr()` | x |
`rocsparse_coo2csr()` | x |
`rocsparse_ell2csr_nnz()` | x |
`rocsparse_Xell2csr()` | x |
`rocsparse_hyb2csr_buffer_size()` | x |
`rocsparse_Xhyb2csr()` | x |
`rocsparse_Xbsr2csr()` | x |
`rocsparse_Xgebsr2csr()` | x |
`rocsparse_Xgebsr2gebsr_buffer_size()` | x |
`rocsparse_gebsr2gebsr_nnz()` | x |
`rocsparse_Xgebsr2gebsr()` | x |
`rocsparse_Xcsr2csr_compress()` | x |
`rocsparse_create_identity_permutation()` | x |
`rocsparse_inverse_permutation()` | x |
`rocsparse_cscsort_buffer_size()` | x |
`rocsparse_cscsort()` | x |
`rocsparse_csrsort_buffer_size()` | x |
`rocsparse_csrsort()` | x |
`rocsparse_coosort_buffer_size()` | x |
`rocsparse_coosort_by_row()` | x |
`rocsparse_coosort_by_column()` | x |
`rocsparse_Xdense2csr()` | x |
`rocsparse_Xdense2csc()` | x |
`rocsparse_Xdense2coo()` | x |
`rocsparse_Xcsr2dense()` | x |
`rocsparse_Xcsc2dense()` | x |
`rocsparse_Xcoo2dense()` | x |
`rocsparse_Xnnz_compress()` | x |
`rocsparse_Xnnz()` | x |
`rocsparse_Xprune_dense2csr_buffer_size()` | x |
`rocsparse_Xprune_dense2csr_nnz()` | x |
`rocsparse_Xprune_dense2csr()` | x |
`rocsparse_Xprune_csr2csr_buffer_size()` | x |
`rocsparse_Xprune_csr2csr_nnz()` | x |
`rocsparse_Xprune_csr2csr()` | x |
`rocsparse_Xprune_dense2csr_by_percentage_buffer_size()` | x |
`rocsparse_Xprune_dense2csr_nnz_by_percentage()` | x |
`rocsparse_Xprune_dense2csr_by_percentage()` | x |
`rocsparse_Xprune_csr2csr_by_percentage_buffer_size()` | x |
`rocsparse_Xprune_csr2csr_nnz_by_percentage()` | x |
`rocsparse_Xprune_csr2csr_by_percentage()` | x |
`rocsparse_Xbsrpad_value()` | x |

## Reordering functions

Function name | yes | no
--- | --- | ---
`rocsparse_Xcsrcolor()` | x |

## Utility functions

Function name | yes | no
--- | --- | ---
`rocsparse_Xcheck_matrix_csr_buffer_size()` | x |
`rocsparse_Xcheck_matrix_csr()` | x |
`rocsparse_Xcheck_matrix_csc_buffer_size()` | x |
`rocsparse_Xcheck_matrix_csc()` | x |
`rocsparse_Xcheck_matrix_coo_buffer_size()` | x |
`rocsparse_Xcheck_matrix_coo()` | x |
`rocsparse_Xcheck_matrix_gebsr_buffer_size()` | x |
`rocsparse_Xcheck_matrix_gebsr()` | x |
`rocsparse_Xcheck_matrix_gebsc_buffer_size()` | x |
`rocsparse_Xcheck_matrix_gebsc()` | x |
`rocsparse_Xcheck_matrix_ell_buffer_size()` | x |
`rocsparse_Xcheck_matrix_ell()` | x |
`rocsparse_check_matrix_hyb_buffer_size()` | x |
`rocsparse_check_matrix_hyb()` | x |

## Sparse generic functions

Function name | yes | no
--- | --- | ---
`rocsparse_axpby()` | x |
`rocsparse_gather()` | x |
`rocsparse_scatter()` | x |
`rocsparse_rot()` | x |
`rocsparse_spvv()` | x |
`rocsparse_sparse_to_dense()` | x |
`rocsparse_dense_to_sparse()` | x |
`rocsparse_spsv()` |  | x
`rocsparse_spsm()` |  | x
`rocsparse_spgemm()` |  | x
`rocsparse_v2_spmv_buffer_size()` | x |
`rocsparse_spgeam_buffer_size()` | x |
`rocsparse_spgeam()` | x |
`rocsparse_sddmm_buffer_size()` | x |
`rocsparse_sddmm_preprocess()` | x |
`rocsparse_sddmm()` | x |
`rocsparse_sparse_to_sparse_buffer_size()` | x |
`rocsparse_sparse_to_sparse()` | x |
`rocsparse_extract_buffer_size()` | x |
`rocsparse_extract()` | x |

The reproducibility of `rocsparse_spmv()` and `rocsparse_v2_spmv()` is more complicated because these generic routines support multiple sparse matrix formats and algorithms. See the chart below to determine whether a given algorithm is deterministic.

Bit-wise reproducibility of SpMV/v2_SpMV
Algorithm | A non-transpose | A transpose
--- | --- | ---
Yes | No | Yes | No
rocsparse_spmv_alg_csr_stream | x |  |  | x
rocsparse_spmv_alg_csr_rowsplit | x |  |  | x
rocsparse_spmv_alg_csr_adaptive |  | x |  | x
rocsparse_spmv_alg_csr_lrb |  | x |  | x
rocsparse_spmv_alg_csr_stream (CSC FORMAT) |  | x | x |
rocsparse_spmv_alg_csr_rowsplit (CSC FORMAT) |  | x | x |
rocsparse_spmv_alg_csr_adaptive (CSC FORMAT) |  | x |  | x
rocsparse_spmv_alg_csr_lrb (CSC FORMAT) |  | x |  | x
rocsparse_spmv_alg_coo | x |  |  | x
rocsparse_spmv_alg_coo_atomic |  | x |  | x
rocsparse_spmv_alg_ell | x |  | N/A | N/A
rocsparse_spmv_alg_bsr | x |  | N/A | N/A

The reproducibility of `rocsparse_spmm()` is more complicated because this generic routine supports multiple sparse matrix formats and algorithms. See the chart below to determine whether a given algorithm is deterministic.

Bit-wise reproducibility of SpMM
Algorithm | A non-transpose | A transpose
--- | --- | ---
Yes | No | Yes | No
rocsparse_spmm_alg_csr | x |  |  | x
rocsparse_spmm_alg_csr_row_split | x |  |  | x
rocsparse_spmm_alg_csr_nnz_split |  | x |  | x
rocsparse_spmm_alg_csr_merge_path |  | x |  | x
rocsparse_spmm_alg_csr (CSC FORMAT) |  | x | x |
rocsparse_spmm_alg_csr_row_split (CSC FORMAT) |  | x | x |
rocsparse_spmm_alg_csr_nnz_split (CSC FORMAT) |  | x |  | x
rocsparse_spmm_alg_csr_merge_path (CSC FORMAT) |  | x |  | x
rocsparse_spmm_alg_coo_segmented | x |  |  | x
rocsparse_spmm_alg_coo_atomic |  | x |  | x
rocsparse_spmm_alg_coo_segmented_atomic |  | x |  | x
rocsparse_spmm_alg_bell | x |  | N/A | N/A
rocsparse_spmm_alg_bsr | x |  | N/A | N/A