[英]Some questions about acc routine
一個 MPI 代碼,我試圖用 openacc 並行化它的一個簡單循環,並且預計不會出現 output。 在這里,循環有一個調用,我在子例程中添加了一個“accroutine seq”。 如果我手動將此調用內聯並刪除子例程,結果將是正確的。 我是否正確使用 OpenACC“例程”指令? 或其他錯誤?
MPI版本:openmpi4.0.5
高性能計算 SDK 20.11
CUDA 版本:10.2
!The main program
program test
use simple
use mpi
implicit none
integer :: i,id,size,ierr,k,n1
call MPI_INIT(ierr)
call MPI_COMM_RANK(MPI_COMM_WORLD,id,ierr)
call MPI_COMM_SIZE(MPI_COMM_WORLD,size,ierr)
allocate(type1(m))
do i=1,m
allocate(type1(i)%member(n))
type1(i)%member=-1
type1(i)%member(i)=i
enddo
!$acc update device(m,n)
do k=1,m
n1=0
allocate(dev_mol(k:2*k))
dev_mol=type1(k)%member(k:2*k)
!$acc update device(dev_mol(k:2*k))
!$acc parallel copy(n1) firstprivate(k)
!$acc loop independent
do i=k,2*k
call test1(k,n1,i)
enddo
!$acc end parallel
!$acc update self(dev_mol(k:2*k))
type1(k)%member(k:2*k)=dev_mol
write(*,"('k=',I3,' n1=',I2)") k,n1
deallocate(dev_mol)
enddo
do i=1,m
write(*,"('i=',I2,' member=',I3)") i,type1(i)%member(i)
deallocate(type1(i)%member)
enddo
deallocate(type1)
call MPI_Barrier(MPI_COMM_WORLD,ierr)
call MPI_Finalize(ierr)
end
!Here is the module
module simple
implicit none
integer :: m=5,n=2**15
integer,parameter :: p1=15
integer,allocatable :: dev_mol(:)
type type_related
integer,allocatable :: member(:)
end type
type(type_related),allocatable :: type1(:)
!$acc declare create(m,n,dev_mol)
!$acc declare copyin(p1)
contains
subroutine test1(k,n1,i)
implicit none
integer :: k,n1,i
!$acc routine seq
if(dev_mol(i)>0) then
!write(*,*) 'gpu',k,n1,i
n1=dev_mol(i)
dev_mol(i)=p1
else
if(i==k)write(*,*) 'err',i,dev_mol(i)
endif
end
end
編譯命令:mpif90 test.f90 -o test
運行命令:mpirun -n 1./test
結果如下:
k= 1 n1= 1
k= 2 n1= 2
k= 3 n1= 3
k= 4 n1= 4
k= 5 n1= 5
i= 1 member= 15
i= 2 member= 15
i= 3 member= 15
i= 4 member= 15
i= 5 member= 15
編譯命令:mpif90 test.f90 -o test -ta=tesla:cuda10.2 -Minfo=accel
運行命令:mpirun -n 1./test
錯誤結果如下:
k= 1 n1= 0
k= 2 n1= 0
k= 3 n1= 0
k= 4 n1= 0
k= 5 n1= 0
i= 1 member= 1
i= 2 member= 2
i= 3 member= 3
i= 4 member= 4
i= 5 member= 5
問題在於“i”通過引用傳遞(默認使用 Fortran)。 最簡單的解決方案是按值傳遞:
contains
subroutine test1(k,n1,i)
implicit none
integer, value :: i
integer :: n1, k
現在有一個小的編譯器錯誤,因為“i”是循環索引變量,所以應該隱式地將變量私有化。 然而,由於它是通過引用傳遞的,這會導致它被共享。 我們將在未來的編譯器版本中修復此問題。 盡管通常建議盡可能按值傳遞標量。
使用更新運行的示例:
% mpif90 test2.f90 -acc -Minfo=accel -V21.2 ; mpirun -np 1 a.out
test1:
16, Generating acc routine seq
Generating Tesla code
test:
48, Generating update device(m,n)
53, Generating update device(dev_mol(k:k*2))
54, Generating copy(n1) [if not already present]
Generating Tesla code
56, !$acc loop gang, vector(128) ! blockidx%x threadidx%x
60, Generating update self(dev_mol(k:k*2))
k= 1 n1= 1
k= 2 n1= 2
k= 3 n1= 3
k= 4 n1= 4
k= 5 n1= 5
i= 1 member= 15
i= 2 member= 15
i= 3 member= 15
i= 4 member= 15
i= 5 member= 15
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.