###質問内容( Fortran における配列リダクション )
Fortranを使用してちょっとした並列計算を書いています.
初歩的な質問なのですが,リダクションを実施する際,リダクションの対象に配列を指定することは可能なのでしょうか?
よくあるのは,vec(1:100)の配列に対して,スカラー変数totに対してリダクションを行う以下のようなプログラムです.
fortran
1!$omp parallel 2!$omp do private(i) reduction(+:tot) 3do i=1, 100 4 tot = tot + vec(i) 5enddo 6!$omp end do 7!$omp end parallel
当方が知りたいのは,例えば1-4の番地が格納された配列addr(1:4)に従って総和を求めるような問題で,以下のような並列構文は可能でありましょうか?
fortran
1!$omp parallel 2!$omp do private(i) reduction(+:tot) 3do i=1, 100 4 tot( addr(i) ) = tot( addr(i)) + vec(i) 5enddo 6!$omp end do 7!$omp end parallel
ここでは,リダクションの対象がtot(1:4)の配列になっております.
末尾に示しますサンプルコードを動かしてみた結果,できているようにも,みうけられます(末尾参照).
しかし,実際,このような用法を解説している文献等を見つけることができておらず,古い文献では,このような操作はできないと書かれておりました.
検索すると,配列のリダクションはver.1.1から実装されているという記述もあります.
(https://ccportal.ims.ac.jp/sites/default/files/SGI.pdf) - 52P
しかし,2015年のウェブ上のスライドではスカラ変数のみ可能とされております.
(http://www.cc.u-tokyo.ac.jp/support/kosyu/X01/shiryou-3.pdf) - 25P
また,別のウェブ上のpdfですが,そのように記述されております.
(http://mikilab.doshisha.ac.jp/dia/seminar/2001/pdf/openmp1.pdf ) - 4P
結局のところ,配列に対するリダクションは可能なのでしょうか?(公式に保証されているのでしょうか?)
文献等を示しながら回答いただけますと幸いです.
よろしくお願いします.
Fortranにおいて試してみたサンプルコード
fortran
1program main 2 3 !$ use omp_lib 4 5 implicit none 6 7 integer, parameter :: N = 100000 8 integer :: i, j, addr(N), mythread 9 real :: vec(N), tot(4), cnt(4) 10 11 call random_number( vec ) 12 do i=1, N 13 addr(i) = ceiling( vec(i) * 4.0 ) 14 enddo 15 16 call random_number( vec ) 17 18 cnt(:) = 0 19 tot(:) = 0.0 20 21 !$omp parallel shared(cnt,tot,addr,vec) 22 !$omp do private(i) reduction(+:cnt,tot) 23 do i=1, N 24 cnt( addr(i) ) = cnt( addr(i) ) + 1 25 tot( addr(i) ) = tot( addr(i) ) + vec(i) 26 enddo 27 !$omp end do 28 !$omp end parallel 29 30 write(6,*) ' total ' 31 do i=1, 4 32 write(6,*) i, cnt(i), tot(i) 33 enddo 34 35end program main
結果
total 1 24983.0000 12355.9531 2 25140.0000 12573.2100 3 24988.0000 12573.5654 4 24889.0000 12426.2803
あなたの回答
tips
プレビュー