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
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
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.
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”.