Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28958 Discussions

File units are reused with newunit when library is dynamically loaded on linux

HarmenW
Novice
299 Views

I have created a small reproducer here: https://github.com/harmenwierenga/newunit_error_reproducer 
It gives the following output on my machine:
File main.txt was opened, unit number -129 , error value 0
lib.txt was openend, new unit number -129 , error value 0
Unit -129 is connected to file: <machine_path>/main.txt

If I open a file in the main program using open(newunit=...), I get unit number -129. If I then dynamically load a shared library (.so) that is also written in Fortran, and open a new file in there, newunit again gives -129 as the new unit number.

If I simply dynamically link the library, then I receive -130 for the second file. Only when I load the library at runtime through dlopen, I get the same unit numbers. I have tried the ifort from OneAPI 2023.1.0 and the ifx from OneAPI 2025.0.0, and both have the same issue. I have also tried to add RTLD_GLOBAL to the dlopen call, but it does not change anything.

I found this previous question that may be related: Ifort-2021-7-reusing-file-units-despite-newunit-specifier/m-p/1425918 


Is there a way to get around this issue other than tracking the unit numbers myself? Since inquire works, I could create a loop that checks for existing unit numbers and pick a new one that way, but that is not exactly thread safe.

0 Kudos
1 Solution
HarmenW
Novice
216 Views

The build commands used by make (added -D CMAKE_VERBOSE_MAKEFILE=TRUE, I removed some system specific paths):

ifx -Dlib_EXPORTS -g -diag-disable:10440 -fPIC -c lib.f90 -o lib.f90.o
ifx -fPIC -g -diag-disable:10440 -shared -nofor-main -Wl,-soname,liblib.so -o liblib.so lib.f90.o

ifx -g -diag-disable:10440 -c main.f90 -o main.f90.o
ifx -g -diag-disable:10440 main.f90.o -o main

I am not exactly sure how the dynamic loader works, I thought that the result would be the same as when dynamically linking the library directly, but it obviously is not. To try your theory, I found the -shared-intel flag, so I retried the build with 

cmake -S . -B build -D CMAKE_BUILD_TYPE=Debug -G 'Unix Makefiles' -D CMAKE_Fortran_COMPILER=ifx -D CMAKE_VERBOSE_MAKEFILE=TRUE -D CMAKE_Fortran_FLAGS=-shared-intel

and that works! Thanks for the help. I guess that I'll need to ship the intel fortran runtime libraries now

View solution in original post

0 Kudos
2 Replies
Steve_Lionel
Honored Contributor III
285 Views

I don't see the actual commands used to build the shared object. The symptom you describe indicates that the .so has its own copy of the Fortran run-time library. I'm not familiar with how this works on Linux - I know you could see this on Windows if the shared library was linked to a static copy of the RTL. It could be that using dlopen doesn't "connect" the main program's reference to the Intel Fortran .so and loads a second copy.

HarmenW
Novice
217 Views

The build commands used by make (added -D CMAKE_VERBOSE_MAKEFILE=TRUE, I removed some system specific paths):

ifx -Dlib_EXPORTS -g -diag-disable:10440 -fPIC -c lib.f90 -o lib.f90.o
ifx -fPIC -g -diag-disable:10440 -shared -nofor-main -Wl,-soname,liblib.so -o liblib.so lib.f90.o

ifx -g -diag-disable:10440 -c main.f90 -o main.f90.o
ifx -g -diag-disable:10440 main.f90.o -o main

I am not exactly sure how the dynamic loader works, I thought that the result would be the same as when dynamically linking the library directly, but it obviously is not. To try your theory, I found the -shared-intel flag, so I retried the build with 

cmake -S . -B build -D CMAKE_BUILD_TYPE=Debug -G 'Unix Makefiles' -D CMAKE_Fortran_COMPILER=ifx -D CMAKE_VERBOSE_MAKEFILE=TRUE -D CMAKE_Fortran_FLAGS=-shared-intel

and that works! Thanks for the help. I guess that I'll need to ship the intel fortran runtime libraries now

0 Kudos
Reply