/*! \file */ /* ************************************************************************ * Copyright (C) 2020-2025 Advanced Micro Devices, Inc. All rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * ************************************************************************ */ #include "rocsparse_init.hpp" #include "../include/rocsparse_host.hpp" #include "rocsparse_import.hpp" #include "rocsparse_importer_impls.hpp" #include "rocsparse_matrix.hpp" #include "rocsparse_clients_routine_trace.hpp" /* ==================================================================================== */ /*! \brief matrix/vector initialization: */ // for vector x (M=1, N=lengthX, lda=incx); // for complex number, the real/imag part would be initialized with the same value // Initialize vector with random values template void rocsparse_init_exact( T* A, size_t M, size_t N, size_t lda, size_t stride, size_t batch_count, int a, int b) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; for(size_t i_batch = 0; i_batch < batch_count; i_batch++) { for(size_t j = 0; j < N; ++j) { for(size_t i = 0; i < M; ++i) { A[i + j * lda + i_batch * stride] = random_cached_generator_exact(a, b); } } } } template void rocsparse_init_1d_array(T* A, size_t size, bool use_exact, T a, T b) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; rocsparse_init(A, size, 1, 1, use_exact, 0, 1, a, b); } template void rocsparse_init(T* A, size_t M, size_t N, size_t lda, bool use_exact, size_t stride, size_t batch_count, T a, T b) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; if(use_exact) { rocsparse_init_exact( A, M, N, lda, stride, batch_count, static_cast(a), static_cast(b)); } else { rocsparse_init_inexact(A, M, N, lda, stride, batch_count, a, b); } } template <> void rocsparse_init(rocsparse_float_complex* A, size_t M, size_t N, size_t lda, bool use_exact, size_t stride, size_t batch_count, rocsparse_float_complex a, rocsparse_float_complex b) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; if(use_exact) { rocsparse_init_exact(A, M, N, lda, stride, batch_count, static_cast(std::real(a)), static_cast(std::real(b))); } else { rocsparse_init_inexact(A, M, N, lda, stride, batch_count, a, b); } } template <> void rocsparse_init(rocsparse_double_complex* A, size_t M, size_t N, size_t lda, bool use_exact, size_t stride, size_t batch_count, rocsparse_double_complex a, rocsparse_double_complex b) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; if(use_exact) { rocsparse_init_exact(A, M, N, lda, stride, batch_count, static_cast(std::real(a)), static_cast(std::real(b))); } else { rocsparse_init_inexact(A, M, N, lda, stride, batch_count, a, b); } } template void rocsparse_init_inexact( T* A, size_t M, size_t N, size_t lda, size_t stride, size_t batch_count, T a, T b) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; for(size_t i_batch = 0; i_batch < batch_count; i_batch++) { for(size_t j = 0; j < N; ++j) { for(size_t i = 0; i < M; ++i) { A[i + j * lda + i_batch * stride] = random_cached_generator(a, b); } } } } template void rocsparse_init_exact(std::vector& A, size_t M, size_t N, size_t lda, size_t stride, size_t batch_count, int a, int b) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; rocsparse_init_exact(A.data(), M, N, lda, stride, batch_count, a, b); } template void rocsparse_init_1d_array(std::vector& A, size_t size, bool use_exact, T a, T b) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; rocsparse_init(A.data(), size, 1, 1, use_exact, 0, 1, a, b); } template void rocsparse_init(std::vector& A, size_t M, size_t N, size_t lda, bool use_exact, size_t stride, size_t batch_count, T a, T b) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; rocsparse_init(A.data(), M, N, lda, use_exact, stride, batch_count, a, b); } template void rocsparse_init_inexact( std::vector& A, size_t M, size_t N, size_t lda, size_t stride, size_t batch_count, T a, T b) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; rocsparse_init_inexact(A.data(), M, N, lda, stride, batch_count, a, b); } // Initializes sparse index vector with nnz entries ranging from start to end template void rocsparse_init_index(std::vector& x, size_t nnz, size_t start, size_t end) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; std::vector check(end - start, false); size_t num = 0; while(num < nnz) { I val = random_generator_exact(start, end - 1); if(!check[val - start]) { x[num++] = val; check[val - start] = true; } } std::sort(x.begin(), x.end()); } // Initialize matrix so adjacent entries have alternating sign. // In gemm if either A or B are initialized with alernating // sign the reduction sum will be summing positive // and negative numbers, so it should not get too large. // This helps reduce floating point inaccuracies for 16bit // arithmetic where the exponent has only 5 bits, and the // mantissa 10 bits. template void rocsparse_init_alternating_sign( std::vector& A, size_t M, size_t N, size_t lda, size_t stride, size_t batch_count) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; for(size_t i_batch = 0; i_batch < batch_count; i_batch++) for(size_t i = 0; i < M; ++i) for(size_t j = 0; j < N; ++j) { auto value = random_cached_generator_exact(); A[i + j * lda + i_batch * stride] = (i ^ j) & 1 ? value : -value; } } /* ==================================================================================== */ /*! \brief Initialize an array with random data, with NaN where appropriate */ template void rocsparse_init_nan(T* A, size_t N) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; for(size_t i = 0; i < N; ++i) A[i] = T(rocsparse_nan_rng()); } template void rocsparse_init_nan( std::vector& A, size_t M, size_t N, size_t lda, size_t stride, size_t batch_count) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; for(size_t i_batch = 0; i_batch < batch_count; i_batch++) for(size_t i = 0; i < M; ++i) for(size_t j = 0; j < N; ++j) A[i + j * lda + i_batch * stride] = T(rocsparse_nan_rng()); } /* ==================================================================================== */ /*! \brief Generate a random sparse matrix in COO format */ template void rocsparse_init_coo_matrix(std::vector& row_ind, std::vector& col_ind, std::vector& val, I M, I N, int64_t nnz, rocsparse_index_base base, bool full_rank, bool to_int) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; if(nnz == 0) { row_ind.resize(nnz); col_ind.resize(nnz); val.resize(nnz); return; } // If M > N, full rank is not possible if(full_rank && M > N) { std::cerr << "ERROR: M > N, cannot generate matrix with full rank" << std::endl; full_rank = false; } // If nnz < M, full rank is not possible if(full_rank && nnz < M) { std::cerr << "ERROR: nnz < M, cannot generate matrix with full rank" << std::endl; full_rank = false; } if(row_ind.size() != nnz) { row_ind.resize(nnz); } if(col_ind.size() != nnz) { col_ind.resize(nnz); } if(val.size() != nnz) { val.resize(nnz); } // Generate histogram of non-zero counts per row based on average non-zeros per row std::vector count(M, 0); I start = full_rank ? (I)std::min((int64_t)M, nnz) : 0; if(full_rank) { for(I k = 0; k < start; ++k) { count[k] = 1; } } int64_t remaining_nnz = nnz - start; I avg_nnz_per_row = remaining_nnz / M; for(I k = 0; k < M; k++) { I nnz_in_row = std::min(random_cached_generator_exact(0, 2 * avg_nnz_per_row), N); nnz_in_row = (I)std::min(remaining_nnz, (int64_t)nnz_in_row); count[k] += nnz_in_row; remaining_nnz -= nnz_in_row; } // Sprinkle any remaining non-zeros amoung the rows for(int64_t k = 0; k < remaining_nnz; ++k) { I i = random_generator_exact(0, M - 1); int maxiter = 0; while(count[i] >= N && maxiter++ < 10) { i = random_generator_exact(0, M - 1); } if(maxiter >= 10) { for(i = 0; i < M; ++i) { if(count[i] < N) { break; } } if(i == M) { std::cerr << "rocsparse_init_coo_matrix error" << std::endl; exit(1); } } count[i] += 1; } // Compute row index array from non-zeros per row count histogram int64_t offset = 0; I max_nnz_per_row = count[0]; for(I k = 0; k < M; k++) { I nnz_in_row = count[k]; if(max_nnz_per_row < nnz_in_row) max_nnz_per_row = nnz_in_row; for(I i = 0; i < nnz_in_row; i++) { row_ind[offset + i] = k; } offset += nnz_in_row; } // Generate column index array with values clustered around the diagonal I sec = std::min(2 * max_nnz_per_row, N); std::vector random(2 * sec + 1); int64_t at = 0; for(I i = 0; i < M; ++i) { int64_t begin = at; I nnz_in_row = count[i]; I bmax = std::min(i + sec, N - 1); I bmin = std::max(bmax - 2 * sec, ((I)0)); // Initial permutation of column indices for(I k = 0; k <= (bmax - bmin); ++k) { random[k] = k; } // shuffle permutation for(I k = 0; k < nnz_in_row; ++k) { std::swap(random[k], random[random_generator_exact(0, bmax - bmin)]); } if(full_rank) { col_ind[at++] = i; for(I k = 1; k < nnz_in_row; ++k) { if(bmin + random[k] == i) { col_ind[at++] = bmin + random[bmax - bmin]; } else { col_ind[at++] = bmin + random[k]; } } } else { for(I k = 0; k < nnz_in_row; ++k) { col_ind[at++] = bmin + random[k]; } } if(nnz_in_row > 0) { std::sort(col_ind.data() + begin, col_ind.data() + begin + nnz_in_row); } } // Correct index base accordingly if(base == rocsparse_index_base_one) { for(int64_t i = 0; i < nnz; ++i) { ++row_ind[i]; ++col_ind[i]; } } if(to_int) { // Sample random values for(int64_t i = 0; i < nnz; ++i) { val[i] = random_cached_generator_exact(); } } else { if(full_rank) { for(int64_t i = 0; i < nnz; ++i) { if(row_ind[i] == col_ind[i]) { // Sample diagonal values val[i] = random_cached_generator(static_cast(4.0), static_cast(8.0)); val[i] += val[i] * random_cached_generator(static_cast(-1.0e-2), static_cast(1.0e-2)); } else { // Samples off-diagonal values val[i] = random_cached_generator(static_cast(-0.5), static_cast(0.5)); } } } else { for(int64_t i = 0; i < nnz; ++i) { val[i] = random_cached_generator(static_cast(-1.0), static_cast(1.0)); } } } } /* ==================================================================================== */ /*! \brief Generate 2D 9pt laplacian on unit square in CSR format */ template void rocsparse_init_csr_laplace2d(std::vector& row_ptr, std::vector& col_ind, std::vector& val, int32_t dim_x, int32_t dim_y, J& M, J& N, I& nnz, rocsparse_index_base base) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; // Do nothing if(dim_x == 0 || dim_y == 0) { return; } M = dim_x * dim_y; N = dim_x * dim_y; // Approximate 9pt stencil I nnz_mat = 9 * M; row_ptr.resize(M + 1); col_ind.resize(nnz_mat); val.resize(nnz_mat); nnz = base; row_ptr[0] = base; // Fill local arrays #ifdef _OPENMP #pragma omp parallel for schedule(dynamic, 1024) #endif for(int32_t iy = 0; iy < dim_y; ++iy) { for(int32_t ix = 0; ix < dim_x; ++ix) { J row = iy * dim_x + ix; for(int32_t sy = -1; sy <= 1; ++sy) { if(iy + sy > -1 && iy + sy < dim_y) { for(int32_t sx = -1; sx <= 1; ++sx) { if(ix + sx > -1 && ix + sx < dim_x) { J col = row + sy * dim_x + sx; col_ind[nnz - base] = col + base; val[nnz - base] = (col == row) ? 8.0 : -1.0; ++nnz; } } } } row_ptr[row + 1] = nnz; } } // Adjust nnz by index base nnz -= base; // compress to actual nnz col_ind.resize(nnz); val.resize(nnz); } /* ==================================================================================== */ /*! \brief Generate 2D 9pt laplacian on unit square in COO format */ template void rocsparse_init_coo_laplace2d(std::vector& row_ind, std::vector& col_ind, std::vector& val, int32_t dim_x, int32_t dim_y, I& M, I& N, int64_t& nnz, rocsparse_index_base base) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; // Always load using int64 as we dont know ahead of time how many nnz exist in matrix std::vector row_ptr; // Sample CSR matrix rocsparse_init_csr_laplace2d(row_ptr, col_ind, val, dim_x, dim_y, M, N, nnz, base); // Convert to COO host_csr_to_coo(M, nnz, row_ptr, row_ind, base); } /* ==================================================================================== */ /*! \brief Generate 2D 9pt laplacian on unit square in GEBSR format */ template void rocsparse_init_gebsr_laplace2d(std::vector& row_ptr, std::vector& col_ind, std::vector& val, int32_t dim_x, int32_t dim_y, J& Mb, J& Nb, I& nnzb, J row_block_dim, J col_block_dim, rocsparse_index_base base) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; rocsparse_init_csr_laplace2d(row_ptr, col_ind, val, dim_x, dim_y, Mb, Nb, nnzb, base); const size_t nvalues = size_t(nnzb) * row_block_dim * col_block_dim; val.resize(nvalues); for(size_t i = 0; i < nvalues; ++i) { val[i] = random_cached_generator(); } } /* ==================================================================================== */ /*! \brief Generate 2D 9pt laplacian on unit square in ELL format */ template void rocsparse_init_ell_laplace2d(std::vector& col_ind, std::vector& val, int32_t dim_x, int32_t dim_y, I& M, I& N, I& width, rocsparse_index_base base) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; I csr_nnz; std::vector csr_row_ptr; std::vector csr_col_ind; std::vector csr_val; // Sample CSR matrix rocsparse_init_csr_laplace2d( csr_row_ptr, csr_col_ind, csr_val, dim_x, dim_y, M, N, csr_nnz, base); // Convert to ELL host_csr_to_ell(M, csr_row_ptr, csr_col_ind, csr_val, col_ind, val, width, base, base); } /* ==================================================================================== */ /*! \brief Generate 3D 27pt laplacian on unit square in CSR format */ template void rocsparse_init_csr_laplace3d(std::vector& row_ptr, std::vector& col_ind, std::vector& val, int32_t dim_x, int32_t dim_y, int32_t dim_z, J& M, J& N, I& nnz, rocsparse_index_base base) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; // Do nothing if(dim_x == 0 || dim_y == 0 || dim_z == 0) { return; } M = dim_x * dim_y * dim_z; N = dim_x * dim_y * dim_z; // Approximate 27pt stencil I nnz_mat = 27 * M; row_ptr.resize(M + 1); col_ind.resize(nnz_mat); val.resize(nnz_mat); nnz = base; row_ptr[0] = base; // Fill local arrays #ifdef _OPENMP #pragma omp parallel for schedule(dynamic, 1024) #endif for(int32_t iz = 0; iz < dim_z; ++iz) { for(int32_t iy = 0; iy < dim_y; ++iy) { for(int32_t ix = 0; ix < dim_x; ++ix) { J row = iz * dim_x * dim_y + iy * dim_x + ix; for(int32_t sz = -1; sz <= 1; ++sz) { if(iz + sz > -1 && iz + sz < dim_z) { for(int32_t sy = -1; sy <= 1; ++sy) { if(iy + sy > -1 && iy + sy < dim_y) { for(int32_t sx = -1; sx <= 1; ++sx) { if(ix + sx > -1 && ix + sx < dim_x) { J col = row + sz * dim_x * dim_y + sy * dim_x + sx; col_ind[nnz - base] = col + base; val[nnz - base] = (col == row) ? 26.0 : -1.0; ++nnz; } } } } } } row_ptr[row + 1] = nnz; } } } // Adjust nnz by index base nnz -= base; // compress to actual nnz col_ind.resize(nnz); val.resize(nnz); } /* ==================================================================================== */ /*! \brief Generate 3D 27pt laplacian on unit square in COO format */ template void rocsparse_init_coo_laplace3d(std::vector& row_ind, std::vector& col_ind, std::vector& val, int32_t dim_x, int32_t dim_y, int32_t dim_z, I& M, I& N, int64_t& nnz, rocsparse_index_base base) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; // Always load using int64 as we dont know ahead of time how many nnz exist in matrix std::vector row_ptr; // Sample CSR matrix rocsparse_init_csr_laplace3d(row_ptr, col_ind, val, dim_x, dim_y, dim_z, M, N, nnz, base); // Convert to COO host_csr_to_coo(M, nnz, row_ptr, row_ind, base); } /* ==================================================================================== */ /*! \brief Generate 3D 27pt laplacian on unit square in GEBSR format */ template void rocsparse_init_gebsr_laplace3d(std::vector& row_ptr, std::vector& col_ind, std::vector& val, int32_t dim_x, int32_t dim_y, int32_t dim_z, J& Mb, J& Nb, I& nnzb, J row_block_dim, J col_block_dim, rocsparse_index_base base) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; rocsparse_init_csr_laplace3d(row_ptr, col_ind, val, dim_x, dim_y, dim_z, Mb, Nb, nnzb, base); const size_t nvalues = size_t(nnzb) * row_block_dim * col_block_dim; val.resize(nvalues); for(size_t i = 0; i < nvalues; ++i) { val[i] = random_cached_generator(); } } /* ==================================================================================== */ /*! \brief Read matrix from mtx file in CSR format */ template void rocsparse_init_csr_mtx(const char* filename, std::vector& csr_row_ptr, std::vector& csr_col_ind, std::vector& csr_val, J& M, J& N, I& nnz, rocsparse_index_base base) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; I coo_M, coo_N; int64_t coo_nnz; std::vector coo_row_ind; std::vector coo_col_ind; // Read COO matrix rocsparse_init_coo_mtx( filename, coo_row_ind, coo_col_ind, csr_val, coo_M, coo_N, coo_nnz, base); // Convert to CSR M = (J)coo_M; N = (J)coo_N; nnz = (I)coo_nnz; csr_row_ptr.resize(M + 1); csr_col_ind.resize(nnz); host_coo_to_csr(coo_M, nnz, coo_row_ind.data(), csr_row_ptr.data(), base); for(I i = 0; i < nnz; ++i) { csr_col_ind[i] = (J)coo_col_ind[i]; } } /* ============================================================================================ */ /*! \brief Read matrix from mtx file in COO format */ template void rocsparse_init_coo_mtx(const char* filename, std::vector& coo_row_ind, std::vector& coo_col_ind, std::vector& coo_val, I& M, I& N, int64_t& nnz, rocsparse_index_base base) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; rocsparse_importer_matrixmarket importer(filename); rocsparse_status status = rocsparse_import_sparse_coo(importer, coo_row_ind, coo_col_ind, coo_val, M, N, nnz, base); CHECK_ROCSPARSE_THROW_ERROR(status); } /* ============================================================================================ */ /*! \brief Read matrix from mtx file in GEBSR format */ template void rocsparse_init_gebsr_mtx(const char* filename, std::vector& bsr_row_ptr, std::vector& bsr_col_ind, std::vector& bsr_val, J& Mb, J& Nb, I& nnzb, J row_block_dim, J col_block_dim, rocsparse_index_base base) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; // this->init_csr(bsr_row_ptr, bsr_col_ind, bsr_val, Mb, Nb, nnzb, base); rocsparse_init_csr_mtx(filename, bsr_row_ptr, bsr_col_ind, bsr_val, Mb, Nb, nnzb, base); const size_t nvalues = size_t(nnzb) * row_block_dim * col_block_dim; bsr_val.resize(nvalues); for(size_t i = 0; i < nvalues; ++i) { bsr_val[i] = random_cached_generator(); } } /* ==================================================================================== */ /*! \brief Read matrix from smtx file in CSR format */ template void rocsparse_init_csr_smtx(const char* filename, std::vector& csr_row_ptr, std::vector& csr_col_ind, std::vector& csr_val, J& M, J& N, I& nnz, rocsparse_index_base base) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; rocsparse_importer_mlcsr importer(filename); const rocsparse_status status = rocsparse_import_sparse_csr(importer, csr_row_ptr, csr_col_ind, csr_val, M, N, nnz, base); for(size_t i = 0; i < nnz; ++i) { csr_val[i] = random_cached_generator(); } CHECK_ROCSPARSE_THROW_ERROR(status); } /* ============================================================================================ */ /*! \brief Read matrix from smtx file in COO format */ template void rocsparse_init_coo_smtx(const char* filename, std::vector& coo_row_ind, std::vector& coo_col_ind, std::vector& coo_val, I& M, I& N, int64_t& nnz, rocsparse_index_base base) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; std::vector csr_row_ptr; rocsparse_init_csr_smtx( filename, csr_row_ptr, coo_col_ind, coo_val, M, N, nnz, base); coo_row_ind.resize(nnz); host_csr_to_coo(M, nnz, csr_row_ptr, coo_row_ind, base); } /* ============================================================================================ */ /*! \brief Read matrix from smtx file in GEBSR format */ template void rocsparse_init_gebsr_smtx(const char* filename, std::vector& bsr_row_ptr, std::vector& bsr_col_ind, std::vector& bsr_val, J& Mb, J& Nb, I& nnzb, J row_block_dim, J col_block_dim, rocsparse_index_base base) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; rocsparse_importer_mlcsr importer(filename); const rocsparse_status status = rocsparse_import_sparse_csr( importer, bsr_row_ptr, bsr_col_ind, bsr_val, Mb, Nb, nnzb, base); CHECK_ROCSPARSE_THROW_ERROR(status); const size_t nvalues = size_t(nnzb) * row_block_dim * col_block_dim; bsr_val.resize(nvalues); for(size_t i = 0; i < nvalues; ++i) { bsr_val[i] = random_cached_generator(); } } /* ==================================================================================== */ /*! \brief Read matrix from smtx file in CSR format */ template void rocsparse_init_csr_bsmtx(const char* filename, std::vector& csr_row_ptr, std::vector& csr_col_ind, std::vector& csr_val, J& M, J& N, I& nnz, rocsparse_index_base base) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; std::vector bsr_row_ptr; std::vector bsr_col_ind; std::vector bsr_val; J Mb; J Nb; I nnzb; J row_block_dim; J col_block_dim; rocsparse_importer_mlbsr importer(filename); rocsparse_direction import_dir = {}; const rocsparse_status status = rocsparse_import_sparse_gebsr(importer, bsr_row_ptr, bsr_col_ind, bsr_val, import_dir, Mb, Nb, nnzb, row_block_dim, col_block_dim, base); CHECK_ROCSPARSE_THROW_ERROR(status); nnz = nnzb * row_block_dim * col_block_dim; M = Mb * row_block_dim; N = Nb * col_block_dim; csr_row_ptr.resize(M + 1); csr_col_ind.resize(nnz); csr_val.resize(nnz); csr_row_ptr[0] = base; for(size_t i = 0; i < Mb; ++i) { const size_t nnz_in_row = (bsr_row_ptr[i + 1] - bsr_row_ptr[i]) * col_block_dim; for(rocsparse_int k = 0; k < row_block_dim; ++k) { const size_t row = i * row_block_dim + k; csr_row_ptr[row + 1] = csr_row_ptr[row] + nnz_in_row; } } for(J i = 0; i < Mb; ++i) { const I start = bsr_row_ptr[i] - base; const I end = bsr_row_ptr[i + 1] - base; for(I k = start; k < end; ++k) { const J j = bsr_col_ind[k] - base; for(J r = 0; r < row_block_dim; ++r) { for(J c = 0; c < col_block_dim; ++c) { const J col = col_block_dim * j + c; const I index = start * row_block_dim * col_block_dim + (end - start) * col_block_dim * r + (k - start) * col_block_dim + c; csr_col_ind[index] = col + base; } } } } for(size_t i = 0; i < nnz; ++i) { csr_val[i] = random_cached_generator(); } } /* ============================================================================================ */ /*! \brief Read matrix from smtx file in COO format */ template void rocsparse_init_coo_bsmtx(const char* filename, std::vector& coo_row_ind, std::vector& coo_col_ind, std::vector& coo_val, I& M, I& N, int64_t& nnz, rocsparse_index_base base) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; std::vector csr_row_ptr; rocsparse_init_csr_bsmtx( filename, csr_row_ptr, coo_col_ind, coo_val, M, N, nnz, base); coo_row_ind.resize(nnz); host_csr_to_coo(M, nnz, csr_row_ptr, coo_row_ind, base); } /* ============================================================================================ */ /*! \brief Read matrix from smtx file in GEBSR format */ template void rocsparse_init_gebsr_bsmtx(const char* filename, std::vector& bsr_row_ptr, std::vector& bsr_col_ind, std::vector& bsr_val, J& Mb, J& Nb, I& nnzb, J row_block_dim, J col_block_dim, rocsparse_index_base base) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; rocsparse_importer_mlbsr importer(filename); rocsparse_direction import_dir = {}; const rocsparse_status status = rocsparse_import_sparse_gebsr(importer, bsr_row_ptr, bsr_col_ind, bsr_val, import_dir, Mb, Nb, nnzb, row_block_dim, col_block_dim, base); CHECK_ROCSPARSE_THROW_ERROR(status); const size_t nvalues = size_t(nnzb) * row_block_dim * col_block_dim; bsr_val.resize(nvalues); for(size_t i = 0; i < nvalues; ++i) { bsr_val[i] = random_cached_generator(); } } template void rocsparse_init_csr_rocalution(const char* filename, std::vector& row_ptr, std::vector& col_ind, std::vector& val, J& M, J& N, I& nnz, rocsparse_index_base base) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; rocsparse_importer_rocalution importer(filename); rocsparse_status status = rocsparse_import_sparse_csr(importer, row_ptr, col_ind, val, M, N, nnz, base); CHECK_ROCSPARSE_THROW_ERROR(status); } /* ==================================================================================== */ /*! \brief Read matrix from binary file in rocALUTION format */ template void rocsparse_init_coo_rocalution(const char* filename, std::vector& row_ind, std::vector& col_ind, std::vector& val, I& M, I& N, int64_t& nnz, rocsparse_index_base base) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; I csr_nnz = 0; std::vector row_ptr(M + 1); // Sample CSR matrix rocsparse_init_csr_rocalution(filename, row_ptr, col_ind, val, M, N, csr_nnz, base); host_csr_to_coo(M, csr_nnz, row_ptr, row_ind, base); nnz = csr_nnz; } /* ==================================================================================== */ /*! \brief Read matrix from binary file in rocALUTION format */ template void rocsparse_init_gebsr_rocalution(const char* filename, std::vector& row_ptr, std::vector& col_ind, std::vector& val, J& Mb, J& Nb, I& nnzb, J row_block_dim, J col_block_dim, rocsparse_index_base base) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; // Temporarily the file contains a CSR matrix. rocsparse_init_csr_rocalution(filename, row_ptr, col_ind, val, Mb, Nb, nnzb, base); // Then temporarily skip the values. const size_t nvalues = size_t(nnzb) * row_block_dim * col_block_dim; val.resize(nvalues); for(size_t i = 0; i < nvalues; ++i) { val[i] = random_cached_generator(); } } /* ==================================================================================== */ /*! \brief Read matrix from binary file in rocSPARSEIO format */ template void rocsparse_init_csr_rocsparseio(const char* filename, std::vector& row_ptr, std::vector& col_ind, std::vector& val, J& M, J& N, I& nnz, rocsparse_index_base base) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; rocsparse_importer_rocsparseio importer(filename); rocsparse_status status = rocsparse_import_sparse_csr(importer, row_ptr, col_ind, val, M, N, nnz, base); CHECK_ROCSPARSE_THROW_ERROR(status); } /* ==================================================================================== */ /*! \brief Read matrix from binary file in rocSPARSEIO format */ template void rocsparse_init_coo_rocsparseio(const char* filename, std::vector& row_ind, std::vector& col_ind, std::vector& val, I& M, I& N, int64_t& nnz, rocsparse_index_base base) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; rocsparse_importer_rocsparseio importer(filename); rocsparse_status status = rocsparse_import_sparse_coo(importer, row_ind, col_ind, val, M, N, nnz, base); CHECK_ROCSPARSE_THROW_ERROR(status); } /* ==================================================================================== */ /*! \brief Read matrix from binary file in rocSPARSEIO format */ template void rocsparse_init_gebsr_rocsparseio(const char* filename, std::vector& row_ptr, std::vector& col_ind, std::vector& val, rocsparse_direction dir, J& Mb, J& Nb, I& nnzb, J row_block_dim, J col_block_dim, rocsparse_index_base base) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; rocsparse_direction import_dir = {}; rocsparse_importer_rocsparseio importer(filename); rocsparse_status status = rocsparse_import_sparse_gebsr(importer, row_ptr, col_ind, val, import_dir, Mb, Nb, nnzb, row_block_dim, col_block_dim, base); CHECK_ROCSPARSE_THROW_ERROR(status); if(import_dir != dir) { std::cerr << "TODO, reorder ?" << std::endl; exit(1); } } /* ==================================================================================== */ /*! \brief Generate a random sparse matrix in CSR format */ template void rocsparse_init_csr_random(std::vector& csr_row_ptr, std::vector& csr_col_ind, std::vector& csr_val, J M, J N, I& nnz, rocsparse_index_base base, rocsparse_matrix_init_kind init_kind, bool full_rank, bool to_int) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; switch(init_kind) { case rocsparse_matrix_init_kind_tunedavg: { rocsparse_int alpha = static_cast(0); if(N >= 16384) { alpha = static_cast(8); } else if(N >= 8192) { alpha = static_cast(8); } else if(N >= 4096) { alpha = static_cast(16); } else if(N >= 1024) { alpha = static_cast(32); } else { alpha = static_cast(64); } nnz = static_cast(M) * alpha; nnz = std::min(nnz, static_cast(M) * static_cast(N)); // Sample random matrix std::vector row_ind(nnz); // Sample COO matrix rocsparse_init_coo_matrix( row_ind, csr_col_ind, csr_val, M, N, nnz, base, full_rank, to_int); // Convert to CSR csr_row_ptr.resize(M + 1); host_coo_to_csr(M, nnz, row_ind.data(), csr_row_ptr.data(), base); break; } case rocsparse_matrix_init_kind_default: { if(M < 32 && N < 32) { nnz = (static_cast(M) * static_cast(N)) / 4; if(full_rank) { nnz = std::max(nnz, static_cast(M)); } nnz = std::max(nnz, static_cast(M)); nnz = std::min(nnz, static_cast(M) * static_cast(N)); } else { nnz = static_cast(M) * ((M > 1000 || N > 1000) ? 2.0 / std::max(M, N) : 0.02) * static_cast(N); } // Sample random matrix std::vector row_ind(nnz); // Sample COO matrix rocsparse_init_coo_matrix( row_ind, csr_col_ind, csr_val, M, N, nnz, base, full_rank, to_int); // Convert to CSR csr_row_ptr.resize(M + 1); host_coo_to_csr(M, nnz, row_ind.data(), csr_row_ptr.data(), base); break; } } } /* ==================================================================================== */ /*! \brief Generate a random sparse matrix in COO format */ template void rocsparse_init_coo_random(std::vector& row_ind, std::vector& col_ind, std::vector& val, I M, I N, int64_t& nnz, rocsparse_index_base base, rocsparse_matrix_init_kind init_kind, bool full_rank, bool to_int) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; switch(init_kind) { case rocsparse_matrix_init_kind_tunedavg: { rocsparse_int alpha = static_cast(0); if(N >= 16384) { alpha = static_cast(8); } else if(N >= 8192) { alpha = static_cast(16); } else if(N >= 4096) { alpha = static_cast(32); } else if(N >= 1024) { alpha = static_cast(64); } else { alpha = static_cast(128); } nnz = static_cast(M) * alpha; nnz = std::min(nnz, static_cast(M) * static_cast(N)); // Sample random matrix rocsparse_init_coo_matrix(row_ind, col_ind, val, M, N, nnz, base, full_rank, to_int); break; } case rocsparse_matrix_init_kind_default: { // Compute non-zero entries of the matrix if(M < 32 && N < 32) { nnz = (static_cast(M) * static_cast(N)) / 4; } else { nnz = static_cast(M) * ((M > 1000 || N > 1000) ? 2.0 / std::max(M, N) : 0.02) * static_cast(N); } // Sample random matrix rocsparse_init_coo_matrix(row_ind, col_ind, val, M, N, nnz, base, full_rank, to_int); break; } } } /* ==================================================================================== */ /*! \brief Generate a random sparse matrix in GEBSR format */ template void rocsparse_init_gebsr_random(std::vector& row_ptr, std::vector& col_ind, std::vector& val, J Mb, J Nb, I& nnzb, J row_block_dim, J col_block_dim, rocsparse_index_base base, rocsparse_matrix_init_kind init_kind, bool full_rank, bool to_int) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; rocsparse_init_csr_random( row_ptr, col_ind, val, Mb, Nb, nnzb, base, init_kind, full_rank, to_int); const size_t nvalues = size_t(nnzb) * row_block_dim * col_block_dim; val.resize(nvalues); if(to_int) { for(size_t i = 0; i < nvalues; ++i) { val[i] = random_cached_generator_exact(); } } else { for(size_t i = 0; i < nvalues; ++i) { val[i] = random_cached_generator(); } } } /* ==================================================================================== */ /*! \brief Generate a tridiagonal sparse matrix in COO format */ template void rocsparse_init_coo_tridiagonal(std::vector& row_ind, std::vector& col_ind, std::vector& val, I M, I N, int64_t& nnz, rocsparse_index_base base, I l, I u) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; if(l >= 0 || -l >= M) { std::cerr << "ERROR: l >= 0 || -l >= M" << std::endl; return; } if(u <= 0 || u >= N) { std::cerr << "ERROR: u <= 0 || u >= N" << std::endl; return; } int64_t l_length = std::min((M + l), N); int64_t d_length = std::min(M, N); int64_t u_length = std::min((N - u), M); nnz = l_length + d_length + u_length; row_ind.resize(nnz); col_ind.resize(nnz); val.resize(nnz); int64_t index = 0; for(I i = 0; i < M; i++) { I l_col = i + l; I d_col = i; I u_col = i + u; if(l_col >= 0 && l_col < N) { row_ind[index] = i + base; col_ind[index] = l_col + base; val[index] = random_cached_generator(static_cast(-1.0), static_cast(1.0)); index++; } if(d_col >= 0 && d_col < N) { row_ind[index] = i + base; col_ind[index] = d_col + base; val[index] = random_cached_generator(static_cast(2.0), static_cast(4.0)); index++; } if(u_col >= 0 && u_col < N) { row_ind[index] = i + base; col_ind[index] = u_col + base; val[index] = random_cached_generator(static_cast(-1.0), static_cast(1.0)); index++; } } } /* ==================================================================================== */ /*! \brief Generate a tridiagonal sparse matrix in CSR format */ template void rocsparse_init_csr_tridiagonal(std::vector& row_ptr, std::vector& col_ind, std::vector& val, J M, J N, I& nnz, rocsparse_index_base base, J l, J u) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; int64_t coo_nnz; std::vector row_ind; // Sample COO matrix rocsparse_init_coo_tridiagonal(row_ind, col_ind, val, M, N, coo_nnz, base, l, u); if(std::is_same() && coo_nnz > std::numeric_limits::max()) { std::cerr << "Error: Attempting to create CSR tridiagonal matrix with more than " << std::numeric_limits::max() << " non-zeros while using int32_t row indexing." << std::endl; exit(1); } nnz = (I)coo_nnz; // Convert to CSR row_ptr.resize(M + 1); host_coo_to_csr(M, nnz, row_ind.data(), row_ptr.data(), base); } /* ==================================================================================== */ /*! \brief Generate a tridiagonal sparse matrix in GEBSR format */ template void rocsparse_init_gebsr_tridiagonal(std::vector& row_ptr, std::vector& col_ind, std::vector& val, J Mb, J Nb, I& nnzb, J row_block_dim, J col_block_dim, rocsparse_index_base base, J l, J u) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; rocsparse_init_csr_tridiagonal(row_ptr, col_ind, val, Mb, Nb, nnzb, base, l, u); const size_t nvalues = size_t(nnzb) * row_block_dim * col_block_dim; val.resize(nvalues); for(size_t i = 0; i < nvalues; ++i) { val[i] = random_cached_generator(); } } /* ==================================================================================== */ /*! \brief Generate a pentadiagonal sparse matrix in COO format */ template void rocsparse_init_coo_pentadiagonal(std::vector& row_ind, std::vector& col_ind, std::vector& val, I M, I N, int64_t& nnz, rocsparse_index_base base, I ll, I l, I u, I uu) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; if(ll >= 0 || l >= 0 || ll >= l || -l >= M || -ll >= M) { std::cerr << "ERROR: ll >= 0 || l >= 0 || ll >= l || -l >= M || -ll >= M" << std::endl; return; } if(u <= 0 || uu <= 0 || uu <= u || u >= N || uu >= N) { std::cerr << "ERROR: u <= 0 || uu <= 0 || uu <= u || u >= N || uu >= N" << std::endl; return; } int64_t l_length = std::min((M + l), N); int64_t ll_length = std::min((M + ll), N); int64_t d_length = std::min(M, N); int64_t u_length = std::min((N - u), M); int64_t uu_length = std::min((N - uu), M); nnz = ll_length + l_length + d_length + u_length + uu_length; row_ind.resize(nnz); col_ind.resize(nnz); val.resize(nnz); int64_t index = 0; for(I i = 0; i < M; i++) { I ll_col = i + ll; I l_col = i + l; I d_col = i; I u_col = i + u; I uu_col = i + uu; if(ll_col >= 0 && ll_col < N) { row_ind[index] = i + base; col_ind[index] = ll_col + base; val[index] = random_cached_generator(static_cast(-1.0), static_cast(1.0)); index++; } if(l_col >= 0 && l_col < N) { row_ind[index] = i + base; col_ind[index] = l_col + base; val[index] = random_cached_generator(static_cast(-1.0), static_cast(1.0)); index++; } if(d_col >= 0 && d_col < N) { row_ind[index] = i + base; col_ind[index] = d_col + base; val[index] = random_cached_generator(static_cast(4.0), static_cast(6.0)); index++; } if(u_col >= 0 && u_col < N) { row_ind[index] = i + base; col_ind[index] = u_col + base; val[index] = random_cached_generator(static_cast(-1.0), static_cast(1.0)); index++; } if(uu_col >= 0 && uu_col < N) { row_ind[index] = i + base; col_ind[index] = uu_col + base; val[index] = random_cached_generator(static_cast(-1.0), static_cast(1.0)); index++; } } } /* ==================================================================================== */ /*! \brief Generate a pentadiagonal sparse matrix in CSR format */ template void rocsparse_init_csr_pentadiagonal(std::vector& row_ptr, std::vector& col_ind, std::vector& val, J M, J N, I& nnz, rocsparse_index_base base, J ll, J l, J u, J uu) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; int64_t coo_nnz; std::vector row_ind; // Sample COO matrix rocsparse_init_coo_pentadiagonal(row_ind, col_ind, val, M, N, coo_nnz, base, ll, l, u, uu); if(std::is_same() && coo_nnz > std::numeric_limits::max()) { std::cerr << "Error: Attempting to create CSR pentadiagonal matrix with more than " << std::numeric_limits::max() << " non-zeros while using int32_t row indexing." << std::endl; exit(1); } nnz = (I)coo_nnz; // Convert to CSR row_ptr.resize(M + 1); host_coo_to_csr(M, nnz, row_ind.data(), row_ptr.data(), base); } /* ==================================================================================== */ /*! \brief Generate a pentadiagonal sparse matrix in GEBSR format */ template void rocsparse_init_gebsr_pentadiagonal(std::vector& row_ptr, std::vector& col_ind, std::vector& val, J Mb, J Nb, I& nnzb, J row_block_dim, J col_block_dim, rocsparse_index_base base, J ll, J l, J u, J uu) { ROCSPARSE_CLIENTS_ROUTINE_TRACE; rocsparse_init_csr_pentadiagonal(row_ptr, col_ind, val, Mb, Nb, nnzb, base, ll, l, u, uu); const size_t nvalues = size_t(nnzb) * row_block_dim * col_block_dim; val.resize(nvalues); for(size_t i = 0; i < nvalues; ++i) { val[i] = random_cached_generator(); } } #define INSTANTIATEI(TYPE) \ template void rocsparse_init_index( \ std::vector & x, size_t nnz, size_t start, size_t end); #define INSTANTIATE_COMPLEX(TYPE) \ template void rocsparse_init_inexact(TYPE * A, \ size_t M, \ size_t N, \ size_t lda, \ size_t stride, \ size_t batch_count = 1, \ TYPE a = static_cast(0), \ TYPE b = static_cast(1)); \ template void rocsparse_init_exact(TYPE * A, \ size_t M, \ size_t N, \ size_t lda, \ size_t stride, \ size_t batch_count, \ int a = 1, \ int b = 10); \ template void rocsparse_init_1d_array(std::vector & A, \ size_t size, \ bool use_exact, \ TYPE a = static_cast(0), \ TYPE b = static_cast(1)); \ template void rocsparse_init(std::vector & A, \ size_t M, \ size_t N, \ size_t lda, \ bool use_exact, \ size_t stride, \ size_t batch_count = 1, \ TYPE a = static_cast(0), \ TYPE b = static_cast(1)); \ template void rocsparse_init_inexact(std::vector & A, \ size_t M, \ size_t N, \ size_t lda, \ size_t stride, \ size_t batch_count, \ TYPE a = static_cast(0), \ TYPE b = static_cast(1)); \ template void rocsparse_init_exact(std::vector & A, \ size_t M, \ size_t N, \ size_t lda, \ size_t stride, \ size_t batch_count, \ int a = 1, \ int b = 10); \ template void rocsparse_init_alternating_sign( \ std::vector & A, size_t M, size_t N, size_t lda, size_t stride, size_t batch_count); \ template void rocsparse_init_nan(TYPE * A, size_t N); \ template void rocsparse_init_nan(std::vector & A, \ size_t M, \ size_t N, \ size_t lda, \ size_t stride = 0, \ size_t batch_count); #define INSTANTIATE(TYPE) \ template void rocsparse_init_1d_array(TYPE * A, \ size_t size, \ bool use_exact, \ TYPE a = static_cast(0), \ TYPE b = static_cast(1)); \ template void rocsparse_init(TYPE * A, \ size_t M, \ size_t N, \ size_t lda, \ bool use_exact, \ size_t stride, \ size_t batch_count = 1, \ TYPE a = static_cast(0), \ TYPE b = static_cast(1)); \ INSTANTIATE_COMPLEX(TYPE); #define INSTANTIATE2(ITYPE, TTYPE) \ template void rocsparse_init_coo_tridiagonal(std::vector & row_ind, \ std::vector & col_ind, \ std::vector & val, \ ITYPE M, \ ITYPE N, \ int64_t & nnz, \ rocsparse_index_base base, \ ITYPE l, \ ITYPE u); \ template void rocsparse_init_coo_pentadiagonal(std::vector & row_ind, \ std::vector & col_ind, \ std::vector & val, \ ITYPE M, \ ITYPE N, \ int64_t & nnz, \ rocsparse_index_base base, \ ITYPE ll, \ ITYPE l, \ ITYPE u, \ ITYPE uu); \ template void rocsparse_init_coo_laplace2d(std::vector & row_ind, \ std::vector & col_ind, \ std::vector & val, \ int32_t dim_x, \ int32_t dim_y, \ ITYPE & M, \ ITYPE & N, \ int64_t & nnz, \ rocsparse_index_base base); \ template void rocsparse_init_ell_laplace2d(std::vector & col_ind, \ std::vector & val, \ int32_t dim_x, \ int32_t dim_y, \ ITYPE & M, \ ITYPE & N, \ ITYPE & width, \ rocsparse_index_base base); \ template void rocsparse_init_coo_matrix(std::vector & row_ind, \ std::vector & col_ind, \ std::vector & val, \ ITYPE M, \ ITYPE N, \ int64_t nnz, \ rocsparse_index_base base, \ bool full_rank, \ bool to_int); \ template void rocsparse_init_coo_laplace3d(std::vector & row_ind, \ std::vector & col_ind, \ std::vector & val, \ int32_t dim_x, \ int32_t dim_y, \ int32_t dim_z, \ ITYPE & M, \ ITYPE & N, \ int64_t & nnz, \ rocsparse_index_base base); \ template void rocsparse_init_coo_mtx(const char* filename, \ std::vector& coo_row_ind, \ std::vector& coo_col_ind, \ std::vector& coo_val, \ ITYPE& M, \ ITYPE& N, \ int64_t& nnz, \ rocsparse_index_base base); \ template void rocsparse_init_coo_smtx(const char* filename, \ std::vector& coo_row_ind, \ std::vector& coo_col_ind, \ std::vector& coo_val, \ ITYPE& M, \ ITYPE& N, \ int64_t& nnz, \ rocsparse_index_base base); \ template void rocsparse_init_coo_bsmtx(const char* filename, \ std::vector& coo_row_ind, \ std::vector& coo_col_ind, \ std::vector& coo_val, \ ITYPE& M, \ ITYPE& N, \ int64_t& nnz, \ rocsparse_index_base base); \ template void rocsparse_init_coo_rocalution(const char* filename, \ std::vector& row_ind, \ std::vector& col_ind, \ std::vector& val, \ ITYPE& M, \ ITYPE& N, \ int64_t& nnz, \ rocsparse_index_base base); \ template void rocsparse_init_coo_rocsparseio(const char* filename, \ std::vector& row_ind, \ std::vector& col_ind, \ std::vector& val, \ ITYPE& M, \ ITYPE& N, \ int64_t& nnz, \ rocsparse_index_base base); \ template void rocsparse_init_coo_random(std::vector & row_ind, \ std::vector & col_ind, \ std::vector & val, \ ITYPE M, \ ITYPE N, \ int64_t & nnz, \ rocsparse_index_base base, \ rocsparse_matrix_init_kind init_kind, \ bool full_rank, \ bool to_int); #define INSTANTIATE3(ITYPE, JTYPE, TTYPE) \ template void rocsparse_init_csr_tridiagonal( \ std::vector & row_ptr, \ std::vector & col_ind, \ std::vector & val, \ JTYPE M, \ JTYPE N, \ ITYPE & nnz, \ rocsparse_index_base base, \ JTYPE l, \ JTYPE u); \ template void rocsparse_init_csr_pentadiagonal( \ std::vector & row_ptr, \ std::vector & col_ind, \ std::vector & val, \ JTYPE M, \ JTYPE N, \ ITYPE & nnz, \ rocsparse_index_base base, \ JTYPE ll, \ JTYPE l, \ JTYPE u, \ JTYPE uu); \ template void rocsparse_init_csr_laplace2d(std::vector & row_ptr, \ std::vector & col_ind, \ std::vector & val, \ int32_t dim_x, \ int32_t dim_y, \ JTYPE & M, \ JTYPE & N, \ ITYPE & nnz, \ rocsparse_index_base base); \ template void rocsparse_init_csr_laplace3d(std::vector & row_ptr, \ std::vector & col_ind, \ std::vector & val, \ int32_t dim_x, \ int32_t dim_y, \ int32_t dim_z, \ JTYPE & M, \ JTYPE & N, \ ITYPE & nnz, \ rocsparse_index_base base); \ template void rocsparse_init_csr_mtx(const char* filename, \ std::vector& csr_row_ptr, \ std::vector& csr_col_ind, \ std::vector& csr_val, \ JTYPE& M, \ JTYPE& N, \ ITYPE& nnz, \ rocsparse_index_base base); \ template void rocsparse_init_csr_smtx(const char* filename, \ std::vector& csr_row_ptr, \ std::vector& csr_col_ind, \ std::vector& csr_val, \ JTYPE& M, \ JTYPE& N, \ ITYPE& nnz, \ rocsparse_index_base base); \ template void rocsparse_init_csr_bsmtx(const char* filename, \ std::vector& csr_row_ptr, \ std::vector& csr_col_ind, \ std::vector& csr_val, \ JTYPE& M, \ JTYPE& N, \ ITYPE& nnz, \ rocsparse_index_base base); \ template void rocsparse_init_csr_rocalution(const char* filename, \ std::vector& row_ptr, \ std::vector& col_ind, \ std::vector& val, \ JTYPE& M, \ JTYPE& N, \ ITYPE& nnz, \ rocsparse_index_base base); \ template void rocsparse_init_csr_rocsparseio(const char* filename, \ std::vector& row_ptr, \ std::vector& col_ind, \ std::vector& val, \ JTYPE& M, \ JTYPE& N, \ ITYPE& nnz, \ rocsparse_index_base base); \ template void rocsparse_init_csr_random( \ std::vector & row_ptr, \ std::vector & col_ind, \ std::vector & val, \ JTYPE M, \ JTYPE N, \ ITYPE & nnz, \ rocsparse_index_base base, \ rocsparse_matrix_init_kind init_kind, \ bool full_rank, \ bool to_int); \ template void rocsparse_init_gebsr_tridiagonal( \ std::vector & row_ptr, \ std::vector & col_ind, \ std::vector & val, \ JTYPE Mb, \ JTYPE Nb, \ ITYPE & nnzb, \ JTYPE row_block_dim, \ JTYPE col_block_dim, \ rocsparse_index_base base, \ JTYPE l, \ JTYPE u); \ template void rocsparse_init_gebsr_pentadiagonal( \ std::vector & row_ptr, \ std::vector & col_ind, \ std::vector & val, \ JTYPE Mb, \ JTYPE Nb, \ ITYPE & nnzb, \ JTYPE row_block_dim, \ JTYPE col_block_dim, \ rocsparse_index_base base, \ JTYPE ll, \ JTYPE l, \ JTYPE u, \ JTYPE uu); \ template void rocsparse_init_gebsr_laplace2d( \ std::vector & row_ptr, \ std::vector & col_ind, \ std::vector & val, \ int32_t dim_x, \ int32_t dim_y, \ JTYPE & Mb, \ JTYPE & Nb, \ ITYPE & nnzb, \ JTYPE row_block_dim, \ JTYPE col_block_dim, \ rocsparse_index_base base); \ template void rocsparse_init_gebsr_laplace3d( \ std::vector & row_ptr, \ std::vector & col_ind, \ std::vector & val, \ int32_t dim_x, \ int32_t dim_y, \ int32_t dim_z, \ JTYPE & Mb, \ JTYPE & Nb, \ ITYPE & nnzb, \ JTYPE row_block_dim, \ JTYPE col_block_dim, \ rocsparse_index_base base); \ template void rocsparse_init_gebsr_mtx(const char* filename, \ std::vector& bsr_row_ptr, \ std::vector& bsr_col_ind, \ std::vector& bsr_val, \ JTYPE& Mb, \ JTYPE& Nb, \ ITYPE& nnzb, \ JTYPE row_block_dim, \ JTYPE col_block_dim, \ rocsparse_index_base base); \ template void rocsparse_init_gebsr_smtx(const char* filename, \ std::vector& bsr_row_ptr, \ std::vector& bsr_col_ind, \ std::vector& bsr_val, \ JTYPE& Mb, \ JTYPE& Nb, \ ITYPE& nnzb, \ JTYPE row_block_dim, \ JTYPE col_block_dim, \ rocsparse_index_base base); \ template void rocsparse_init_gebsr_bsmtx(const char* filename, \ std::vector& bsr_row_ptr, \ std::vector& bsr_col_ind, \ std::vector& bsr_val, \ JTYPE& Mb, \ JTYPE& Nb, \ ITYPE& nnzb, \ JTYPE row_block_dim, \ JTYPE col_block_dim, \ rocsparse_index_base base); \ template void rocsparse_init_gebsr_rocalution( \ const char* filename, \ std::vector& row_ptr, \ std::vector& col_ind, \ std::vector& val, \ JTYPE& Mb, \ JTYPE& Nb, \ ITYPE& nnzb, \ JTYPE row_block_dim, \ JTYPE col_block_dim, \ rocsparse_index_base base); \ template void rocsparse_init_gebsr_rocsparseio( \ const char* filename, \ std::vector& row_ptr, \ std::vector& col_ind, \ std::vector& val, \ rocsparse_direction dir, \ JTYPE& Mb, \ JTYPE& Nb, \ ITYPE& nnzb, \ JTYPE row_block_dim, \ JTYPE col_block_dim, \ rocsparse_index_base base); \ template void rocsparse_init_gebsr_random( \ std::vector & row_ptr, \ std::vector & col_ind, \ std::vector & val, \ JTYPE Mb, \ JTYPE Nb, \ ITYPE & nnzb, \ JTYPE row_block_dim, \ JTYPE col_block_dim, \ rocsparse_index_base base, \ rocsparse_matrix_init_kind init_kind, \ bool full_rank, \ bool to_int); INSTANTIATEI(int32_t); INSTANTIATEI(int64_t); INSTANTIATE(int8_t); INSTANTIATE(int32_t); INSTANTIATE(int64_t); INSTANTIATE(size_t); INSTANTIATE(_Float16); INSTANTIATE(rocsparse_bfloat16); INSTANTIATE(float); INSTANTIATE(double); INSTANTIATE_COMPLEX(rocsparse_float_complex); INSTANTIATE_COMPLEX(rocsparse_double_complex); INSTANTIATE2(int32_t, int8_t); INSTANTIATE2(int64_t, int8_t); INSTANTIATE2(int32_t, _Float16); INSTANTIATE2(int64_t, _Float16); INSTANTIATE2(int32_t, rocsparse_bfloat16); INSTANTIATE2(int64_t, rocsparse_bfloat16); INSTANTIATE2(int32_t, float); INSTANTIATE2(int64_t, float); INSTANTIATE2(int32_t, double); INSTANTIATE2(int64_t, double); INSTANTIATE2(int32_t, rocsparse_float_complex); INSTANTIATE2(int64_t, rocsparse_float_complex); INSTANTIATE2(int32_t, rocsparse_double_complex); INSTANTIATE2(int64_t, rocsparse_double_complex); INSTANTIATE3(int32_t, int32_t, int8_t); INSTANTIATE3(int64_t, int32_t, int8_t); INSTANTIATE3(int64_t, int64_t, int8_t); INSTANTIATE3(int32_t, int32_t, _Float16); INSTANTIATE3(int64_t, int32_t, _Float16); INSTANTIATE3(int64_t, int64_t, _Float16); INSTANTIATE3(int32_t, int32_t, rocsparse_bfloat16); INSTANTIATE3(int64_t, int32_t, rocsparse_bfloat16); INSTANTIATE3(int64_t, int64_t, rocsparse_bfloat16); INSTANTIATE3(int32_t, int32_t, float); INSTANTIATE3(int64_t, int32_t, float); INSTANTIATE3(int64_t, int64_t, float); INSTANTIATE3(int32_t, int32_t, double); INSTANTIATE3(int64_t, int32_t, double); INSTANTIATE3(int64_t, int64_t, double); INSTANTIATE3(int32_t, int32_t, rocsparse_float_complex); INSTANTIATE3(int64_t, int32_t, rocsparse_float_complex); INSTANTIATE3(int64_t, int64_t, rocsparse_float_complex); INSTANTIATE3(int32_t, int32_t, rocsparse_double_complex); INSTANTIATE3(int64_t, int32_t, rocsparse_double_complex); INSTANTIATE3(int64_t, int64_t, rocsparse_double_complex);