Open marsdeno opened 1 month ago
Hi @marsdeno,
We are currently providing hipmemcpy2D
interface members for up to dimension 2 (as you have observed) via assumed-shape array arguments (ex: real :: A(:,:)
).
Example of such an interface member procedure (from : https://github.com/ROCm/hipfort/blob/develop/lib/hipfort/hipfort_hipmemcpy.f):
function hipMemcpy_l_2_c_int(dest,src,length,myKind)
use iso_c_binding
#ifdef USE_CUDA_NAMES
use hipfort_cuda_errors
#endif
use hipfort_enums
use hipfort_types
implicit none
logical(c_bool),target,dimension(:,:),intent(inout) :: dest
logical(c_bool),target,dimension(:,:),intent(in) :: src
integer(c_int),intent(in) :: length
integer(kind(hipMemcpyHostToHost)) :: myKind
#ifdef USE_CUDA_NAMES
integer(kind(cudaSuccess)) :: hipMemcpy_l_2_c_int
#else
integer(kind(hipSuccess)) :: hipMemcpy_l_2_c_int
#endif
!
hipMemcpy_l_2_c_int = hipMemcpy_(c_loc(dest),c_loc(src),length*1_8,myKind)
end function
On the short term, you could create an overloaded interface for hipmemcpy2D
yourself; see the next section.
As a workaround, you can create a similar procedure yourself that agrees with your application's datatypes and ranks and then overload the interface hipmemcpy2D
yourself to support what you want to to do.
Below is a minimal example that showcases the steps to do (developed and tested via https://onlinegdb.com/2elbMJizz):
module hipfort
interface hipmemcpy2D
module procedure :: foo
end interface
contains
subroutine foo(bar)
integer :: bar
print *,"a scalar"
end subroutine
end module
Program Hello
use hipfort
! user-side overloading of interface
interface hipmemcpy2D
procedure :: foo2
end interface
integer :: a, b(2)
! call already existing hipfort interface member
call hipmemcpy2D(a) ! output: "a scalar"
! call our custom interface member
call hipmemcpy2D(b) ! output: "an array"
contains
subroutine foo2(bar)
integer :: bar(:)
print *, "an array"
end subroutine
End Program Hello
Out of curiosity: What Fortran standard do you currently assume for your application?
With Fortran 2018, one could use assumed-rank array arguments (ex: real :: A(..)
).
This would allow to construct interface members such as the routine sub1
in the below snippet that can take arrays of any rank as argument:
REAL :: a0
REAL :: a1(10)
REAL :: a2(10, 20)
REAL, POINTER :: a3(:,:,:)
CALL sub1(a0)
CALL sub1(a1)
CALL sub1(a2)
CALL sub1(a3)
CONTAINS
SUBROUTINE sub1(a)
REAL :: a(..)
PRINT *, RANK(a)
END
END
There is ongoing work to revise the interfaces to support more ranks/provide better interfaces for users of more modern Fortran compilers. So feedback from your side on this is highly appreciated!
Suggestion Description
cudaMemcpy2D accepts fortran pointers to arrays with ranks greater than 2., while hip equivalent does not. Is this a conscious choice? I have code which uses memcpy2d on 3- and 4-d arrays. I can obviously rewrite, but was hoping to keep changes with respect to cuda version minimal.
Operating System
No response
GPU
No response
ROCm Component
No response