PGI User Forum
 SearchSearch   MemberlistMemberlist     RegisterRegister   ProfileProfile    Log inLog in 

CUDA-x86.

question on !$acc declare and Fortran modules

 
Post new topic   Reply to topic    PGI User Forum Forum Index -> Accelerator Programming
View previous topic :: View next topic  
Author Message
franzisko



Joined: 11 Jan 2011
Posts: 25

PostPosted: Wed Jun 06, 2012 12:06 am    Post subject: question on !$acc declare and Fortran modules Reply with quote

Hello,

I need to port to OpenACC a code like this:

Code:

module storage_1
   integer, parameter :: N=1000
   real, dimension(:,:), allocatable :: A,B,C
end module storage_1

subroutine allocate_1()
   use storage_1
   allocate(A(N,N),B(N,N),C(N,N))
   A = 1.  ; B = 2.  ; C = 0.
end subroutine allocate_1

module storage_2
   integer, parameter :: N=1000
   real, dimension(:,:), allocatable :: A,B,C
end module storage_2

subroutine allocate_2()
   use storage_2
   allocate(A(N,N),B(N,N),C(N,N))
   A = 2.  ; B = 3.  ; C = 0.
end subroutine allocate_2
   
subroutine matadd_sub_1()
   use storage_1; implicit none 
   integer :: i,j
!$acc kernels loop present(A,B,C)
   do i=1,N 
      do j=1,N 
         C(i,j) = A(i,j) + B(i,j)
      enddo     
   enddo     
!$acc end kernels
end subroutine matadd_sub_1

subroutine matadd_sub_2() 
   use storage_2; implicit none
   integer :: i,j
!$acc kernels loop present(A,B,C)
   do i=1,N 
      do j=1,N 
         C(i,j) = A(i,j) + B(i,j)
      enddo
   enddo     
!$acc end kernels
end subroutine matadd_sub_2

subroutine print_1
   use storage_1; implicit none
   print*,"1: C: ",C(6,3)
end subroutine print_1

subroutine print_2
   use storage_2; implicit none
   print*,"2: C: ",C(6,3)
end subroutine print_2

program matadd
   implicit none
   call allocate_1  ;
   call allocate_2

!$acc data region create(???)
!$acc update device(???)
   call matadd_sub_1
   call matadd_sub_2
   !.... many other calls for 1 and 2.....
!$acc update host(???)
!$acc end data region

   call print_1
   call print_2

end program matadd



where I need to control CPU-GPU copies by means of update directives.

The problem is that I cannot specify the list of variables when declaring the data region because the main programm cannot see the storage variables which have the same names but are defined in different modules.

Maybe, the declare directive could help if the allocate subroutines become module subprograms of the corresponding storage modules, according to the standard (If my understanding is correct):

"If the directive appears in a Fortran MODULE subprogram, the associated region is the implicit region for the whole program".

Is this feature implemented in PGI 12.5? I cannot have it working but maybe I am in a mistake.

Or the best would be to use declare directly in the storage modules but I think the standard does not allow for it. Is it?

I thank you very much for any help,

Francesco
Back to top
View user's profile
mkcolg



Joined: 30 Jun 2004
Posts: 6120
Location: The Portland Group Inc.

PostPosted: Wed Jun 06, 2012 2:35 pm    Post subject: Reply with quote

Hi Francesco,

What you want to use here is the "declare device_resident" directive in your modules. However, as you noticed, "device_resident" is still under development so not available in 12.5.

In the meantime, you can use the PGI Accelerator "mirror" directive which does the same thing. For example:
Code:

 module storage_1
   integer, parameter :: N=1000
   real, dimension(:,:), allocatable :: A,B,C
!$acc mirror(A,B,C)
!acc declare device_resident(A,B,C)
end module storage_1

subroutine allocate_1()
   use storage_1
   allocate(A(N,N),B(N,N),C(N,N))
   A = 1.  ; B = 2.  ; C = 0.
!$acc update device(A,B)
end subroutine allocate_1

module storage_2
   integer, parameter :: N=1000
   real, dimension(:,:), allocatable :: A,B,C
!$acc mirror(A,B,C)
!acc declare device_resident(A,B,C)
end module storage_2

subroutine allocate_2()
   use storage_2
   allocate(A(N,N),B(N,N),C(N,N))
   A = 2.  ; B = 3.  ; C = 0.
!$acc update device(A,B)
end subroutine allocate_2
   
subroutine matadd_sub_1()
   use storage_1; implicit none
   integer :: i,j
!$acc kernels loop
   do i=1,N
      do j=1,N
         C(i,j) = A(i,j) + B(i,j)
      enddo     
   enddo     
!$acc end kernels
!$acc update host(C)
end subroutine matadd_sub_1

subroutine matadd_sub_2()
   use storage_2; implicit none
   integer :: i,j
!$acc kernels loop
   do i=1,N
      do j=1,N
         C(i,j) = A(i,j) + B(i,j)
      enddo
   enddo     
!$acc end kernels
!$acc update host(C)
end subroutine matadd_sub_2

subroutine print_1
   use storage_1; implicit none
   print*,"1: C: ",C(6,3)
end subroutine print_1

subroutine print_2
   use storage_2; implicit none
   print*,"2: C: ",C(6,3)
end subroutine print_2

program matadd
   implicit none

   call allocate_1 
   call allocate_2

   call matadd_sub_1
   call matadd_sub_2

   call print_1
   call print_2

end program matadd


Hope this helps,
Mat
Back to top
View user's profile
franzisko



Joined: 11 Jan 2011
Posts: 25

PostPosted: Fri Jun 08, 2012 11:02 am    Post subject: device_resident Reply with quote

Hi Mat,

It helps, thank you.

My code now uses mirror directives and works fine but I would like to use OpenACC. Reading the standard I cannot see how device_resident could help me (becase I need data also in the host), but your example starts clarifying it.

I wait for the new compiler version to test it

thanks again
Francesco
Back to top
View user's profile
Display posts from previous:   
Post new topic   Reply to topic    PGI User Forum Forum Index -> Accelerator Programming All times are GMT - 7 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © phpBB Group