gfortran -std=f2008 compile flag errors if call fseek present - fortran

I'm trying to enforce a Fortran 2008 consistency check with gfortran. When I compile with -std=f2008, I get the following error:
Undefined symbols for architecture x86_64:
"_fseek_", referenced from:
_MAIN__ in ccJtOcKa.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
The following simple test program shows the issue. It compiles and runs fine without the -std=f2008, but doesn't compile when this flag is set.
program main
implicit none
integer :: i
open(unit=10, file='test.bin', access='stream')
write(10) 100
!fseek works, but will not compile with -std=f2008
call fseek(10, -4, 1)
read(10) i
print *, i
end program
This works:
gfortran main.f90
This gives the error:
gfortran -std=f2008 main.f90
I'm using MacPorts version of gfortran 8.2
GNU Fortran (MacPorts gcc8 8.2.0_3) 8.2.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Is fseek not a part of the fortran 2008 standard? If so, is there an alternative way to do this?

FSEEK an an extension intrinsic subroutine which is unnecessary for stream access. You can just read from any position you want
read(10, pos=42) i
You can also get the current position with the inquire statement.
inquire(unit=10, pos=current_pos)

As others have indicated, FSEEK is not in a Fortran standard. The Fortran standard does, however, permit a processor to supply additional intrinsics subprograms. To avoid the problem you are having, you can use the -fall-intrinsics option. Thus, gfortran -std=f2008 -fall-intrinsics will try to adhere to the Fortran 2008 standard with the exceptional that all intrinsic subprograms supplied by gfortran are available.

Related

Using FFTW3 Fortran library in MacOS

I am getting the following error while trying to compile a Fortran program with gfortran and FFTW3 library. The program however compiles successfully with the Intel compiler ifort.
Error
Undefined symbols for architecture x86_64:
"__gfortran_os_error_at", referenced from:
_MAIN__ in ccAVlghr.o
ld: symbol(s) not found for architecture x86_64
Compile Command
gfortran -I/usr/local/include -L/usr/local/lib pois.f90 -lfftw3 -lm
pois.f90 is the program which contains FFTW3 commands to solve a Poisson equation through Fourier transform.
The equivalent C program also compiles and executes successfully. The FFTW3 statements are inserted in Poisson.f90 as per FFTW3 documents. The routine which uses FFTW3 commands is given below
subroutine fft_forward(j,f,Fr,Fi)
use, intrinsic :: iso_c_binding
implicit none
include 'fftw3.f03'
double precision :: f(j),Fr(j),Fi(j)
integer :: i,j
type(C_PTR) :: plan
complex(C_DOUBLE_COMPLEX) :: FF(j)
plan = fftw_plan_dft_r2c_1d(j,f,FF,FFTW_ESTIMATE)
call fftw_execute_dft_r2c(plan,f,FF)
call fftw_destroy_plan(plan)
do i = 1,j
Fr(i) = real(FF(i))/j
Fi(i) = aimag(FF(i))/j
enddo
Fr = Fr/j; Fi = Fi/j
end
I also tried using a compiler flag -lgfortran but got the same error. Any suggestion will be of great help.
It probably depends on what you did while installing GNU Fortran, FFTW, et al.
In my case, it works as expected.
I have GNU Fortran installed from sources: gcc-9-2-0
Then, I have built FFTW using my own installation of GNU Fortran
./configure --prefix=$HOME/opt/usr/local/fftw/fftw-3.3.10 CC=gcc-9.2.0 MPICC=mpicc F77=gfortran-9.2.0
make
make install
and then, I have compiled your sample using
gfortran-9.2.0 -I$HOME/opt/usr/local/fftw/fftw-3.3.10/include -L$HOME/opt/usr/local/fftw/fftw-3.3.10/lib -lfftw3 -lm -c simple.f90
I have also added short _main stuff like so to double check it links with the stuff
program main
print *, 'Hello'
end program main
after building, it runs as expected
gfortran-9.2.0 -I$HOME/opt/usr/local/fftw/fftw-3.3.10/include -L$HOME/opt/usr/local/fftw/fftw-3.3.10/lib -lfftw3 -lm simple.f90 -o main
./main
Hello
I guess you have sort of a messy GNU Fortran + FFTW installation.

How to debug g++: internal compiler error: Segmentation fault?

I've implemented this LRU cache sample from HackerRank. It includes 500,000 test cases for the cache in the main function. When I try to compile it with
g++ -Wall -std=c++17 cache.cpp -o cache
it fails with this message:
g++: internal compiler error: Segmentation fault signal terminated program cc1plus
Please submit a full bug report,
with preprocessed source if appropriate.
See <file:///usr/share/doc/gcc-9/README.Bugs> for instructions.
Memory usage during compilation was decent, far away from any limits. My g++ version is
me#vie:$ g++ --version
g++ (Ubuntu 9.3.0-11ubuntu0~18.04.1) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
How do do I find out more what exactly is causing the compiler to fail? I've seen similar questions and comments saying this is a bug but before I submit an issue I'd like to doublecheck if this isn't just some bad design on my end.

Truncation of deferred-length string when passing as optional

I am passing optional deferred-length strings (character(len=:), allocatable, optional) between subroutines and getting unexpected behavior in GCC.
Here is my minimal example, where I pass an optional string through an interface routine to a routine that sets it:
$ cat main.f90
module deepest_call_m
implicit none
contains
subroutine deepest_call(str)
character(len=:), allocatable, intent(OUT), optional :: str
if (present(str)) str = '12345'
write(*,*) 'at bot of deepest_call, str is "'//trim(str)//'"'
end subroutine deepest_call
end module deepest_call_m
module interface_call_m
implicit none
contains
subroutine interface_call(str)
use deepest_call_m, only : deepest_call
character(len=:), allocatable, intent(OUT), optional :: str
call deepest_call(str=str)
write(*,*) 'at bot of interface_call, str is "'//trim(str)//'"'
end subroutine interface_call
end module interface_call_m
program main
use interface_call_m, only : interface_call
implicit none
character(len=:), allocatable :: str
call interface_call(str=str)
write(*,*) 'at bot of main, str is "'//trim(str)//'"'
end program main
(Note that, for simplicity, I'm not wrapping the write statements in if(present) and if(allocated), although that would be necessary for a real implementation.)
In Intel 16.0 and 2019_U4, and PGI 15.10, this routine gives the expected result: str is set in deepest_call and remains the same through interface_call and in main:
$ ifort --version
ifort (IFORT) 16.0.0 20150815
Copyright (C) 1985-2015 Intel Corporation. All rights reserved.
$ ifort main.f90 && ./a.out
at bot of deepest_call, str is "12345"
at bot of interface_call, str is "12345"
at bot of main, str is "12345"
However, with gfortran 4.8.5:
$ gfortran --version
GNU Fortran (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36)
Copyright (C) 2015 Free Software Foundation, Inc.
GNU Fortran comes with NO WARRANTY, to the extent permitted by law.
You may redistribute copies of GNU Fortran
under the terms of the GNU General Public License.
For more information about these matters, see the file named COPYING
$ gfortran main.f90 && ./a.out
at bot of deepest_call, str is "12345"
at bot of interface_call, str is ""
at bot of main, str is ""
The string has been truncated when returning from the deepest_call in interface_call. With gfortran 7.3.0 and 8.2.0, the code crashes at runtime when no compile-time options are provided:
[chaud106#epyc-login-1-0 Testing]$ gfortran --version && gfortran main.f90 && ./a.out
GNU Fortran (GCC) 8.2.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
at bot of deepest_call, str is "12345"
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
#0 0x2af39a82733f in ???
#1 0x400c68 in ???
#2 0x400d9c in ???
#3 0x400f0e in ???
#4 0x2af39a813494 in ???
#5 0x400878 in ???
#6 0xffffffffffffffff in ???
Segmentation fault
However, adding compile-time checking recovers the previous truncation behavior:
$ gfortran --version
GNU Fortran (GCC) 8.2.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ gfortran -g -fbacktrace -Wall -Wextra -std=f2008 -fcheck=all -Og main.f90 && ./a.out
at bot of deepest_call, str is "12345"
at bot of interface_call, str is ""
at bot of main, str is ""
This looks a lot like a compiler bug to me, so perhaps I just need to post on the bugzilla. But I would like some feedback here first, specifically:
Is my test case standard-conforming? I'm specifically curious about the str=str argument to deepest_call. I use this structure often to pass an argument as optional if and only if it's optional in the present scope, but I couldn't easily find this in the standard and I'm not sure if it's really valid. Passing just str seemed to give the same behavior, though.
Are there any simple workarounds? Given that this issue affects a wide range of versions (4.8.5 to 8.2.0) simply avoiding them is not feasible.
Is anybody aware of this behavior for other versions of gfortran, or other compilers? I only have easy access to GCC, Intel, and PGI.
Your code is standard compliant.
An optional dummy argument may be an actual dummy argument in a subsequent call without the keyword, and whether or not it is present. (Of course, it may only be not present in the case that the following dummy argument is optional.) That is:
call interface_call(str)
is just as correct as
call interface_call(str=str)
As to (suboptimal) workarounds (I see this fail with gfortran 9.1.0, but working with gfortran 10.0.0 20190625), you could consider having the arguments as not deferred-length. After all, you're using trim everywhere, so trailing whitespace would be chomped.
Your code is just one small change away from not being compliant: the write statements aren't protected by a presence check for the optional dummy. If the optional dummy is not present in the call chain then the program would be invalid.

Catching Exceptions in Oracle on Solaris fails

In our code we trying to catch an exception. This code has been working fine for years with different architectures and operating systems (x86, x64, SuSe Linux 11 SP2, Oracle 11g, Oracle 12c). Now we also tried out Solaris 11.3 on x86/64 and Sparc with Oracle 12c.
It turns out that we are not able to catch the exceptions and that the whole program crashes. We produce a shared object library which is then loaded into Oracle and used by a stored procedure. Within that stored procedure we might throw an exception but catch it and make it pretty for Oracle.
The combination of Solaris 11.3/Oracle 12c/x64 now behaves strange:
The extproc process is being killed and Oracle just delivers an ORA-28576: lost RPC connection to external procedure agent error message.
Please find an MVCE at https://gist.github.com/pgab/13ac10f4302d11cab45ba80584eeca0f.
The complete output on Solaris with SQL Developer is:
declare
ret number;
begin
"thrower".test_throw(ret);
end;
Error report -
ORA-28576: lost RPC connection to external procedure agent
ORA-06512: at "thrower.TEST_THROW", line 1
ORA-06512: at line 4
28576. 00000 - "lost RPC connection to external procedure agent"
*Cause: A fatal error occurred in either an RPC network connection,
the extproc agent, or the invoked 3GL after communication had
been established successfully.
*Action: First check the 3GL code you are invoking; the most likely
cause of this error is abnormal termination of the
invoked "C" routine. If this is not the case, check for
network problems. Correct the problem if you find it. If all
components appear to be normal but the problem persists, the
problem could be an internal logic error in the RPC transfer
code. Contact your customer support representative.
Also the used /tmp/debug.log produces just:
about to throw
In comparison the output with SuSe is:
declare
ret number;
begin
"thrower".test_throw(ret);
end;
Error report -
ORA-20001: foo
ORA-06512: at "thrower.TEST_THROW", line 1
ORA-06512: at line 4
And in /tmp/debug.log
about to throw
foo
To be even more confusing:
The same code works perfectly fine on Solaris 11.3 on Sparc,
A single executable is able to throw and catch exceptions properly.
Which bit am I missing here? Maybe it a special linker flag or something else which needs to be activated for Solaris or even for Oracle?
Edit:
With the hint of #Andrew Henle I was digging into compiler and linker versions being used within extproc and the library being produced using strings -a and scanning the output:
On Solaris liboragst contained the following strings (c.f. https://nopaste.xyz/?63251ef69b12e0ac#zgE4Hfagu08eBnSkbIWKcV/Zoux9X6UWw+AH2eGESxM=):
GNU C++ 4.8.2 -m64 -mtune=generic -march=x86-64 -g -fPIC
ld: Software Generation Utilities - Solaris Link Editors: 5.11-1.2458
where as extproc (the process spawned by Oracle RDBMS to load the external procedure) contains this (c.f. https://nopaste.xyz/?913cef4a7fdd4c0d#cHkGRMpWn3IiFwpqv0auys4nn04wfrwtom3eIHEimLE=):
ld: Software Generation Utilities - Solaris Link Editors: 5.11-1.2329
Xa;O;p;F;R=Sun C 5.12 SunOS_i386 Patch 148918-06 2013/06/11;backend;raw;cd;
/opt/SunProd/studio12u3/solarisstudio12.3-148906-08/prod/bin/cc
But there is nothing at /opt/SunProd/studio12u3 being installed.
Furthermore please find below the versions of gcc/g++ and ld:
Solaris:
g++ --version
g++ (GCC) 4.8.2
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
ld --version
ld: Software Generation Utilities - Solaris Link Editors: 5.11-1.2458
2nd Edit:
I have no managed to compile the library with Oracle's developerstudio but still get an ORA-28576 error instead of the wanted ORA-20001. It is a "clean" Solaris 11.3 installation with just Oracle Database, CMake and Developer Studio 12.6.
Cmake issues:
/opt/developerstudio12.6/bin/CC -DoraGST_EXPORTS -fpic -m64 -std=c++03 -g -KPIC -I/export/opt/ora12cg3d/product/12.1.0/dbhome_1/rdbms/public -o CMakeFiles/oraGST.dir/oGST_manual.cpp.o -c /export/home/paul/test/oGST_manual.cpp
and
/opt/developerstudio12.6/bin/CC -KPIC -fpic -m64 -std=c++03 -g -m64 -std=c++03 -G -hliboraGST.so -o liboraGST.so CMakeFiles/oraGST.dir/oGST_manual.cpp.o -lstdc++
ldd -d liboraGST.so yields:
libstdc++.so.6 => /opt/developerstudio12.6/lib/compilers/CC-gcc/lib/amd64/libstdc++.so.6
libgcc_s.so.1 => /opt/developerstudio12.6/lib/compilers/CC-gcc/lib/amd64/libgcc_s.so.1
libstatomic.so.1 => /opt/developerstudio12.6/lib/compilers/atomic/amd64/libstatomic.so.1
libCrunG3.so.1 => /usr/lib/64/libCrunG3.so.1
libm.so.2 => /lib/64/libm.so.2
librt.so.1 => /lib/64/librt.so.1
libc.so.1 => /lib/64/libc.so.1
For you reference you can find the output of strings -a at https://nopaste.xyz/?50daded482074bd3#9KLZaMYDiVBEFLLrTFV1UOY5ZRaZWnz006iBwSnCzMk=

compiling with cygwin/gfortran or ifort with acml

I would like to compile my program linking to acml. In cygwin (win64) with gfortran linking to acml:
$ gfortran empty.f90 -L/c:/cygwin64/acml5.3.1/win64/lib/libacml_dll.lib
yields
/tmp/ccKechZN.o:empty.f90:(.text+0xff): undefined reference to `drandinitialize_'
/tmp/ccKechZN.o:empty.f90:(.text+0xff): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `drandinitialize_'
/tmp/ccKechZN.o:empty.f90:(.text+0x13b): undefined reference to `drandgaussian_'
/tmp/ccKechZN.o:empty.f90:(.text+0x13b): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `drandgaussian_'
collect2: error: ld returned 1 exit status
I tried a few other things with the help of the documentation, but nothing has successfully allowed the compiler to link with acml. I also tried to link to the library by adding -l acml_dll and received the following error:
/usr/lib/gcc/x86_64-pc-cygwin/4.9.3/../../../../x86_64-pc-cygwin/bin/ld: cannot find -lacml_dll
collect2: error: ld returned 1 exit status
I have verified that the .lib exists in the directory specified. Perhaps a related problem, I am also trying to execute the output from ifort linked to acml on win64. I am using "Intel 64 Visual Studio 2013 mode" command prompt to compile an example program that calls subroutines from acml (see documentation for linking in win64):
ifort /libs:dll empty.f90 c:/AMD/acml5.3.1/ifort64_int64/lib/libacml__dll.lib
which yields
Intel(R) Visual Fortran Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 14.0.5.239 Build 20150212
Copyright (C) 1985-2014 Intel Corporation. All rights reserved.
Microsoft (R) Incremental Linker Version 12.00.21005.1
Copyright (C) Microsoft Corporation. All rights reserved.
-out:empty.exe
-subsystem:console
empty.obj
At least with ifort the program compiles successfully. Then when I execute empty.exe I get the following error:
The program can't start because libacml_dll.dll is missing from your computer. Try reinstalling the program to fix this problem.
I tried reinstalling acml 5.3.1 as well as trying acml 6.1.0, but encountered the same error upon execution.
Just specifying the library path alone is not sufficient. You have to tell the compiler to link against the library as well. Simply add -l acml_dll to the compile options.
Additionally, specifying the library path with -L expects a path, not a file. So the complete command should look like
gfortran empty.f90 -L/c:/cygwin64/acml5.3.1/win64/lib/ -lacml_dll
When you run the program, the library needs to be found at runtime as well. The easiest way to achieve this is to use rpath:
gfortran empty.f90 -L/c:/cygwin64/acml5.3.1/win64/lib/ -lacml_dll \
-Wl,-rpath=/c:/cygwin64/acml5.3.1/win64/lib/