Comments (6)
Hi!
I am afraid I don't understand your question.
trexio_open_c
is just the ISO_C_BINDING
of the C function. But as C and Fortran handle strings differently, we created trexio_open
, a fortran-friendly function that avoids the annoyance of handling the null character for C strings in Fortran.
So it makes sense that the function that you should call in Fortran is trexio_open
and not trexio_open_c
.
trexio_open
is not intended to be private: if you use trexio
, you should be able to call trexio_open
.
Does trexio_open
behave as a private function for you? If it does, something is not working as expected. I see 3 possibilities:
- In your environment you might have a compilation flag that changes the default behavior of the fortran compiler to make all module functions private
- In modern Fortran, it is possible that the default behavior has changed, and that you are using a more recent compiler than those we tested.
- You forgot to link the *.o file containing the functions of the trexio module.
If your problem is number 3 (which seems the most probable), a good trick is to create a file trexio_module.F90
inside your code, containing only:
#include <trexio_f.F90>
The F90
with a capital F
extension is a convention to specify that the C preprocessor should be used. It will inline the content of the trexio module located in a standard installation location, just like if the trexio_module.F90
file was a copy of this file.
This trick lets you install trexio in a standard place such as /usr/local
, and not necessarily inside your code. If you later install a more recent version of trexio on your system, then you don't need to do any modification into your source code. This guarantees that the Fortran module you are using when you compile will be consistent with the library with which you link.
So you need to compile the trexio_module.F90
, and the corresponding trexio_module.o
file should contain the trexio_open
function contained in the module. I suspect that you forgot to link the trexio_module.o
.
If this was not the problem:
- Can you show the error message given by your compiler?
- What compiler are you using?
- Can you also try to compile this file with your compiler (outside the CP2K environment) and tell us if it works?
program test_trexio
use trexio
integer (trexio_t) :: trexio_file
integer (trexio_exit_code) :: rc
trexio_file = trexio_open('test_file', 'w', TREXIO_TEXT, rc)
print *, rc
end
if I compile it with gfortran 12 like so:
gfortran /usr/local/include/trexio_f.f90 test_trexio.F90 -ltrexio
I obtain:
$ ./a.out
0
$ ls -tr | tail -1
test_file
from trexio.
Thanks for the comprehensive reply. Here are the steps to reproduce the behavior using gfortran 13.2.1 and hdf5 1.14.3 or 1.14.4 :
- Download the latest release in the tarball and extract it
- Compile according to the instructions using either
./configure
orcmake
, install it in a local folder - Manually copy the compiled
trexio.mod
file to theinclude
directory at the installation path - Compile the program with
gfortran test.F90 -ltrexio -L ../trexio-2.4.2/install/lib -I ../trexio-2.4.2/install/include
Using trexio_open
results in this error:
/usr/bin/ld: /tmp/ccm9WQwX.o: in function `MAIN__':
test.F90:(.text+0x49): undefined reference to `__trexio_MOD_trexio_open'
collect2: error: ld returned 1 exit status
using trexio_open_c
compiles and works.
from trexio.
If instead I do the exact same steps as above, but do not copy the trexio.mod
from the build directory into the install location, and try to compile with gfortran ../trexio-2.4.2/install/include/trexio_f.f90 test.F90 -ltrexio
I get the following error:
/usr/bin/ld: cannot find -ltrexio: No such file or directory
collect2: error: ld returned 1 exit status
Ok, but using also -L ../trexio-2.4.2/install/lib
compiles fine. I see what I was doing wrong.
from trexio.
Thanks for the comprehensive reply. Here are the steps to reproduce the behavior using gfortran 13.2.1 and hdf5 1.14.3 or 1.14.4 :
- Download the latest release in the tarball and extract it
- Compile according to the instructions using either
./configure
orcmake
, install it in a local folder- Manually copy the compiled
trexio.mod
file to theinclude
directory at the installation path- Compile the program with
gfortran test.F90 -ltrexio -L ../trexio-2.4.2/install/lib -I ../trexio-2.4.2/install/include
Using
trexio_open
results in this error:/usr/bin/ld: /tmp/ccm9WQwX.o: in function `MAIN__': test.F90:(.text+0x49): undefined reference to `__trexio_MOD_trexio_open' collect2: error: ld returned 1 exit status
using
trexio_open_c
compiles and works.
Hi!
The reason why trexio_open_c works and not trexio_open is because trexio_open_c is in libtrexio.a or libtrexio.so, that you link.
The mod file does not contain the compiled functions. Your object file for the trexio module is missing.
There is a problem in fortran with module (.mod) files, because they are not standardized. As opposed to object files (.o), you need to have the module file compiled with the same compiler as your code. This is a problem with libraries: suppose you have 2 codes using the same library. Because of the mod file of the library, you would need to have the 2 codes compiled with the same compiler, which is not acceptable. So the common practice is to re-compile the library with different compilers, and use the proper mod file with the code. And when you update your compiler from gfortran 11.2 to gfortran 11.3, you need to rebuild all your libraries because of the module file.
So, in my opinion, module files in Fortran have been very badly designed, and they should be bypassed when developing a library. For example, using HDF5 in Fortran is a pain, unless you use the C variant with your own bindings.
With trexio we try to solve this problem by using a procedure similar to what you would do in C:
- You compile trexio with the compiler of your choice, you get a dynamic and/or static library, and a header file
- You install the library where you want: in a sandard location, or somewhere in your source code tree. For that, you can use
configure --prefix
, as you would do for standard GNU libraries - We provide pkg-config files to help the users of the library know what flags to add to the compiler and linker
- When you compile your code, you just need to include the header file in some Fortran file, or to copy this file in your source code. Because this header has some functions, it will produce an object file. Doing that forces the trexio module to be produced by the exact same compiler as your code at the time you compile your code.
- The trexio.mod file has been built by your own compiling process, so it should be visible by your whole code when you compile
- At link time, you should link the object file containing the functions of the trexio modules. This should be natural because this file is now part of your source code by design (it was included or copied)
- When you link, you only need to link libtrexio.so, which is the C library.
from trexio.
If instead I do the exact same steps as above, but do not copy the
trexio.mod
from the build directory into the install location, and try to compile withgfortran ../trexio-2.4.2/install/include/trexio_f.f90 test.F90 -ltrexio
I get the following error:/usr/bin/ld: cannot find -ltrexio: No such file or directory collect2: error: ld returned 1 exit status
Ok, but using also
-L ../trexio-2.4.2/install/lib
compiles fine. I see what I was doing wrong.
With the way you are doing things, I would recommend you to either
- use the static trexio library: using
../trexio-2.4.2/install/lib/libtrexio.a
instead of
-L ../trexio-2.4.2/install/lib -ltrexio
because otherwise you will need to add the location oflibtrexio.so
toLD_LIBRARY_PATH
when you run your code, or you will need to link your code with-rpath
(see https://medium.com/obscure-system/rpath-vs-runpath-883029b17c45 for more info), or - consider it as an external dependency that users install by themselves, like they would install gzip or MKL.
The advantage of 1 is that it stays in your philosophy of installing dependencies for users and doesn't change your workflow. It is a minimal change.
The advantage of 2 is that if you update TREXIO, you don't need to recompile your code. In addition, all your codes using TREXIO will use the same TREXIO library, which guarantees some homogeneous behavior of the library. If you update the library because of a performance improvement of a bug fix, all your codes will immediately take advantage of it.
You can combine 1 and 2 in CP2K by first checking if trexio is already available. If it is, you just need to include the header and to link with -ltrexio
. If it is not already installed, than you can install it and link it with method 1.
from trexio.
If your problem is number 3 (which seems the most probable), a good trick is to create a file
trexio_module.F90
inside your code, containing only:#include <trexio_f.F90>
The
F90
with a capitalF
extension is a convention to specify that the C preprocessor should be used. It will inline the content of the trexio module located in a standard installation location, just like if thetrexio_module.F90
file was a copy of this file.
I finally went for this design, as I can compile the C library independently, and then the Fortran API is embedded in the source code of the project without explicitly copying any file into the source tree.
from trexio.
Related Issues (20)
- pkg-config is broken after HDF5 detection rewriting
- External group HOT 2
- Loss of precision in Python HOT 3
- Versioning of python packages HOT 2
- pip installation without HDF5 installed. HOT 12
- trexio --without-hdf5 needs hdf5 HOT 3
- Multidimensional lists not flatten correctly in Python front end HOT 3
- `TREXIO` group indirection in HDF5 backend HOT 1
- Add the ability to read arbitrary hyper-rectangles of dense arrays
- MacOS ARM64 runners HOT 4
- MO-coefficients get mangled when written and read again HOT 2
- Import only used variables and procedures HOT 4
- Static and dynamic library compilation with cmake result in static library only HOT 7
- Fortran interface to write reciprocal lattice vectors is broken HOT 4
- Generally contracted basis sets and number of primitives HOT 1
- Partial ECPs HOT 3
- Installation on aarch64 (13.2.1 and M2) HOT 3
- Test TREXIO Python API with Numpy 2.0
- Python TREXIO HDF5 HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from trexio.