-
aoclsparse_status aoclsparse_ssyrkd(const aoclsparse_operation opA, const aoclsparse_matrix A, const float alpha, const float beta, float *C, const aoclsparse_order orderC, const aoclsparse_int ldc)#
-
aoclsparse_status aoclsparse_dsyrkd(const aoclsparse_operation opA, const aoclsparse_matrix A, const double alpha, const double beta, double *C, const aoclsparse_order orderC, const aoclsparse_int ldc)#
-
aoclsparse_status aoclsparse_csyrkd(const aoclsparse_operation opA, const aoclsparse_matrix A, const aoclsparse_float_complex alpha, const aoclsparse_float_complex beta, aoclsparse_float_complex *C, const aoclsparse_order orderC, const aoclsparse_int ldc)#
-
aoclsparse_status aoclsparse_zsyrkd(const aoclsparse_operation opA, const aoclsparse_matrix A, const aoclsparse_double_complex alpha, const aoclsparse_double_complex beta, aoclsparse_double_complex *C, const aoclsparse_order orderC, const aoclsparse_int ldc)#
Multiplication of a sparse matrix and its transpose (or conjugate transpose) for all data types.
aoclsparse_syrkdmultiplies a sparse matrix with its transpose (or conjugate transpose) in CSR storage format. The result is stored in a dense format, such that\[ C := \alpha \cdot A \cdot op(A) + \beta \cdot C \]if \(opA\) is aoclsparse_operation_none.Otherwise,
\[ C := \alpha \cdot op(A) \cdot A + \beta \cdot C \]\[\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\) sparse matrix,
opAis 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 dense symmetric (or Hermitian) matrix stored as an upper triangular matrix.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 << "----- syrkd sample program -----" << std::endl 38 << "-------------------------------" << std::endl 39 << std::endl; 40 41 aoclsparse_matrix A; 42 aoclsparse_status status; 43 aoclsparse_index_base base = aoclsparse_index_base_zero; 44 aoclsparse_mat_descr descr; 45 double alpha = 2.1; 46 double beta = 1.3; 47 aoclsparse_int ldc = 10; 48 aoclsparse_operation op = aoclsparse_operation_none; 49 aoclsparse_order layout = aoclsparse_order_row; 50 aoclsparse_int m_C; 51 double *C = nullptr; 52 double *C_exp = nullptr; 53 54 // By default aoclsparse_create_mat_descr sets aoclsparse_matrix_type to aoclsparse_matrix_type_general 55 status = aoclsparse_create_mat_descr(&descr); 56 if(status != aoclsparse_status_success) 57 return status; 58 59 // Matrix sizes 60 aoclsparse_int m = 4, k = 3; 61 aoclsparse_int nnz = 7; 62 // Matrix A 63 // [ 0. -1.2 2.3] 64 // [ 4.6 0. 0. ] 65 // [ 0. 3.0 -8.1 ] 66 // [ 0.3 0. -5.1 ] 67 aoclsparse_int row_ptr[] = {0, 2, 3, 5, 7}; 68 aoclsparse_int col_ind[] = {1, 2, 0, 1, 2, 0, 2}; 69 double csr_val[] = {-1.2, 2.3, 4.6, 3.0, -8.1, 0.3, -5.1}; 70 71 status = aoclsparse_create_dcsr(&A, base, m, k, nnz, row_ptr, col_ind, csr_val); 72 if(status != aoclsparse_status_success) 73 { 74 return status; 75 } 76 77 // output matrix dimension 78 m_C = 4; 79 80 C = (double *)malloc(sizeof(double) * ldc * m_C); 81 C_exp = (double *)malloc(sizeof(double) * ldc * m_C); 82 83 // set the large C matrix to -1, only a window of size 4x4 (upper triangular part) 84 // is updated with the syrkd call 85 for(aoclsparse_int i = 0; i < ldc * m_C; i++) 86 { 87 C[i] = -1; 88 C_exp[i] = -1; 89 } 90 91 // Expected value of C which is C_exp 92 // [ 12.8330 -1.3000 -47.9830 -25.9330, -1, -1, ....] 93 // [ -1 43.1360 -1.3000 1.5980, -1, -1, ....] 94 // [ -1 -1 155.3810 85.4510, -1, -1, ....] 95 // [ -1 -1 -1 53.5100, -1, -1, ....] 96 // [ -1 -1 -1 -1, -1, -1, ....] 97 // ... 98 C_exp[0] = 12.8330; 99 C_exp[1] = -1.3000; 100 C_exp[2] = -47.9830; 101 C_exp[3] = -25.9330; 102 C_exp[11] = 43.1360; 103 C_exp[12] = -1.3000; 104 C_exp[13] = 1.5980; 105 C_exp[22] = 155.3810; 106 C_exp[23] = 85.4510; 107 C_exp[33] = 53.5100; 108 109 status = aoclsparse_dsyrkd(op, A, alpha, beta, C, layout, ldc); 110 if(status != aoclsparse_status_success) 111 { 112 return status; 113 } 114 115 bool oki, ok = true; 116 //Initializing precision tolerance range for double 117 const double tol = 1e-03; 118 std::cout << "Expected output\n" 119 << "-------------------------------\n"; 120 for(aoclsparse_int i = 0; i < m_C; i++) 121 { 122 for(aoclsparse_int j = 0; j < ldc; j++) 123 { 124 std::cout << std::setw(10) << C_exp[i * ldc + j] << std::setw(3) << ""; 125 } 126 std::cout << std::endl; 127 } 128 129 std::cout << "Actual output\n" 130 << "-------------------------------\n"; 131 for(aoclsparse_int i = 0; i < m_C; i++) 132 { 133 for(aoclsparse_int j = 0; j < ldc; j++) 134 { 135 oki = ((std::abs(C[i * ldc + j] - C_exp[i * ldc + j]) <= tol)); 136 ok &= oki; 137 std::cout << std::setw(10) << C[i * ldc + j] << std::setw(3) << (oki ? "" : " !"); 138 } 139 std::cout << std::endl; 140 } 141 aoclsparse_destroy_mat_descr(descr); 142 aoclsparse_destroy(&A); 143 free(C); 144 free(C_exp); 145 146 return (ok ? 0 : 6); 147}
Note
aoclsparse_syrkdassumes that the input CSR matrix has sorted column indices in each row. If not, call aoclsparse_order_mat() before callingaoclsparse_syrkd.Note
For complex type, only the real parts of \(\alpha\) and \(\beta\) are taken into account to preserve Hermitian \(C\).
Note
aoclsparse_syrkdcurrently does not support aoclsparse_operation_transpose for complexA.- Parameters:
opA – [in] Matrix \(A\) operation type.
A – [in] Sorted sparse CSR matrix \(A\).
alpha – [in] Scalar \(\alpha\).
beta – [in] Scalar \(\beta\).
C – [inout] Output dense matrix. Only upper triangular part of the matrix is processed during the computation, the strictly lower triangle is not modified.
orderC – [in] Storage format of the output dense matrix, \(C\). It can be aoclsparse_order_row or aoclsparse_order_column.
ldc – [in] Leading dimension of \(C\).
- Return values:
aoclsparse_status_success – The operation completed successfully.
aoclsparse_status_invalid_pointer –
A,Cis invalid.aoclsparse_status_wrong_type –
Aand 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,orderCorldcis invalid.aoclsparse_status_unsorted_input – Input matrix is not sorted.
aoclsparse_status_memory_error – Memory allocation failure.