====== OpenMPについて ====== * 使い方は以下の文献を参考に * [[http://download.intel.com/jp/business/japan/pdf/527J-002.pdf|インテル® Fortran コンパイラー OpenMP* 活用ガイド]]が分かりやすい. * OpenMPによる並列プログラミングと数値計算法牛島省(著)も良い. ===== コンパイル方法 ===== * gfortran -fopenmp file.f90 * ifort -openmp file.f90 * frt -KOMP -Am file.f90 (thinの場合) ===== 基本的なこと ===== * !$ use omp_lib を最初に宣言.**!$とuseの間にはスペースが必要.** progaram hoge !$ use omp_lib !$ use another_module implicit none ... end program hoge * 並列化したいところを!$OMP parallelと!$OMP end parallelではさむ.はさまれたところは複数のCPUで計算される. * !$OMP doと!$OMP singleが分かれば大体のことはできる. * 「!$につづけてスペース+命令文」とすると,openmpとしてコンパイルしたときだけその命令が実行される. * コンパイルの仕方は gfortran -fopenmp, ifort -openmp, frt -KOMP. ===== 注意点 ===== * !$の後にOMPが続く場合は!$OMPと続けて書く.!$の後にOMPが続かない場合はスペースを入れる. program hoge !$ use omp_lib !$OMP parallel default(none) private(j) !$ j=omp_get_num_threads() !$ write(*,*) j !$ j=omp_get_thread_num() !$ write(*,*) j !$ !$OMP end parallel end program hoge * defaultの後は(none)が無難?FIXME * doループの制御変数はいわゆる定義済み変数になるので共有属性節((sharedとかprivateとかfirstprivateとか))に記述する必要はない.書くとすればprivateかfirstprivateのいずれか. program hoge !$ use omp_lib implicit none integer i,j,k !$OMP parallel default(none) private(j) !$OMP do do i=1,4 !$ j=omp_get_thread_num() !$ write(*,*) i,j end do !$OMP end do !$OMP end parallel end program hoge * !$OMPのついた文を改行するときは改行した文にも!$OMPが必要 program hoge !$ use omp_lib implicit none integer i,j,k k=-1 !$OMP parallel default(none) private(i,j)& !$OMP & shared(k) !$ i=omp_get_thread_num() !$ j=omp_get_num_threads() !$ write(*,*) i,j,k !$OMP end parallel end program hoge * doループが入れ子になっている場合,外側で回すのが一般的らしいFIXME.ただし,MPIとのハイブリッドの場合は外をMPI,内をOpenMPとするのが良いらしいFIXME. !$OMP do do i=1,n do j=1,m 実行文 end do end do !$OMP end do ===== threadprivate ===== moduleなどで、グローバル変数を定義している場合に、thread間ではその変数を共有しないで欲しいときに。 module common implicit none real(8) a,b,c !$OMP threadprivate(a,b,c) end module common