Why does 'use mpi' fail with mpif90 - fortran

In order to compile MPI code in gfortran I have to use the syntax
include mpif.h
in my code instead of
use mpi
Several websites indicate that this syntax is for Fortran 77 however, I am using gfortran gcc version 4.7.2 (Debian 4.7.2-5) and mpfi90 for MPICH2 version 1.4.1p1.
The command line
mpif90 test1.f90 -o test1.exe
produces the following error
test1.f90:4.8: use mpi 1 Fatal Error: Parse error when checking module version for file 'mpi.mod' opened at (1)
test1.f90 (from Coursera course on HPC)
program test1
use mpi !(fails to compile)
implicit none
include 'mpif.h' !(this works)
integer :: ierr, numprocs, proc_num
call mpi_init(ierr)
call mpi_comm_size(MPI_COMM_WORLD, numprocs, ierr)
call mpi_comm_rank(MPI_COMM_WORLD, proc_num, ierr)
print *, 'Hello from Process number', proc_num, &
' of ', numprocs, ' processes'
call mpi_finalize(ierr)
end program test1

Another option I often encounter is when the Fortran compiler used to build the MPI library is not compatible with your current Fortran compiler. Then the problem is the incompatibility of the .mod files. Gfortran is more susceptible to this, than say Intel Fortran, because it changes the module format more often.

Depending on how MPICH2 was compiled, perhaps the F90 interface wasn't built. That tends to happen depressingly often when using packages built by C-heads.

Related

Is this linker error in 32 bit Windows gFortran a bug?

The following code compiles to 64 bit but the use of Fortran Generic Interfaces seems to confuse the gcc attribute in 32 bit (required to call the 32 bit STDCALL API). The code is a stripped down version of the f03gl project which I am attempting to build for Windows (I couldn't create a smaller repro).
A rework of the code (shown at the bottom) without the generic interface and passing arguments direct does compile and work. I'm hoping I won't have to rewrite all of the calls to work around this issue.
The error is;
callglutbad.o:callglutbad.f90:(.text+0x27): undefined reference to `glutInit'
callglut.f90 (fails 32 bit compilation)
MODULE GlutModule
USE ISO_C_BINDING
IMPLICIT NONE
PUBLIC glutInit
INTERFACE glutInit
MODULE PROCEDURE glutInit_f03
END INTERFACE glutInit
INTERFACE
SUBROUTINE glutInit_gl(pargc, argv) BIND(C,NAME="glutInit")
IMPORT
#ifdef x86
!GCC$ ATTRIBUTES stdcall :: glutInit
#endif
INTEGER(C_INT) :: pargc
TYPE(C_PTR), INTENT(IN) :: argv
END SUBROUTINE glutInit_gl
END INTERFACE
CONTAINS
SUBROUTINE glutInit_f03()
INTEGER(C_INT) :: argcp=1
TYPE(C_PTR), DIMENSION(1), TARGET :: argv=C_NULL_PTR
CHARACTER(C_CHAR), DIMENSION(1), TARGET :: empty_string=C_NULL_CHAR
argv(1)=C_LOC(empty_string)
CALL glutInit_gl(argcp, C_LOC(argv))
END SUBROUTINE
END MODULE GlutModule
program main
USE GlutModule
PRINT *,"Calling glutInit"
call glutInit()
PRINT *,"Called glutInit"
end program main
build.bat
REM 32 bit
#setlocal
#SET PATH=%PATH%;C:\msys64\mingw32\bin\
gfortran -Dx86 -cpp -c callglut.f90 -o callglut.o
gcc callglut.o -o callglut32.exe ..\x86\lib\freeglut.lib -lgfortran
#endlocal
REM 64 bit
#setlocal
#SET PATH=%PATH%;C:\msys64\mingw64\bin\
gfortran -cpp -c callglut.f90 -o callglut.o
gcc callglut.o -o callglut64.exe ..\x64\lib\freeglut.lib -lgfortran
#endlocal
The generic interface is used to call glutInit without parameters from Fortran (the parameters are filled in by the proxy subroutine).
callglut.f90 (compiles and runs on both platforms)
MODULE GlutModule
USE ISO_C_BINDING
IMPLICIT NONE
PUBLIC glutInit
INTERFACE
SUBROUTINE glutInit(pargc, argv) BIND(C,NAME="glutInit")
IMPORT
#ifdef x86
!GCC$ ATTRIBUTES stdcall :: glutInit
#endif
INTEGER(C_INT) :: pargc
TYPE(C_PTR), INTENT(IN) :: argv
END SUBROUTINE glutInit
END INTERFACE
END MODULE GlutModule
program main
USE GlutModule
PRINT *,"Calling glutInit"
call glutInit(0,C_NULL_PTR)
PRINT *,"Called glutInit"
end program main
Am I seeing a compiler bug with the attribute statement not being applied to a generic interface or is it something that I am doing? I suspect this and the 32 bit STDCALL name mangling from glutInit to _glutInit#8 is not being performed.
I am using gfortran under msys2 (GNU Fortran (Rev2, Built by MSYS2 project) 7.1.0) on 64 bit Windows with both 32 and 64 bit compilers.
It doesn't make sense to apply the STDCALL attribute to an identifier that is only a generic name. From the compiler's perspective, a generic name is a common label for a number of procedures. While the individual specific procedures may have different calling conventions, the label for them does not.
If you want to tell the compiler that a specific procedure has a certain calling convention, use the name that the compiler knows the specific procedure by, in the relevant declaration.
!GCC$ ATTRIBUTES stdcall :: glutInit_gl

ieee_arithmetic intrinsic module in gfortran

I need to use gfortran to compile a library that is dependent on ieee_arithmetic. However, it is found that gfortran can not identify this module.
For example with the code a.f90
program test
use,intrinsic :: ieee_arithmetic
real :: x
read *, x
if (ieee_is_nan(x)) then
print *, "Nan"
else
print *, "Not NaN"
end if
end program test
I have the following message when compiling
$ gfortran a.f90
a.f90:2.19:
use,intrinsic :: ieee_arithmetic
1
Fatal Error: Can't find an intrinsic module named 'ieee_arithmetic' at (1)
How can I let gfortran know where the ieee_arithmetic intrinsic module is?
ifort is found to be able to use the ieee_arithmetic module. But I wish to make gfortran work for this case.
The IEEE modules are supported as of GFortran version 5. See https://gcc.gnu.org/gcc-5/changes.html If you are using an older version, you should see the error message you have shown in your post.

Error in building MPI program

I'm new to MPI. I'm trying to write a program for calculating PI using MPI and FORTRAN. But when I try to build the program I get the following messages.
make all
gfortran -O2 -g \
-o bin/MpiTest.exe \
src/MpiTest.f -fno-range-check
C:/Program Files/MicrosoftMPI/Inc/mpif.h:344.38:
Included at src/MpiTest.f:11:
PARAMETER (MPI_AINT=z'4c00043b')
1
Error: PARAMETER attribute of 'mpi_aint' conflicts with PARAMETER attribute at (1)
C:/Program Files/MicrosoftMPI/Inc/mpif.h:359.35:
Included at src/MpiTest.f:11:
PARAMETER (MPI_ADDRESS_KIND=INT_PTR_KIND())
1
Error: Function 'int_ptr_kind' in initialization expression at (1) must be an intrinsic function
make: *** [all] Error 1
Can anyone help me here ?
P.S :
PROGRAM CalculatePI
include "C:/Program Files/MicrosoftMPI/Inc/mpif.h"
INTEGER :: i = 0, nThrows = 0, nSuccess = 0, ierror =0, numOfProcessors=0,myID=0
REAL :: x = 0, y = 0, results = 0
INTEGER :: Counter = 0
call mpi_init(ierror)
call mpi_comm_rank(MPI_COMM_WORLD, myID, ierror)
call mpi_comm_size(MPI_COMM_WORLD, numOfProcessors, ierror)
....
INT_PTR_KIND is an Intel Fortran compiler extension function; that is, it is not a Fortran intrinsic. The second of the error messages that you report indicates that gfortran is baulking at compiling code which contains references to a function it can't find. I guess the first error arises from the same problem, you are trying to compile with the 'wrong' compiler.
As Alexander Vogt has suggested you might make better progress using a compiler wrapper such as mpif90, but it has to be the right wrapper, the one which calls gfortran and links with the MS MPI library. Whether that wrapper exists I do not know, but look for it under C:/Program Files/MicrosoftMPI/.
However, since those errors emanate from the mpif.h file you have included you'll also have to find a corresponding include file for compiling with gfortran. I don't use MS MPI but it won't surprise me if you find that it only provides tools, libraries and include files for compilation with Intel Fortran.
You should not compile your MPI code with gfortran alone. Instead, use the wrapper provided by your MPI library. Typically it is called mpif90.
Thanks to High Performance Mark for the clarifications.

Fortran: Syntax error in CHARACTER declaration

I am trying to run a program, which works fine on my laptop, on a remote supercomputer. But the program is not compiling there. Trying to trace the problem, I reduced the program to the basic minimum, and still it is giving me a compilation error. Anyone has any ideas what might be going wrong here?
[k00603#fe01p08 python_utilities]$cat test.f90
program test
character(:), allocatable :: out
end program test
[k00603#fe01p08 python_utilities]$gfortran test.f90
In file test.f90:3
character(:), allocatable :: out
1
Error: Syntax error in CHARACTER declaration at (1)
I guess the gfortran is running fine as when I do the following, it works:
[k00603#fe01p08 python_utilities]$cat test.f90
program test
print *, "Hello World!"
end program test
[k00603#fe01p08 python_utilities]$gfortran test.f90
[k00603#fe01p08 python_utilities]$./a.out
Hello World!
The compiler on the supercomputer is:
[k00603#fe01p08 256]$gfortran --version
GNU Fortran (GCC) 4.1.2 20080704 (Red Hat 4.1.2-51)
Copyright (C) 2007 Free Software Foundation, Inc.
CHARACTER(:)... is a Fortran 2003 feature known as deferred length character. It was only recently added to gfortran and support in some areas (deferred length character components) is still incomplete.
Your supercomputer is probably running a older version of the compiler which lacks support for this feature.
character(:), allocatable :: out is declaring an allocatable scaler. This is a new feature of Fortran 2003. The compiler on the super computer likely doesn't support this newer feature.
You imply that you are using gfortran. http://gcc.gnu.org/wiki/GFortran lists allocatable scalers as added in gfortran version 4.5 (see 4.5 / Fortran 2003). The current release version is 4.7.

Open MPI "Hello, World!" is not compiling

Here is a simple MPI "Hello, World!" program.
#include <stdio.h>
#include <mpi.h>
int main(int argc, char **argv)
{
int size, rank;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
printf("SIZE = %d RANK = %d\n",size,rank);
MPI_Finalize();
return(0);
}
However, it doesn't seem to compile:
Undefined first referenced
symbol in file
MPI::Datatype::Free() /var/tmp//ccE6aG2w.o
MPI::Win::Free() /var/tmp//ccE6aG2w.o
MPI::Comm::Comm() /var/tmp//ccE6aG2w.o
ld: fatal: symbol referencing errors. No output written to main
collect2: ld returned 1 exit status
I've googled a lot, viewed mailing lists, thousands of them. They say libmpi_cxx is not linking. But it's in the compiler flags.
Here is --showme data:
mpic++ --showme:compile
-I/usr/openmpi/ompi-1.5/include -I/usr/openmpi/ompi-1.5/include/openmpi
mpic++ --showme:link
-R/opt/mx/lib -R/usr/openmpi/ompi-1.5/lib -L/usr/openmpi/ompi-1.5/lib -lmpi -lopen-rte -lopen-pal -lnsl -lrt -lm -ldl -lsocket -lmpi_cxx
My compiler is g++.
Just place the mpi.h header file above all header files
sometimes that causes problem to compile
I am not sure how u execute your code.
Compiling
mpic++ your_code_file.c
Execution
mpirun -np <no. of Processors> ./a.out
A few notes:
Note that Open MPI 1.5 is ancient. Please upgrade to the latest version in the Open MPI 1.6.x series (which is currently 1.6.3, but note that the www.open-mpi.org web site is currently undergoing a planned year-end maintenance and won't be back up until later today, Thursday, December 28, 2012).
I'm curious: why are you compiling a C program with mpic++? You only need to use mpicc -- the C MPI wrapper compiler. That would definitely avoid your issue. However, if you are using this small C hello world program as a simple example and your actual target is to compile a C++ MPI program, then mpic++ is the correct wrapper to try (even with a simple C program). If that's the case, then you have some kind of incompatibility / misconfiguration between your C++ compiler and the C++ compiler that Open MPI was compiled/installed with.
Looking at your mpic++ --showme output, it looks like you have some kind of package distribution of Open MPI -- -R is not put in the flags by default, for example. Where did you get this Open MPI installation? It's quite possible that it is not (fully) compatible with your g++ installation (e.g., if it was compiled with a different version of g++).
That being said, your mpic++ --showme output is also weird in that it lists -lmpi_cxx at the end of the line. It should be to the left of -lmpi, not to the right of it. I'm not show how your installation got borked like that, but that is another possible cause.
So to sum up, my answer is:
Please try upgrading Open MPI and see if the problem goes away.
Double check that your installation of Open MPI is compatible with your system.
It is a also much easer and more flexible to compile openmpi and mpi programs in a "Eclipse for Parallel Application Developers" IDE.
http://www.eclipse.org/downloads/packages/eclipse-parallel-application-developers/junosr1