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.
Related
I have the following code that uses a character variable with allocatable length.
PROGRAM testprog
IMPLICIT NONE
CHARACTER(LEN=5) :: param
CHARACTER(LEN=:), ALLOCATABLE :: val
param = '12455'
val = param
WRITE(*,*) val
END PROGRAM testprog
I compile it using gfortran versions 7.5 or 8.4 with all warnings activated (option -Wall) and I get the following warning:
test.f90:6:0:
val = param
Warning: ‘.val’ may be used uninitialized in this function [-Wmaybe-uninitialized]
The program works. However, I do not understand why this warning message appears.
This is a compiler bug. It is well-known, but not fixed in GCC yet. You can see the report at https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91442
You can either ignore it, or disable the "may be used uninitialized" warnings with -Wno-maybe-uninitialized or compile with optimizations (-O1 and more).
When compiling the following Fortran program using IFORT 2015 (for Mac OS X):
MODULE X
USE, INTRINSIC :: iso_c_binding, ONLY: c_intptr_t
IMPLICIT NONE
INTERFACE
INTEGER(c_int) FUNCTION process(variable) BIND(C, name = "_process")
USE, INTRINSIC :: iso_c_binding, ONLY: c_int
!DEC$ ATTRIBUTES NO_ARG_CHECK :: variable
!GCC$ ATTRIBUTES NO_ARG_CHECK :: variable
TYPE(*), INTENT(IN) :: variable
END FUNCTION
END INTERFACE
END MODULE
... it gives the following error:
example.f90(13): error #5082: Syntax error, found ',' when expecting one of: , <END_OF_STATEMENT> ;
TYPE(*), INTENT(IN) :: variable
-------^
This is how I compile the Fortran program (example.f90):
ifort example.f90 -free -m64 -c -fPIC -02 -o wrapper.o
The assumed-type declaration type(*) is a feature of Fortran 2018 (or TS29113 addition to Fortran 2008) that is first supported by Intel Fortran Compiler in release 16.0.
You should use a later version of the compiler or rewrite the code to avoid using this feature.
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
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 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.