Detect if MPI compiler is used in Fortran - fortran

I would like to write a Fortran code that could use MPI if it is compiled by mpif90 but that could also run if it is compiled with gfortran (only, without MPI lib).
So I though using a preprocessing condition, but looking on the Internet I found nothing about such preprocessing variable defined by MPI.
For example, I would like to compile this trivial code test.f90:
Program Main
#ifdef __MPI
USE MPI
#endif
implicite none
integer Ierror
#ifdef __MPI
call MPI_INTI(Ierror)
write (*,*) 'MPI detected'
#else
write (*,*) 'MPI not detected'
#endif
End
Then, if I compile the previous Non-working example with mpif90 I shoud get
$ mpif90 -cpp -o prog test.f90 && prog
> MPI detected
while if I compile with gfortran, I should get
$ gfortran -cpp -o prog test.f90 && prog
> MPI not detected
So is there a preprocessing condition (or another way) that could make this kind of example working ?

Related

All processor think they are the root when I compile with mpifort

I have code that compiles and runs fine with mpif90 and mpiifort, however when I compile it with mpifort all processors will have rank 0.
That typically occurs when you mix two MPI implementations.
For example, mpif90 and mpirun might be from MPICH (or its derivative) but mpifort is provided by Open MPI (or its derivative).
I recommend you double check that:
which mpif90
which mpifort
which mpirun
and compare the outputs of ldd a.out when compiled with mpif90 vs mpifort.

Compile oct file with fortran openmp using LDFLAGS

Using ubuntu 14.04 octave 3.8.1.
I'm attempting to create an .oct file which makes use of multithreaded fortran program. However, mkoctfile fails to use the related libraries during linking.
The files I'm using look as follows:
c:
#include <octave/oct.h>
extern "C" {
void fort5();
}
DEFUN_DLD (ce5, args, ,"help here")
{
fort5();
}
fortran:
subroutine fort5() bind(c)
use iso_c_binding
implicit none
!$OMP PARALLEL
write(*,*) "Hello"
!$OMP END PARALLEL
end subroutine fort5
I expect this code to result in output of four lines of "Hello".
I compile it with following command
mkoctfile CPP.cpp FORTRAN.f90
As a result I get only one output line, which indicates multitrhreading was ignored.
When compiled outside octave (with minor alterations to c++ file) with following command:
gcc -c CPP.cpp && gfortran -Wall -fimplicit-none -Wtabs -fdefault -real-8 -fopenmp -c FORTRAN.f90 &&gfortran -fopenmp -o3 CPP.o FORTRAN.o -lstdc++ -o OUT.out
The result is as it should be.
From several tests it becomes apparent, that mkoctfile is not capable to use -fopenmp flag in any form. As found on the internet this should be solvable by using LDFLAGS, however, for some reason I fail at that.
I set the enviroment variable in octave terminal with
setenv("LDFLAGS","-Wl,-Bsymbolic-functions, -Wl,-z,relro, -fopenmp")
setenv("FFLAGS","-g -O2 -fstack-protector --param=ssp-buffer-size=4 -fopenmp")
the $mkoctfile --print LDFLAGS indicates that the variable was set successfully. However, the compiled function fails to load: $undefined symbol: GOMP_parallel_start
I've tried explicitly listing the library but the result was the same.
mkoctfile ce5.cpp fort5.o '-Wl,-fopenmp' '-l /usr/lib/x86_64-linux-gnu/libgomp.so.1
mkoctfile ce5.cpp fort5.o '-Wl,-fopenmp' '-L /usr/lib/x86_64-linux-gnu/'
Did I use the flags correctly? What else should I do to get correct compilation?
Problem solved:
Seems like consecutive application of the following commands done the trick:
setenv("FFLAGS","-g -O2 -fstack-protector --param=ssp-buffer-size=4 -fopenmp")
setenv("LDFLAGS","-Wl,-Bsymbolic-functions, -Wl,-z,relro, -Wl,-fopenmp")
mkoctfile ce5.cpp fort5.o '-L, /usr/lib/x86_64-linux-gnu/libgomp.so.1'
Most likely the problem was setting correct flag for compiler ($-fopenmp in FFLAGS) and correct indication of library location.

gmon file not appearing after compiling a fortran 90 program with -pg

I have a Fortran program that I want to profile using gprof. What I do is I compile the files using the -pg option as follows (this is just a simple example):
program main
implicit none
real, dimension(100,100,100,100) :: A
integer :: i,j,k,l
do i=1,100
do j=1,100
do k=1,100
do l=1,100
A(i,j,k,l) = real( i+j+k+l )
end do
end do
end do
end do
print*, "END OF PROGRAM"
end program main
And then I compile manually:
gfortran -c main.f90 -pg
gfortran main.o -o prog -pg
But no gmon file appears as the program exits. Any ideas why this does not work?
I did install the binutils beforehand.
Versions:
gfortran 5.1
binutils 2.25
Operating system: OS X Yosemite
EDIT 21/07: I changed the example code following to a comment that was made

error with compilation of nr.f90

I need to use MRQMIN subroutine in my Fortran 90 code. Inside this subroutine there are some other modules nrtype.90, nrutil.f90 and nr.f90. I'm compiling all these modules and my own code with these commands
ifort -c nrtype.90
ifort -c nrutil.f90
ifort -c nr.f90
ifort test.f90 nrtype.o nrutil.o nr.o -o test
but I'm receiving this error
/tmp/ifortcx4Tb3.o: In function `mrqmin_IP_mrqmin_private_':
test.f90:(.text+0x4041): undefined reference to `gaussj_'
test.f90:(.text+0x4896): undefined reference to `covsrt_'
test.f90:(.text+0x48a5): undefined reference to `covsrt_'
am I missing some thing here during the compilation?
nr.f90 only provides the interfaces to the subroutines, not the subroutines themselves.
You have to compile gaussj.f90 and covsrt.f90 separately and specify them as well (I tried it for gfortran but it should work with ifort as well):
gfortran -c gaussj.f90
gfortran -c covsrt.f90
gfortran test.f90 mrqmin.o nr.o nrtype.o nrutil.o gaussj.o covsrt.o

Tell ifort to show tool commands

Say I have two files file_1.f90 and file_2.f90 and they use some libraries. Could be any programming language. Then I compile and link in one step using
ifort -I/include_dir_loc -o my.o file_1.f90 file_2.f90 -L/Lib_dir_loc
Is there a way to tell the terminal or ifort or whoever takes over to tell me the individual steps it carries out. It could be that it goes
ifort -I/include_dir_loc -c -o file_1.f90
ifort -I/include_dir_loc -c -o file_2.f90
ifort -o my.o file_1.o file_2.o -L/Lib_dir_loc
What actually happens after I type the first command? Who carries out the compilation using what commands and who coordinates between the compiler and the linker?
for ifort:
-v will show the tool commands and execute them
-dryrun will show the tool commands but will not execute