aoclsparse_syrk() - 5.2 English - 68552

AOCL API Guide (68552)

Document ID
68552
Release Date
2025-12-29
Version
5.2 English
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_syrk multiplies 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_syrk assumes that the input CSR matrix has sorted column indices in each row. If not, call aoclsparse_order_mat() before calling aoclsparse_syrk.

Note

aoclsparse_syrk currently does not support aoclsparse_operation_transpose for complex A.

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_pointerA, C is 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 opA is aoclsparse_operation_transpose and A has 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.