Intel® DevCloud
Help for those needing help starting or connecting to the Intel® DevCloud
1641 Discussions

Help with sparse matrix multiplication

Disha
Beginner
683 Views

I'm trying to multiply sparse x dense matrix using MKL. The output matrix appears to be wrong. Is there any issue with initializing matrix A? I'm running the code on DevCloud. Could someone help me with this? 

#include <stdio.h>
#include <stdlib.h>
#include "mkl.h"
#include "mkl_spblas.h"
#include <stdbool.h>

#define CALL_AND_CHECK_STATUS(function, error_message) do { \
          if(function != SPARSE_STATUS_SUCCESS)             \
          {                                                 \
          printf(error_message); fflush(0);                 \
          status = 1;                                       \
          }                                                 \
} while(0)

/* Consider adjusting LOOP_COUNT based on the performance of your computer */
/* to make sure that total run time is at least 1 second */
#define LOOP_COUNT 10

int main()
{
    double *B, *C, *values, *rv;
    int m, n, p, i, r, j, count, number;
    double alpha, beta;
    double s_initial, s_elapsed;
   
    sparse_matrix_t A = NULL;
    sparse_operation_t operation = SPARSE_OPERATION_NON_TRANSPOSE;
    
    struct matrix_descr descrA;
    descrA.type = SPARSE_MATRIX_TYPE_GENERAL;
    
    sparse_layout_t layout = SPARSE_LAYOUT_ROW_MAJOR;
    sparse_index_base_t indexing = SPARSE_INDEX_BASE_ZERO;
    
    MKL_INT *rows; 
    MKL_INT status;
    MKL_INT *col_indx;
    MKL_INT *bi, *ei, *indx;

    m = p = n = 4; 
    printf (" Initializing data for matrix multiplication C=A*B for matrix \n"
            " A(%ix%i) and matrix B(%ix%i)\n\n", m, p, p, n);
    alpha = 1.0; beta = 0.0;

    printf (" Allocating memory for matrices aligned on 64-byte boundary for better \n"
            " performance \n\n");

   
    values = (double *)mkl_malloc( m *sizeof( double ), 64 );
    B = (double *)mkl_malloc( p*n *sizeof( double ), 64 );
    C = (double *)mkl_malloc( m*n *sizeof( double ), 64 );
    col_indx = (MKL_INT *)mkl_malloc(m *sizeof(MKL_INT), 64);
    rows = (MKL_INT *)mkl_malloc((m + 1) *sizeof(MKL_INT), 64);

    printf (" Intializing matrix data \n\n");
    
    for( i = 0; i < m; i++ )
          values[i] = (rand() % (20 - 1 + 1)) + 1;
    
    for( i = 0; i < m; i++)
          col_indx[i] = i % 3;
    
        
    rows[0] = 0;
    for( i = 1; i < (m + 1); i++ )
          rows[i] = rows[i - 1] + 2;
    
    for (i = 0; i < (p*n); i++) 
    {
        B[i] = (double)(i+1);
    }

    
    for (i = 0; i < (m*n); i++) 
    {
        C[i] = 0.0;
    }


    printf (" Making the first run of matrix product using Intel(R) MKL to get stable run time measurements \n\n");
    
    mkl_sparse_d_create_csr (&A, indexing, m, p, rows, rows + 1, col_indx, values);
    
    mkl_sparse_d_export_csr (A, &indexing, rows, col_indx, &bi, &ei, &indx, &rv);
    
    printf("\nMatrix A \n");
    for(i = 0; i < p; i++) 
    {
        for(long l = 0; l < p; l++) 
        {
                bool flag = false;
                for(long j = bi[i]; j < ei[i]; j++) 
                {
                        if(indx[j] == l) 
                        {
                                flag = true;
                                printf("%.0lf ", rv[j]);
                                break;
                        }
                }
                if(!flag)
                        printf("%d ",0);

        }       printf("\n");
    }
    
    printf("\n Matrix B \n");
    for (i = 0; i < p; i++)
    {
        printf("\n");
        for (j = 0; j < n; j++)
        printf(" %f ",*( B + i * n + j));
    }
    
    CALL_AND_CHECK_STATUS (mkl_sparse_d_mm(operation, alpha, A, descrA, layout, B, n, p, beta, C, m), "Error after MKL_SPARSE_D_MV, csrC*x  \n");

    printf (" Measuring performance of matrix product using Intel(R) MKL \n\n");
    s_initial = dsecnd();
    
    for (r = 0; r < LOOP_COUNT; r++) 
    {
        CALL_AND_CHECK_STATUS (mkl_sparse_d_mm(operation, alpha, A, descrA, layout, B, n, p, beta, C, m), "Error after MKL_SPARSE_D_MV, csrC*x  \n");
    
    }
    
    s_elapsed = (dsecnd() - s_initial) / LOOP_COUNT;

    printf (" == Matrix multiplication using Intel(R) MKL completed == \n"
            " == at %.5f milliseconds == \n\n", (s_elapsed * 1000));
    
    for (i = 0; i < m; i++)
        {
            printf("\n");
            for (j = 0; j < n; j++)
            printf(" %f ", *(C + i * n + j));
        }
    
    printf ("\n Deallocating memory \n\n");
    mkl_free(A);
    mkl_free(B);
    mkl_free(C);
    
    if (s_elapsed < 0.9/LOOP_COUNT) {
        s_elapsed=1.0/LOOP_COUNT/s_elapsed;
        i=(int)(s_elapsed*LOOP_COUNT)+1;
        printf(" It is highly recommended to define LOOP_COUNT for this example on your \n"
               " computer as %i to have total execution time about 1 second for reliability \n"
               " of measurements\n\n", i);
    }

    printf (" Example completed. \n\n");
    return 0;
    
    
    
}

 

 

0 Kudos
3 Replies
ChithraJ_Intel
Moderator
658 Views

Hi Disha,


Thanks for reaching out to us. Since your issue is related more on matrix multiplication using MKL, we would suggest you to post the query in Intel MKL forum. Here is the link to the forum:

https://community.intel.com/t5/Intel-oneAPI-Math-Kernel-Library/bd-p/oneapi-math-kernel-library

Since your issue regarding running the MKL sample for sparse X dense multiply is resolved, shall we discontinue monitoring this thread?


Regards,

Chithra


0 Kudos
Disha
Beginner
650 Views

Yes I have posted the question on the MKL site. You can discontinue this thread

0 Kudos
ChithraJ_Intel
Moderator
640 Views

Hi Disha,


Thanks for the confirmation.  We would discontinue monitoring this issue,please raise a new thread if you have further issues.


Regards,

Chithra


0 Kudos
Reply