How to use cusparseCsr2cscEx2() in CUDA Fortran?

Hi all,

I want to use cuSparse in my CUDA Fortran code. I need to transpose a sparse matrix, so I intend to use the function cusparseCsr2cscEx2() following the document. However, valType here is kind of ambiguous to me. I cannot find its default value or definition. Can someone please explain it to me? Thanks!

The function pasted from the doc:

 integer(4) function cusparseScsr2cscEx2(handle, m, n, nnz, csrVal, csrRowPtr, csrColInd, cscVal, cscColPtr, cscRowInd, valType, copyValues, idxBase, alg, buffer)
   type(cusparseHandle) :: handle
   integer(4) :: m, n, nnz, valType, copyValues, idxBase, alg
   real(4), device :: csrVal(*), cscVal(*)  ! Can be any supported type
   integer(4), device :: csrRowPtr(*), csrColInd(*), cscRowInd(*), cscColPtr(*)
   integer(1), device :: buffer ! Can be any type 
1 Like

When I compiled the code, I got the same error as in this former post.

NVFORTRAN-S-0038-Symbol, cusparsecsr2cscex2_buffersize, has not been explicitly declared (update.cuf)
NVFORTRAN-S-0038-Symbol, cusparsecsr2cscex2, has not been explicitly declared (update.cuf)

I am not familiar with wrapper things, maybe I missed something?

What version of the HPC SDK are you using? These functions should be in the cusparse module of recent versions. The valType is an integer in our cusparse wrappers. You can use the name from the C library_types.h. Not sure how well this is documented, but these are supported from Fortran. Identifiers like CUDA_R_32F and CUDA_R_64F.

Thanks for your reply.
I am using nvfortran 20.11-0 LLVM 64-bit target on x86-64 Linux -tp skylake.
Should I upgrade to a newer version?

BTW, here is the my call to the function, I wonder if I used the right argumentsā€¦

subroutine foo
    use parameter
    use cusparse
    implicit none
    !A is a num x dgridsize sparse matrix
    !B is the transpose of A
    !C is the result of A*B
    !num*25 is the number of nonzeros in A
    type(cusparseHandle) :: handle
    type(cusparseMatDescr) :: csrA,cscB,csrC 
    integer,device::num,dgridsize
    real,device::csrAval(num*25),cscBval(num*25)
    real,device::csrrowptr(num+1),csrcolind(num*25)
    real,device::csccolptr(num+1),cscrowind(num*25)
    real,device,dimension(:),allocatable::buffer
    integer::buffersize
    ierr= cusparsecreate(handle)
    ierr= cusparsecreatematdescr(csrA)
    ierr= cusparsecreatematdescr(cscB)
    ierr= cusparsecreatematdescr(csrC)
    ierr= cusparsesetmatindexbase(csrA,CUSPARSE_INDEX_BASE_ONE)
    ierr= cusparsesetmatindexbase(cscB,CUSPARSE_INDEX_BASE_ONE)
    ierr= cusparsesetmatindexbase(csrC,CUSPARSE_INDEX_BASE_ONE)
    ierr= cusparsesetmattype(csrA,CUSPARSE_MATRIX_TYPE_GENERAL)
    ierr= cusparsesetmattype(cscB,CUSPARSE_MATRIX_TYPE_GENERAL)
    ierr= cusparsesetmattype(csrC,CUSPARSE_MATRIX_TYPE_GENERAL)
    ierr= cusparseCsr2cscEx2_bufferSize(handle,num,dgridsize,num*25,csrAval,&
        csrrowptr,csrcolind,cscBval,csccolptr,cscrowind,CUDA_R_32F,CUSPARSE_ACTION_NUMERIC,&
        CUSPARSE_INDEX_BASE_ONE,CUSPARSE_CSR2CSC_ALG2,buffersize)
    allocate(buffer(buffersize))
    ierr= cusparsecsr2cscEx2(handle,num,dgridsize,num*25,csrAval,csrrowptr,&
        csrcolind,cscBval,csccolptr,cscrowind,CUDA_R_32F,CUSPARSE_ACTION_NUMERIC,&
        CUSPARSE_INDEX_BASE_ONE,CUSPARSE_CSR2CSC_ALG2,buffer)
    ierr= cusparseScsrgemm2(...)
end subroutine foo

Unfortunately still got the same compiling errorā€¦

It is likely because the Fortran cusparse module from 20.11 does not have an interface for those functions. You could update your compiler to something from 2022, or write the interface yourself. Hereā€™s an example of the bufferSize function:
interface
integer(c_int) function cusparseCsr2cscEx2_bufferSize(handle, m, n, nnz, csrVal, csrRowPtr, csrColInd, &
cscVal, cscColPtr, cscRowInd, valType, copyValues, idxBase, alg, bufferSize) &
bind(C,name=ā€˜cusparseCsr2cscEx2_bufferSizeā€™)
use iso_c_binding
import cusparseHandle
type(cusparseHandle), value :: handle
integer(c_int), value :: m, n, nnz, valType, copyValues, idxBase, alg
!pgi$ ignore_tkr csrVal, cscVal ! Ignore the type, kind and rank
real(4), device :: csrVal(), cscVal()
integer(c_int), device :: csrRowPtr(), csrColInd(), cscRowInd(), cscColPtr()
integer(8) :: bufferSize
end function cusparseCsr2cscEx2_bufferSize
end interface

1 Like

Thank you! It works under 21.7.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.