I am running a Fortran model with a large number of modules and functions, and it has a derived type (grid type, G
) of several arrays, and will be used widely across the model. Although we don’t have any global variables, I would like this to be copied onto our GPU early and used across many different functions.
I am trying to slowly migrate our loops to the GPU with OpenACC. If I select a loop containing G
, such as this:
do j=js,je ; do I=Isq,Ieq
diffu(I,j,k) = ((G%IdyCu(I,j)*(CS%dy2h(i,j)*str_xx(i,j) - CS%dy2h(i+1,j)*str_xx(i+1,j)) + &
G%IdxCu(I,j)*(CS%dx2q(I,J-1)*str_xy(I,J-1) - CS%dx2q(I,J)*str_xy(I,J))) * &
G%IareaCu(I,j)) / (h_u(I,j) + h_neglect)
enddo ; enddo
then I get an error like this (running through ncu
):
FATAL ERROR: variable in data clause is partially present on the device: name=g
I can get around this by locally copying G
at the beginning of the function:
!$acc enter data copyin(G, CS)
then use
!$acc kernels present(G, CS)
...
(Performance is poor, but that’s not my concern at the moment.). Although G
is an argument into the function, it and its contents are essentially static across the run.
I would like to widen this operation so that multiple functions can see this copy of G
. I have tried something like this, which occurs in a different file:
! NOTE: A function another file is calling this function
! horizontal_viscosity() contains the loop from above.
!$acc enter data copyin(G)
call horizontal_viscosity(..., G, ...)
!$acc exist data delete(G)
but this does not seem to have any actual association. Instead, I get the following error:
FATAL ERROR: data in PRESENT clause was not found on device 1: name=g host:0x1709ea0
At this point, I’m unsure how to proceed, or if it is even possible.
Can I create data regions outside of functions, so that the loops inside of functions can see this data?