Reputation: 31
I am try to see if I can send the contents of an array in a c++ code to a fortran 90 code. I'm using openmpi 1.4.3 built using intel 11.1.072 compilers. They are installed on Linux version 2.6.18-108chaos (mockbuild@chaos4builder1) (gcc version 4.1.2 20080704 (Red Hat 4.1.2-48)).
Here is the c++ side:
# 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();
}
and here is the f90 side:
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
after I've compiled the two codes, I run with
$mpirun -n 1 *c_executable* : -n 1 *fortran_executable* > output
The numbers I get on the fortran side are not 10.0.
Upvotes: 3
Views: 1269
Reputation: 195
Here is a modified working version in C
#include <stdio.h>
#include <mpi.h>
main(int argc, char **argv)
{
int i,ierr, num_procs, my_id;
double a[10];
for (i=0;i<10;i++)
{
a[i]=10.0;
}
ierr = MPI_Init(&argc, &argv);
printf(" Hello C Code\n");
/**/
ierr = MPI_Comm_rank(MPI_COMM_WORLD, &my_id);
ierr = MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
ierr = MPI_Send(&a[0],10,MPI_DOUBLE,1,100, MPI_COMM_WORLD);
ierr = MPI_Finalize();
}
Here is a modified working version in F
program main
use mpi
implicit none
integer:: ierr,stat(MPI_STATUS_SIZE)
double precision:: a(10)
call mpi_init(ierr)
write(*,*)"Hello F Code"
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
Upvotes: 1
Reputation: 74455
The MPI standard indeed has provisions for language interoperability - the whole §16.3 of the MPI 2.2 document is dedicated to language interoperability between Fortran and 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 isMPI_BYTE
orMPI_PACKED
. Interlanguage communication is allowed if it complies with these rules.
Then it goes on to show an example where the same construced datatype is used to send a message from a Fortran code and to receive it in a piece of C code. The type is constructed so as to allow the C code to receive the data into a buffer that belongs to the Fortran code, but what is more relevant to your question is that the C code uses a datatype that was constructed from the Fortran MPI_REAL
. Using Fortran datatypes in C functions and vice versa is perfectly legal if it makes sense:
§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.
(predefined MPI datatypes like MPI_REAL
and MPI_DOUBLE
are committed)
On the contrary, using Fortran datatypes on the one side and C datatypes on the other is allowed but considered not portable:
§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 typeint
, then an MPI implementation may allow data to be sent with datatypeMPI_INTEGER
and be received with datatypeMPI_INT
. However, such code is not portable.
(emphasis mine)
Changing REAL(8)
to DOUBLE PRECISION
does nothing to increase the portablity of your code as the Fortran standard guarantees nothing about the representation of the DOUBLE PRECISION
type - it only says that DOUBLE PRECISION
is an alternative specifier for one kind of REAL
type, namely the double precision kind, which should have greater decimal precision than the default real. Sending REAL(8)
with a datatype of MPI_DOUBLE_PRECISION
is not portable. Instead a portable program would use the SELECTED_REAL_KIND
intrinsic of Fortran together with MPI_Type_create_f90_real
to register a matching MPI datatype.
The best option IMHO is to rely on the language interoperability between C and Fortran and stick to the same datatypes on both sides. Since your compiler suite is recent enough, you can use the ISO_C_BINDING
mechanism of Fortran to get REAL
and INTEGER
kinds, compatible with C, and use the C datatypes in the Fortran calls. For example:
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)
...
Upvotes: 4
Reputation: 50937
Yes, you can do this; the main problem is that in your C++ code, your a
array is of type float
, not double.
You're also only sending 1, not 10, of these not-doubles; the MPI_RECV()
would still work, but of course the other 9 values wouldn't be set.
Something else that you should note is that you should use MPI_DOUBLE
in C/C++, and MPI_DOUBLE_PRECISION
in Fortran; they need not be the same, and in fact I imagine the use of MPI_DOUBLE_PRECISION
in C is undefined.
You also probably want to use double precision
in the fortran program rather than real(8)
, which is common but not standard.
In principle, you would even want to worry about heterogeneity, about the encoding of the floating point numbers on the machines running the two programs, but for most of us this isn't an issue.
Upvotes: 1