Please Note: Before you get into the steps below, I strongly recommend using WSL for mpi coding on windows. These steps are from a time before WSL. Do yourself a favor and use WSL!
This is tested on Windows 7 and and Windows 10 and gcc version 7.1.0 (x86_64-posix-seh-rev2, Built by MinGW-W64 project).
2024.04.30 Update: I tested this with
gcc (MinGW-W64 x86_64-ucrt-posix-seh, built by Brecht Sanders) 13.2.0
and
Microsoft MPI (MS-MPI) v10.1.3
.
These are instructions to get Mingw + MPI going on windows. I have tested it for gcc and gfortran. You should really use WSL for this.
We need to download 3 items: mingw-w64, MSMPI and MSMPI SDK
MSMPI provides "mpiexec.exe" MSMPI SDK provides the MPI libraries and header files. We need msmpi.lib and msmpi.dll and the headers files for linking purposes. Upon installation, some environment variables are set-up. Doing "set MSMPI" in a cmd shell will show the directories of interest. For example,
C:\>set MSMPI
MSMPI_BIN=C:\Program Files\Microsoft MPI\Bin\
MSMPI_INC=C:\Program Files (x86)\Microsoft SDKs\MPI\Include\
MSMPI_LIB32=C:\Program Files (x86)\Microsoft SDKs\MPI\Lib\x86\
MSMPI_LIB64=C:\Program Files (x86)\Microsoft SDKs\MPI\Lib\x64\
%MSMPI_INC%
is the mpi include directory.
mpiexec
is in %MSMPI_BIN%
msmpi.lib
is present in %MPI_LIB64%
msmpi.dll
is present in %SYSTEMROOT%\System32
.
Before going further make sure that mingw and mpiexec are added to path. Easiest way to do this is to open a MINGW shell first and then add mpiexec to the path by doing
C:\> set PATH=%PATH%;%MSMPI_BIN%
Check that mpiexec
and gcc
both work. Use this shell to carry out the following steps, by
navigating into the various directories from here.
msmpi.dll
and msmpi.lib
to a temporary folder and navigate the mingw cmd window to
this folder. Create a static library "libmsmpi.a" using gendef and dlltool.
C:\> mkdir tempdir
C:\> cd tempdir
C:\> mkdir include
C:\tempdir\> xcopy /E "%MSMPI_INC%" include
C:\tempdir\> xcopy "%MSMPI_LIB64%"\msmpi.lib .
C:\tempdir\> xcopy %SYSTEMROOT%\System32\msmpi.dll .
C:\tempdir\> gendef msmpi.dll
C:\tempdir\> dlltool -d msmpi.def -l libmsmpi.a -D msmpi.dll
libmsmpi.a
is the mpi library ready to be used. Put it in a convenient library folder. I suggest
C:\lib\mpi\lib
include
folder to another convenient place. I suggest copying to C:\lib\mpi
, so
that the path to mpi.h is C:\lib\mpi\include\mpi.h
. We need to edit some of these files. Leave the
original files alone and only edit the copy you make. mpi.h
and add #include <stdint.h>
, just before the linetypedef __int64 MPI_Aint;
At this point MPI C/C++ programs are ready to be compiled. For example, if libmsmpi.a
is in
C:\lib\mpi\lib
and mpi.h
is in C:\lib\mpi\include
we can compile
my_mpi_program.c
by:
gcc -o out.exe my_mpi_program.c -IC:\lib\mpi\include -LC:\lib\mpi\lib -lmsmpi
Make sure that mpiexec
is in PATH
and run the program with
mpiexec -np 4 out.exe
With mingw, gcc has some default search dirs. Additionally, you can set environment variables to point gcc to search in a certain directories for includes or libraries. You can see the default search directories by doing
gcc --print-search-dirs.
It shows the directories where it looks for <...> includes and "..." includes and libraries by default. If the mpi.h and libmsmpi.a are present in the default search dirs, then compiling MPI C programs is just
gcc -o out.exe my_mpi_program.c -lmsmpi
The mpi header and library are automatically found. We are just letting the linker know that it needs to link against msmpi. More info at http://www.mingw.org/wiki/includepathhowto
Now moving on to finish the configuration for GFortran plus MPI. We need to create the mpi module files so that we can
use mpi
in our fortran code. To use mpi with include "mpif.h"
is also
possible but we need to provide some macros for it to work . Here we generate the mpi module file that we can use by
adding use mpi
and avoid passing extra macros to the compiler
everytime.(mpi_f08
is not
available in this method as far as I know. Another reason to use WSL!)
Navigate to your copy of the MPI "include" folder in the mingw shell and run the following command to generate
mpi
module files for fortran:
gfortran -c -cpp -fallow-invalid-boz -fno-range-check -Ix64 -D_WIN64 -DINT_PTR_KIND()=8 mpi.f90
If you are using PowerShell, you may need to wrap the part with -D INT_PTR_KIND()=8
in single quotes like
below:
gfortran -c -cpp -fallow-invalid-boz -fno-range-check -Ix64 -D_WIN64 -D'INT_PTR_KIND()=8' -fno-range-check mpi.f90
Note that -fallow-invalid-boz
was introduced in gfortran v10. If you are using an older version, this
will not be recognized. It will work if you remove this flag for older versions.
This should create mpi.mod
file along with some other module files. It also create mpi.o
file that you can delete. It wont be used for anything. Now MPI with gfortran is ready for use. One
caveat is we have to do use mpi
rather than include "mpif.h"
in the program. For
example:
program hello
use mpi
implicit none
integer rank, num_procs, ierror
call MPI_INIT(ierror)
call MPI_COMM_SIZE(MPI_COMM_WORLD, num_procs, ierror)
call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierror)
print*, 'Process ', rank, ': Hello world'
call MPI_FINALIZE(ierror)
end
A fortran program using MPI can be compiled with
gfortran -o out.exe my_mpi_program.F90 -IC:\lib\mpi\include -LC:\lib\mpi\lib -lmsmpi
It can be run exactly like the C program.
If libmsmpi.a
is found automatically then -LC:\lib\mpi\lib
may be left out. The include
directory (-I###) is needed because gfortran in mingw does not look anywhere for include files. Also there isn't
an environment variable that can be set for include files. So, the include path always has to be explicitly
specified for fortran programs with mpi.
The End.
Written with help from:
PS:
The procedure shown here creates a static library for mpi. We could have used the dynamic libraries as well.
Instead of making libmsmpi.a
we can use msmpi.dll
directly by placing it in the library
search path. The commands are same as before. With the dynanmic library GCC works A-okay but gfortran does not.
There is some problem during linking. Compiling to .o with gfortran and linking with gcc with -lgfortran works.