我正在使用 OpenACC 检测一个相当大的代码。现在,我正在处理一个调用其他一些例程 bar、far 和 boo 的例程 foo,如下所示:
subroutine foo
real x(100,25),y(100,25),z(100,25)
real barout(25), farout(25), booout(25)
do i=1,25
call bar(barout, x(1,i),y(1,i),z(1,i))
call far(farout, x(1,i),y(1,i),z(1,i))
call boo(booout, x(1,i),y(1,i),z(1,i))
enddo
....
end subroutine foo
几点:1) x、y 和 z 在循环中保持不变。2) 你可能不喜欢这里的代码结构,但这超出了我的工作描述。我应该使用 OpenACC 进行测试,期间。
我目前正专注于对“酒吧”的呼吁。我想让 bar 成为向量例程。我还没有准备好为 far 和 boo 做同样的事情。所以我想在一个平行区域内调用 bar,但我还没有准备好对 far 和 boo 做同样的事情。(我说这是一项正在进行的工作,对吗?)现在,我可以——我想!-- 在它自己的并行区域中的夹层条,并在每次循环迭代中将数据复制到它和从中复制数据
!$acc data copy(barout) &
!$acc& copyin(x(:,:),y(:,:),z(:,:))
!$acc parallel
call bar( .... )
!$acc en parallel
!$acc end data
但这是很多数据传输。如果我可以只将 x、y 和 z 传输到设备一次,那就太好了。每个例程都有自己的数据区域,所以据我了解(如果我错了,请纠正我!)我无法将整个循环包含在单个数据区域中。这是我尝试过的另一种选择
subroutine foo
!$acc routine(bar) vector
real x(100,25),y(100,25),z(100,25)
real barout(25), farout(25), booout(25)
!$acc data create(x(:,:),y(:,:),z(:,:))
!$acc end data
do i=1,25
!$acc data copy(barout(:)) &
!$acc& present(x(:,:),y(:,:),z(:,:))
!$acc parallel
call bar(barout, x(1,i),y(1,i),z(1,i))
!$acc end parallel
!$acc end data
call far(farout, x(1,i),y(1,i),z(1,i))
call boo(booout, x(1,i),y(1,i),z(1,i))
enddo
....
end subroutine foo
但这不起作用,因为 中的数据copyin
不会保留在设备上。data present
当子句出现时它就消失了。(我也试过data create
了data copyin
。)
那么有没有办法做我在这里想做的事情?谢谢。