Intel® oneAPI Math Kernel Library
Ask questions and share information with other developers who use Intel® Math Kernel Library.

MKL help with mkl_sparse_s_create_coo and MKL_SPARSE_CONVERT_CSR

Brandon_R_
Beginner
989 Views

Hello,

I am trying to use mkl_spblas and I am having some strange issues. Firstly, here is the code I am trying to compile using mkl-16.2.181 and impi-intel-5.1.3-16.0.2.

 

MODULE test

contains

subroutine tester_sub(l,N,Pf)

use MKL_SPBLAS

include 'mkl_spblas.fi'

include 'mkl_sparse_handle.fi'

!declaring variables                                                              

integer, intent(in) :: l,N

integer, DIMENSION(1) :: seed = (/300/) 

real :: num                                                                                                                                                                                                                                  

real, dimension(4) :: sum1                                                                                                                                              

real, dimension(2) :: sum2

real :: hf,hc,U,Z

real, intent(out) :: pf 

integer :: i,nf,nc,N1

real, allocatable, dimension(:) :: cf_m,cfd,cf_p,cf,cc_m,ccd,cc_p,cc,RHS,ones_f,ones_c,uf,uc

integer, allocatable, dimension(:,:) :: coords_d, coords_m,coords_p

type (SPARSE_MATRIX_T) :: A0f,A1f,A0c,A1c,LHS,Identity_c,Identity_f,A1f_csr

integer :: stat 

real, allocatable,dimension(:) :: cf_full,cc_full 

type(MATRIX_DESCR) :: descr!SPARSE_MATRIX_TYPE_GENERAL  

nf = 2**(l+1)

!creating a ones array for f                                                                                                            

ALLOCATE(ones_f(nf-1))

ones_f = real(-1)

ALLOCATE(cf(nf),cf_m(nf-1),cfd(nf-1),cf_p(nf-1))

hf = real(1)/real(nf)

cf = real(1)

cf_m = hf**(-2)*cf(2:size(cf))

cfd = hf**(-2)*-cf(2:size(cf)) - hf**(-2)*cf(1:size(cf)-1)

cf_p = hf**(-2)*cf(1:size(cf)-1)

ALLOCATE(coords_d(nf-1,2))

ALLOCATE(coords_m(nf-1,2))

ALLOCATE(coords_p(nf-1,2))

!creating the coordinates of the vectors                                                                                                                                 

do i = 1,nf-1

   coords_d(i,:) = i

end do

!don't want last row of matrix                                        

do i = 1,nf-1

   coords_m(i,1) = i + 1     !row position    

   coords_m(i,2) = i         !column position                                                                                                                                                                                   end do

!don't want last row of matrix                                                                                                                                                                                                     do i = 1,nf-1

   coords_p(i,1) = i         !row position                                                                                                                                                                                            coords_p(i,2) = i + 1     !column position                                                                                                                                                                                 end do

allocate(cf_full(3*nf-3))

!holding all of the values for the sparse matrix           

cf_full = (/ cf_m,cfd,cf_p  /)

stat = mkl_sparse_s_create_coo(A0f,1,nf-1,nf-1,size(cf_full),(/ coords_m(1:nf-2,1),coords_d(:,1), &

     coords_p(1:nf-2,1) /),(/ coords_m(1:nf-2,2),coords_d(:,2),coords_p(1:nf-2,2) /),cf_full)

print *, stat                                                                                                                                                                                                                                     

print *, 'here 0'

stat = MKL_SPARSE_CONVERT_CSR(A0f,SPARSE_OPERATION_NON_TRANSPOSE,A0f)

print *, 'here 1'

end subroutine tester_sub

end MODULE test

 

I can compile the code so I believe that all of the libraries are linked correctly.

When I do print *, stat  after mkl_sparse_s_create_coo I get the value 3. I am unsure of what this value actually means. From https://software.intel.com/en-us/node/590112 it seems like mkl_sparse_s_create_coo is supposed to return a Character, but I can only use integer type for stat. 

Once I try to use  MKL_SPARSE_CONVERT_CSR the program either has a segmentation fault or it hangs. I believe this is because A0f is not created correctly. 

So, I guess my question is

1) What does stat = 3 mean?

2) If I am creating the sparse matrix A0f incorrectly, how do I create it correctly? 

 

 

0 Kudos
6 Replies
Zhen_Z_Intel
Employee
989 Views

Hi Brandon,

You could check the enum value defined in mkl_spbals.f90 , the "status=3" represents invalid input value. Please make sure your type and value of input attributes. In your code, you indicate input array index from 1, row size and column size are 2^(I+1)-1, but what is the value of I? It might be the problem with... Here's an example called "sparse_s_csrmv.f90" in %MKLROOT%\examples\examples_core_f\spblasf\source, you could refer how function "mkl_sparse_s_create_csc" can be used. The function for creating matrix in csc format is similar to function of creating matrix in coo format, just change some attributes. Hope it could help you.

Best regards,

Fiona

0 Kudos
Brandon_R_
Beginner
989 Views

Hello Fiona,

Since the last time we spoke, I have instead created sparse matrices A and B using the CSR format. I am still having some issues though. Here is the code where

                 |   1       2      0    0     0   |                                                                                                                               
                 |   0       3      4    5     0   |                                                                                                                               
  A    =         |   0       0      6    7     8   |                                                                                                                              
                 |   0       0      0    9     10  |   


                 |   2       2      0    0     0   |                                                                                                                               
                 |   0       2      2    2     0   |                                                                                                                               
  B    =         |   0       0      2    2     2   |                                                                                                                              
                 |   0       0      0    2     2   |                                                                                                                             

 

! code start ***************************************************************************************************************
type (SPARSE_MATRIX_T) :: A,B,C
integer :: stat                                                                                                                                                                                                                                                                                                                                             
real :: values_a(10),values_b(10),values_b_x(10)
integer :: col_a(10),col_b(10),row_start_a(5),row_start_b(5),row_end_a(4),row_end_b(4)
integer :: col_b_x(10),row_start_b_x(5),row_end_b_x(4)
integer :: rows, cols,indexing

values_a(1:10) = real((/1,2,3,4,5,6,7,8,9,10/))
values_b(1:10) = real((/2,2,2,2,2,2,2,2,2,2/))

col_a(1:10) = (/1,2,2,3,4,3,4,5,4,5/)
col_b(1:10) = (/1,2,2,3,4,3,4,5,4,5/)

row_start_a(1:5) = (/1,3,6,9,11/)
row_start_b(1:5) = (/1,3,6,9,11/)

row_end_a(1:4) = (/2,5,8,10/)
row_end_b(1:4) = (/2,5,8,10/)

stat = mkl_sparse_s_create_csr(A,SPARSE_INDEX_BASE_ONE,4,5,row_start_a,row_end_a,col_a,values_a)

print *, stat

stat = mkl_sparse_s_create_csr(B,SPARSE_INDEX_BASE_ONE,4,5,row_start_b,row_end_b,col_b,values_b)

print *, stat

stat = mkl_sparse_s_export_csr(B,indexing,rows,cols,row_start_b_x,row_end_b_x,col_b_x,values_b_x)

print *, stat
print *, row_start_b_x

stat = mkl_sparse_s_add(SPARSE_OPERATION_NON_TRANSPOSE,B,real(1.0),A,C)                                                                                                                                                                    

print *, stat

! code end ***************************************************************************************************************

However, I get the following output:
           0
           0
           0
     7183776           0           0           0           0
           2

It seems like I am not creating the matrices correctly, but I believe I am. Printing stat, shows that creating A and B is 
successful and that exporting the csr format is also successful, but adding the two matrices gives the error SPARSE_STATUS_ALLOC_FAILED.

What exactly is going on here? 

Thank you,
Brandon 

 

0 Kudos
Zhen_Z_Intel
Employee
989 Views

Hi Brandon,

You didn't assign value for variables "indexing", "rows" and "cols"...... Please check with your code. Thanks. 

Fiona

0 Kudos
Irina_S_Intel
Employee
989 Views

Hi Brandon, Fiona,

Parameters  "indexing", "rows" and "cols" are output parameters and should not be assigned.

Brandon, I need some time to check your issue and see how we can help you.

Best regards,

Irina

0 Kudos
Brandon_R_
Beginner
989 Views

Hello Irina,

Thank you very much for your help. Also, I was wondering if you could possibly try to run the program that I have implemented above? It might be possible that I am not correctly linked to the library. 

 

Thank you,

Brandon

0 Kudos
Irina_S_Intel
Employee
989 Views

Hi Brandon,

Concerning the second problem with mkl_sparse_s_add, I run your code and see similar behavior. This issue will be fixed in future MKL releases, the problem is caused by incorrect behavior of mkl_sparse_s_export_csr. I can suggest you two workarounds:

  1. If it’s not possible, use C. If it is not possible:

  2. Add correct interface of mkl_sparse_s_export_csr in the beginning of your program, pass C pointers in the body of mkl_sparse_s_export_csr and cast them to fortran pointers afterwards. Here is an example how this can be done with the code that you’ve sent. Please let me know if you've succeeded in using such approach.

        PROGRAM test
	USE ISO_C_BINDING
        USE MKL_SPBLAS
        
       !Declare new interface with aarrays rows, cols, values of type C pointer
       !Change name of the routine to EXPORT_CSR_FIXED so it doesn’t conflict with existing MKL interface        
        INTERFACE
            FUNCTION MKL_SPARSE_S_EXPORT_CSR_FIXED(source,indexing,rows,cols,rows_start,rows_end,col_indx,values) &
                 BIND(C, name='MKL_SPARSE_S_EXPORT_CSR')
            USE, INTRINSIC :: ISO_C_BINDING , ONLY : C_INT, C_FLOAT, C_PTR
            IMPORT SPARSE_MATRIX_T
            TYPE(SPARSE_MATRIX_T), INTENT(IN) :: source
            INTEGER(C_INT)      , INTENT(INOUT) :: indexing
            INTEGER(C_INT)      , INTENT(INOUT) :: rows
            INTEGER(C_INT)      , INTENT(INOUT) :: cols
            TYPE(C_PTR)         , INTENT(INOUT) :: rows_start
            TYPE(C_PTR)         , INTENT(INOUT) :: rows_end
            TYPE(C_PTR)         , INTENT(INOUT) :: col_indx
            TYPE(C_PTR)         , INTENT(INOUT) :: values
            INTEGER(C_INT) MKL_SPARSE_S_EXPORT_CSR_FIXED
            END FUNCTION
        END INTERFACE

        type (SPARSE_MATRIX_T) :: A,B,C
        integer :: stat
        real :: values_a(10),values_b(10),values_b_x(10)
        integer :: col_a(10),col_b(10),row_start_a(5),row_start_b(5),row_end_a(4),row_end_b(4)
        integer :: col_b_x(10),row_start_b_x(5),row_end_b_x(4)
        integer :: rows, cols,indexing
        

        !declare C and fortran pointers. C pointers will be passed to the body of export_csr routine.
        integer nnz, nrows
        type(c_ptr) :: row_start_c, row_end_c, col_c, values_c
      
      
        integer, pointer, dimension(:) :: row_start_f, row_end_f, col_f
        real, pointer, dimension(:) :: values_f
            

        values_a(1:10) = real((/1,2,3,4,5,6,7,8,9,10/))
        values_b(1:10) = real((/2,2,2,2,2,2,2,2,2,3/))

       col_a(1:10) = (/1,2,2,3,4,3,4,5,4,5/)
        col_b(1:10) = (/1,2,2,3,4,3,4,5,4,5/)

        row_start_a(1:5) = (/1,3,6,9,11/)
        row_start_b(1:5) = (/1,3,6,9,11/)

        row_end_a(1:4) = (/2,5,8,10/)
        row_end_b(1:4) = (/2,5,8,10/)

        stat = mkl_sparse_s_create_csr(A,SPARSE_INDEX_BASE_ONE,4,5, &
        row_start_a,row_end_a,col_a,values_a)

        print *, stat

        stat = mkl_sparse_s_create_csr(B,SPARSE_INDEX_BASE_ONE,4,5,&
        row_start_b,row_end_b,col_b,values_b)

        print *, stat

        stat = mkl_sparse_s_add(SPARSE_OPERATION_NON_TRANSPOSE,&
        B,real(1.0),A,C)

        !call export_csr with C pointers       
        stat = mkl_sparse_s_export_csr_fixed(C,indexing,rows,cols,&
        row_start_c,row_end_c,col_c,values_c)

        print *, stat
        print *, 'rows ', rows
        
        print *, 'indexing', indexing

        nrows = rows

        !Cast C pointers that came from export routine to Fortran pointers
                        call c_f_pointer(row_start_c, row_start_f, [nrows+1])
        call c_f_pointer(row_end_c, row_end_f, [nrows])

        nnz = row_start_f(nrows+1)-indexing        
        print *, nnz
        call c_f_pointer(col_c,     col_f,     [nnz])
        call c_f_pointer(values_c,   values_f,   [nnz])

        print *,'row_start_f', row_start_f
        print *,'row_end_f', row_end_f
        print *,'col_f', col_f
        print *,'values_f', values_f


        print *, stat

        END PROGRAM test

 

0 Kudos
Reply