如何解决OpenACC常数参数
我想知道在OpenACC内核中处理常量的正确方法是什么。
例如,在以下代码中
module vecaddmod
implicit none
integer,parameter :: n = 100000
!$acc declare create(n)
contains
subroutine vecaddgpu(r,a,b)
real,dimension(:) :: r,b
integer :: i
!$acc update self(n)
!$acc data present(n)
!$acc kernels loop copyin(a(1:n),b(1:n)) copyout(r(1:n))
do i = 1,n
r(i) = a(i) + b(i)
enddo
!$acc end data
end subroutine vecaddgpu
end module vecaddmod
program main
use vecaddmod
implicit none
integer :: i,errs,argcount
real,dimension(:),allocatable :: a,b,r,e
character*10 :: arg1
allocate( a(n),b(n),r(n),e(n) )
do i = 1,n
a(i) = i
b(i) = 1000*i
enddo
! compute on the GPU
call vecaddgpu( r,b )
! compute on the host to compare
do i = 1,n
e(i) = a(i) + b(i)
enddo
! compare results
errs = 0
do i = 1,n
if( r(i) /= e(i) )then
errs = errs + 1
endif
enddo
print *,' errors found'
if( errs ) call exit(errs)
end program main
n
在模块中的cpu上声明为常量,并在循环中用作范围。 nvfortran
向我警告Constant or Parameter used in data clause
。上面的示例是处理此问题的正确方法吗?我是否可以利用GPU上的恒定内存,这样就不必在每次内核启动时将其从cpu复制到GPU?
谢谢。
解决方法
编译器将用文字值替换参数,因此无需将其放在数据区域中。
module vecaddmod
implicit none
integer,parameter :: n = 100000
contains
subroutine vecaddgpu(r,a,b)
real,dimension(:) :: r,b
integer :: i
!$acc kernels loop copyin(a(1:n),b(1:n)) copyout(r(1:n))
do i = 1,n
r(i) = a(i) + b(i)
enddo
end subroutine vecaddgpu
end module vecaddmod
...
% nvfortran -acc -Minfo=accel test.f90
vecaddgpu:
11,Generating copyin(a(:100000)) << "n" is replaced with 100000
Generating copyout(r(:100000))
Generating copyin(b(:100000))
12,Loop is parallelizable
Generating Tesla code
12,!$acc loop gang,vector(128) ! blockidx%x threadidx%x
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。