Getting IP addresses from an MPI program on a supercomputer - fortran

I have the following MPI Program:
program hello
include 'mpif.h'
integer my_pe_num,errcode
call MPI_INIT(errcode)
call MPI_COMM_RANK(MPI_COMM_WORLD,my_pe_num,errcode)
print *, 'Hello from ', my_pe_num, '.'
call MPI_FINALIZE(errcode)
end program hello
It's fine. Now I would like to get the IP address from each process to go along with the rank. I looked at MPI_Get_Processor_name, but that's not what I want.
When I run this, it is via batch on a supercomputer. The actual step that runs the program is:
mpirun -np 4 ./hello

Related

Error occurs while trying to print variables in fortran

I use window 10. I use Xstart compiler.
The exact problem is to write type declarations to declare them as real variables.
Temperature, Pressure, Volume Type declarations are needed to declare these three as real variables.
I should print it and show the result.
Below is my program. To run the program I write pgf90 ww.f90.
Since a.out is the command that shows the latest calculation result, use a.out to print the result.
program disting
implicit none
REAL :: Temperature, Pressure, Volume print *
end program disting
When I run this program, I get this error.
error at or near identifier print (ww.f90: 3)
0 informs, 0 warnings, 1 severes, 0 fatal for disting.
Why is this not printing?
program disting
implicit none
REAL :: Temperature, Pressure, Volume
print *, Temperature, Pressure, Volume
end program disting
If you explicitly print out your variables it works fine. The * is not a wildcard, it simply tells the computer to output the data that follows in a format compatible with the type of items contained in the following comma delimited list. You were missing the list to print out.
I tested this here: https://www.jdoodle.com/execute-fortran-online/

Problem when reading Fortran file with CodeBlocks IDE

Recently, i've begun learning Fortran programmation language.
I am using CodeBlocks IDE with GNU Fortran Compiler.
I have a problem in simple code that i found in a Fortran Course online that explains how to read and write from a file.
The program is the following:
program main
implicit none
character (len=14) :: c1,c2,c3
integer :: n
real :: T
open(unit=10,file='titi.txt')
read(10,*) c1,n,c2
read(10,*) c3,T
close(10)
open(unit=20,file='toto.txt')
write(20,*) c1,'il est',n,c2
write(20,*)'la',c3,'est de',T,'degres'
close(20)
end
Where the file 'titi.txt' contains:
bonjour 4 heures
temperature 37.2
The error message that appears in the console is the following:
Program received signal SIGSEGV: Segmentation fault - invalid memory
reference.
Backtrace for this error:
#0 ffffffff
I tried using the flag
-g
And than i found using the debugger that the problem is in the first line where 'read' was used
read(10,*) c1,n,c2
I really don't know how to deal with this. The code seems pretty simple to me and i have never seen this error message before, so i don't know what does it mean.
Thanks for your answers in advance.
Thank you all for your responds.
Actually what caused the problem is that i was using an old compiler. So when i downloaded the last version it all worked perfectly without changing any line in the code.
This is not an answer, but it's too much text for a comment.
It's running fine on my computer.
Can you compile it with
gfortran -g -O0 -fbacktrace -Wall -fcheck=all
That way you should get a lot more information. Also, you can add some error checking:
Add the following variables:
integer :: ios
character(len=100) :: iomsg
Then you can add error checking to all io statements like this:
read(10,*) c1,n,c2
becomes:
read(10,*,iostat=ios,iomsg=iomsg) c1,n,c2
if (ios /= 0) then
print*, "Error reading c1, n, c2:"
print*, trim(iomsg)
STOP
end if
That can also give you some hints.

How to pass parameters from input file to fortran 77 mpirun during run time?

I am an MPI and Fortran 77 noob. I have a fortran 77 code FKRPRO.f which I wanted to parallelize using OpenMPI. The code requires a lot of parameters which are fed into it during run time from a separate file. Compilation and running is something like this
gfortran -o FKRPRO FKRPRO.f
./FKRPRO < Modelfile.txt
the equivalent lines in the code (not my code) are
PARAMETER(LIN=5)
INTEGER ERROR
LOGICAL PRNTA
PRNTA=.FALSE.
READ(LIN,'(L3)') PRNTA
READ(LIN,21) M1,M2
21 FORMAT(11I5)
and so on. Can someone please explain to me what READ(LIN,'(L3)') PRNTA means. The input in the input file Modelfile.txt is something like this
.F.
0 64
and so on..
I put the necessary MPI statements in the code.
INCLUDE 'MPIF.H'
...
CALL MPI_INIT(ERROR)
CALL MPI_COMM_SIZE(MPI_COMM_WORLD,NPROCS,ERROR)
CALL MPI_COMM_RANK(MPI_COMM_WORLD,PRANK,ERROR)
...
CALL MPI_TYPE_FREE(NEWMATRIX,ERROR)
CALL MPI_FINALIZE(ERROR)
All processes are not being able to read the input file. I have compiled and run the code like this
mpif77 -o bc3 FKRPROG5.f
mpirun -np 4 bc3 < Modelfile.txt
This is not working. I get the following errors. Only the first process or rank 0 can read the file.
At line 50 of file FKRPROG5.f (unit = 5, file = 'stdin')
Fortran runtime error: End of file
At line 50 of file FKRPROG5.f (unit = 5, file = 'stdin')
Fortran runtime error: End of file
At line 50 of file FKRPROG5.f (unit = 5, file = 'stdin')
Fortran runtime error: End of file
mpirun has exited due to process rank 3 with PID 866 on
node Avinash-rMBP.local exiting improperly. There are two reasons this could occur:
1. this process did not call "init" before exiting, but others in
the job did. This can cause a job to hang indefinitely while it waits
for all processes to call "init". By rule, if one process calls "init",
then ALL processes must call "init" prior to termination.
2. this process called "init", but exited without calling "finalize".
By rule, all processes that call "init" MUST call "finalize" prior to
exiting or it will be considered an "abnormal termination"
This may have caused other processes in the application to be
terminated by signals sent by mpirun (as reported here).
50th line is READ(LIN,'(L3)') PRNTA.Someone kindly point out where I am going wrong :(
So, how can I make all processes read from this input file < Modelfile.txt ?? Thanks.
The statement
READ(LIN,'(L3)') PRNTA
causes the program to read, from the unit attached to the channel with id LIN, a 3-character sequence which represents a logical value and assigns the value read to the variable PRNTA. From the fragments you've shown us the program will read .F. and set PRNTA to .false..
LIN is set to the constant value 5, which usually means stdin. This use of 5 to denote stdin is not a de jure standard, it is more of a de facto standard.
The straightforward way to read a parameter file into an MPI program is to ensure that only one process reads the file and then sends out the values to the other processes which need them.
You seem to have written a program in which all processes try to read the same input file but, at run-time, the redirection you've used to pass Modelfile.txt is only working for one process (presumably the process with rank 0). The other processes are not getting an input file at all and are complaining, then bringing the program crashing down. The error message you show is typical of a Fortran program which doesn't find an input file at all when it tries to read.
Far better to write code along the lines:
call mpi_init ...
...
if (myrank==0) then
open(...) inputfile
read(...) parameters
close(...)
end if
...
call mpi_bcast(parameters from 0 to all)
...
In general, don't expect the run-time environment for MPI processes to be identical copies of the run-time environment for a sequential program. I think that you are seeing evidence that your run-time directs the input only to the first process created when your program runs. Since mpirun is not standardised (though mpiexec is) I don't think you can rely on this run-time behaviour being the same for all MPI implementations. For portability and compatibility you're better off handling I/O explicitly within your program than using o/s features such as redirection.
You could, rather than have process 0 read the parameters and distribute them to other processes, write your code such that each process reads the same file. If you do write your code this way take care to ensure that the processes aren't fighting over access to the I/O channels; having multiple processes trying to (nearly-)simultaneously read across a single input channel is a sure way to slow things down.

Does a program started with mpiexec know it was started with mpiexec?

I'm in the process of adding an option to a Fortran program to run it using multiple processors using MPI. If the user is going to run it in parallel, the user needs to specify different input files---one file for each domain (processor) of the problem. The program will look for a specific filename by default (a file called "serial.inp"). So I need the program to know when it is being run in parallel so that it can instead look for the other filenames instead (e.g. "parallel_1.inp", "parallel_2.inp", "parallel_3.inp", etc.). My first thought is to have the user pass an argument to the program when they execute it, e.g.:
mpiexec -n 4 myprogram.exe -parallel
This way, it will look for the parallel files when that argument is present. But it seems kind of redundant. If the program is being called with mpiexec, there is no question that the user is attempting to run it in parallel. Is there any way that my program will know it was started using mpiexec? Or is the command line argument my best bet?
Alex Leach is right in that you can do this with MPI-implementation-specific environment variable lookups, but there's no portable way to do this.
But as I understand, I don't think you really need to; you can get most of what you want with just checking to see if it was run with one rank:
program filenames
use mpi
implicit none
integer :: comsize, rank, ierr
character(len=128) :: inputfilename
call MPI_Init(ierr)
call MPI_Comm_size(MPI_COMM_WORLD,comsize,ierr)
call MPI_Comm_rank(MPI_COMM_WORLD,rank,ierr)
if (comsize == 1) then
inputfilename = 'serial.inp'
else
write(inputfilename, '(A,I0,A)'), 'parallel_',rank,'.imp'
endif
write(*,'(I,1X,A)'), rank, trim(inputfilename)
call MPI_Finalize(ierr)
end program filenames
Running gives
$ mpirun -np 4 ./filenames
0 parallel_0.imp
1 parallel_1.imp
2 parallel_2.imp
3 parallel_3.imp
$ ./filenames
0 serial.inp
That's not perfect; it'll give the serial result if you run using mpirun -np 1 filenames, but depending on your use case that may not be a terrible thing in exchange for having something portable.
Processes run with mpiexec will have various environment variables set, indicating to the subprocesses whether they are the master process or slaves, amongst other things.
Look in your mpiexec's documentation for specific details. Microsoft have some documentation online too.
Why not do it programmatically? This is how I do it in my program:
#ifdef MPI
CALL MPI_Init(ierr) ! Initialize MPI
CALL MPI_Comm_rank(mpicomm,nproc,ierr) ! Who am I?
CALL MPI_Comm_size(mpicomm,size,ierr) ! How many processes?
#else
nproc = 0
size = 1
#endif
After this point in the program, you can inquire whether the program is serial or parallel by inquiring the value of size.

FORTRAN Read() issue

Hey so I am trying to learn Fortran basics so that I can use it for a basic physics project. I am having trouble with getting input properly. My code is:
program main
write(*, *) "Enter n:"
read(*, *) n
print *, "Number is ", n
end program main
It is quite simple. Except that when I compile and run it, nothing happens until I enter the input in which it looks like this
gfortran num.f90 -o num
./num
(nothing happens until I type) 3
Enter n:
Number is: 3
Is there a problem with my memory allocation? Or could it be my compiler? I honestly have no clue.
Your program is fine, on my machine it prints the Enter n: before reading the variable. If you do not see the message until you enter a value (and hit Enter), it could have to do with the buffering of your command window you use. For checking this, you could just open an xterminal (type xterm in your command window), and run the program there.