13

送信バッファとして呼び出そうとするとmpi_reduce、クラッシュします。mpi_in_placeGoogle のトロールにより、これが OMPI 1.3.3 の Mac OS で問題であったことが明らかになりましたが、私は OMPI 1.6.3 (gfortran 4.4.6 を使用) で CentOS を使用しています。

次のプログラムがクラッシュします。

PROGRAM reduce

  USE mpi

  IMPLICIT NONE

  REAL, DIMENSION(2, 3) :: buffer, gbuffer

  INTEGER :: ierr, me_world
  INTEGER :: buf_shape(2), counts

  CALL mpi_init(ierr)
  CALL mpi_comm_rank(mpi_comm_world, me_world, ierr)

  buffer = 1.
  IF (me_world .EQ. 0) PRINT*, "buffer: ", buffer

  buf_shape = SHAPE(buffer)
  counts = buf_shape(1)*buf_shape(2)

  CALL mpi_reduce(MPI_IN_PLACE, buffer, counts, mpi_real, mpi_sum, 0, mpi_comm_world, ierr)
  IF (me_world .EQ. 0) PRINT*, "buffer: ", buffer

  CALL mpi_finalize(ierr)

END PROGRAM reduce

MPI エラーは次のとおりです。

MPI_ERR_ARG: invalid argument of some other kind

これはあまり役に立ちません。

mpi_reduceどのように呼び出されるべきかについて何かが欠けていますか? これは他のコンパイラ/MPI 実装で動作しますか?

4

1 に答える 1

24

インプレース リダクション操作が MPI でどのように機能するかの非常に重要な部分が欠けています (太字のテキストを参照)。

コミュニケーターがイントラコミュニケーターの場合、reduce 操作をインプレースで実行できます (出力バッファーは入力バッファーとして使用されます)。この変数をルート プロセスsendbufMPI_IN_PLACEの値として使用します。この場合、入力データはルートで受信バッファから取得され、そこで出力データに置き換えられます。

他のプロセスは、ローカル バッファをではなくsendbufMPI_IN_PLACEとして提供する必要があります。

IF (me_world == 0) THEN
  CALL mpi_reduce(MPI_IN_PLACE, buffer, counts, MPI_REAL, MPI_SUM, 0, MPI_COMM_WORLD, ierr)
ELSE
  CALL mpi_reduce(buffer, buffer, counts, MPI_REAL, MPI_SUM, 0, MPI_COMM_WORLD, ierr)
END IF

root 以外のプロセスではsendbufrecvbufbufferの両方として安全に渡すことができます。これらのプロセスではrecvbufに書き込みを行わないためです。MPI_REDUCE

于 2013-07-19T11:17:34.417 に答える