Can I pass MPI.jl communicator to the Fortran side?

I have a Fortran program that uses File I/O, which I want to modify to a subroutine so that I can directly call it from Julia without writing to / reading from files.

The problem is that the program depends heavily on MPI. After wrapping the main program to a subroutine, I could call it and get it running, but in this way, it could not run in parallel.

I tried using MPI.jl and initiating the communicator at the Julia side and then passing it to the Fortran side, instead of initiating at the Fortran side, but did not make any progress right now.

Are there any suggestions?

You may need to call MPI_Comm_c2f to convert the C-style communicator (used in MPI.jl) to a Fortran-style one. MPI.jl doesn’t provide a high-level interface to this, but you can always wrap it with ccall.

Maybe something like:

import MPI
@static if MPI.MPI_Comm === Cint
    # some MPI libraries don't define MPI_Comm_c2f … they use
    # a Fortran-like integer communicator even in the C api
    comm2f(comm::MPI.Comm) = comm.val
else
    comm2f(comm::MPI.Comm) =
        ccall((:MPI_Comm_c2f, MPI.libmpi), Cint, (MPI.MPI_Comm,), comm)
end

Note also that you pass arguments to Fortran as pointers, i.e. declare the comm argument as Ref{Cint} when passing to Fortran.

(The MPI.MPI_Comm === Cint probably isn’t quite right; you should really check whether MPI_Comm_c2f is defined in MPI.libmpi.)

2 Likes

Also, make sure that your Fortran code is compiled with the same version of MPI that Julia is using. See Configuring MPI.jl.

e.g. you might want to set ENV["JULIA_MPI_BINARY"]="system" and re-build MPI.jl.

1 Like

The part of passing comm as Ref{Cint} turned out to be the key point I missed. Thanks a lot!

It turned out that I do not need to initiate MPI at the Julia side. I measured the run time wrongly so I thought the program was not running in parallel, but actually, it was already running in parallel.