mirror of
https://github.com/TREX-CoE/trexio.git
synced 2025-01-03 10:06:01 +01:00
add top-level read/write functions for string arrays [fortran]
This commit is contained in:
parent
eadc2c63ac
commit
b92a15cce7
1
src/.gitignore
vendored
1
src/.gitignore
vendored
@ -1,6 +1,7 @@
|
|||||||
templates_front/*.c
|
templates_front/*.c
|
||||||
templates_front/*.h
|
templates_front/*.h
|
||||||
templates_front/*.f90
|
templates_front/*.f90
|
||||||
|
templates_front/*.fh_90
|
||||||
templates_front/*.dump
|
templates_front/*.dump
|
||||||
templates_front/populated/
|
templates_front/populated/
|
||||||
|
|
||||||
|
@ -12,6 +12,9 @@ cat populated/pop_*.h >> trexio.h
|
|||||||
|
|
||||||
# fortran front end
|
# fortran front end
|
||||||
cat populated/pop_*.f90 >> trexio_f.f90
|
cat populated/pop_*.f90 >> trexio_f.f90
|
||||||
|
# add helper functions
|
||||||
|
cat helper_fortran.f90 >> trexio_f.f90
|
||||||
|
cat populated/pop_*.fh_90 >> trexio_f.f90
|
||||||
|
|
||||||
# suffixes
|
# suffixes
|
||||||
cat suffix_s_front.h >> trexio_s.h
|
cat suffix_s_front.h >> trexio_s.h
|
||||||
|
@ -1762,23 +1762,23 @@ trexio_has_$group_dset$ (trexio_t* const file)
|
|||||||
|
|
||||||
#+begin_src f90 :tangle write_dset_str_front_fortran.f90
|
#+begin_src f90 :tangle write_dset_str_front_fortran.f90
|
||||||
interface
|
interface
|
||||||
integer function trexio_write_$group_dset$ (trex_file, dset, max_str_len) bind(C, name="trexio_write_$group_dset$_low")
|
integer function trexio_write_$group_dset$_low (trex_file, dset, max_str_len) bind(C)
|
||||||
use, intrinsic :: iso_c_binding
|
use, intrinsic :: iso_c_binding
|
||||||
integer(8), intent(in), value :: trex_file
|
integer(8), intent(in), value :: trex_file
|
||||||
character, intent(in) :: dset(*)
|
character, intent(in) :: dset(*)
|
||||||
integer(4), intent(in), value :: max_str_len
|
integer(4), intent(in), value :: max_str_len
|
||||||
end function trexio_write_$group_dset$
|
end function trexio_write_$group_dset$_low
|
||||||
end interface
|
end interface
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src f90 :tangle read_dset_str_front_fortran.f90
|
#+begin_src f90 :tangle read_dset_str_front_fortran.f90
|
||||||
interface
|
interface
|
||||||
integer function trexio_read_$group_dset$ (trex_file, dset, max_str_len) bind(C, name="trexio_read_$group_dset$_low")
|
integer function trexio_read_$group_dset$_low (trex_file, dset, max_str_len) bind(C)
|
||||||
use, intrinsic :: iso_c_binding
|
use, intrinsic :: iso_c_binding
|
||||||
integer(8), intent(in), value :: trex_file
|
integer(8), intent(in), value :: trex_file
|
||||||
character, intent(out) :: dset(*)
|
character, intent(out) :: dset(*)
|
||||||
integer(4), intent(in), value :: max_str_len
|
integer(4), intent(in), value :: max_str_len
|
||||||
end function trexio_read_$group_dset$
|
end function trexio_read_$group_dset$_low
|
||||||
end interface
|
end interface
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
@ -1791,6 +1791,59 @@ interface
|
|||||||
end interface
|
end interface
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src f90 :tangle helper_read_dset_str_front_fortran.fh_90
|
||||||
|
integer function trexio_read_$group_dset$ (trex_file, dset, max_str_len)
|
||||||
|
use, intrinsic :: iso_c_binding
|
||||||
|
implicit none
|
||||||
|
integer(8), intent(in), value :: trex_file
|
||||||
|
integer(4), intent(in), value :: max_str_len
|
||||||
|
character(len=*), intent(inout) :: dset(*)
|
||||||
|
|
||||||
|
character, allocatable :: str_compiled(:)
|
||||||
|
integer(8) :: $group_dset_dim$
|
||||||
|
integer :: rc
|
||||||
|
|
||||||
|
rc = trexio_read_$group_dset_dim$_64(trex_file, $group_dset_dim$)
|
||||||
|
if (rc /= TREXIO_SUCCESS) trexio_read_$group_dset$ = rc
|
||||||
|
|
||||||
|
allocate(str_compiled($group_dset_dim$*(max_str_len+1)+1))
|
||||||
|
|
||||||
|
rc = trexio_read_$group_dset$_low(trex_file, str_compiled, max_str_len)
|
||||||
|
if (rc /= TREXIO_SUCCESS) then
|
||||||
|
deallocate(str_compiled)
|
||||||
|
trexio_read_$group_dset$ = rc
|
||||||
|
else
|
||||||
|
call trexio_str2strarray(str_compiled, $group_dset_dim$, max_str_len, dset)
|
||||||
|
deallocate(str_compiled)
|
||||||
|
trexio_read_$group_dset$ = TREXIO_SUCCESS
|
||||||
|
endif
|
||||||
|
|
||||||
|
end function trexio_read_$group_dset$
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src f90 :tangle helper_write_dset_str_front_fortran.fh_90
|
||||||
|
integer function trexio_write_$group_dset$ (trex_file, dset, max_str_len)
|
||||||
|
use, intrinsic :: iso_c_binding
|
||||||
|
implicit none
|
||||||
|
integer(8), intent(in), value :: trex_file
|
||||||
|
integer(4), intent(in), value :: max_str_len
|
||||||
|
character(len=*), intent(in) :: dset(*)
|
||||||
|
|
||||||
|
character(len=:), allocatable :: str_compiled
|
||||||
|
integer(8) :: $group_dset_dim$
|
||||||
|
integer :: rc
|
||||||
|
|
||||||
|
rc = trexio_read_$group_dset_dim$_64(trex_file, $group_dset_dim$)
|
||||||
|
if (rc /= TREXIO_SUCCESS) then
|
||||||
|
trexio_write_$group_dset$ = rc
|
||||||
|
else
|
||||||
|
call trexio_strarray2str(dset, $group_dset_dim$, max_str_len, str_compiled)
|
||||||
|
trexio_write_$group_dset$ = trexio_write_$group_dset$_low(trex_file, str_compiled, max_str_len)
|
||||||
|
endif
|
||||||
|
|
||||||
|
end function trexio_write_$group_dset$
|
||||||
|
#+end_src
|
||||||
|
|
||||||
** Templates for front end has/read/write a single string attribute
|
** Templates for front end has/read/write a single string attribute
|
||||||
*** Introduction
|
*** Introduction
|
||||||
|
|
||||||
@ -1945,7 +1998,7 @@ end interface
|
|||||||
unlike strings in Fortran.
|
unlike strings in Fortran.
|
||||||
Note, that Fortran interface calls the main ~TREXIO~ API, which is written in C.
|
Note, that Fortran interface calls the main ~TREXIO~ API, which is written in C.
|
||||||
|
|
||||||
#+begin_src f90 :tangle suffix_fortran.f90
|
#+begin_src f90 :tangle helper_fortran.f90
|
||||||
contains
|
contains
|
||||||
integer(8) function trexio_open (filename, mode, backend)
|
integer(8) function trexio_open (filename, mode, backend)
|
||||||
use, intrinsic :: iso_c_binding
|
use, intrinsic :: iso_c_binding
|
||||||
@ -1964,14 +2017,14 @@ contains
|
|||||||
as a delimeter and adds ~NULL~ character in the end in order to properly pass the desired string to
|
as a delimeter and adds ~NULL~ character in the end in order to properly pass the desired string to
|
||||||
C API. This is needed due to the fact that strings in C are terminated by ~NULL~ character ~\0~.
|
C API. This is needed due to the fact that strings in C are terminated by ~NULL~ character ~\0~.
|
||||||
|
|
||||||
#+begin_src f90 :tangle suffix_fortran.f90
|
#+begin_src f90 :tangle helper_fortran.f90
|
||||||
subroutine trexio_strarray2str(str_array, max_num_str, max_len_str, str_res)
|
subroutine trexio_strarray2str(str_array, max_num_str, max_len_str, str_res)
|
||||||
use, intrinsic :: iso_c_binding, only : c_null_char
|
use, intrinsic :: iso_c_binding, only : c_null_char
|
||||||
implicit none
|
implicit none
|
||||||
|
|
||||||
integer, intent(in), value :: max_num_str ! number of elements in strign array
|
integer(8), intent(in), value :: max_num_str ! number of elements in strign array
|
||||||
integer, intent(in), value :: max_len_str ! maximum length of a string in an array
|
integer, intent(in), value :: max_len_str ! maximum length of a string in an array
|
||||||
character(len=max_len_str), intent(in) :: str_array(*)
|
character(len=*), intent(in) :: str_array(*)
|
||||||
character(len=:), allocatable, intent(out) :: str_res
|
character(len=:), allocatable, intent(out) :: str_res
|
||||||
integer :: i
|
integer :: i
|
||||||
|
|
||||||
@ -1984,11 +2037,51 @@ contains
|
|||||||
end subroutine trexio_strarray2str
|
end subroutine trexio_strarray2str
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
The subroutine below does the reverse tranformation from one big string with delimeters into an array of Fortran strings.
|
||||||
|
|
||||||
|
#+begin_src f90 :tangle helper_fortran.f90
|
||||||
|
subroutine trexio_str2strarray(str_flat, max_num_str, max_len_str, str_array)
|
||||||
|
use, intrinsic :: iso_c_binding, only : c_null_char
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
integer(8), intent(in), value :: max_num_str ! number of elements in strign array
|
||||||
|
integer, intent(in), value :: max_len_str ! maximum length of a string in an array
|
||||||
|
character, intent(in) :: str_flat(*)
|
||||||
|
character(len=*), intent(inout) :: str_array(*)
|
||||||
|
|
||||||
|
character(len=max_len_str) :: tmp_str
|
||||||
|
integer :: i, j, k, ind, offset
|
||||||
|
integer(8) :: len_flat
|
||||||
|
|
||||||
|
len_flat = (max_len_str+1)*max_num_str + 1
|
||||||
|
|
||||||
|
ind=1
|
||||||
|
offset=1
|
||||||
|
do i=1,max_num_str
|
||||||
|
k = 1
|
||||||
|
tmp_str=''
|
||||||
|
do j=ind,len_flat
|
||||||
|
if ( str_flat(j)==TREXIO_DELIM ) then
|
||||||
|
ind=j+1
|
||||||
|
exit
|
||||||
|
endif
|
||||||
|
tmp_str(k:k) = str_flat(j)
|
||||||
|
k = k + 1
|
||||||
|
enddo
|
||||||
|
str_array(i)=tmp_str
|
||||||
|
!write(*,*) str_array(i)
|
||||||
|
offset=ind
|
||||||
|
enddo
|
||||||
|
|
||||||
|
end subroutine trexio_str2strarray
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
|
||||||
The subroutine is a Fortran analogue of ~assert~ in C. It check that the the return code of the
|
The subroutine is a Fortran analogue of ~assert~ in C. It check that the the return code of the
|
||||||
TREXIO API call is equal to a given return code. It can optionally print a success message if the
|
TREXIO API call is equal to a given return code. It can optionally print a success message if the
|
||||||
two code are identical, i.e. if the ~assert~ statement pass.
|
two code are identical, i.e. if the ~assert~ statement pass.
|
||||||
|
|
||||||
#+begin_src f90 :tangle suffix_fortran.f90
|
#+begin_src f90 :tangle helper_fortran.f90
|
||||||
subroutine trexio_assert(trexio_rc, check_rc, success_message)
|
subroutine trexio_assert(trexio_rc, check_rc, success_message)
|
||||||
implicit none
|
implicit none
|
||||||
|
|
||||||
|
@ -16,14 +16,14 @@ int main() {
|
|||||||
assert (rc == 0);
|
assert (rc == 0);
|
||||||
test_write("test_write.h5", TREXIO_HDF5);
|
test_write("test_write.h5", TREXIO_HDF5);
|
||||||
test_read ("test_write.h5", TREXIO_HDF5);
|
test_read ("test_write.h5", TREXIO_HDF5);
|
||||||
// rc = system("rm -rf test_write.h5");
|
rc = system("rm -rf test_write.h5");
|
||||||
assert (rc == 0);
|
assert (rc == 0);
|
||||||
|
|
||||||
rc = system("rm -rf test_write.dir");
|
rc = system("rm -rf test_write.dir");
|
||||||
assert (rc == 0);
|
assert (rc == 0);
|
||||||
test_write("test_write.dir", TREXIO_TEXT);
|
test_write("test_write.dir", TREXIO_TEXT);
|
||||||
test_read ("test_write.dir", TREXIO_TEXT);
|
test_read ("test_write.dir", TREXIO_TEXT);
|
||||||
// rc = system("rm -rf test_write.dir");
|
rc = system("rm -rf test_write.dir");
|
||||||
assert (rc == 0);
|
assert (rc == 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -38,9 +38,8 @@ subroutine test_write(file_name, back_end)
|
|||||||
double precision :: charge(12)
|
double precision :: charge(12)
|
||||||
double precision :: coord(3,12)
|
double precision :: coord(3,12)
|
||||||
|
|
||||||
character(len=:), allocatable :: label_str
|
|
||||||
character(len=:), allocatable :: sym_str
|
character(len=:), allocatable :: sym_str
|
||||||
character(len=4):: label(12)
|
character(len=:), allocatable :: label(:)
|
||||||
|
|
||||||
! parameters to be written
|
! parameters to be written
|
||||||
num = 12
|
num = 12
|
||||||
@ -61,8 +60,6 @@ subroutine test_write(file_name, back_end)
|
|||||||
|
|
||||||
label = [character(len=8) :: 'C', 'Na','C', 'C 66', 'C','C', 'H 99', 'Ru', 'H', 'H', 'H', 'H' ]
|
label = [character(len=8) :: 'C', 'Na','C', 'C 66', 'C','C', 'H 99', 'Ru', 'H', 'H', 'H', 'H' ]
|
||||||
|
|
||||||
call trexio_strarray2str(label, num, 4, label_str)
|
|
||||||
|
|
||||||
sym_str = 'B3U with some comments' // c_null_char
|
sym_str = 'B3U with some comments' // c_null_char
|
||||||
|
|
||||||
! ================= START OF TEST ===================== !
|
! ================= START OF TEST ===================== !
|
||||||
@ -84,8 +81,7 @@ subroutine test_write(file_name, back_end)
|
|||||||
rc = trexio_write_nucleus_coord(trex_file, coord)
|
rc = trexio_write_nucleus_coord(trex_file, coord)
|
||||||
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS WRITE COORD')
|
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS WRITE COORD')
|
||||||
|
|
||||||
rc = trexio_write_nucleus_label(trex_file, label_str, 5)
|
rc = trexio_write_nucleus_label(trex_file, label, 5)
|
||||||
deallocate(label_str)
|
|
||||||
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS WRITE LABEL')
|
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS WRITE LABEL')
|
||||||
|
|
||||||
rc = trexio_write_nucleus_point_group(trex_file, sym_str, 32)
|
rc = trexio_write_nucleus_point_group(trex_file, sym_str, 32)
|
||||||
@ -127,7 +123,7 @@ subroutine test_read(file_name, back_end)
|
|||||||
|
|
||||||
character :: label_str(128)
|
character :: label_str(128)
|
||||||
character(len=4) :: tmp_str
|
character(len=4) :: tmp_str
|
||||||
character(len=4) :: label(12)
|
character(len=4) :: label(12) ! also works with allocatable arrays
|
||||||
|
|
||||||
character(len=32) :: sym_str
|
character(len=32) :: sym_str
|
||||||
|
|
||||||
@ -170,30 +166,8 @@ subroutine test_read(file_name, back_end)
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
rc = trexio_read_nucleus_label(trex_file, label_str, 2)
|
rc = trexio_read_nucleus_label(trex_file, label, 2)
|
||||||
call trexio_assert(rc, TREXIO_SUCCESS)
|
call trexio_assert(rc, TREXIO_SUCCESS)
|
||||||
! --------------------------------------------------
|
|
||||||
! dummy parser of big string with TREXIO_DELIM delimeters
|
|
||||||
! --------------------------------------------------
|
|
||||||
ind=1
|
|
||||||
offset=1
|
|
||||||
do i=1,num
|
|
||||||
k = 1
|
|
||||||
tmp_str=''
|
|
||||||
do j=ind,128
|
|
||||||
|
|
||||||
if ( (label_str(j)==TREXIO_DELIM) ) then
|
|
||||||
ind=j+1
|
|
||||||
exit
|
|
||||||
endif
|
|
||||||
tmp_str(k:k) = label_str(j)
|
|
||||||
k = k + 1
|
|
||||||
enddo
|
|
||||||
label(i)=tmp_str
|
|
||||||
write(*,*) label(i)
|
|
||||||
offset=ind
|
|
||||||
enddo
|
|
||||||
! --------------------------------------------------
|
|
||||||
if (trim(label(2)) == 'Na') then
|
if (trim(label(2)) == 'Na') then
|
||||||
write(*,*) 'SUCCESS READ LABEL'
|
write(*,*) 'SUCCESS READ LABEL'
|
||||||
else
|
else
|
||||||
|
@ -119,7 +119,7 @@ def recursive_populate_file(fname: str, paths: dict, detailed_source: dict) -> N
|
|||||||
if not dim.isdigit() and not dim in num_written:
|
if not dim.isdigit() and not dim in num_written:
|
||||||
num_written.append(dim)
|
num_written.append(dim)
|
||||||
templine = line.replace('$group_dset_dim$', dim)
|
templine = line.replace('$group_dset_dim$', dim)
|
||||||
if '_read' in templine:
|
if '_read' in templine and (not 'fortran' in fname):
|
||||||
line_toadd = indentlevel*" " + rc_line
|
line_toadd = indentlevel*" " + rc_line
|
||||||
templine += line_toadd
|
templine += line_toadd
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user