Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature]: inputs to hipMemcyp2D with rank greater than two #175

Open
marsdeno opened this issue Jul 11, 2024 · 1 comment
Open

[Feature]: inputs to hipMemcyp2D with rank greater than two #175

marsdeno opened this issue Jul 11, 2024 · 1 comment

Comments

@marsdeno
Copy link

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

@domcharrier
Copy link
Contributor

domcharrier commented Jul 17, 2024

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.

Short term: Workaround?

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

Should we use Fortran 2018 features?

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants