I have compiled a program to execute sequentially (not parallel) in fortran 90. I am trying to debug the program with print statements to check my rusty gdb fu. I am compiling the files with gfortran -c -O2 -ffast-math -ggdb. However, none of these statements print anything:
print *, variablename1, variablename2
write(6,*) variablename1, variablename2
write(*,*) variablename1, variablename2
The compiled program prints nothing and executes as if the statements are not there. Could I be missing something simple and obvious?
In the comments it turned out that there was a problem with buffering of the output stream. This can be controled by calling the flush statement, the non-standard flush() intrinsic subroutine or by compiler-specific environment variables like GFORTRAN_UNBUFFERED_ALL.
Related
I am fairly new to use Fortran preprocessing statement and have a question which is probably pretty native. Can Fortran preprocessing statement be indented? I tested using Gfortran 4.8.1 on Linux (openSUSE Leap) and it turned out I it can not be indented at all.
The following code main.f90 works with gfortran -cpp main.f90 -o main:
program main
implicit none
#ifdef DEBUG
print *, "I am in debug mode"
#endif
print *, "hello world!"
end program main
But the following throws an error:
program main
implicit none
#ifdef DEBUG
print *, "I am in debug mode"
#endif
print *, "hello world!"
end program main
The error message is Error: Invalid character in name at (1).
Does this mean that we should always write the preprocessing statement from the first beginning of the line or it is just a compiler specific rule? Any help would be greatly appreciated and thanks in advance!
No, they cannot be indented because gfortran runs CPP in traditional mode which does not allow indentation. They must always start in the first column.
You could run CPP manually, but be very very careful about that.
If you use the // string concatenation operator somewhere the preprocessor would treat it as a comment. You must use the -C flag as shown by #ewcz in his/her answer which disables discarding of comments.
Some compilers supply their own FPP preprocessor which behaves differently.
you could use the C preprocessor to do the processing and then compile the processed file, i.e., assuming that your program is in main.f90, then something like:
cpp -nostdinc -C -P -w main.f90 > _main.f90
gfortran -o main _main.f90
In this connection, this question is quite useful: Indenting #defines
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.
I am trying to compile a c++ program but it does not work.
At first, I should said that c++ is not a language I really know, I use Fortran. Anyway, the main c++ program calls a fortran subroutine. I can compile this subroutine but when I want to compile the c++ program there is a link error.
The real program is just huge and calls many subroutines, so I did a simple test (simple program calling just one subroutine) and it does not work as well! When I want to create the .x my subroutine is undefined.
Here is the c++ program (test-TQINIT.cpp) and the subroutine (TQINIT.f).
test-TQINIT.cpp:
#include <iostream>
using namespace std;
extern "C"
{
void TQINIT_(int*, int*);
}
main()
{ int NWG;
NWG=80000;
int *IWSG = new int[NWG];
TQINIT_(IWSG,&NWG);
}
TQINIT.f:
SUBROUTINE TQINIT(IWSG,NWG)
IMPLICIT NONE
INTEGER NWG
INTEGER IWSG(NWG)
LOGICAL TQG2ERR
INTEGER IERR
CALL TQRSERR
CALL TQINI(NWG,IWSG)
IF (TQG2ERR(IERR)) THEN
WRITE(6,*)'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
WRITE(6,*)'ERROR INITIALIZING (TQINIT) !!!'
WRITE(6,*)'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
STOP
ENDIF
END
I compile the subroutine using:
gfortran -c TQINIT.f
and get a TQINIT.o
Then I compile the main program using:
g++ -c test-TQINIT.cpp
and get a test-TQINIT.o.
Then for create the .x I use (TQINIT.f need the library):
g++ test-TQINIT.o TQINIT.o -L/usr/local/thermocalc/3.0/SDK/TQ8 -ltq-linux-x86_64-gfortran44-8 -o test-TQINIT.x
This is what I get:
test-TQINIT.o: In function `main':
test-TQINIT.cpp:(.text+0x33): undefined reference to `TQINIT_'
collect2: ld returned 1 exit status
I hope someone will be able to help me.
Thank you by advance.
Fortran is case-insensitive, and the name of the subroutines in the object file normally (as far as I know) end up in lowercase with an underscore, so yours is probably named tqinit_ and not TQINIT_, so your call in C++ should be lowercase.
You can verify the name in the object file with the objdump -t TQINIT.o command given in Alexander Vogt's answer, or the simpler nm TQINIT.o which is more terse.
If you use the ISO_C_BINDING in Fortran, you will have control over the precise routine names that will be seen by the other language, e.g., case, no underscores. You can also declare the arguments so that consistency with C/C++ will be guaranteed. For more on this topic, see https://stackoverflow.com/questions/tagged/fortran-iso-c-binding
I'm no expert on mixing C and Fortran, but I have always linked the Fortran Code directly using
g++ test-TQINIT.cpp TQINIT.o -L/usr/local/thermocalc/3.0/SDK/TQ8 \
-ltq-linux-x86_64-gfortran44-8 -o test-TQINIT.x
instead of compiling those two files separately and then linking... Perhaps this helps (although your way should work as well, at least it does with the simple example I tried).
BTW:
You can find out how the functions in your Fortran object are called by issuing
objdump -t TQINIT.o
This should give you the correct function name to call.
This is a short question but I have tried to give as much detail as possible.
I am compiling an old, but still actively developed, fortran code (f77 standard) on Scientific Linux. The recommended compilers for this code are ifort and gfortran. Using gfortran I can compile and run this code. However, if I make with the DEBUG=1 flag the code compiles but terminates with a SEG FAULT. Stepping through with gdb leads to the following source of error:
REAL*4 TIME_CURRENT
CALL CPU_TIME(TIME_CURRENT)
ISECS = 100*INT(TIME_CURRENT)
The program terminates with:
Program received signal SIGFPE, Arithmetic exception.
timer (init=1, isecs=0) at myprog.f:1818
1818 ISECS = 100*INT(TIME_CURRENT)
If I stop execution on line 1818 and examine ISECS and TIME_CURRENT I get:
(gdb) ptype(TIME_CURRENT)
type = real(kind=4)
(gdb) ptype(ISECS)
type = integer(kind=4)
I've tried being more specific and using:
ISECS = 100*INT(TIME_CURRENT,4)
But it doesn't help. I fail to see how this could equate to an Arithmetic error?
My (makefile generated) debug compile flags are:
gfortran -fno-automatic -m32 -O0 -g \
-ffpe-trap=invalid,zero,overflow,underflow,precision -static-libgfortran
When I compile out of debug I no longer receive a SEG FAULT but and my compile flags are
gfortran -fno-automatic -m32 -O2 -ffast-math -static-libgfortran
I am not a fortran programmer so any assistance would be greatly appreciated. Please note, I am compiling on a 64bit system but forcing a 32bit compilation, as this is required.
Your code does not look like FORTRAN 77, CPU_TIME is from Fortran 95. Anyway, your options for the debug are extremely strict. -ffpe-trap=invalid,zero,overflow,underflow,precision means many legitimate uses of floating point arithmetic will cause an exception. I recommend to use just -ffpe-trap=invalid,zero,overflow.
Specifically from gfortran manual:
Some of the routines in the Fortran runtime library, like CPU_TIME ,
are likely to trigger floating point exceptions when "ffpe-trap=precision"
is used. For this reason, the use of "ffpe-trap=precision" is not recommended.
Is there any way for gfortran to compile a f90 program but with a non-f90 extension, or even no file extension at all?
How to suppress pause statement warning used in a f90 program when compiled with gforTRan?
Many thanks.
gfortran -c sourfile.xyz does not work. I know the manpage explains these options, but I did not find one working.
I mean in my f90 program, I have a pause statement. If I compile it, I got a warning saying the use of pause is obsolete. I want to suppress this warning during compilation.
Suppress all warnings with -w option?