私は、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 を 1 回だけデバイスに転送できればよいのですが。各ルーチンには独自のデータ領域があるため、私が理解しているように (間違っていたら訂正してください!)、ループ全体を 1 つのデータ領域に入れることはできません。ここに私が試した代替案があります
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
。)
私がここでやろうとしていることをする方法はありますか?ありがとう。