从c代码发送mpi消息到fortran 90代码

我试着看看我是否可以将c代码中的数组内容发送到fortran 90代码.我正在使用使用intel 11.1.072编译器构建的openmpi 1.4.3.它们安装在Linux版本2.6.18-108chaos(mockbuild @ chaos4builder1)上(gcc版本4.1.2 20080704(Red Hat 4.1.2-48)).

这是c方面:

# include <cstdlib>
# include <iostream>
# include <mpi.h>
using namespace std;

void printarray (float arg[], int length) {
   for (int n=0; n<length; n++)
    cout << arg[n] << " ";
  cout << "\n";
}

int main(int argc, char *argv[] ){
   float a[10];
   int myrank,i;
   MPI::Init ( argc, argv );
   myrank=MPI::COMM_WORLD.Get_rank();
   cout << "rank "<<myrank<<" is c++ rank."<<std::endl;
   for (i=0;i<10;i++){
      a[i]=10.0;
   }
   printarray(a,10);
   MPI::COMM_WORLD.Send(&a[0],1,MPI::DOUBLE_PRECISION,1,100);
   MPI::Finalize();
}

这是f90方面:

program main
implicit none
include "mpif.h"
integer:: ierr,stat(MPI_STATUS_SIZE)
real(8):: a(10)

call mpi_init(ierr)
a=0
print*,a
call mpi_recv(a(1),10,MPI_DOUBLE_PRECISION,0,100,MPI_COMM_WORLD,stat,ierr)
print*,a
call mpi_finalize(ierr)
end program

在我编译了两个代码后,我运行了

$mpirun -n 1 *c_executable* : -n 1 *fortran_executable* > output

我在fortran方面获得的数字不是10.0.

解决方法:

MPI标准确实具有语言互操作性的规定 – MPI 2.2文档的整个§16.3专用于Fortran和C之间的语言互操作性.

§16.3.10 Interlanguage Communication

The type maching rules for communications in MPI anr not changed: the datatype specification for each item sent should match, in type signature, the datatype specification used to receive this item (unless one of the types is MPI_PACKED). Also, the type of a message item should match the type declaration for the corresponding communication buffer location, unless the type is MPI_BYTE or MPI_PACKED. Interlanguage communication is allowed if it complies with these rules.

然后继续展示一个示例,其中使用相同的构造数据类型从Fortran代码发送消息并在一段C代码中接收它.构造类型是为了允许C代码将数据接收到属于Fortran代码的缓冲区中,但与您的问题更相关的是C代码使用从Fortran MPI_REAL构造的数据类型.如果有意义的话,在C函数中使用Fortran数据类型(反之亦然)是完全合法的:

§16.3.6 MPI Opaque Objects – Datatypes

… If a datatype defined in one language is used for a communication call in another language, then the message sent will be identical to the message that would be sent from the first language: the same communication buffer is accessed, and the same representation conversion is performed, if needed. All predefined datatypes can be used in datatype constructors in any language. If a datatype is committed, it can be used for communication in any language.

(已提交MPI_REAL和MPI_DOUBLE等预定义的MPI数据类型)

相反,允许一方使用Fortran数据类型,另一方使用C数据类型,但认为不可移植:

§16.3.10 Interlanguage Communication

… MPI implementations may weaken these type matching rules, and allow messages to be sent with Fortran types and received with C types, and vice versa, when those types match. I.e., if the Fortran type INTEGER is identical to the C type int, then an MPI implementation may allow data to be sent with datatype MPI_INTEGER and be received with datatype MPI_INT. However, such code is not portable.

(强调我的)

将REAL(8)更改为DOUBLE PRECISION不会增加代码的可移植性,因为Fortran标准不保证DOUBLE PRECISION类型的表示 – 它只说DOUBLE PRECISION是一种REAL类型的替代说明符,即双精度类,应该具有比默认实数更大的小数精度.使用MPI_DOUBLE_PRECISION数据类型发送REAL(8)不可移植.相反,可移植程序将使用Fortran的SELECTED_REAL_KIND内部函数和MPI_Type_create_f90_real来注册匹配的MPI数据类型.

恕我直言的最佳选择是依赖C和Fortran之间的语言互操作性,并坚持双方相同的数据类型.由于您的编译器套件足够新,您可以使用Fortran的ISO_C_BINDING机制来获取与C兼容的REAL和INTEGER类型,并在Fortran调用中使用C数据类型.例如:

USE, INTRINSIC :: ISO_C_BINDING
REAL(C_DOUBLE), DIMENSION(10) :: darray
INTEGER(C_INT) :: ival
...
CALL MPI_SEND(darray, 10, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, ierr)
CALL MPI_BCAST(ival, 1, MPI_INT, 0, MPI_COMM_WORLD, ierr)
...
上一篇:Oracle if else 、case when 判断示例


下一篇:python – mpi4py返回排名差异