Problems with !$acc declare creat and copyin

I have written a program but got a wrong answer, I want to know how to copy data to/from GPU with declare creat and declare copyin directives and how can I get the right answer?
Here is the program.

      program main
      use global
      implicit none
      integer i
!$acc routine(add1,add2,add3) seq
      N=100
      do i=1,N
      a(i)=i
      b(i)=N-i
      enddo  
!$acc parallel loop
      do i=1,1024
        call add1()
      enddo
      print *,"c(100)=",c(100)
      endprogram



      module global
      implicit none
      integer N
      integer a(100),b(100),c(100)
!$acc declare copyin(a(100),b(100),c(100),N)
      end module



      subroutine add1()
      use global
!$acc routine seq
      implicit none      
      integer i
c!$acc enter data copyin(a,b,c)
      do i=1,N
      c(i)=a(i)+b(i)
      end do
      return
      end

Hi xll_bit,

When using “declare” in a module, the device variables are created when the device is initialize. In this case, the initialization occurs upon entering the “parallel loop”. Though while a, b, c, and N are initialized on the device, you’re getting wrong answers since you need and “update self(c)” to update the host values of “c”.

Note that I would recommend using “declare create” instead of “declare copyin”, and then add an “update device(a,b,N)” after you initialize the variables on the host. My assumption is that as you write more programs, you may include other compute or data regions before initializing the host data. Since they get created at device initialization, they could be copied in before you initialize the host variables. Explicitly updating the variables on the device will cause less issues for you later.

For example:

% cat test.F90
      module global
      implicit none
      integer N
      integer a(100),b(100),c(100)
!$acc declare create(a(100),b(100),c(100),N)
      end module

      subroutine add1()
      use global
!$acc routine seq
      implicit none
      integer i
      do i=1,N
      c(i)=a(i)+b(i)
      end do
      return
      end

      program main
      use global
      implicit none
      integer i
!$acc routine(add1,add2,add3) seq
      N=100
      do i=1,N
      a(i)=i
      b(i)=N-i
      enddo
!$acc update device(a,b,N)
!$acc parallel loop
      do i=1,1024
        call add1()
      enddo
!$acc update self(c)
      print *,"c(100)=",c(100)
      endprogram
% pgfortran -ta=tesla test.F90 ; a.out
 c(100)=          100

Hope this helps,
Mat

Hi Mat,

Thanks for your help, it really works. But I met another problem when I dealt with the continuation directive lines.
I saw the openacc 2.7, it gives me this"Fixed form line length, white space, continuation, and column rules apply to the directive line. Initial directive lines must have a space or zero in column 6, and continuation directive lines must have a character other than a space or zero in column 6." But,when I wrote in this way below, it did not work.

!$acc declare create(jdim,kdim,idim,jj2,kk2,ii2,nblc,js,ks,is,je,ke,ie
!$acc& lq,lqj0,lqk0,lqi0,lsj,lsk,lsi,lvol,ldtj,lx,ly,lz)

Xll

Hi Xll,

What error are you getting?
What is the suffix of your source files? “.f”, “.f90”, something else?

My best guess is that you’re file has a “.f90” suffix (like my example). In that case, the default is to use free format. For fixed format, either rename the file using a “.f” suffix (default is fixed format) or add the flag “-Mfixed”.

Hope this helps,
Mat