Coder Social home page Coder Social logo

Name convention for trexio_open about trexio HOT 6 CLOSED

trex-coe avatar trex-coe commented on September 15, 2024
Name convention for trexio_open

from trexio.

Comments (6)

scemama avatar scemama commented on September 15, 2024

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:

  1. In your environment you might have a compilation flag that changes the default behavior of the fortran compiler to make all module functions private
  2. 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.
  3. 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.

stefabat avatar stefabat commented on September 15, 2024

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 or cmake, install it in a local folder
  • Manually copy the compiled trexio.mod file to the include 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.

stefabat avatar stefabat commented on September 15, 2024

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.

scemama avatar scemama commented on September 15, 2024

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 or cmake, install it in a local folder
  • Manually copy the compiled trexio.mod file to the include 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.

scemama avatar scemama commented on September 15, 2024

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.

With the way you are doing things, I would recommend you to either

  1. 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 of libtrexio.so to LD_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
  2. 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.

stefabat avatar stefabat commented on September 15, 2024

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.

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.