passing device data to C function from Fortran

Suppose that I have a C function which receives void* arguments pointing to a location in device memory. This C host function will do something with these device data, e.g. call a C kernel to perform adding two arrays arr1, arr2 into arr3.

My question is that

void func1(const void* arr1,const void*arr2, void* arr3)

How could I call this function from Fortran.
I tried this

interface 
  subroutine func1(arr1, arr2, arr3) 
     use iso_c_binding
      type(c_ptr), intent(IN) :: arr1, arr2
      type(c_ptr) :: arr3
  end subroutine
end interface

double precision, allocatable, dimension(:), device, target: arr1,arr2, arr3
type(c_ptr) :: carr1, carr2, carr3
// generate data for arr1, arr2, arr3 on device
   ...

// map to C ptr
carr1 = c_loc(arr1)
carr2 = c_loc(arr2)
carr3 = c_loc(arr3)
//
call func1(carr1, carr2, carr3)

However, it seems that I cannot use TARGET with DEVICE attribute together. Could you please give me a solution for this problem.

Thanks,
Tuan

Hi Tuan,

For device pointers, you shouldn’t need to use the c_ptr type. Just declare them as ‘device’ allocatable.

Something like:

interface
  subroutine func1(arr1, arr2, arr3)
     use iso_c_binding
      real(c_double), allocatable, dimension(:), device :: arr1,arr2, arr3 
  end subroutine
end interface

double precision, allocatable, dimension(:), device :: arr1,arr2, arr3

Hope this helps,
Mat

Thanks Mat for your prompt response. I’ll check it.

Tuan

The assumed shape might give you troubles. Try this:

interface
subroutine func1(arr1, arr2, arr3) bind(c)
real(c_double), device, dimension(*) :: arr1, arr2, arr3
end subroutine
end interface