如何在 CUDA Fortran 中使用 cusparse 库的 gtsv2 函数?
How do I use gtsv2 functions of the cusparse library in CUDA Fortran?
我一直在使用 cusparseDgtsv
求解具有多个右侧的三对角矩阵。我最近发现 cusparseDgtsv2
可以提高并发性。但是文档说 cusparseDgtsv2
需要一个 void *pBuffer argument
,而 cusparseDgtsv2_bufferSizeExt
需要一个 size_t *bufferSizeInBytes
参数。对于 CUDA Fortran 中的 void
和 size_t
对应项,我应该使用什么样的参数?
*编辑
cusparseStatus_t cusparseDgtsv2(
cusparseHandle_t handle,
int m,
int n,
const double *dl,
const double *d,
const double *du,
double *B,
int ldb,
void *pBuffer)
@SteveLionel 我写了下面的代码,工作正常,但是当调用函数 cusparseDgtsv2
时,我收到一条警告消息说 "Argument to ISO_C_BINDING intrinsic must have TARGET attribute set." 另外,有没有更好的方法分配 N
字节而不是使用 character
数组?
function cusparseDgtsv2 (h,m,n,dl,d,du,B,ldb,pBuffer) bind(C,name='cusparseDgtsv2')
use iso_c_binding
use cusparse
type (cusparseHandle), value :: h
integer (c_int), value :: m,n
real (c_double), device :: dl(*)
real (c_double), device :: d(*)
real (c_double), device :: du(*)
real (c_double), device :: B(*)
integer (c_int), value :: ldb
type (c_ptr), value :: pBuffer
integer (c_int), value :: cusparseDgtsv2
end function
integer :: istat
integer :: m, n
integer (c_size_t) :: N
type (cusparseHandle) :: handle
real, allocatable, device :: d_A(:), d_B(:), d_C(:), d_D(:)
character, allocatable, device :: buf(:)
allocate (buf(N))
istat = cusparseDgtsv2 ( handle, m, n, d_A, d_B, d_C, d_D, m, c_loc(buf) )
在 Fortran 2018 之前,C void
没有 Fortran 等效项。支持 F2018 的 "Further Interoperability with C" 功能的编译器支持可与 void *
互操作的 type(*)
。我不知道您使用的是哪个编译器 - 如果是 PGI,我认为他们还不支持。
另一种方法是将参数声明为 type(C_PTR)
以及 value
属性。然后你会通过 C_LOC(arg)
.
对于 size_t
,即 integer(C_SIZE_T)
。所有这些都假定您已添加 USE ISO_C_BINDING
,您的过程接口具有 BIND(C)
,并且您的编译器至少支持 F2003 C 互操作性功能。
我一直在使用 cusparseDgtsv
求解具有多个右侧的三对角矩阵。我最近发现 cusparseDgtsv2
可以提高并发性。但是文档说 cusparseDgtsv2
需要一个 void *pBuffer argument
,而 cusparseDgtsv2_bufferSizeExt
需要一个 size_t *bufferSizeInBytes
参数。对于 CUDA Fortran 中的 void
和 size_t
对应项,我应该使用什么样的参数?
*编辑
cusparseStatus_t cusparseDgtsv2(
cusparseHandle_t handle,
int m,
int n,
const double *dl,
const double *d,
const double *du,
double *B,
int ldb,
void *pBuffer)
@SteveLionel 我写了下面的代码,工作正常,但是当调用函数 cusparseDgtsv2
时,我收到一条警告消息说 "Argument to ISO_C_BINDING intrinsic must have TARGET attribute set." 另外,有没有更好的方法分配 N
字节而不是使用 character
数组?
function cusparseDgtsv2 (h,m,n,dl,d,du,B,ldb,pBuffer) bind(C,name='cusparseDgtsv2')
use iso_c_binding
use cusparse
type (cusparseHandle), value :: h
integer (c_int), value :: m,n
real (c_double), device :: dl(*)
real (c_double), device :: d(*)
real (c_double), device :: du(*)
real (c_double), device :: B(*)
integer (c_int), value :: ldb
type (c_ptr), value :: pBuffer
integer (c_int), value :: cusparseDgtsv2
end function
integer :: istat
integer :: m, n
integer (c_size_t) :: N
type (cusparseHandle) :: handle
real, allocatable, device :: d_A(:), d_B(:), d_C(:), d_D(:)
character, allocatable, device :: buf(:)
allocate (buf(N))
istat = cusparseDgtsv2 ( handle, m, n, d_A, d_B, d_C, d_D, m, c_loc(buf) )
在 Fortran 2018 之前,C void
没有 Fortran 等效项。支持 F2018 的 "Further Interoperability with C" 功能的编译器支持可与 void *
互操作的 type(*)
。我不知道您使用的是哪个编译器 - 如果是 PGI,我认为他们还不支持。
另一种方法是将参数声明为 type(C_PTR)
以及 value
属性。然后你会通过 C_LOC(arg)
.
对于 size_t
,即 integer(C_SIZE_T)
。所有这些都假定您已添加 USE ISO_C_BINDING
,您的过程接口具有 BIND(C)
,并且您的编译器至少支持 F2003 C 互操作性功能。