1
0
mirror of https://github.com/TREX-CoE/trexio.git synced 2024-07-22 18:57:39 +02:00

Merge pull request #33 from TREX-CoE/fortran-interface-1

basic Fortran interface
This commit is contained in:
Evgeny Posenitskiy 2021-03-25 11:44:58 +01:00 committed by GitHub
commit 1feb3a6595
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 265 additions and 26 deletions

6
src/.gitignore vendored
View File

@ -1,5 +1,6 @@
templates_front/*.c
templates_front/*.h
templates_front/*.f90
templates_front/populated/
templates_hdf5/*.c
@ -16,8 +17,11 @@ libtrexio.so
trexio.c
trexio_text.c
trexio_hdf5.c
trexio_f.f90
trexio.mod
test
test_write.h5
test_f
*.h5
trexio_test/

View File

@ -6,7 +6,10 @@ ifeq ($(COMPILER),GNU)
CC=gcc -g
CFLAGS=-fPIC -fexceptions -Wall -Werror -Wpedantic -Wextra
LIBS= -L/usr/lib/x86_64-linux-gnu/hdf5/serial/ -lz -lm -lhdf5 -lhdf5_hl #-lgfortran
FS=gfortran -g
FFLAGS=-fPIC -fcheck=all -Waliasing -Wampersand -Wconversion -Wsurprising -Wintrinsics-std -Wno-tabs -Wintrinsic-shadow -Wline-truncation -Wreal-q-constant -Wuninitialized -fbacktrace -ffpe-trap=zero,overflow,underflow -finit-real=nan
LIBS= -L/usr/lib/x86_64-linux-gnu/hdf5/serial/ -lz -lm -lhdf5 -lhdf5_hl -lgfortran
INCLUDE = -I/usr/include/hdf5/serial
endif
@ -31,23 +34,36 @@ FFLAGS=fPIC -g -O2
LIBS=-lm
endif
RM=rm -f
OBJECT_FILES= trexio.o trexio_text.o trexio_hdf5.o
HEADER_FILES= trexio.h trexio_text.h trexio_hdf5.h trexio_s.h
export CC CFLAGS LIBS
export CC CFLAGS FC FFLAGS LIBS
.PHONY: clean
libtrexio.so: $(OBJECT_FILES) $(HEADER_FILES)
$(CC) -shared $(OBJECT_FILES) -o libtrexio.so
test: libtrexio.so test.c
$(CC) $(CFLAGS) $(INCLUDE) -Wl,-rpath,$(PWD) -L. test.c -ltrexio $(LIBS) -o test
fortran: libtrexio.so trexio_f.f90
$(FC) $(FFLAGS) -c trexio_f.f90 -o trexio_f.o
test_c: libtrexio.so test.c
$(CC) $(CFLAGS) $(INCLUDE) -Wl,-rpath,$(PWD) -L. test.c -ltrexio $(LIBS) -o test_c
test_f: libtrexio.so test.f90 trexio_f.o
$(CC) $(CFLAGS) $(INCLUDE) -Wl,-rpath,$(PWD) -L. test.f90 trexio_f.o -ltrexio $(LIBS) -o test_f
test: test_c test_f
$(RM) -r trexio_test
$(RM) -r trexio_test_fort
./test_c
./test_f
clean:
rm -f *.o libtrexio.so test test_*.h5
rm -r trexio_test/
$(RM) *.o libtrexio.so test_*.h5 test_f test_c
$(RM) -r trexio_test/ trexio_test_fort/
%.o: %.c $(HEADER_FILES)
$(CC) $(CFLAGS) $(INCLUDE) -c $*.c -o $*.o

View File

@ -17,7 +17,7 @@ mkdir -p templates_hdf5/populated
# not options. It is safer.
echo "remove existing templates"
rm -f -- templates_front/*.{c,h}
rm -f -- templates_front/*.{c,h,f90}
rm -f -- templates_text/*.{c,h}
rm -f -- templates_hdf5/*.{c,h}

View File

@ -82,6 +82,7 @@ templ_path_front = join(fileDir,'templates_front')
files_exclude = ['prefix_hdf5.c', 'prefix_hdf5.h', 'suffix_hdf5.h',
'prefix_text.c', 'prefix_text.h', 'suffix_text.h',
'prefix_front.c', 'prefix_front.h', 'suffix_front.h',
'prefix_fortran.f90', 'suffix_fortran.f90',
'prefix_s_front.h', 'suffix_s_front.h',
'templator_front.org', 'templator_hdf5.org', 'templator_text.org']
@ -259,12 +260,16 @@ for fname in files_funcs_dsets:
if params['dtype'] == 'double':
h5_dtype = 'double'
f_dtype = 'real(8)'
elif params['dtype'] == 'int64_t':
h5_dtype = 'long'
f_dtype = 'integer(8)'
templine1 = templine2.replace('$group_dset_h5_dtype$', h5_dtype)
templine2 = templine1.replace('$group_dset_h5_dtype$'.upper(), h5_dtype.upper())
templine1 = templine2.replace('$group_dset_f_dtype$', f_dtype)
templine2 = templine1.replace('$group_dset_f_dtype$'.upper(), f_dtype.upper())
templine1 = templine2.replace('$group_dset_rank$', str(params['rank']))
templine2 = templine1

View File

@ -1,15 +1,20 @@
#!/bin/bash
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
# prefixes
cat prefix_front.c > trexio.c
cat prefix_front.h > trexio.h
cat prefix_s_front.h > trexio_s.h
cat prefix_fortran.f90 > trexio_f.f90
cat $DIR/prefix_front.c > trexio.c
cat $DIR/prefix_front.h > trexio.h
cat $DIR/prefix_s_front.h > trexio_s.h
# c front end
cat populated/pop_*.c >> trexio.c
cat populated/pop_*.h >> trexio.h
cat $DIR/populated/pop_*.c >> trexio.c
cat $DIR/populated/pop_*.h >> trexio.h
cat $DIR/suffix_s_front.h >> trexio_s.h
cat $DIR/suffix_front.h >> trexio.h
# fortran front end
cat populated/pop_*.f90 >> trexio_f.f90
# suffixes
cat suffix_s_front.h >> trexio_s.h
cat suffix_front.h >> trexio.h
cat suffix_fortran.f90 >> trexio_f.f90

View File

@ -2,17 +2,29 @@
* Constant file prefixes (not used by generator) :noxport:
** Prefixes
#+NAME:header
#+begin_src c
/* This file was generated from the trexio.org org-mode file.
/* This file was generated from the templator_front.org org-mode file.
To generate it, open trexio.org in Emacs and execute
M-x org-babel-tangle
*/
#+end_src
#+begin_src fortran :tangle prefix_fortran.f90 :noweb yes
module trexio
use, intrinsic :: iso_c_binding
implicit none
integer, parameter :: TREXIO_HDF5 = 0
integer, parameter :: TREXIO_TEXT = 1
! integer, parameter :: TREXIO_JSON = 2
integer, parameter :: TREXIO_INVALID_BACK_END = 3
#+end_src
#+begin_src c :tangle prefix_front.h :noweb yes
<<header>>
#ifndef _TREXIO_H
@ -80,6 +92,7 @@
#define FREE(X) { free(X) ; (X)=NULL; }
#+end_src
* Front end
All calls to TREXIO are thread-safe.
@ -280,6 +293,17 @@ trexio_t* trexio_open(const char* file_name, const char mode, const back_end_t b
}
#+end_src
#+begin_src fortran :tangle prefix_fortran.f90
interface
integer(8) function trexio_open_c (filename, mode, backend) bind(C, name="trexio_open")
use, intrinsic :: iso_c_binding
character(kind=c_char), dimension(*) :: filename
character, intent(in), value :: mode
integer, intent(in), value :: backend
end function trexio_open_c
end interface
#+end_src
** File closing
#+begin_src c :tangle prefix_front.h
@ -354,9 +378,16 @@ trexio_exit_code trexio_close(trexio_t* file) {
}
#+end_src
#+begin_src fortran :tangle prefix_fortran.f90
interface
integer function trexio_close (trex_file) bind(C)
use, intrinsic :: iso_c_binding
integer(8), intent(in), value :: trex_file
end function trexio_close
end interface
#+end_src
* Templates for front end
** Template for frontend read/write a number
#+begin_src c :tangle rw_num_front.h
@ -424,6 +455,32 @@ trexio_exit_code trexio_write_$group_num$(trexio_t* file, const int64_t num) {
#+end_src
#+begin_src fortran :tangle write_num_front_fortran.f90
interface
integer function trexio_write_$group_num$ (trex_file, num) bind(C)
use, intrinsic :: iso_c_binding
integer(8), intent(in), value :: trex_file
integer(8), intent(in), value :: num
end function trexio_write_$group_num$
end interface
#+end_src
#+begin_src fortran :tangle read_num_front_fortran.f90
interface
integer function trexio_read_$group_num$ (trex_file, num) bind(C)
use, intrinsic :: iso_c_binding
integer(8), intent(in), value :: trex_file
integer(8), intent(out) :: num
end function trexio_read_$group_num$
end interface
#+end_src
** Template for frontend read/write a dataset
#+begin_src c :tangle rw_dset_front.h
@ -532,6 +589,29 @@ trexio_exit_code trexio_write_$group$_$group_dset$(trexio_t* file, const $group_
}
#+end_src
#+begin_src fortran :tangle write_dset_front_fortran.f90
interface
integer function trexio_write_$group$_$group_dset$ (trex_file, dset) bind(C)
use, intrinsic :: iso_c_binding
integer(8), intent(in), value :: trex_file
$group_dset_f_dtype$, intent(in) :: dset(*)
end function trexio_write_$group$_$group_dset$
end interface
#+end_src
#+begin_src fortran :tangle read_dset_front_fortran.f90
interface
integer function trexio_read_$group$_$group_dset$ (trex_file, dset) bind(C)
use, intrinsic :: iso_c_binding
integer(8), intent(in), value :: trex_file
$group_dset_f_dtype$, intent(out) :: dset(*)
end function trexio_read_$group$_$group_dset$
end interface
#+end_src
* Back ends
@ -541,6 +621,25 @@ trexio_exit_code trexio_write_$group$_$group_dset$(trexio_t* file, const $group_
- Text files: not to be used for production, but useful for debugging
- JSON: for portability
* Fortran helper/wrapper functions
#+begin_src fortran :tangle suffix_fortran.f90
contains
integer(8) function trexio_open (filename, mode, backend)
use, intrinsic :: iso_c_binding
implicit none
character(len=*) :: filename
character, intent(in), value :: mode
integer, intent(in), value :: backend
character(len=len_trim(filename)+1) :: filename_c
filename_c = trim(filename) // c_null_char
trexio_open = trexio_open_c(filename_c, mode, backend)
end function trexio_open
#+end_src
* File suffixes :noxport:
#+begin_src c :tangle suffix_front.h
@ -551,5 +650,9 @@ trexio_exit_code trexio_write_$group$_$group_dset$(trexio_t* file, const $group_
#endif
#+end_src
#+begin_src fortran :tangle suffix_fortran.f90
end module trexio
#+end_src

View File

@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
cat prefix_hdf5.c > trexio_hdf5.c
cat prefix_hdf5.h > trexio_hdf5.h

View File

@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
cat prefix_text.c > trexio_text.c
cat prefix_text.h > trexio_text.h

106
src/test.f90 Normal file
View File

@ -0,0 +1,106 @@
program test_trexio
call test_write()
call test_read()
end program test_trexio
subroutine test_write()
use trexio
use, intrinsic :: iso_c_binding
implicit none
integer(8) :: trex_file
integer :: rc = 1
integer(8) :: num
double precision :: charge(12)
double precision :: coord(36)
num = 12
charge = (/6., 6., 6., 6., 6., 6., 1., 1., 1., 1., 1., 1. /)
coord = (/ 0.00000000 , 1.39250319 , 0.00000000 , &
-1.20594314 , 0.69625160 , 0.00000000 , &
-1.20594314 , -0.69625160 , 0.00000000 , &
0.00000000 , -1.39250319 , 0.00000000 , &
1.20594314 , -0.69625160 , 0.00000000 , &
1.20594314 , 0.69625160 , 0.00000000 , &
-2.14171677 , 1.23652075 , 0.00000000 , &
-2.14171677 , -1.23652075 , 0.00000000 , &
0.00000000 , -2.47304151 , 0.00000000 , &
2.14171677 , -1.23652075 , 0.00000000 , &
2.14171677 , 1.23652075 , 0.00000000 , &
0.00000000 , 2.47304151 , 0.00000000 /)
! trex_file = trexio_open('trexio_test_fort', 'w', TREXIO_TEXT)
trex_file = trexio_open('test_hdf5_fort.h5', 'w', TREXIO_HDF5)
rc = trexio_write_nucleus_num(trex_file, num)
if (rc == 0) write(*,*) 'SUCCESS WRITE NUM'
rc = trexio_write_nucleus_charge(trex_file, charge)
if (rc == 0) write(*,*) 'SUCCESS WRITE CHARGE'
rc = trexio_write_nucleus_coord(trex_file, coord)
if (rc == 0) write(*,*) 'SUCCESS WRITE COORD'
rc = trexio_close(trex_file)
if (rc == 0) write(*,*) 'SUCCESS CLOSE'
! ---------------------------------- !
! to modify fiels of existing file:
! text backend -> open with 'w'
! hdf5 backend -> open with 'a'
! ---------------------------------- !
!! trex_file = trexio_open('trexio_test_fort', 'w', TREXIO_TEXT);
!! trex_file = trexio_open('test_hdf5_fort.h5', 'a', TREXIO_HDF5)
! coord(1) = 666.666
! rc = trexio_write_nucleus_coord(trex_file,coord)
! if (rc == 0) write(*,*) 'SUCCESS MODIFY COORD'
! rc = trexio_close(trex_file)
! if (rc == 0) write(*,*) 'SUCCESS CLOSE'
end subroutine test_write
subroutine test_read()
use trexio
use, intrinsic :: iso_c_binding
implicit none
integer(8) :: trex_file
integer :: rc = 1
integer(8) :: num, num_read
double precision :: charge(12)
double precision :: coord(36)
num = 12
! trex_file = trexio_open('trexio_test_fort', 'r', TREXIO_TEXT)
trex_file = trexio_open('test_hdf5_fort.h5', 'r', TREXIO_HDF5)
rc = trexio_read_nucleus_num(trex_file, num_read)
if (rc == 0 .and. num_read == num) write(*,*) 'SUCCESS READ NUM'
rc = trexio_read_nucleus_charge(trex_file, charge)
if (rc == 0 .and. (abs (charge(11) - 1.0) < 1.0D-8) ) write(*,*) 'SUCCESS READ CHARGE'
rc = trexio_read_nucleus_coord(trex_file, coord)
if (rc == 0 .and. (abs (coord(2) - 1.39250319) < 1.0D-8) ) write(*,*) 'SUCCESS READ COORD'
rc = trexio_close(trex_file)
if (rc == 0) write(*,*) 'SUCCESS CLOSE'
end subroutine test_read