我正在使用OpenACC处理相当大的代码。现在,我有一个程序foo的调用其他几个例程酒吧,远远的,嘘delaing,就像这样:如何在OpenACC数据区域中创建子例程
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进行测试。
我目前专注于“酒吧”的电话。我想让酒吧成为一个向量例程。我还没有准备好做同样的事情。所以我想在一个平行区域内打电话给酒吧,但我还没有准备好做同样的事情。 (我说这是一项正在进行的工作,对吧?)现在,我可以 - 我想! - 在它自己的并行区域三明治吧和数据复制到和它在每次循环迭代
!$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
。)
那么有没有办法做我想在这里做的事情?谢谢。