質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
FORTRAN

FORTRAN(フォートラン)は科学時術計算に向いた手続き型プログラミング言語です。 並列計算の最適化が行いやすい特性上、数値予報および気候モデルなどの大規模な計算を行う分野のスーパーコンピュータで使われています。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

0回答

4060閲覧

OpenMPにおける配列のリダクションについて

KentoNishida

総合スコア6

FORTRAN

FORTRAN(フォートラン)は科学時術計算に向いた手続き型プログラミング言語です。 並列計算の最適化が行いやすい特性上、数値予報および気候モデルなどの大規模な計算を行う分野のスーパーコンピュータで使われています。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2017/05/27 10:05

###質問内容( 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

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問