非同期通信の相互運用可能変数 (技術仕様)

Fortran 変数の非同期通信は、Fortran の呼び出し以外の方法でプロシージャーが定義されるときに行われることがあります。 非同期通信に使用される変数に、ASYNCHRONOUS 属性を指定する必要があります。 例えば、変数が非ブロッキングのメッセージ受け渡しインターフェース (MPI) 呼び出しで使用される場合、変数に ASYNCHRONOUS 属性でマークを付ける必要があります。

非同期通信の変数の場合、非同期は非同期通信開始プロシージャーの実行によって開始され、非同期通信完了プロシージャーの実行によって完了します。 開始プロシージャーと完了プロシージャーの実行の間には、保留通信アフェクターが存在します。 非同期通信に参加する変数は、保留通信アフェクターです。 保留通信アフェクター (またはその一部) と一部分が関連付けられているすべての変数も、保留通信アフェクターです。

非同期通信は、入力通信または出力通信のいずれかです。

制約事項:
注: パフォーマンスにおける不必要な縮小を避け、変数が ASYNCHRONOUS 属性を持つ有効範囲を制限するために、BLOCK 構文を使用して、非同期通信開始および終了プロシージャーを囲み、BLOCK 構文内で通信アフェクターに対して ASYNCHRONOUS 属性を指定することができます。 詳しくは、以下の例を参照してください。
PROGRAM sum2arrays
  IMPLICIT NONE
  INCLUDE 'mpif.h'

  INTEGER :: mpierr, i
  INTEGER :: status(MPI_STATUS_SIZE)
  INTEGER, PARAMETER :: DIM = 100
  INTEGER, PARAMETER :: TAG_SEND_ARR = 10, TAG_RES_READY = 11
  REAL :: arraya(DIM)
  REAL :: arrayb(DIM)
  INTEGER :: reqs(2)
  REAL :: partialSum1 = 0, partialSum2=0

  ! initialization
  CALL MPI_INIT (mpierr)

  ! Assume there are two tasks in the world communicator:
  ! Task 0: to compute the sum of arrayb and the sum of square of arrayb
  ! Task 1: to compute the sum of arraya
  IF (rank .eq. 0) THEN
    arraya = [(real(i), i=1, DIM, 1)]
    BLOCK
      ASYNCHRONOUS :: arraya
      CALL MPI_ISEND(arraya, DIM, MPI_REAL, 1, TAG_SEND_ARR, 
                     MPI_COMM_WORLD, reqs(1), mpierr)

      ! While waiting for the arraya to be sent, you
      ! can do some calculations for arrayb.
      arrayb = [(real(i+1*2), i=1, DIM, 1)]
      partialSum1 = SUM(arrayb)

      CALL MPI_WAIT(reqs(1), status, mpierr)

      ! Now arraya has been sent. You can modify it.
      arraya = arrayb**2
      PRINT *, "Sum(b**2) = ", SUM(arraya)
    END BLOCK

    ! Get the sum calculated by task 1.
    CALL MPI_RECV(partialSum2, 1, MPI_REAL, 1, TAG_RES_READY,
                  MPI_COMM_WORLD, status, mpierr)
 
    ! The final result is computed by adding the two 
    ! values that are computed by task 0 and task 1.
    PRINT *, "Sum(a) + Sum(b) = ", partialSum1 + partialSum2

  END IF

  CALL MPI_FINALIZE(mpierr)
END

関連情報