-
aoclsparse_status aoclsparse_syrk(const aoclsparse_operation opA, const aoclsparse_matrix A, aoclsparse_matrix *C)#
Multiplication of a sparse matrix and its transpose (or conjugate transpose) stored as a sparse matrix.
aoclsparse_syrkmultiplies a sparse matrix with its transpose (or conjugate transpose) in CSR storage format. The result is stored in a newly allocated sparse matrix in CSR format, such that\[ C := A \cdot op(A) \]if \(opA\) is aoclsparse_operation_none.Otherwise,
\[ C := op(A) \cdot A, \]where
\[\begin{split} op(A) = \left\{ \begin{array}{ll} A^T, & \text{transpose of } {\bf\mathsf{A}} \text{ for real matrices}\\ A^H, & \text{conjugate transpose of } {\bf\mathsf{A}} \text{ for complex matrices}\\ \end{array} \right. \end{split}\]where \(A\) is a \(m \times n\) matrix, opA is one of aoclsparse_operation_none, aoclsparse_operation_transpose (for real matrices) or aoclsparse_operation_conjugate_transpose (for complex matrices). The output matrix \(C\) is a sparse symmetric (or Hermitian) matrix stored as an upper triangular matrix in CSR format.
1/* ************************************************************************ 2 * Copyright (c) 2024 Advanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a copy 5 * of this software and associated documentation files (the "Software"), to deal 6 * in the Software without restriction, including without limitation the rights 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 * copies of the Software, and to permit persons to whom the Software is 9 * furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 * THE SOFTWARE. 21 * 22 * ************************************************************************ */ 23 24#include "aoclsparse.h" 25 26#include <complex> 27#include <cstring> 28#include <iomanip> 29#include <iostream> 30#include <limits> 31#include <vector> 32 33// An example to illustrate the usage of aoclsparse_syrk 34int main(void) 35{ 36 std::cout << "-------------------------------" << std::endl 37 << "----- syrk sample program -----" << std::endl 38 << "-------------------------------" << std::endl 39 << std::endl; 40 41 aoclsparse_matrix A; 42 aoclsparse_matrix C; 43 aoclsparse_status status; 44 aoclsparse_index_base base = aoclsparse_index_base_zero; 45 aoclsparse_int *csr_row_ptr_C = NULL; 46 aoclsparse_int *csr_col_ind_C = NULL; 47 double *csr_val_C = NULL; 48 aoclsparse_int C_m, C_n, C_nnz; 49 50 // Matrix sizes 51 aoclsparse_int m = 4, k = 3; 52 aoclsparse_int nnz = 7; 53 // Matrix A 54 // [ 0. -1.2 2.3] 55 // [ 4.6 0. 0. ] 56 // [ 0. 3.0 -8.1 ] 57 // [ 0.3 0. -5.1 ] 58 aoclsparse_int row_ptr[] = {0, 2, 3, 5, 7}; 59 aoclsparse_int col_ind[] = {1, 2, 0, 1, 2, 0, 2}; 60 double csr_val[] = {-1.2, 2.3, 4.6, 3.0, -8.1, 0.3, -5.1}; 61 aoclsparse_operation op = aoclsparse_operation_none; 62 63 status = aoclsparse_create_dcsr(&A, base, m, k, nnz, row_ptr, col_ind, csr_val); 64 if(status != aoclsparse_status_success) 65 { 66 return status; 67 } 68 69 // expected output matrices 70 aoclsparse_int C_m_exp = 4, C_n_exp = 4, C_nnz_exp = 8; 71 aoclsparse_int csr_row_ptr_C_exp[] = {0, 3, 5, 7, 8}; 72 aoclsparse_int csr_col_ind_C_exp[] = {0, 2, 3, 1, 3, 2, 3, 3}; 73 double csr_val_C_exp[] 74 = {6.73000, -22.23000, -11.73000, 21.16000, 1.38000, 74.61000, 41.31000, 26.10000}; 75 76 // output matrices; 77 78 status = aoclsparse_syrk(op, A, &C); 79 if(status != aoclsparse_status_success) 80 { 81 return status; 82 } 83 aoclsparse_export_dcsr( 84 C, &base, &C_m, &C_n, &C_nnz, &csr_row_ptr_C, &csr_col_ind_C, &csr_val_C); 85 86 bool oka, okb, okc, oki, okj, okk, ok = true; 87 std::cout << std::endl 88 << "Output Matrix C: " << std::endl 89 << std::setw(11) << "C_m" << std::setw(3) << "" << std::setw(11) << "expected" 90 << std::setw(3) << "" << std::setw(11) << "C_n" << std::setw(3) << "" << std::setw(11) 91 << "expected" << std::setw(3) << "" << std::setw(11) << "C_nnz" << std::setw(3) << "" 92 << std::setw(11) << "expected" << std::endl; 93 oka = C_m == C_m_exp; 94 ok &= oka; 95 std::cout << std::setw(11) << C_m << std::setw(3) << "" << std::setw(11) << C_m_exp 96 << std::setw(2) << (oka ? "" : " !"); 97 okb = C_n == C_n_exp; 98 ok &= okb; 99 std::cout << std::setw(11) << C_n << std::setw(3) << "" << std::setw(11) << C_n_exp 100 << std::setw(2) << (okb ? "" : " !"); 101 okc = C_nnz == C_nnz_exp; 102 ok &= okc; 103 std::cout << std::setw(11) << C_nnz << std::setw(3) << "" << std::setw(11) << C_nnz_exp 104 << std::setw(2) << (okc ? "" : " !"); 105 std::cout << std::endl; 106 std::cout << std::endl; 107 std::cout << std::setw(11) << "csr_val_C" << std::setw(3) << "" << std::setw(11) << "expected" 108 << std::setw(3) << "" << std::setw(11) << "csr_col_ind_C" << std::setw(3) << "" 109 << std::setw(11) << "expected" << std::setw(3) << "" << std::setw(11) 110 << "csr_row_ptr_C" << std::setw(3) << "" << std::setw(11) << "expected" << std::endl; 111 //Initializing precision tolerance range for double 112 const double tol = 1e-03; 113 for(aoclsparse_int i = 0; i < C_nnz; i++) 114 { 115 oki = ((std::abs(csr_val_C[i] - csr_val_C_exp[i]) <= tol)); 116 ok &= oki; 117 std::cout << std::setw(11) << csr_val_C[i] << "" << std::setw(11) << csr_val_C_exp[i] 118 << (oki ? "" : " !"); 119 okj = csr_col_ind_C[i] == csr_col_ind_C_exp[i]; 120 ok &= okj; 121 std::cout << std::setw(11) << csr_col_ind_C[i] << std::setw(3) << "" << std::setw(11) 122 << csr_col_ind_C_exp[i] << std::setw(2) << (okj ? "" : " !"); 123 if(i <= C_m) 124 { 125 okk = csr_row_ptr_C[i] == csr_row_ptr_C_exp[i]; 126 ok &= okk; 127 std::cout << " " << std::setw(11) << csr_row_ptr_C[i] << std::setw(3) << "" 128 << std::setw(11) << csr_row_ptr_C_exp[i] << std::setw(2) << (okk ? "" : " !"); 129 } 130 std::cout << std::endl; 131 } 132 aoclsparse_destroy(&A); 133 aoclsparse_destroy(&C); 134 135 return (ok ? 0 : 6); 136}
Note
aoclsparse_syrkassumes that the input CSR matrix has sorted column indices in each row. If not, call aoclsparse_order_mat() before callingaoclsparse_syrk.Note
aoclsparse_syrkcurrently does not support aoclsparse_operation_transpose for complexA.- Parameters:
opA – [in] Matrix \(A\) operation type.
A – [in] Sorted sparse CSR matrix \(A\).
*C – [out] Pointer to the new sparse CSR symmetric/Hermitian matrix \(C\). Only upper triangle of the result matrix is computed. The column indices of the output matrix in CSR format might be unsorted. The matrix should be freed by aoclsparse_destroy() when no longer needed.
- Return values:
aoclsparse_status_success – The operation completed successfully.
aoclsparse_status_invalid_pointer –
A,Cis invalid.aoclsparse_status_wrong_type – A and its operation type do not match.
aoclsparse_status_not_implemented – The input matrix is not in the CSR format or
opAis aoclsparse_operation_transpose andAhas complex values.aoclsparse_status_invalid_value – The value of opA is invalid.
aoclsparse_status_unsorted_input – Input matrices are not sorted.
aoclsparse_status_memory_error – Memory allocation failure.