6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

FortranAdvent Calendar 2018

Day 10

fortran+MPIコーディング入門(4) オブジェクト指向コードの並列化

Last updated at Posted at 2018-12-09

前回まででMPIの基本的機能は説明しました。ですが通信については組み込み型のみを対象としていました。

MPIは1991年に開発されており、当時のfortranの仕様であった手続き型パラダイムで書かれています。その後オブジェクト指向パラダイムが主流となり、fortranもfortran2003でオブジェクト指向がサポートされました。オブジェクト指向言語ではクラスとそのインスタンスを対象にプログラミングします。今回はそのようなクラスをMPIで扱う方法を解説します。

目次

  1. 並列処理とは
  2. [プロセス並列の基本] (https://qiita.com/items/5cce1174ac48367948bc)
  3. [集団通信] (https://qiita.com/Bluepost59/items/f1871b37669b38352a7c)
  4. [1対1通信] (https://qiita.com/Bluepost59/items/f1426e8cb098d6632402)
  5. オブジェクト指向コードの並列化 ←今ココ

クラスを通信する

MPIデータ型

MPIで通信するためには、前回までで述べた通り、送受信データの型を指定する必要があります。それはMPIで定義された型でなければならず、integerやdouble precisionなど組み込み型のみが定義されています。

つまり、自分で定義したクラスはそのままではMPIコマンドを使って通信することができません。そのため自分で「クラスのすべてのメンバを通信してやる」というコマンドも用意してやる必要があります1

実装する場所

サブルーチンの実装の場所については、次のようにいくつかの選択肢が思いつきます。

  1. 通常のモジュールサブルーチンとして。
  2. 通信するクラスをコンポジットするクラスのメンバ関数として。
    例えば、particleをメンバに持つsystemクラスのメンバ関数として。
  3. 通信するクラスのメンバ関数として。

基本的にはどの方法でも実装できます。通信するクラスのメンバ関数にするのは少し難しそうな気もしますが、特に問題なく動作します。

例として、次のクラスを通信します。

  type smp
     integer :: id
     double precision :: xx
     character(len=40) :: name
   contains
     procedure :: return_id => smp_return_id
     procedure :: bcast => smp_bcast
  end type smp

bcastをメンバとして実装する

subroutine smp_bcast(self,ierr)
    class(smp) self
    integer :: ierr
    
    call mpi_bcast(self%id, 1, mpi_integer, 1, mpi_comm_world, ierr)
    call mpi_bcast(self%xx, 1, mpi_double_precision, 1, mpi_comm_world, ierr)
    call mpi_bcast(self%name, 40, mpi_character, 1, mpi_comm_world, ierr)

end subroutine smp_bcast

MPIだからといって大変なところは、ierrを作らないといけないことくらいしかありません。実際のところ、MPIコマンドの組み立て上通信されるクラスのメンバにするよりは、それをコンポジットにするクラスのメンバとして実装するのが設計しやすいと思います。

注意点

  • クラスを使う場合、クラスは別ファイルのmoduleとして宣言して分割コンパイルする場合も多いと思いますが、use文でonlyを使わない場合、mpif.hのincludeは一番最初にコンパイルするものだけにしないと多重取り込みでエラーが出ます。

  • fortranのcharacter型はC言語のように中身は配列なので、配列同様の扱いをする必要があります。例えばallocateしないで使ったりはできません。

  1. C++のboostのmpiでは構造体やクラスも送れるので、ひょっとするとうまくやるとfortranでもできるのかも知れません。僕はよく知りません。

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?