【发布时间】:2016-02-26 06:07:48
【问题描述】:
我正在使用 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”的调用。我想让 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。)
那么有没有办法做我在这里想做的事情?谢谢。
【问题讨论】: