mirror of
https://github.com/TREX-CoE/trexio.git
synced 2024-08-25 06:31:43 +02:00
Merge pull request #50 from TREX-CoE/add-strings
Add strings functionality
This commit is contained in:
commit
aac439803f
11
.gitignore
vendored
11
.gitignore
vendored
@ -12,6 +12,8 @@ config.log
|
||||
config.status
|
||||
config.sub
|
||||
configure
|
||||
config.h.in
|
||||
config.h
|
||||
depcomp
|
||||
include/config.h.in
|
||||
include/stamp-h1
|
||||
@ -19,10 +21,15 @@ install-sh
|
||||
libtool
|
||||
ltmain.sh
|
||||
ltximg/
|
||||
Makefile
|
||||
missing
|
||||
Makefile
|
||||
Makefile.in
|
||||
pkgconfig/trexio.pc
|
||||
test_write.h5
|
||||
trexio.pc
|
||||
trexio.mod
|
||||
test-driver
|
||||
test-suite.log
|
||||
*.h5
|
||||
trexio-*.tar.gz
|
||||
|
||||
|
||||
|
@ -91,7 +91,7 @@ $(test_trexio_f): $(trexio_f)
|
||||
cp $(trexio_f) $(test_trexio_f)
|
||||
|
||||
clean-local:
|
||||
-rm -rf -- test_write.dir/ test_write_f.dir/ test_write.h5
|
||||
-rm -rf -- test_write.dir/ test_write_f.dir/ test_write.h5 test_write_f.h5
|
||||
|
||||
if TREXIO_DEVEL
|
||||
|
||||
|
@ -21,7 +21,6 @@ AC_SUBST([VERSION_MINOR])
|
||||
AC_SUBST([VERSION_PATCH])
|
||||
|
||||
|
||||
|
||||
## -------------------
|
||||
## Checks for programs
|
||||
## -------------------
|
||||
@ -88,8 +87,7 @@ CPPFLAGS="${HDF5_CPPFLAGS} ${CPPFLAGS}"
|
||||
LDFLAGS="${HDF5_LDFLAGS} ${LDFLAGS}"
|
||||
LIBS="${HDF5_LIBS} ${LIBS}"
|
||||
|
||||
|
||||
# Check if hdf5 if available with pkg-config
|
||||
# Check if HDF5 if available with pkg-config
|
||||
|
||||
PKG_CHECK_MODULES([HDF5], [hdf5 >= 1.8], [
|
||||
PKG_HDF5="hdf5"
|
||||
@ -169,7 +167,8 @@ LDFLAGS .......: ${LDFLAGS}
|
||||
LIBS ..........: ${LIBS}
|
||||
|
||||
Package features:
|
||||
Compilation with HDF5: ${with_hdf5}
|
||||
Compilation with HDF5...: ${with_hdf5}
|
||||
HDF5 version............: ${HDF5_VERSION}
|
||||
|
||||
Now type 'make @<:@<target>@:>@'
|
||||
where the optional <target> is:
|
||||
|
1
src/.gitignore
vendored
1
src/.gitignore
vendored
@ -1,6 +1,7 @@
|
||||
templates_front/*.c
|
||||
templates_front/*.h
|
||||
templates_front/*.f90
|
||||
templates_front/*.fh_90
|
||||
templates_front/*.dump
|
||||
templates_front/populated/
|
||||
|
||||
|
@ -12,6 +12,9 @@ cat populated/pop_*.h >> trexio.h
|
||||
|
||||
# fortran front end
|
||||
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
|
||||
cat suffix_s_front.h >> trexio_s.h
|
||||
|
@ -31,6 +31,8 @@ module trexio
|
||||
integer(trexio_backend), parameter :: TREXIO_TEXT = 1
|
||||
! integer(trexio_backend), parameter :: TREXIO_JSON = 2
|
||||
integer(trexio_backend), parameter :: TREXIO_INVALID_BACK_END = 2
|
||||
|
||||
character(kind=c_char), parameter :: TREXIO_DELIM = c_new_line
|
||||
#+end_src
|
||||
|
||||
#+end_src
|
||||
@ -144,6 +146,7 @@ typedef int32_t trexio_exit_code;
|
||||
| ~TREXIO_GROUP_WRITE_ERROR~ | 20 | 'Error writing group' |
|
||||
| ~TREXIO_ELEM_READ_ERROR~ | 21 | 'Error reading element' |
|
||||
| ~TREXIO_ELEM_WRITE_ERROR~ | 22 | 'Error writing element' |
|
||||
| ~TREXIO_INVALID_STR_LEN~ | 30 | 'Invalid max_str_len' |
|
||||
|
||||
# We need to force Emacs not to indent the Python code:
|
||||
# -*- org-src-preserve-indentation: t
|
||||
@ -174,7 +177,7 @@ return '\n'.join(result)
|
||||
|
||||
#+RESULTS:
|
||||
:results:
|
||||
#+begin_src c :tangle prefix_front.h :exports none
|
||||
#+begin_src c :tangle prefix_front.h
|
||||
#define TREXIO_FAILURE ((trexio_exit_code) -1)
|
||||
#define TREXIO_SUCCESS ((trexio_exit_code) 0)
|
||||
#define TREXIO_INVALID_ARG_1 ((trexio_exit_code) 1)
|
||||
@ -199,9 +202,10 @@ return '\n'.join(result)
|
||||
#define TREXIO_GROUP_WRITE_ERROR ((trexio_exit_code) 20)
|
||||
#define TREXIO_ELEM_READ_ERROR ((trexio_exit_code) 21)
|
||||
#define TREXIO_ELEM_WRITE_ERROR ((trexio_exit_code) 22)
|
||||
#define TREXIO_INVALID_STR_LEN ((trexio_exit_code) 30)
|
||||
#+end_src
|
||||
|
||||
#+begin_src f90 :tangle prefix_fortran.f90 :exports none
|
||||
#+begin_src f90 :tangle prefix_fortran.f90
|
||||
integer(trexio_exit_code), parameter :: TREXIO_FAILURE = -1
|
||||
integer(trexio_exit_code), parameter :: TREXIO_SUCCESS = 0
|
||||
integer(trexio_exit_code), parameter :: TREXIO_INVALID_ARG_1 = 1
|
||||
@ -226,6 +230,7 @@ return '\n'.join(result)
|
||||
integer(trexio_exit_code), parameter :: TREXIO_GROUP_WRITE_ERROR = 20
|
||||
integer(trexio_exit_code), parameter :: TREXIO_ELEM_READ_ERROR = 21
|
||||
integer(trexio_exit_code), parameter :: TREXIO_ELEM_WRITE_ERROR = 22
|
||||
integer(trexio_exit_code), parameter :: TREXIO_INVALID_STR_LEN = 30
|
||||
#+end_src
|
||||
:end:
|
||||
|
||||
@ -388,6 +393,8 @@ typedef int32_t back_end_t;
|
||||
#define TREXIO_TEXT ( (back_end_t) 1 )
|
||||
/*#define TREXIO_JSON ( (back_end_t) 2 )*/
|
||||
#define TREXIO_INVALID_BACK_END ( (back_end_t) 2 )
|
||||
|
||||
#define TREXIO_DELIM "\n"
|
||||
#+end_src
|
||||
** Read/write behavior
|
||||
|
||||
@ -712,30 +719,8 @@ interface
|
||||
end interface
|
||||
#+end_src
|
||||
|
||||
** C helper functions
|
||||
|
||||
#+begin_src c :tangle prefix_front.c
|
||||
trexio_exit_code transform_str (char** dest, const char** src, uint64_t str_max_num, uint32_t str_max_len){
|
||||
|
||||
if (dest == NULL) return TREXIO_INVALID_ARG_1;
|
||||
assert (str_max_num > 0);
|
||||
assert (str_max_len > 0);
|
||||
|
||||
char* tmp_str = (char*)calloc(str_max_num*(str_max_len+1)+1,sizeof(char));
|
||||
|
||||
for (int i=0; i<str_max_num; i++){
|
||||
dest[i] = tmp_str;
|
||||
strncpy(tmp_str, src[i], str_max_len);
|
||||
tmp_str += str_max_len + 1;
|
||||
}
|
||||
|
||||
/*tmp_str cannot be freed here but it is taken case of when pointer to dest is deallocated */
|
||||
|
||||
return TREXIO_SUCCESS;
|
||||
}
|
||||
#+end_src c
|
||||
|
||||
* Templates for front end
|
||||
** Description
|
||||
|
||||
Consider the following block of =trex.json=:
|
||||
|
||||
@ -801,7 +786,7 @@ trexio_exit_code transform_str (char** dest, const char** src, uint64_t str_max_
|
||||
*read* and *write* functionality. TREXIO supports I/O with single
|
||||
or double precision for integer and floating point numbers.
|
||||
|
||||
** Templates for front end has/read/write a dimension
|
||||
** Templates for front end has/read/write a single dimensioning variable
|
||||
|
||||
This section concerns API calls related to dimensioning variables.
|
||||
|
||||
@ -877,26 +862,23 @@ trexio_write_$group_num$_64 (trexio_t* const file, const int64_t num)
|
||||
if (num < 0 ) return TREXIO_INVALID_ARG_2;
|
||||
if (trexio_has_$group_num$(file) == TREXIO_SUCCESS) return TREXIO_NUM_ALREADY_EXISTS;
|
||||
|
||||
trexio_exit_code rc = TREXIO_GROUP_WRITE_ERROR;
|
||||
|
||||
switch (file->back_end) {
|
||||
|
||||
case TREXIO_TEXT:
|
||||
rc = trexio_text_write_$group_num$(file, (int64_t) num);
|
||||
return trexio_text_write_$group_num$(file, (int64_t) num);
|
||||
break;
|
||||
|
||||
case TREXIO_HDF5:
|
||||
rc = trexio_hdf5_write_$group_num$(file, (int64_t) num);
|
||||
return trexio_hdf5_write_$group_num$(file, (int64_t) num);
|
||||
break;
|
||||
/*
|
||||
case TREXIO_JSON:
|
||||
rc = trexio_json_write_$group_num$(file, (int64_t) num);
|
||||
return trexio_json_write_$group_num$(file, (int64_t) num);
|
||||
break;
|
||||
,*/
|
||||
}
|
||||
if (rc != TREXIO_SUCCESS) return rc;
|
||||
|
||||
return TREXIO_SUCCESS;
|
||||
return TREXIO_FAILURE;
|
||||
}
|
||||
#+end_src
|
||||
|
||||
@ -941,26 +923,23 @@ trexio_write_$group_num$_32 (trexio_t* const file, const int32_t num)
|
||||
if (num < 0 ) return TREXIO_INVALID_ARG_2;
|
||||
if (trexio_has_$group_num$(file) == TREXIO_SUCCESS) return TREXIO_NUM_ALREADY_EXISTS;
|
||||
|
||||
trexio_exit_code rc = TREXIO_GROUP_WRITE_ERROR;
|
||||
|
||||
switch (file->back_end) {
|
||||
|
||||
case TREXIO_TEXT:
|
||||
rc = trexio_text_write_$group_num$(file, (int64_t) num);
|
||||
return trexio_text_write_$group_num$(file, (int64_t) num);
|
||||
break;
|
||||
|
||||
case TREXIO_HDF5:
|
||||
rc = trexio_hdf5_write_$group_num$(file, (int64_t) num);
|
||||
return trexio_hdf5_write_$group_num$(file, (int64_t) num);
|
||||
break;
|
||||
/*
|
||||
case TREXIO_JSON:
|
||||
rc = trexio_json_write_$group_num$(file, (int64_t) num);
|
||||
return trexio_json_write_$group_num$(file, (int64_t) num);
|
||||
break;
|
||||
,*/
|
||||
}
|
||||
if (rc != TREXIO_SUCCESS) return rc;
|
||||
|
||||
return TREXIO_SUCCESS;
|
||||
return TREXIO_FAILURE;
|
||||
}
|
||||
#+end_src
|
||||
|
||||
@ -1004,8 +983,8 @@ trexio_has_$group_num$ (trexio_t* const file)
|
||||
break;
|
||||
,*/
|
||||
}
|
||||
return TREXIO_FAILURE;
|
||||
|
||||
return TREXIO_FAILURE;
|
||||
}
|
||||
#+end_src
|
||||
|
||||
@ -1083,7 +1062,7 @@ interface
|
||||
end interface
|
||||
#+end_src
|
||||
|
||||
** Templates for front end has/read/write a dataset
|
||||
** Templates for front end has/read/write a dataset of numerical data
|
||||
|
||||
This section concerns API calls related to datasets.
|
||||
|
||||
@ -1106,7 +1085,7 @@ end interface
|
||||
The basic (non-suffixed) API call on datasets deals with double precision (see Table above).
|
||||
|
||||
|
||||
#+begin_src c :tangle hrw_dset_front.h :exports none
|
||||
#+begin_src c :tangle hrw_dset_data_front.h :exports none
|
||||
trexio_exit_code trexio_has_$group_dset$(trexio_t* const file);
|
||||
trexio_exit_code trexio_read_$group_dset$(trexio_t* const file, $group_dset_dtype_default$* const $group_dset$);
|
||||
trexio_exit_code trexio_write_$group_dset$(trexio_t* const file, const $group_dset_dtype_default$* $group_dset$);
|
||||
@ -1116,7 +1095,7 @@ trexio_exit_code trexio_read_$group_dset$_64(trexio_t* const file, $group_dset_d
|
||||
trexio_exit_code trexio_write_$group_dset$_64(trexio_t* const file, const $group_dset_dtype_double$* $group_dset$);
|
||||
#+end_src
|
||||
|
||||
#+begin_src c :tangle read_dset_64_front.c
|
||||
#+begin_src c :tangle read_dset_data_64_front.c
|
||||
trexio_exit_code
|
||||
trexio_read_$group_dset$_64 (trexio_t* const file, $group_dset_dtype_double$* const $group_dset$)
|
||||
{
|
||||
@ -1171,7 +1150,7 @@ trexio_read_$group_dset$_64 (trexio_t* const file, $group_dset_dtype_double$* co
|
||||
}
|
||||
#+end_src
|
||||
|
||||
#+begin_src c :tangle write_dset_64_front.c
|
||||
#+begin_src c :tangle write_dset_data_64_front.c
|
||||
trexio_exit_code
|
||||
trexio_write_$group_dset$_64 (trexio_t* const file, const $group_dset_dtype_double$* $group_dset$)
|
||||
{
|
||||
@ -1192,7 +1171,7 @@ trexio_write_$group_dset$_64 (trexio_t* const file, const $group_dset_dtype_doub
|
||||
uint32_t rank = $group_dset_rank$;
|
||||
uint64_t dims[$group_dset_rank$] = {$group_dset_dim_list$};
|
||||
|
||||
$group_dset_dtype_double$* $group_dset$_p = $group_dset$;
|
||||
$group_dset_dtype_double$* $group_dset$_p = ($group_dset_dtype_double$*) $group_dset$;
|
||||
|
||||
/* Handle index type */
|
||||
if ($is_index$) {
|
||||
@ -1238,7 +1217,7 @@ trexio_write_$group_dset$_64 (trexio_t* const file, const $group_dset_dtype_doub
|
||||
}
|
||||
#+end_src
|
||||
|
||||
#+begin_src c :tangle read_dset_32_front.c
|
||||
#+begin_src c :tangle read_dset_data_32_front.c
|
||||
trexio_exit_code
|
||||
trexio_read_$group_dset$_32 (trexio_t* const file, $group_dset_dtype_single$* const $group_dset$)
|
||||
{
|
||||
@ -1305,7 +1284,7 @@ trexio_read_$group_dset$_32 (trexio_t* const file, $group_dset_dtype_single$* co
|
||||
}
|
||||
#+end_src
|
||||
|
||||
#+begin_src c :tangle write_dset_32_front.c
|
||||
#+begin_src c :tangle write_dset_data_32_front.c
|
||||
trexio_exit_code
|
||||
trexio_write_$group_dset$_32 (trexio_t* const file, const $group_dset_dtype_single$* $group_dset$)
|
||||
{
|
||||
@ -1371,7 +1350,7 @@ trexio_write_$group_dset$_32 (trexio_t* const file, const $group_dset_dtype_sing
|
||||
}
|
||||
#+end_src
|
||||
|
||||
#+begin_src c :tangle read_dset_def_front.c
|
||||
#+begin_src c :tangle read_dset_data_def_front.c
|
||||
trexio_exit_code
|
||||
trexio_read_$group_dset$ (trexio_t* const file, $group_dset_dtype_default$* const $group_dset$)
|
||||
{
|
||||
@ -1379,7 +1358,7 @@ trexio_read_$group_dset$ (trexio_t* const file, $group_dset_dtype_default$* cons
|
||||
}
|
||||
#+end_src
|
||||
|
||||
#+begin_src c :tangle write_dset_def_front.c
|
||||
#+begin_src c :tangle write_dset_data_def_front.c
|
||||
trexio_exit_code
|
||||
trexio_write_$group_dset$ (trexio_t* const file, const $group_dset_dtype_default$* $group_dset$)
|
||||
{
|
||||
@ -1387,7 +1366,7 @@ trexio_write_$group_dset$ (trexio_t* const file, const $group_dset_dtype_default
|
||||
}
|
||||
#+end_src
|
||||
|
||||
#+begin_src c :tangle has_dset_front.c
|
||||
#+begin_src c :tangle has_dset_data_front.c
|
||||
trexio_exit_code
|
||||
trexio_has_$group_dset$ (trexio_t* const file)
|
||||
{
|
||||
@ -1420,7 +1399,7 @@ trexio_has_$group_dset$ (trexio_t* const file)
|
||||
The ~Fortran~ templates that provide an access to the ~C~ API calls from ~Fortran~.
|
||||
These templates are based on the use of ~iso_c_binding~. Pointers have to be passed by value.
|
||||
|
||||
#+begin_src f90 :tangle write_dset_64_front_fortran.f90
|
||||
#+begin_src f90 :tangle write_dset_data_64_front_fortran.f90
|
||||
interface
|
||||
integer function trexio_write_$group_dset$_64 (trex_file, dset) bind(C)
|
||||
use, intrinsic :: iso_c_binding
|
||||
@ -1430,7 +1409,7 @@ interface
|
||||
end interface
|
||||
#+end_src
|
||||
|
||||
#+begin_src f90 :tangle read_dset_64_front_fortran.f90
|
||||
#+begin_src f90 :tangle read_dset_data_64_front_fortran.f90
|
||||
interface
|
||||
integer function trexio_read_$group_dset$_64 (trex_file, dset) bind(C)
|
||||
use, intrinsic :: iso_c_binding
|
||||
@ -1440,7 +1419,7 @@ interface
|
||||
end interface
|
||||
#+end_src
|
||||
|
||||
#+begin_src f90 :tangle write_dset_32_front_fortran.f90
|
||||
#+begin_src f90 :tangle write_dset_data_32_front_fortran.f90
|
||||
interface
|
||||
integer function trexio_write_$group_dset$_32 (trex_file, dset) bind(C)
|
||||
use, intrinsic :: iso_c_binding
|
||||
@ -1450,7 +1429,7 @@ interface
|
||||
end interface
|
||||
#+end_src
|
||||
|
||||
#+begin_src f90 :tangle read_dset_32_front_fortran.f90
|
||||
#+begin_src f90 :tangle read_dset_data_32_front_fortran.f90
|
||||
interface
|
||||
integer function trexio_read_$group_dset$_32 (trex_file, dset) bind(C)
|
||||
use, intrinsic :: iso_c_binding
|
||||
@ -1460,7 +1439,7 @@ interface
|
||||
end interface
|
||||
#+end_src
|
||||
|
||||
#+begin_src f90 :tangle write_dset_def_front_fortran.f90
|
||||
#+begin_src f90 :tangle write_dset_data_def_front_fortran.f90
|
||||
interface
|
||||
integer function trexio_write_$group_dset$ (trex_file, dset) bind(C)
|
||||
use, intrinsic :: iso_c_binding
|
||||
@ -1470,7 +1449,7 @@ interface
|
||||
end interface
|
||||
#+end_src
|
||||
|
||||
#+begin_src f90 :tangle read_dset_def_front_fortran.f90
|
||||
#+begin_src f90 :tangle read_dset_data_def_front_fortran.f90
|
||||
interface
|
||||
integer function trexio_read_$group_dset$ (trex_file, dset) bind(C)
|
||||
use, intrinsic :: iso_c_binding
|
||||
@ -1480,7 +1459,7 @@ interface
|
||||
end interface
|
||||
#+end_src
|
||||
|
||||
#+begin_src f90 :tangle has_dset_front_fortran.f90
|
||||
#+begin_src f90 :tangle has_dset_data_front_fortran.f90
|
||||
interface
|
||||
integer function trexio_has_$group_dset$ (trex_file) bind(C)
|
||||
use, intrinsic :: iso_c_binding
|
||||
@ -1603,6 +1582,524 @@ trexio_read_chunk_ao_2e_int_eri_value_64(trexio_t* const file,
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
** Templates for front end has/read/write a dataset of strings
|
||||
*** Introduction
|
||||
This section concerns API calls related to datasets of strings.
|
||||
|
||||
| Function name | Description |
|
||||
|-----------------------------+-------------------------------------|
|
||||
| ~trexio_has_$group_dset$~ | Check if a dataset exists in a file |
|
||||
| ~trexio_read_$group_dset$~ | Read a dataset |
|
||||
| ~trexio_write_$group_dset$~ | Write a dataset |
|
||||
|
||||
*** C templates for front end
|
||||
|
||||
First parameter is the ~TREXIO~ file handle. Second parameter is the variable to be written/read
|
||||
to/from the ~TREXIO~ file (except for ~trexio_has_~ functions).
|
||||
|
||||
|
||||
#+begin_src c :tangle hrw_dset_str_front.h :exports none
|
||||
trexio_exit_code trexio_has_$group_dset$(trexio_t* const file);
|
||||
trexio_exit_code trexio_read_$group_dset$_low(trexio_t* const file, char* dset, const uint32_t max_str_len);
|
||||
trexio_exit_code trexio_write_$group_dset$_low(trexio_t* const file, const char* dset, const uint32_t max_str_len);
|
||||
trexio_exit_code trexio_read_$group_dset$(trexio_t* const file, char** dset, const uint32_t max_str_len);
|
||||
trexio_exit_code trexio_write_$group_dset$(trexio_t* const file, const char** dset, const uint32_t max_str_len);
|
||||
#+end_src
|
||||
|
||||
#+begin_src c :tangle read_dset_str_front.c
|
||||
trexio_exit_code
|
||||
trexio_read_$group_dset$_low (trexio_t* const file, char* dset, const uint32_t max_str_len)
|
||||
{
|
||||
|
||||
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||
if (dset == NULL) return TREXIO_INVALID_ARG_2;
|
||||
if (max_str_len <= 0) return TREXIO_INVALID_ARG_3;
|
||||
|
||||
trexio_exit_code rc;
|
||||
int64_t $group_dset_dim$ = 0;
|
||||
|
||||
/* Error handling for this call is added by the generator */
|
||||
rc = trexio_read_$group_dset_dim$_64(file, &($group_dset_dim$));
|
||||
|
||||
if ($group_dset_dim$ == 0L) return TREXIO_INVALID_NUM;
|
||||
|
||||
uint32_t rank = $group_dset_rank$;
|
||||
uint64_t dims[$group_dset_rank$] = {$group_dset_dim_list$};
|
||||
|
||||
assert(file->back_end < TREXIO_INVALID_BACK_END);
|
||||
switch (file->back_end) {
|
||||
|
||||
case TREXIO_TEXT:
|
||||
return trexio_text_read_$group_dset$(file, dset, rank, dims, max_str_len);
|
||||
break;
|
||||
|
||||
case TREXIO_HDF5:
|
||||
return trexio_hdf5_read_$group_dset$(file, dset, rank, dims, max_str_len);
|
||||
break;
|
||||
/*
|
||||
case TREXIO_JSON:
|
||||
rc = trexio_json_read_$group_dset$(file, dset, rank, dims);
|
||||
break;
|
||||
,*/
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
trexio_exit_code
|
||||
trexio_read_$group_dset$ (trexio_t* const file, char** dset, const uint32_t max_str_len)
|
||||
{
|
||||
|
||||
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||
if (dset == NULL) return TREXIO_INVALID_ARG_2;
|
||||
if (max_str_len <= 0) return TREXIO_INVALID_ARG_3;
|
||||
|
||||
assert(file->back_end < TREXIO_INVALID_BACK_END);
|
||||
|
||||
trexio_exit_code rc;
|
||||
int64_t dset_dim = 0;
|
||||
|
||||
/* Error handling for this call is added by the generator */
|
||||
rc = trexio_read_$group_dset_dim$_64(file, &(dset_dim));
|
||||
|
||||
if (dset_dim == 0L) return TREXIO_INVALID_NUM;
|
||||
|
||||
char* str_compiled = CALLOC(dset_dim*(max_str_len+1) + 1, char);
|
||||
if (str_compiled == NULL) return TREXIO_ALLOCATION_FAILED;
|
||||
|
||||
rc = trexio_read_$group_dset$_low(file, str_compiled, max_str_len);
|
||||
if (rc != TREXIO_SUCCESS) {
|
||||
FREE(str_compiled);
|
||||
return rc;
|
||||
}
|
||||
|
||||
char * pch;
|
||||
for (uint64_t i=0; i < dset_dim; i++) {
|
||||
|
||||
pch = i == 0 ? strtok(str_compiled, TREXIO_DELIM) : strtok(NULL, TREXIO_DELIM) ;
|
||||
if (pch == NULL) {
|
||||
FREE(str_compiled);
|
||||
return TREXIO_FAILURE;
|
||||
}
|
||||
|
||||
strcpy(dset[i], "");
|
||||
strcat(dset[i], pch);
|
||||
|
||||
}
|
||||
|
||||
FREE(str_compiled);
|
||||
return TREXIO_SUCCESS;
|
||||
|
||||
}
|
||||
#+end_src
|
||||
|
||||
#+begin_src c :tangle write_dset_str_front.c
|
||||
trexio_exit_code
|
||||
trexio_write_$group_dset$_low (trexio_t* const file, const char* dset, const uint32_t max_str_len)
|
||||
{
|
||||
|
||||
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||
if (dset == NULL) return TREXIO_INVALID_ARG_2;
|
||||
if (max_str_len <= 0) return TREXIO_INVALID_ARG_3;
|
||||
if (trexio_has_$group_dset$(file) == TREXIO_SUCCESS) return TREXIO_DSET_ALREADY_EXISTS;
|
||||
|
||||
trexio_exit_code rc;
|
||||
int64_t $group_dset_dim$ = 0;
|
||||
|
||||
/* Error handling for this call is added by the generator */
|
||||
rc = trexio_read_$group_dset_dim$_64(file, &($group_dset_dim$));
|
||||
|
||||
if ($group_dset_dim$ == 0L) return TREXIO_INVALID_NUM;
|
||||
|
||||
uint32_t rank = $group_dset_rank$;
|
||||
uint64_t dims[$group_dset_rank$] = {$group_dset_dim_list$};
|
||||
|
||||
assert(file->back_end < TREXIO_INVALID_BACK_END);
|
||||
|
||||
char* tmp_str = CALLOC(dims[0]*(max_str_len+1), char);
|
||||
if (tmp_str == NULL) return TREXIO_ALLOCATION_FAILED;
|
||||
char** dset_str = CALLOC(dims[0], char*);
|
||||
if (dset_str == NULL) return TREXIO_ALLOCATION_FAILED;
|
||||
|
||||
char* pch;
|
||||
size_t pch_len;
|
||||
/* parse the string using strtok */
|
||||
for(uint64_t i=0; i<dims[0]; i++) {
|
||||
|
||||
pch = i == 0 ? strtok( (char*) dset, TREXIO_DELIM) : strtok(NULL, TREXIO_DELIM) ;
|
||||
|
||||
if (pch == NULL) {
|
||||
FREE(dset_str[0]);
|
||||
FREE(dset_str);
|
||||
return TREXIO_FAILURE;
|
||||
}
|
||||
|
||||
pch_len = strlen(pch);
|
||||
|
||||
if (pch_len > max_str_len) {
|
||||
FREE(dset_str[0]);
|
||||
FREE(dset_str);
|
||||
return TREXIO_INVALID_STR_LEN;
|
||||
}
|
||||
|
||||
dset_str[i] = tmp_str;
|
||||
strncpy(tmp_str, pch, pch_len);
|
||||
tmp_str += pch_len + 1;
|
||||
}
|
||||
|
||||
rc = TREXIO_FAILURE;
|
||||
switch (file->back_end) {
|
||||
|
||||
case TREXIO_TEXT:
|
||||
rc = trexio_text_write_$group_dset$(file, (const char**) dset_str, rank, dims);
|
||||
break;
|
||||
|
||||
case TREXIO_HDF5:
|
||||
rc = trexio_hdf5_write_$group_dset$(file, (const char**) dset_str, rank, dims);
|
||||
break;
|
||||
/*
|
||||
case TREXIO_JSON:
|
||||
rc = trexio_json_write_$group_dset$(file, dset, rank, dims);
|
||||
break;
|
||||
,*/
|
||||
}
|
||||
|
||||
FREE(dset_str[0]);
|
||||
FREE(dset_str);
|
||||
|
||||
return rc;
|
||||
|
||||
}
|
||||
|
||||
trexio_exit_code
|
||||
trexio_write_$group_dset$ (trexio_t* const file, const char** dset, const uint32_t max_str_len)
|
||||
{
|
||||
|
||||
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||
if (dset == NULL) return TREXIO_INVALID_ARG_2;
|
||||
if (max_str_len <= 0) return TREXIO_INVALID_ARG_3;
|
||||
if (trexio_has_$group_dset$(file) == TREXIO_SUCCESS) return TREXIO_DSET_ALREADY_EXISTS;
|
||||
|
||||
assert(file->back_end < TREXIO_INVALID_BACK_END);
|
||||
|
||||
trexio_exit_code rc;
|
||||
int64_t dset_dim = 0;
|
||||
|
||||
/* Error handling for this call is added by the generator */
|
||||
rc = trexio_read_$group_dset_dim$_64(file, &(dset_dim));
|
||||
|
||||
if (dset_dim == 0L) return TREXIO_INVALID_NUM;
|
||||
|
||||
char* str_compiled = CALLOC(dset_dim*max_str_len + 1, char);
|
||||
if (str_compiled == NULL) return TREXIO_ALLOCATION_FAILED;
|
||||
|
||||
strcpy(str_compiled, "");
|
||||
for (uint64_t i=0; i < dset_dim; i++) {
|
||||
strcat(str_compiled, dset[i]);
|
||||
strcat(str_compiled, TREXIO_DELIM);
|
||||
}
|
||||
|
||||
rc = trexio_write_$group_dset$_low(file, str_compiled, max_str_len);
|
||||
|
||||
FREE(str_compiled);
|
||||
|
||||
return rc;
|
||||
|
||||
}
|
||||
#+end_src
|
||||
|
||||
#+begin_src c :tangle has_dset_str_front.c
|
||||
trexio_exit_code
|
||||
trexio_has_$group_dset$ (trexio_t* const file)
|
||||
{
|
||||
|
||||
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||
|
||||
assert(file->back_end < TREXIO_INVALID_BACK_END);
|
||||
|
||||
switch (file->back_end) {
|
||||
|
||||
case TREXIO_TEXT:
|
||||
return trexio_text_has_$group_dset$(file);
|
||||
break;
|
||||
|
||||
case TREXIO_HDF5:
|
||||
return trexio_hdf5_has_$group_dset$(file);
|
||||
break;
|
||||
/*
|
||||
case TREXIO_JSON:
|
||||
return trexio_json_has_$group_dset$(file);
|
||||
break;
|
||||
,*/
|
||||
}
|
||||
return TREXIO_FAILURE;
|
||||
}
|
||||
#+end_src
|
||||
|
||||
*** Fortran templates for front end
|
||||
|
||||
The ~Fortran~ templates that provide an access to the ~C~ API calls from ~Fortran~.
|
||||
These templates are based on the use of ~iso_c_binding~. Pointers have to be passed by value.
|
||||
|
||||
#+begin_src f90 :tangle write_dset_str_front_fortran.f90
|
||||
interface
|
||||
integer function trexio_write_$group_dset$_low (trex_file, dset, max_str_len) bind(C)
|
||||
use, intrinsic :: iso_c_binding
|
||||
integer(8), intent(in), value :: trex_file
|
||||
character, intent(in) :: dset(*)
|
||||
integer(4), intent(in), value :: max_str_len
|
||||
end function trexio_write_$group_dset$_low
|
||||
end interface
|
||||
#+end_src
|
||||
|
||||
#+begin_src f90 :tangle read_dset_str_front_fortran.f90
|
||||
interface
|
||||
integer function trexio_read_$group_dset$_low (trex_file, dset, max_str_len) bind(C)
|
||||
use, intrinsic :: iso_c_binding
|
||||
integer(8), intent(in), value :: trex_file
|
||||
character, intent(out) :: dset(*)
|
||||
integer(4), intent(in), value :: max_str_len
|
||||
end function trexio_read_$group_dset$_low
|
||||
end interface
|
||||
#+end_src
|
||||
|
||||
#+begin_src f90 :tangle has_dset_str_front_fortran.f90
|
||||
interface
|
||||
integer function trexio_has_$group_dset$ (trex_file) bind(C)
|
||||
use, intrinsic :: iso_c_binding
|
||||
integer(8), intent(in), value :: trex_file
|
||||
end function trexio_has_$group_dset$
|
||||
end interface
|
||||
#+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)
|
||||
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)
|
||||
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
|
||||
*** Introduction
|
||||
|
||||
This section concerns API calls related to string attributes.
|
||||
|
||||
| Function name | Description |
|
||||
|----------------------------+----------------------------------------------|
|
||||
| ~trexio_has_$group_str$~ | Check if a string attribute exists in a file |
|
||||
| ~trexio_read_$group_str$~ | Read a string attribute |
|
||||
| ~trexio_write_$group_str$~ | Write a string attribute |
|
||||
|
||||
*** C templates for front end
|
||||
|
||||
#+begin_src c :tangle hrw_attr_str_front.h :exports none
|
||||
trexio_exit_code trexio_has_$group_str$(trexio_t* const file);
|
||||
trexio_exit_code trexio_read_$group_str$(trexio_t* const file, char* const str, const uint32_t max_str_len);
|
||||
trexio_exit_code trexio_write_$group_str$(trexio_t* const file, const char* str, const uint32_t max_str_len);
|
||||
#+end_src
|
||||
|
||||
#+begin_src c :tangle read_attr_str_front.c
|
||||
trexio_exit_code
|
||||
trexio_read_$group_str$ (trexio_t* const file, char* const str, const uint32_t max_str_len)
|
||||
{
|
||||
|
||||
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||
if (str == NULL) return TREXIO_INVALID_ARG_2;
|
||||
if (max_str_len <= 0) return TREXIO_INVALID_ARG_3;
|
||||
|
||||
trexio_exit_code rc = TREXIO_FAILURE;
|
||||
|
||||
switch (file->back_end) {
|
||||
|
||||
case TREXIO_TEXT:
|
||||
return trexio_text_read_$group_str$(file, str, max_str_len);
|
||||
break;
|
||||
|
||||
case TREXIO_HDF5:
|
||||
return trexio_hdf5_read_$group_str$(file, str, max_str_len);
|
||||
break;
|
||||
/*
|
||||
case TREXIO_JSON:
|
||||
return trexio_json_read_$group_str$(file, str);
|
||||
break;
|
||||
,*/
|
||||
}
|
||||
|
||||
}
|
||||
#+end_src
|
||||
|
||||
#+begin_src c :tangle write_attr_str_front.c
|
||||
trexio_exit_code
|
||||
trexio_write_$group_str$ (trexio_t* const file, const char* str, const uint32_t max_str_len)
|
||||
{
|
||||
|
||||
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||
if (str == NULL) return TREXIO_INVALID_ARG_2;
|
||||
if (max_str_len <= 0) return TREXIO_INVALID_ARG_3;
|
||||
if (trexio_has_$group_str$(file) == TREXIO_SUCCESS) return TREXIO_NUM_ALREADY_EXISTS;
|
||||
|
||||
size_t len_write = strlen(str);
|
||||
if (max_str_len < len_write) return TREXIO_INVALID_STR_LEN;
|
||||
|
||||
switch (file->back_end) {
|
||||
|
||||
case TREXIO_TEXT:
|
||||
return trexio_text_write_$group_str$(file, str);
|
||||
break;
|
||||
|
||||
case TREXIO_HDF5:
|
||||
return trexio_hdf5_write_$group_str$(file, str);
|
||||
break;
|
||||
/*
|
||||
case TREXIO_JSON:
|
||||
return trexio_json_write_$group_str$(file, str);
|
||||
break;
|
||||
,*/
|
||||
}
|
||||
|
||||
}
|
||||
#+end_src
|
||||
|
||||
#+begin_src c :tangle has_attr_str_front.c
|
||||
trexio_exit_code
|
||||
trexio_has_$group_str$ (trexio_t* const file)
|
||||
{
|
||||
|
||||
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||
|
||||
assert(file->back_end < TREXIO_INVALID_BACK_END);
|
||||
|
||||
switch (file->back_end) {
|
||||
|
||||
case TREXIO_TEXT:
|
||||
return trexio_text_has_$group_str$(file);
|
||||
break;
|
||||
|
||||
case TREXIO_HDF5:
|
||||
return trexio_hdf5_has_$group_str$(file);
|
||||
break;
|
||||
/*
|
||||
case TREXIO_JSON:
|
||||
return trexio_json_has_$group_str$(file);
|
||||
break;
|
||||
,*/
|
||||
}
|
||||
|
||||
return TREXIO_FAILURE;
|
||||
}
|
||||
#+end_src
|
||||
|
||||
*** Fortran templates for front end
|
||||
|
||||
The ~Fortran~ templates that provide an access to the ~C~ API calls from Fortran.
|
||||
These templates are based on the use of ~iso_c_binding~. Pointers have to be passed by value.
|
||||
|
||||
|
||||
#+begin_src f90 :tangle write_attr_str_front_fortran.f90
|
||||
interface
|
||||
integer function trexio_write_$group_str$_c (trex_file, str, max_str_len) &
|
||||
bind(C, name="trexio_write_$group_str$")
|
||||
use, intrinsic :: iso_c_binding
|
||||
integer(8), intent(in), value :: trex_file
|
||||
character, intent(in) :: str(*)
|
||||
integer(4), intent(in), value :: max_str_len
|
||||
end function trexio_write_$group_str$_c
|
||||
end interface
|
||||
#+end_src
|
||||
|
||||
#+begin_src f90 :tangle read_attr_str_front_fortran.f90
|
||||
interface
|
||||
integer function trexio_read_$group_str$_c (trex_file, str, max_str_len) &
|
||||
bind(C, name="trexio_read_$group_str$")
|
||||
use, intrinsic :: iso_c_binding
|
||||
integer(8), intent(in), value :: trex_file
|
||||
character, intent(out) :: str(*)
|
||||
integer(4), intent(in), value :: max_str_len
|
||||
end function trexio_read_$group_str$_c
|
||||
end interface
|
||||
#+end_src
|
||||
|
||||
#+begin_src f90 :tangle has_attr_str_front_fortran.f90
|
||||
interface
|
||||
integer function trexio_has_$group_str$ (trex_file) bind(C)
|
||||
use, intrinsic :: iso_c_binding
|
||||
integer(8), intent(in), value :: trex_file
|
||||
end function trexio_has_$group_str$
|
||||
end interface
|
||||
#+end_src
|
||||
|
||||
#+begin_src f90 :tangle helper_read_attr_str_front_fortran.fh_90
|
||||
integer function trexio_read_$group_str$ (trex_file, str, max_str_len)
|
||||
implicit none
|
||||
integer(8), intent(in), value :: trex_file
|
||||
integer(4), intent(in), value :: max_str_len
|
||||
character, intent(out) :: str(*)
|
||||
|
||||
trexio_read_$group_str$ = trexio_read_$group_str$_c(trex_file, str, max_str_len)
|
||||
|
||||
end function trexio_read_$group_str$
|
||||
#+end_src
|
||||
|
||||
#+begin_src f90 :tangle helper_write_attr_str_front_fortran.fh_90
|
||||
integer function trexio_write_$group_str$ (trex_file, str, max_str_len)
|
||||
use, intrinsic :: iso_c_binding, only : c_null_char
|
||||
implicit none
|
||||
integer(8), intent(in), value :: trex_file
|
||||
integer(4), intent(in), value :: max_str_len
|
||||
character(len=*), intent(in) :: str
|
||||
|
||||
character(len=len_trim(str)+1) :: str_c
|
||||
|
||||
str_c = trim(str) // c_null_char
|
||||
|
||||
trexio_write_$group_str$ = trexio_write_$group_str$_c(trex_file, str_c, max_str_len)
|
||||
|
||||
end function trexio_write_$group_str$
|
||||
#+end_src
|
||||
|
||||
* Fortran helper/wrapper functions
|
||||
|
||||
The function below adapts the original C-based ~trexio_open~ for Fortran.
|
||||
@ -1610,12 +2107,12 @@ trexio_read_chunk_ao_2e_int_eri_value_64(trexio_t* const file,
|
||||
unlike strings in Fortran.
|
||||
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
|
||||
integer(8) function trexio_open (filename, mode, backend)
|
||||
use, intrinsic :: iso_c_binding
|
||||
use, intrinsic :: iso_c_binding, only : c_null_char
|
||||
implicit none
|
||||
character(len=*) :: filename
|
||||
character(len=*), intent(in) :: filename
|
||||
character, intent(in), value :: mode
|
||||
integer(trexio_backend), intent(in), value :: backend
|
||||
character(len=len_trim(filename)+1) :: filename_c
|
||||
@ -1634,6 +2131,93 @@ contains
|
||||
end function trexio_open
|
||||
#+end_src
|
||||
|
||||
The subroutine below transforms an array of Fortran strings into one big string using ~TREXIO_DELIM~ symbol
|
||||
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~.
|
||||
|
||||
#+begin_src f90 :tangle helper_fortran.f90
|
||||
subroutine trexio_strarray2str(str_array, max_num_str, max_len_str, str_res)
|
||||
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(len=*), intent(in) :: str_array(*)
|
||||
character(len=:), allocatable, intent(out) :: str_res
|
||||
integer :: i
|
||||
|
||||
str_res = ''
|
||||
do i = 1, max_num_str
|
||||
str_res = str_res // trim(str_array(i)) // TREXIO_DELIM
|
||||
enddo
|
||||
str_res = str_res // c_null_char
|
||||
|
||||
end subroutine trexio_strarray2str
|
||||
#+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)
|
||||
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
|
||||
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
|
||||
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.
|
||||
|
||||
#+begin_src f90 :tangle helper_fortran.f90
|
||||
subroutine trexio_assert(trexio_rc, check_rc, success_message)
|
||||
implicit none
|
||||
|
||||
integer, intent(in), value :: trexio_rc
|
||||
integer, intent(in), value :: check_rc
|
||||
character(len=*), intent(in), optional :: success_message
|
||||
|
||||
character*(128) :: str
|
||||
|
||||
if (trexio_rc == check_rc) then
|
||||
if (present(success_message)) write(*,*) success_message
|
||||
else
|
||||
call trexio_string_of_error(trexio_rc, str)
|
||||
print *, trim(str)
|
||||
call exit(1)
|
||||
endif
|
||||
|
||||
end subroutine trexio_assert
|
||||
#+end_src
|
||||
|
||||
* File suffixes :noexport:
|
||||
|
||||
#+begin_src c :tangle suffix_front.h
|
||||
|
@ -7,14 +7,10 @@ cat populated/pop_def_hdf5.c >> trexio_hdf5.c
|
||||
cat populated/pop_struct_hdf5.h >> trexio_hdf5.h
|
||||
|
||||
cat populated/pop_basic_hdf5.c >> trexio_hdf5.c
|
||||
cat populated/pop_has_dset_hdf5.c >> trexio_hdf5.c
|
||||
cat populated/pop_has_num_hdf5.c >> trexio_hdf5.c
|
||||
cat populated/pop_read_dset_hdf5.c >> trexio_hdf5.c
|
||||
cat populated/pop_read_num_hdf5.c >> trexio_hdf5.c
|
||||
cat populated/pop_write_dset_hdf5.c >> trexio_hdf5.c
|
||||
cat populated/pop_write_num_hdf5.c >> trexio_hdf5.c
|
||||
cat populated/pop_hrw_num_hdf5.h >> trexio_hdf5.h
|
||||
cat populated/pop_hrw_dset_hdf5.h >> trexio_hdf5.h
|
||||
cat populated/pop_has_*.c >> trexio_hdf5.c
|
||||
cat populated/pop_read_*.c >> trexio_hdf5.c
|
||||
cat populated/pop_write_*.c >> trexio_hdf5.c
|
||||
cat populated/pop_hrw_*.h >> trexio_hdf5.h
|
||||
|
||||
cat suffix_hdf5.h >> trexio_hdf5.h
|
||||
|
||||
|
@ -39,7 +39,7 @@
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "hdf5.h"
|
||||
#include "hdf5_hl.h" // needed for high-level APIs like H5LT, requires additional linking in Makefile
|
||||
#include "hdf5_hl.h"
|
||||
|
||||
#+end_src
|
||||
|
||||
@ -56,6 +56,7 @@
|
||||
#define $GROUP$_GROUP_NAME "$group$"
|
||||
#define $GROUP_NUM$_NAME "$group_num$"
|
||||
#define $GROUP_DSET$_NAME "$group_dset$"
|
||||
#define $GROUP_STR$_NAME "$group_str$"
|
||||
#+end_src
|
||||
|
||||
** Template for HDF5 structures
|
||||
@ -152,7 +153,7 @@ trexio_hdf5_deinit (trexio_t* const file)
|
||||
}
|
||||
#+end_src
|
||||
|
||||
** Template for HDF5 has/read/write a number
|
||||
** Template for HDF5 has/read/write a single dimensioning variable
|
||||
|
||||
#+begin_src c :tangle hrw_num_hdf5.h :exports none
|
||||
trexio_exit_code trexio_hdf5_has_$group_num$ (trexio_t* const file);
|
||||
@ -173,11 +174,14 @@ trexio_hdf5_read_$group_num$ (trexio_t* const file, uint64_t* const num)
|
||||
/* Quit if the dimensioning attribute is missing in the file */
|
||||
if (H5Aexists(f->$group$_group, $GROUP_NUM$_NAME) == 0) return TREXIO_FAILURE;
|
||||
|
||||
/* Read the nucleus_num attribute of nucleus group */
|
||||
/* Read the $group_num$ attribute of $group$ group */
|
||||
const hid_t num_id = H5Aopen(f->$group$_group, $GROUP_NUM$_NAME, H5P_DEFAULT);
|
||||
if (num_id <= 0) return TREXIO_INVALID_ID;
|
||||
|
||||
const herr_t status = H5Aread(num_id, H5T_NATIVE_UINT64, num);
|
||||
|
||||
H5Aclose(num_id);
|
||||
|
||||
if (status < 0) return TREXIO_FAILURE;
|
||||
|
||||
return TREXIO_SUCCESS;
|
||||
@ -276,18 +280,17 @@ trexio_hdf5_has_$group_num$ (trexio_t* const file)
|
||||
}
|
||||
#+end_src
|
||||
|
||||
** Template for HDF5 has/read/write a dataset
|
||||
** Template for HDF5 has/read/write a dataset of numerical data
|
||||
|
||||
#+begin_src c :tangle hrw_dset_hdf5.h :exports none
|
||||
#+begin_src c :tangle hrw_dset_data_hdf5.h :exports none
|
||||
trexio_exit_code trexio_hdf5_has_$group_dset$(trexio_t* const file);
|
||||
trexio_exit_code trexio_hdf5_read_$group_dset$(trexio_t* const file, $group_dset_dtype$* const $group_dset$, const uint32_t rank, const uint64_t* dims);
|
||||
trexio_exit_code trexio_hdf5_write_$group_dset$(trexio_t* const file, const $group_dset_dtype$* $group_dset$, const uint32_t rank, const uint64_t* dims);
|
||||
#+end_src
|
||||
|
||||
#+begin_src c :tangle read_dset_hdf5.c
|
||||
#+begin_src c :tangle read_dset_data_hdf5.c
|
||||
trexio_exit_code
|
||||
trexio_hdf5_read_$group_dset$ (trexio_t* const file, $group_dset_dtype$* const $group_dset$,
|
||||
const uint32_t rank, const uint64_t* dims)
|
||||
trexio_hdf5_read_$group_dset$ (trexio_t* const file, $group_dset_dtype$* const $group_dset$, const uint32_t rank, const uint64_t* dims)
|
||||
{
|
||||
|
||||
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||
@ -317,17 +320,17 @@ trexio_hdf5_read_$group_dset$ (trexio_t* const file, $group_dset_dtype$* const $
|
||||
|
||||
H5Dclose(dset_id);
|
||||
if (status < 0) {
|
||||
free(ddims);
|
||||
FREE(ddims);
|
||||
return TREXIO_FAILURE;
|
||||
}
|
||||
|
||||
for (uint32_t i=0; i<rank; ++i){
|
||||
if (ddims[i] != dims[i]) {
|
||||
free(ddims);
|
||||
FREE(ddims);
|
||||
return TREXIO_INVALID_ARG_4;
|
||||
}
|
||||
}
|
||||
free(ddims);
|
||||
FREE(ddims);
|
||||
|
||||
/* High-level H5LT API. No need to deal with dataspaces and datatypes */
|
||||
status = H5LTread_dataset(f->$group$_group,
|
||||
@ -340,10 +343,9 @@ trexio_hdf5_read_$group_dset$ (trexio_t* const file, $group_dset_dtype$* const $
|
||||
}
|
||||
#+end_src
|
||||
|
||||
#+begin_src c :tangle write_dset_hdf5.c
|
||||
#+begin_src c :tangle write_dset_data_hdf5.c
|
||||
trexio_exit_code
|
||||
trexio_hdf5_write_$group_dset$ (trexio_t* const file, const $group_dset_dtype$* $group_dset$,
|
||||
const uint32_t rank, const uint64_t* dims)
|
||||
trexio_hdf5_write_$group_dset$ (trexio_t* const file, const $group_dset_dtype$* $group_dset$, const uint32_t rank, const uint64_t* dims)
|
||||
{
|
||||
|
||||
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||
@ -386,7 +388,7 @@ trexio_hdf5_write_$group_dset$ (trexio_t* const file, const $group_dset_dtype$*
|
||||
}
|
||||
#+end_src
|
||||
|
||||
#+begin_src c :tangle has_dset_hdf5.c
|
||||
#+begin_src c :tangle has_dset_data_hdf5.c
|
||||
trexio_exit_code
|
||||
trexio_hdf5_has_$group_dset$ (trexio_t* const file)
|
||||
{
|
||||
@ -408,6 +410,336 @@ trexio_hdf5_has_$group_dset$ (trexio_t* const file)
|
||||
}
|
||||
#+end_src
|
||||
|
||||
** Template for HDF5 has/read/write a dataset of strings
|
||||
|
||||
#+begin_src c :tangle hrw_dset_str_hdf5.h :exports none
|
||||
trexio_exit_code trexio_hdf5_has_$group_dset$(trexio_t* const file);
|
||||
trexio_exit_code trexio_hdf5_read_$group_dset$(trexio_t* const file, char* const $group_dset$, const uint32_t rank, const uint64_t* dims, const uint32_t max_str_len);
|
||||
trexio_exit_code trexio_hdf5_write_$group_dset$(trexio_t* const file, const char** $group_dset$, const uint32_t rank, const uint64_t* dims);
|
||||
#+end_src
|
||||
|
||||
#+begin_src c :tangle read_dset_str_hdf5.c
|
||||
trexio_exit_code
|
||||
trexio_hdf5_read_$group_dset$ (trexio_t* const file, char* const $group_dset$, const uint32_t rank, const uint64_t* dims, const uint32_t max_str_len)
|
||||
{
|
||||
|
||||
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||
if ($group_dset$ == NULL) return TREXIO_INVALID_ARG_2;
|
||||
|
||||
const trexio_hdf5_t* f = (const trexio_hdf5_t*) file;
|
||||
|
||||
herr_t status;
|
||||
|
||||
// open the dataset to get its dimensions
|
||||
hid_t dset_id = H5Dopen(f->$group$_group, $GROUP_DSET$_NAME, H5P_DEFAULT);
|
||||
if (dset_id <= 0) return TREXIO_INVALID_ID;
|
||||
|
||||
// allocate space for the dimensions to be read
|
||||
hsize_t* ddims = CALLOC( (int) rank, hsize_t);
|
||||
if (ddims == NULL) {
|
||||
H5Dclose(dset_id);
|
||||
return TREXIO_ALLOCATION_FAILED;
|
||||
}
|
||||
|
||||
hid_t dspace = H5Dget_space(dset_id);
|
||||
if (dset_id <= 0) {
|
||||
FREE(ddims);
|
||||
H5Dclose(dset_id);
|
||||
return TREXIO_INVALID_ID;
|
||||
}
|
||||
|
||||
// get the rank of the dataset in a file
|
||||
int rrank = H5Sget_simple_extent_dims(dspace, ddims, NULL);
|
||||
|
||||
if (rrank != (int) rank) {
|
||||
FREE(ddims);
|
||||
H5Dclose(dset_id);
|
||||
H5Sclose(dspace);
|
||||
return TREXIO_INVALID_ARG_3;
|
||||
}
|
||||
|
||||
for (int i=0; i<rrank; i++) {
|
||||
if (ddims[i] != dims[i]) {
|
||||
H5Dclose(dset_id);
|
||||
H5Sclose(dspace);
|
||||
FREE(ddims);
|
||||
return TREXIO_INVALID_ARG_4;
|
||||
}
|
||||
}
|
||||
FREE(ddims);
|
||||
|
||||
hid_t memtype = H5Tcopy (H5T_C_S1);
|
||||
status = H5Tset_size(memtype, H5T_VARIABLE);
|
||||
if (status < 0 || memtype <= 0) {
|
||||
H5Dclose(dset_id);
|
||||
H5Sclose(dspace);
|
||||
return TREXIO_FAILURE;
|
||||
}
|
||||
|
||||
char** rdata = CALLOC(dims[0], char*);
|
||||
if (rdata == NULL) {
|
||||
H5Dclose(dset_id);
|
||||
H5Sclose(dspace);
|
||||
H5Tclose(memtype);
|
||||
return TREXIO_ALLOCATION_FAILED;
|
||||
}
|
||||
|
||||
status = H5Dread(dset_id, memtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata);
|
||||
if (status < 0) {
|
||||
FREE(rdata);
|
||||
H5Dclose(dset_id);
|
||||
H5Sclose(dspace);
|
||||
H5Tclose(memtype);
|
||||
return TREXIO_FAILURE;
|
||||
}
|
||||
|
||||
// copy contents of temporary rdata buffer into the group_dset otherwise they are lost
|
||||
// after calling H5Treclaim or H5Dvlen_reclaim functions
|
||||
strcpy($group_dset$, "");
|
||||
for (uint64_t i=0; i<dims[0]; i++) {
|
||||
strncat($group_dset$, rdata[i], max_str_len);
|
||||
strcat($group_dset$, TREXIO_DELIM);
|
||||
}
|
||||
|
||||
// H5Dvlen_reclaim is deprecated and replaced by H5Treclaim in HDF5 v.1.12.0
|
||||
#if (H5_VERS_MAJOR <= 1 && H5_VERS_MINOR < 12)
|
||||
status = H5Dvlen_reclaim(memtype, dspace, H5P_DEFAULT, rdata);
|
||||
#else
|
||||
status = H5Treclaim(memtype, dspace, H5P_DEFAULT, rdata);
|
||||
#endif
|
||||
|
||||
if (status < 0) {
|
||||
FREE(rdata);
|
||||
H5Dclose(dset_id);
|
||||
H5Sclose(dspace);
|
||||
H5Tclose(memtype);
|
||||
return TREXIO_FAILURE;
|
||||
}
|
||||
|
||||
FREE(rdata);
|
||||
H5Dclose(dset_id);
|
||||
H5Sclose(dspace);
|
||||
H5Tclose(memtype);
|
||||
|
||||
return TREXIO_SUCCESS;
|
||||
}
|
||||
#+end_src
|
||||
|
||||
#+begin_src c :tangle write_dset_str_hdf5.c
|
||||
trexio_exit_code
|
||||
trexio_hdf5_write_$group_dset$ (trexio_t* const file, const char** $group_dset$, const uint32_t rank, const uint64_t* dims)
|
||||
{
|
||||
|
||||
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||
if ($group_dset$ == NULL) return TREXIO_INVALID_ARG_2;
|
||||
|
||||
trexio_exit_code rc;
|
||||
uint64_t $group_dset_dim$;
|
||||
// error handling for rc is added by the generator
|
||||
rc = trexio_hdf5_read_$group_dset_dim$(file, &($group_dset_dim$));
|
||||
if ($group_dset_dim$ == 0L) return TREXIO_INVALID_NUM;
|
||||
|
||||
trexio_hdf5_t* f = (trexio_hdf5_t*) file;
|
||||
|
||||
herr_t status;
|
||||
hid_t dset_id;
|
||||
|
||||
/* we are going to write variable-length strings */
|
||||
hid_t memtype = H5Tcopy (H5T_C_S1);
|
||||
status = H5Tset_size (memtype, H5T_VARIABLE);
|
||||
|
||||
if ( H5LTfind_dataset(f->$group$_group, $GROUP_DSET$_NAME) != 1 ) {
|
||||
|
||||
/* code to create dataset */
|
||||
hid_t filetype = H5Tcopy (H5T_FORTRAN_S1);
|
||||
status = H5Tset_size (filetype, H5T_VARIABLE);
|
||||
|
||||
hid_t dspace = H5Screate_simple( (int) rank, (const hsize_t*) dims, NULL);
|
||||
|
||||
dset_id = H5Dcreate (f->$group$_group, $GROUP_DSET$_NAME, filetype, dspace,
|
||||
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
|
||||
if (dset_id <= 0) return TREXIO_INVALID_ID;
|
||||
|
||||
status = H5Dwrite (dset_id, memtype,
|
||||
H5S_ALL, H5S_ALL, H5P_DEFAULT,
|
||||
$group_dset$);
|
||||
|
||||
H5Dclose (dset_id);
|
||||
H5Sclose (dspace);
|
||||
H5Tclose (filetype);
|
||||
H5Tclose (memtype);
|
||||
|
||||
if (status < 0) return TREXIO_FAILURE;
|
||||
|
||||
} else {
|
||||
|
||||
dset_id = H5Dopen(f->$group$_group, $GROUP_DSET$_NAME, H5P_DEFAULT);
|
||||
if (dset_id <= 0) return TREXIO_INVALID_ID;
|
||||
|
||||
/* code to write dataset */
|
||||
status = H5Dwrite(dset_id, memtype,
|
||||
H5S_ALL, H5S_ALL, H5P_DEFAULT,
|
||||
$group_dset$);
|
||||
|
||||
H5Dclose(dset_id);
|
||||
H5Tclose(memtype);
|
||||
|
||||
if (status < 0) return TREXIO_FAILURE;
|
||||
|
||||
}
|
||||
|
||||
return TREXIO_SUCCESS;
|
||||
|
||||
}
|
||||
#+end_src
|
||||
|
||||
#+begin_src c :tangle has_dset_str_hdf5.c
|
||||
trexio_exit_code
|
||||
trexio_hdf5_has_$group_dset$ (trexio_t* const file)
|
||||
{
|
||||
|
||||
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||
|
||||
trexio_hdf5_t* f = (trexio_hdf5_t*) file;
|
||||
|
||||
herr_t status = H5LTfind_dataset(f->$group$_group, $GROUP_DSET$_NAME);
|
||||
/* H5LTfind_dataset returns 1 if dataset exists, 0 otherwise */
|
||||
if (status == 1){
|
||||
return TREXIO_SUCCESS;
|
||||
} else if (status == 0) {
|
||||
return TREXIO_HAS_NOT;
|
||||
} else {
|
||||
return TREXIO_FAILURE;
|
||||
}
|
||||
|
||||
}
|
||||
#+end_src
|
||||
|
||||
** Template for HDF5 has/read/write a single string attribute
|
||||
|
||||
#+begin_src c :tangle hrw_attr_str_hdf5.h :exports none
|
||||
trexio_exit_code trexio_hdf5_has_$group_str$ (trexio_t* const file);
|
||||
trexio_exit_code trexio_hdf5_read_$group_str$ (trexio_t* const file, char* const str, const uint32_t max_str_len);
|
||||
trexio_exit_code trexio_hdf5_write_$group_str$(trexio_t* const file, const char* str);
|
||||
#+end_src
|
||||
|
||||
|
||||
#+begin_src c :tangle read_attr_str_hdf5.c
|
||||
trexio_exit_code
|
||||
trexio_hdf5_read_$group_str$ (trexio_t* const file, char* const str, const uint32_t max_str_len)
|
||||
{
|
||||
|
||||
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||
if (str == NULL) return TREXIO_INVALID_ARG_2;
|
||||
|
||||
const trexio_hdf5_t* f = (const trexio_hdf5_t*) file;
|
||||
/* Quit if the string attribute is missing in the file */
|
||||
if (H5Aexists(f->$group$_group, $GROUP_STR$_NAME) == 0) return TREXIO_HAS_NOT;
|
||||
|
||||
/* Read the $group_str$ attribute of $group$ group */
|
||||
const hid_t str_id = H5Aopen(f->$group$_group, $GROUP_STR$_NAME, H5P_DEFAULT);
|
||||
if (str_id <= 0) return TREXIO_INVALID_ID;
|
||||
|
||||
const hid_t ftype_id = H5Aget_type(str_id);
|
||||
if (ftype_id <= 0) return TREXIO_INVALID_ID;
|
||||
uint64_t sdim = H5Tget_size(ftype_id);
|
||||
if (sdim <= 0) return TREXIO_FAILURE;
|
||||
sdim++; /* Make room for null terminator */
|
||||
|
||||
const hid_t mem_id = H5Tcopy(H5T_C_S1);
|
||||
if (mem_id <= 0) return TREXIO_INVALID_ID;
|
||||
|
||||
herr_t status;
|
||||
status = (max_str_len+1) > sdim ? H5Tset_size(mem_id, sdim) : H5Tset_size(mem_id, max_str_len+1) ;
|
||||
if (status < 0) return TREXIO_FAILURE;
|
||||
|
||||
status = H5Aread(str_id, mem_id, str);
|
||||
if (status < 0) return TREXIO_FAILURE;
|
||||
|
||||
H5Aclose(str_id);
|
||||
H5Tclose(mem_id);
|
||||
H5Tclose(ftype_id);
|
||||
|
||||
return TREXIO_SUCCESS;
|
||||
|
||||
}
|
||||
#+end_src
|
||||
|
||||
|
||||
#+begin_src c :tangle write_attr_str_hdf5.c
|
||||
trexio_exit_code
|
||||
trexio_hdf5_write_$group_str$ (trexio_t* const file, const char* str)
|
||||
{
|
||||
|
||||
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||
if (str == NULL) return TREXIO_INVALID_ARG_2;
|
||||
|
||||
trexio_hdf5_t* const f = (trexio_hdf5_t*) file;
|
||||
|
||||
|
||||
/* Setup the dataspace */
|
||||
const hid_t dtype_id = H5Tcopy(H5T_C_S1);
|
||||
if (dtype_id <= 0) return TREXIO_INVALID_ID;
|
||||
|
||||
size_t str_attr_len = strlen(str) + 1;
|
||||
|
||||
herr_t status;
|
||||
status = H5Tset_size(dtype_id, str_attr_len);
|
||||
if (status < 0) return TREXIO_FAILURE;
|
||||
|
||||
status = H5Tset_strpad(dtype_id, H5T_STR_NULLTERM);
|
||||
if (status < 0) return TREXIO_FAILURE;
|
||||
|
||||
const hid_t dspace_id = H5Screate(H5S_SCALAR);
|
||||
if (dspace_id <= 0) return TREXIO_INVALID_ID;
|
||||
|
||||
/* Create the $group_str$ attribute of $group$ group */
|
||||
const hid_t str_id = H5Acreate(f->$group$_group, $GROUP_STR$_NAME, dtype_id, dspace_id,
|
||||
H5P_DEFAULT, H5P_DEFAULT);
|
||||
|
||||
if (str_id <= 0) {
|
||||
H5Sclose(dspace_id);
|
||||
H5Tclose(dtype_id);
|
||||
return TREXIO_INVALID_ID;
|
||||
}
|
||||
|
||||
status = H5Awrite(str_id, dtype_id, str);
|
||||
if (status < 0) {
|
||||
H5Aclose(str_id);
|
||||
H5Sclose(dspace_id);
|
||||
H5Tclose(dtype_id);
|
||||
return TREXIO_FAILURE;
|
||||
}
|
||||
|
||||
H5Aclose(str_id);
|
||||
H5Sclose(dspace_id);
|
||||
H5Tclose(dtype_id);
|
||||
return TREXIO_SUCCESS;
|
||||
|
||||
}
|
||||
#+end_src
|
||||
|
||||
#+begin_src c :tangle has_attr_str_hdf5.c
|
||||
trexio_exit_code
|
||||
trexio_hdf5_has_$group_str$ (trexio_t* const file)
|
||||
{
|
||||
|
||||
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||
|
||||
const trexio_hdf5_t* f = (const trexio_hdf5_t*) file;
|
||||
|
||||
htri_t status = H5Aexists(f->$group$_group, $GROUP_STR$_NAME);
|
||||
/* H5Aexists returns positive value if attribute exists, 0 if does not, negative if error */
|
||||
if (status > 0){
|
||||
return TREXIO_SUCCESS;
|
||||
} else if (status == 0) {
|
||||
return TREXIO_HAS_NOT;
|
||||
} else {
|
||||
return TREXIO_FAILURE;
|
||||
}
|
||||
|
||||
}
|
||||
#+end_src
|
||||
* Constant file suffixes (not used by the generator) :noexport:
|
||||
|
||||
#+begin_src c :tangle suffix_hdf5.h
|
||||
|
@ -17,14 +17,22 @@ cat populated/pop_free_group_text.h >> trexio_text.h
|
||||
cat populated/pop_read_group_text.h >> trexio_text.h
|
||||
cat populated/pop_flush_group_text.h >> trexio_text.h
|
||||
|
||||
cat populated/pop_has_dset_text.c >> trexio_text.c
|
||||
cat populated/pop_has_dset_data_text.c >> trexio_text.c
|
||||
cat populated/pop_has_dset_str_text.c >> trexio_text.c
|
||||
cat populated/pop_has_num_text.c >> trexio_text.c
|
||||
cat populated/pop_read_dset_text.c >> trexio_text.c
|
||||
cat populated/pop_has_attr_str_text.c >> trexio_text.c
|
||||
cat populated/pop_read_dset_data_text.c >> trexio_text.c
|
||||
cat populated/pop_read_dset_str_text.c >> trexio_text.c
|
||||
cat populated/pop_read_attr_str_text.c >> trexio_text.c
|
||||
cat populated/pop_read_num_text.c >> trexio_text.c
|
||||
cat populated/pop_write_dset_text.c >> trexio_text.c
|
||||
cat populated/pop_write_dset_data_text.c >> trexio_text.c
|
||||
cat populated/pop_write_dset_str_text.c >> trexio_text.c
|
||||
cat populated/pop_write_attr_str_text.c >> trexio_text.c
|
||||
cat populated/pop_write_num_text.c >> trexio_text.c
|
||||
cat populated/pop_hrw_num_text.h >> trexio_text.h
|
||||
cat populated/pop_hrw_dset_text.h >> trexio_text.h
|
||||
cat populated/pop_hrw_dset_data_text.h >> trexio_text.h
|
||||
cat populated/pop_hrw_dset_str_text.h >> trexio_text.h
|
||||
cat populated/pop_hrw_attr_str_text.h >> trexio_text.h
|
||||
|
||||
cat rdm_text.c >> trexio_text.c
|
||||
cat rdm_text.h >> trexio_text.h
|
||||
|
@ -83,6 +83,8 @@ typedef struct $group$_s {
|
||||
uint32_t rank_$group_dset$;
|
||||
uint32_t to_flush;
|
||||
uint64_t dims_$group_dset$[16];
|
||||
uint64_t len_$group_str$;
|
||||
char* $group_str$;
|
||||
char file_name[TREXIO_MAX_FILENAME_LENGTH];
|
||||
} $group$_t;
|
||||
#+end_src
|
||||
@ -298,7 +300,7 @@ trexio_text_read_$group$ (trexio_text_t* const file)
|
||||
|
||||
/* Read the dimensioning variables */
|
||||
int rc;
|
||||
// START REPEAT GROUP_DSET
|
||||
// START REPEAT GROUP_DSET_ALL
|
||||
rc = fscanf(f, "%1023s", buffer);
|
||||
if ((rc != 1) || (strcmp(buffer, "rank_$group_dset$") != 0)) {
|
||||
FREE(buffer);
|
||||
@ -319,9 +321,9 @@ trexio_text_read_$group$ (trexio_text_t* const file)
|
||||
uint64_t size_$group_dset$ = 0;
|
||||
if ($group$->rank_$group_dset$ != 0) size_$group_dset$ = 1;
|
||||
|
||||
for (unsigned int i=0; i<$group$->rank_$group_dset$; ++i){
|
||||
for (uint32_t i=0; i<$group$->rank_$group_dset$; ++i){
|
||||
|
||||
unsigned int j=0;
|
||||
uint32_t j=0;
|
||||
|
||||
rc = fscanf(f, "%1023s %u", buffer, &j);
|
||||
if ((rc != 2) || (strcmp(buffer, "dims_$group_dset$") != 0) || (j!=i)) {
|
||||
@ -342,7 +344,7 @@ trexio_text_read_$group$ (trexio_text_t* const file)
|
||||
|
||||
size_$group_dset$ *= $group$->dims_$group_dset$[i];
|
||||
}
|
||||
// END REPEAT GROUP_DSET
|
||||
// END REPEAT GROUP_DSET_ALL
|
||||
|
||||
// START REPEAT GROUP_NUM
|
||||
/* Read data */
|
||||
@ -365,13 +367,68 @@ trexio_text_read_$group$ (trexio_text_t* const file)
|
||||
}
|
||||
// END REPEAT GROUP_NUM
|
||||
|
||||
// START REPEAT GROUP_DSET
|
||||
// START REPEAT GROUP_ATTR_STR
|
||||
rc = fscanf(f, "%1023s", buffer);
|
||||
assert(!((rc != 1) || (strcmp(buffer, "len_$group_str$") != 0)));
|
||||
if ((rc != 1) || (strcmp(buffer, "len_$group_str$") != 0)) {
|
||||
FREE(buffer);
|
||||
fclose(f);
|
||||
FREE($group$);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rc = fscanf(f, "%" SCNu64 "", &($group$->len_$group_str$));
|
||||
assert(!(rc != 1));
|
||||
if (rc != 1) {
|
||||
FREE(buffer);
|
||||
fclose(f);
|
||||
FREE($group$);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rc = fscanf(f, "%1023s", buffer);
|
||||
assert(!((rc != 1) || (strcmp(buffer, "$group_str$") != 0)));
|
||||
if ((rc != 1) || (strcmp(buffer, "$group_str$") != 0)) {
|
||||
FREE(buffer);
|
||||
fclose(f);
|
||||
FREE($group$->$group_str$);
|
||||
FREE($group$);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ($group$->len_$group_str$ != 0) {
|
||||
|
||||
$group$->$group_str$ = CALLOC($group$->len_$group_str$, char);
|
||||
assert (!($group$->$group_str$ == NULL));
|
||||
if ($group$->$group_str$ == NULL) {
|
||||
FREE(buffer);
|
||||
fclose(f);
|
||||
FREE($group$->$group_str$);
|
||||
FREE($group$);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rc = fscanf(f, " %1023[^\n]", $group$->$group_str$);
|
||||
assert(!(rc != 1));
|
||||
if (rc != 1) {
|
||||
FREE(buffer);
|
||||
fclose(f);
|
||||
FREE($group$->$group_str$);
|
||||
FREE($group$);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
// END REPEAT GROUP_ATTR_STR
|
||||
|
||||
// START REPEAT GROUP_DSET_NUM
|
||||
/* Allocate arrays */
|
||||
$group$->$group_dset$ = CALLOC(size_$group_dset$, $group_dset_dtype$);
|
||||
assert (!($group$->$group_dset$ == NULL));
|
||||
if ($group$->$group_dset$ == NULL) {
|
||||
FREE(buffer);
|
||||
fclose(f);
|
||||
FREE($group$->$group_dset$);
|
||||
FREE($group$);
|
||||
return NULL;
|
||||
}
|
||||
@ -397,7 +454,57 @@ trexio_text_read_$group$ (trexio_text_t* const file)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
// END REPEAT GROUP_DSET
|
||||
// END REPEAT GROUP_DSET_NUM
|
||||
|
||||
size_t tmp_len;
|
||||
|
||||
// START REPEAT GROUP_DSET_STR
|
||||
/* Allocate arrays */
|
||||
$group$->$group_dset$ = CALLOC(size_$group_dset$, $group_dset_dtype$);
|
||||
assert (!($group$->$group_dset$ == NULL));
|
||||
if ($group$->$group_dset$ == NULL) {
|
||||
FREE(buffer);
|
||||
fclose(f);
|
||||
FREE($group$->$group_dset$);
|
||||
FREE($group$);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rc = fscanf(f, "%1023s", buffer);
|
||||
assert(!((rc != 1) || (strcmp(buffer, "$group_dset$") != 0)));
|
||||
if ((rc != 1) || (strcmp(buffer, "$group_dset$") != 0)) {
|
||||
FREE(buffer);
|
||||
fclose(f);
|
||||
FREE($group$->$group_dset$);
|
||||
FREE($group$);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* WARNING: this tmp array allows to avoid allocation of space for each element of array of string
|
||||
, BUT it's size has to be number_of_str*max_len_str where max_len_str is somewhat arbitrary, e.g. 32.
|
||||
,*/
|
||||
char* tmp_$group_dset$;
|
||||
if(size_$group_dset$ != 0) tmp_$group_dset$ = CALLOC(size_$group_dset$*32, char);
|
||||
tmp_len = 0;
|
||||
for (uint64_t i=0 ; i<size_$group_dset$ ; ++i) {
|
||||
$group$->$group_dset$[i] = tmp_$group_dset$;
|
||||
/* conventional fcanf with "%s" only return the string before the first space character
|
||||
,* to read string with spaces use "%[^\n]" possible with space before or after, i.e. " %[^\n]"
|
||||
,* Q: depending on what ? */
|
||||
rc = fscanf(f, " %1023[^\n]", tmp_$group_dset$);
|
||||
assert(!(rc != 1));
|
||||
if (rc != 1) {
|
||||
FREE(buffer);
|
||||
fclose(f);
|
||||
FREE($group$->$group_dset$);
|
||||
FREE($group$);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tmp_len = strlen($group$->$group_dset$[i]);
|
||||
tmp_$group_dset$ += tmp_len + 1;
|
||||
}
|
||||
// END REPEAT GROUP_DSET_STR
|
||||
|
||||
FREE(buffer);
|
||||
fclose(f);
|
||||
@ -437,7 +544,7 @@ trexio_text_flush_$group$ (trexio_text_t* const file)
|
||||
if (f == NULL) return TREXIO_INVALID_ARG_1;
|
||||
|
||||
/* Write the dimensioning variables */
|
||||
// START REPEAT GROUP_DSET
|
||||
// START REPEAT GROUP_DSET_ALL
|
||||
fprintf(f, "rank_$group_dset$ %u\n", $group$->rank_$group_dset$);
|
||||
// workaround for the case of missing blocks in the file
|
||||
uint64_t size_$group_dset$ = 0;
|
||||
@ -447,21 +554,26 @@ trexio_text_flush_$group$ (trexio_text_t* const file)
|
||||
fprintf(f, "dims_$group_dset$ %u %" PRIu64 "\n", i, $group$->dims_$group_dset$[i]);
|
||||
size_$group_dset$ *= $group$->dims_$group_dset$[i];
|
||||
}
|
||||
|
||||
// END REPEAT GROUP_DSET
|
||||
// END REPEAT GROUP_DSET_ALL
|
||||
|
||||
// START REPEAT GROUP_NUM
|
||||
fprintf(f, "$group_num$ %" PRIu64 "\n", $group$->$group_num$);
|
||||
// END REPEAT GROUP_NUM
|
||||
|
||||
// START REPEAT GROUP_ATTR_STR
|
||||
fprintf(f, "len_$group_str$ %" PRIu64 "\n", $group$->len_$group_str$);
|
||||
fprintf(f, "$group_str$\n");
|
||||
if ($group$->len_$group_str$ != 0) fprintf(f, "%s\n", $group$->$group_str$);
|
||||
// END REPEAT GROUP_ATTR_STR
|
||||
|
||||
/* Write arrays */
|
||||
// START REPEAT GROUP_DSET
|
||||
// START REPEAT GROUP_DSET_ALL
|
||||
|
||||
fprintf(f, "$group_dset$\n");
|
||||
for (uint64_t i=0 ; i<size_$group_dset$ ; ++i) {
|
||||
fprintf(f, "%$group_dset_std_dtype_out$\n", $group$->$group_dset$[i]);
|
||||
}
|
||||
// END REPEAT GROUP_DSET
|
||||
// END REPEAT GROUP_DSET_ALL
|
||||
|
||||
fclose(f);
|
||||
$group$->to_flush = 0;
|
||||
@ -493,11 +605,20 @@ trexio_text_free_$group$ (trexio_text_t* const file)
|
||||
$group$_t* $group$ = file->$group$;
|
||||
if ($group$ == NULL) return TREXIO_SUCCESS;
|
||||
|
||||
// START REPEAT GROUP_DSET
|
||||
// START REPEAT GROUP_DSET_NUM
|
||||
if ($group$->$group_dset$ != NULL) FREE ($group$->$group_dset$);
|
||||
// END REPEAT GROUP_DSET_NUM
|
||||
|
||||
// START REPEAT GROUP_DSET_STR
|
||||
if ($group$->$group_dset$ != NULL) {
|
||||
if($group$->rank_$group_dset$ != 0) FREE ($group$->$group_dset$[0]);
|
||||
FREE ($group$->$group_dset$);
|
||||
}
|
||||
// END REPEAT GROUP_DSET
|
||||
// END REPEAT GROUP_DSET_STR
|
||||
|
||||
// START REPEAT GROUP_ATTR_STR
|
||||
if ($group$->$group_str$ != NULL) FREE ($group$->$group_str$);
|
||||
// END REPEAT GROUP_ATTR_STR
|
||||
|
||||
FREE ($group$);
|
||||
return TREXIO_SUCCESS;
|
||||
@ -505,7 +626,7 @@ trexio_text_free_$group$ (trexio_text_t* const file)
|
||||
}
|
||||
#+end_src
|
||||
|
||||
** Template for has/read/write the ~$group_num$~ attribute
|
||||
** Template for has/read/write the num attribute
|
||||
|
||||
#+begin_src c :tangle hrw_num_text.h :exports none
|
||||
trexio_exit_code trexio_text_has_$group_num$ (trexio_t* const file);
|
||||
@ -568,17 +689,17 @@ trexio_text_has_$group_num$ (trexio_t* const file)
|
||||
}
|
||||
#+end_src
|
||||
|
||||
** Template for has/read/write the ~$group_dset$~ dataset
|
||||
** Template for has/read/write the dataset of numerical data
|
||||
|
||||
The ~group_dset~ array is assumed allocated with the appropriate size.
|
||||
|
||||
#+begin_src c :tangle hrw_dset_text.h :exports none
|
||||
#+begin_src c :tangle hrw_dset_data_text.h :exports none
|
||||
trexio_exit_code trexio_text_has_$group_dset$ (trexio_t* const file);
|
||||
trexio_exit_code trexio_text_read_$group_dset$ (trexio_t* const file, $group_dset_dtype$* const $group_dset$, const uint32_t rank, const uint64_t* dims);
|
||||
trexio_exit_code trexio_text_write_$group_dset$(trexio_t* const file, const $group_dset_dtype$* $group_dset$, const uint32_t rank, const uint64_t* dims);
|
||||
#+end_src
|
||||
|
||||
#+begin_src c :tangle read_dset_text.c
|
||||
#+begin_src c :tangle read_dset_data_text.c
|
||||
trexio_exit_code
|
||||
trexio_text_read_$group_dset$ (trexio_t* const file, $group_dset_dtype$* const $group_dset$,
|
||||
const uint32_t rank, const uint64_t* dims)
|
||||
@ -593,7 +714,7 @@ trexio_text_read_$group_dset$ (trexio_t* const file, $group_dset_dtype$* const $
|
||||
if (rank != $group$->rank_$group_dset$) return TREXIO_INVALID_ARG_3;
|
||||
|
||||
uint64_t dim_size = 1;
|
||||
for (unsigned int i=0; i<rank; ++i){
|
||||
for (uint32_t i=0; i<rank; ++i){
|
||||
if (dims[i] != $group$->dims_$group_dset$[i]) return TREXIO_INVALID_ARG_4;
|
||||
dim_size *= dims[i];
|
||||
}
|
||||
@ -607,7 +728,7 @@ trexio_text_read_$group_dset$ (trexio_t* const file, $group_dset_dtype$* const $
|
||||
}
|
||||
#+end_src
|
||||
|
||||
#+begin_src c :tangle write_dset_text.c
|
||||
#+begin_src c :tangle write_dset_data_text.c
|
||||
trexio_exit_code
|
||||
trexio_text_write_$group_dset$ (trexio_t* const file, const $group_dset_dtype$* $group_dset$,
|
||||
const uint32_t rank, const uint64_t* dims)
|
||||
@ -628,7 +749,7 @@ trexio_text_write_$group_dset$ (trexio_t* const file, const $group_dset_dtype$*
|
||||
$group$->rank_$group_dset$ = rank;
|
||||
|
||||
uint64_t dim_size = 1;
|
||||
for (unsigned int i=0; i<$group$->rank_$group_dset$; ++i){
|
||||
for (uint32_t i=0; i<$group$->rank_$group_dset$; ++i){
|
||||
$group$->dims_$group_dset$[i] = dims[i];
|
||||
dim_size *= dims[i];
|
||||
}
|
||||
@ -645,7 +766,7 @@ trexio_text_write_$group_dset$ (trexio_t* const file, const $group_dset_dtype$*
|
||||
}
|
||||
#+end_src
|
||||
|
||||
#+begin_src c :tangle has_dset_text.c
|
||||
#+begin_src c :tangle has_dset_data_text.c
|
||||
trexio_exit_code
|
||||
trexio_text_has_$group_dset$ (trexio_t* const file)
|
||||
{
|
||||
@ -663,7 +784,182 @@ trexio_text_has_$group_dset$ (trexio_t* const file)
|
||||
|
||||
}
|
||||
#+end_src
|
||||
** Template for has/read/write the dataset of strings
|
||||
|
||||
The ~group_dset~ array is assumed allocated with the appropriate size.
|
||||
|
||||
#+begin_src c :tangle hrw_dset_str_text.h :exports none
|
||||
trexio_exit_code trexio_text_has_$group_dset$ (trexio_t* const file);
|
||||
trexio_exit_code trexio_text_read_$group_dset$ (trexio_t* const file, char* const dset, const uint32_t rank, const uint64_t* dims, const uint32_t max_str_len);
|
||||
trexio_exit_code trexio_text_write_$group_dset$ (trexio_t* const file, const char** dset, const uint32_t rank, const uint64_t* dims);
|
||||
#+end_src
|
||||
|
||||
#+begin_src c :tangle read_dset_str_text.c
|
||||
trexio_exit_code
|
||||
trexio_text_read_$group_dset$ (trexio_t* const file, char* const dset, const uint32_t rank, const uint64_t* dims, const uint32_t max_str_len)
|
||||
{
|
||||
|
||||
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||
if (dset == NULL) return TREXIO_INVALID_ARG_2;
|
||||
|
||||
$group$_t* const $group$ = trexio_text_read_$group$((trexio_text_t*) file);
|
||||
if ($group$ == NULL) return TREXIO_FAILURE;
|
||||
|
||||
if (rank != $group$->rank_$group_dset$) return TREXIO_INVALID_ARG_3;
|
||||
|
||||
for (uint32_t i=0 ; i<rank ; ++i) {
|
||||
if (dims[i] != $group$->dims_$group_dset$[i]) return TREXIO_INVALID_ARG_4;
|
||||
}
|
||||
|
||||
strcpy(dset, "");
|
||||
for (uint64_t i=0 ; i<dims[0] ; ++i) {
|
||||
strncat(dset, $group$->$group_dset$[i], max_str_len);
|
||||
strcat(dset, TREXIO_DELIM);
|
||||
}
|
||||
|
||||
return TREXIO_SUCCESS;
|
||||
|
||||
}
|
||||
#+end_src
|
||||
|
||||
#+begin_src c :tangle write_dset_str_text.c
|
||||
trexio_exit_code
|
||||
trexio_text_write_$group_dset$ (trexio_t* const file, const char** dset, const uint32_t rank, const uint64_t* dims)
|
||||
{
|
||||
|
||||
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||
if (dset == NULL) return TREXIO_INVALID_ARG_2;
|
||||
|
||||
if (file->mode == 'r') return TREXIO_READONLY;
|
||||
|
||||
$group$_t* const $group$ = trexio_text_read_$group$((trexio_text_t*) file);
|
||||
if ($group$ == NULL) return TREXIO_FAILURE;
|
||||
|
||||
if ($group$->$group_dset$ != NULL) {
|
||||
if ($group$->rank_$group_dset$ != 0) FREE($group$->$group_dset$[0]);
|
||||
FREE($group$->$group_dset$);
|
||||
}
|
||||
|
||||
$group$->rank_$group_dset$ = rank;
|
||||
|
||||
for (uint32_t i=0; i<$group$->rank_$group_dset$; ++i){
|
||||
$group$->dims_$group_dset$[i] = dims[i];
|
||||
}
|
||||
|
||||
$group$->$group_dset$ = CALLOC(dims[0], char*);
|
||||
if ($group$->$group_dset$ == NULL) return TREXIO_ALLOCATION_FAILED;
|
||||
|
||||
char* tmp_str = CALLOC(dims[0]*32 + 1, char);
|
||||
if (tmp_str == NULL) return TREXIO_ALLOCATION_FAILED;
|
||||
|
||||
size_t tmp_len = 0;
|
||||
for (uint64_t i=0 ; i<dims[0] ; ++i) {
|
||||
tmp_len = strlen(dset[i]);
|
||||
$group$->$group_dset$[i] = tmp_str;
|
||||
strncpy(tmp_str, dset[i], tmp_len);
|
||||
tmp_str += tmp_len + 1;
|
||||
}
|
||||
|
||||
$group$->to_flush = 1;
|
||||
|
||||
return TREXIO_SUCCESS;
|
||||
|
||||
}
|
||||
#+end_src
|
||||
|
||||
#+begin_src c :tangle has_dset_str_text.c
|
||||
trexio_exit_code
|
||||
trexio_text_has_$group_dset$ (trexio_t* const file)
|
||||
{
|
||||
|
||||
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||
|
||||
$group$_t* const $group$ = trexio_text_read_$group$((trexio_text_t*) file);
|
||||
if ($group$ == NULL) return TREXIO_FAILURE;
|
||||
|
||||
if ($group$->rank_$group_dset$ > 0){
|
||||
return TREXIO_SUCCESS;
|
||||
} else {
|
||||
return TREXIO_HAS_NOT;
|
||||
}
|
||||
|
||||
}
|
||||
#+end_src
|
||||
** Template for has/read/write the string attribute
|
||||
|
||||
#+begin_src c :tangle hrw_attr_str_text.h :exports none
|
||||
trexio_exit_code trexio_text_has_$group_str$ (trexio_t* const file);
|
||||
trexio_exit_code trexio_text_read_$group_str$ (trexio_t* const file, char* const str, const uint32_t max_str_len);
|
||||
trexio_exit_code trexio_text_write_$group_str$ (trexio_t* const file, const char* str);
|
||||
#+end_src
|
||||
|
||||
#+begin_src c :tangle read_attr_str_text.c
|
||||
trexio_exit_code
|
||||
trexio_text_read_$group_str$ (trexio_t* const file, char* const str, const uint32_t max_str_len)
|
||||
{
|
||||
|
||||
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||
if (str == NULL) return TREXIO_INVALID_ARG_2;
|
||||
|
||||
$group$_t* const $group$ = trexio_text_read_$group$((trexio_text_t*) file);
|
||||
if ($group$ == NULL) return TREXIO_FAILURE;
|
||||
|
||||
strncpy(str, $group$->$group_str$, max_str_len);
|
||||
|
||||
return TREXIO_SUCCESS;
|
||||
|
||||
}
|
||||
#+end_src
|
||||
|
||||
#+begin_src c :tangle write_attr_str_text.c
|
||||
trexio_exit_code
|
||||
trexio_text_write_$group_str$ (trexio_t* const file, const char *str)
|
||||
{
|
||||
|
||||
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||
if (str == NULL) return TREXIO_INVALID_ARG_2;
|
||||
|
||||
if (file->mode == 'r') return TREXIO_READONLY;
|
||||
|
||||
$group$_t* const $group$ = trexio_text_read_$group$((trexio_text_t*) file);
|
||||
if ($group$ == NULL) return TREXIO_FAILURE;
|
||||
|
||||
if ($group$->$group_str$ != NULL) FREE($group$->$group_str$);
|
||||
|
||||
size_t tmp_len = strlen(str);
|
||||
|
||||
$group$->$group_str$ = CALLOC(tmp_len + 1, char);
|
||||
if ($group$->$group_str$ == NULL) return TREXIO_ALLOCATION_FAILED;
|
||||
|
||||
$group$->len_$group_str$ = tmp_len + 1;
|
||||
|
||||
strncpy($group$->$group_str$, str, tmp_len + 1);
|
||||
|
||||
$group$->to_flush = 1;
|
||||
|
||||
return TREXIO_SUCCESS;
|
||||
|
||||
}
|
||||
#+end_src
|
||||
|
||||
#+begin_src c :tangle has_attr_str_text.c
|
||||
trexio_exit_code
|
||||
trexio_text_has_$group_str$ (trexio_t* const file)
|
||||
{
|
||||
|
||||
if (file == NULL) return TREXIO_INVALID_ARG_1;
|
||||
|
||||
$group$_t* const $group$ = trexio_text_read_$group$((trexio_text_t*) file);
|
||||
if ($group$ == NULL) return TREXIO_FAILURE;
|
||||
|
||||
if ($group$->len_$group_str$ > 0){
|
||||
return TREXIO_SUCCESS;
|
||||
} else {
|
||||
return TREXIO_HAS_NOT;
|
||||
}
|
||||
|
||||
}
|
||||
#+end_src
|
||||
** RDM struct (hard-coded)
|
||||
*** Read the complete struct
|
||||
|
||||
|
3
tests/.gitignore
vendored
3
tests/.gitignore
vendored
@ -6,6 +6,9 @@ trexio.mod
|
||||
test_c
|
||||
test_f
|
||||
|
||||
*.log
|
||||
*.trs
|
||||
|
||||
*.h5
|
||||
*/
|
||||
|
||||
|
66
tests/test.c
66
tests/test.c
@ -2,6 +2,7 @@
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int test_write(const char* file_name, const back_end_t backend);
|
||||
int test_read(const char* file_name, const back_end_t backend);
|
||||
@ -54,6 +55,20 @@ int test_write(const char* file_name, const back_end_t backend) {
|
||||
0.00000000 , 2.47304151 , 0.00000000 ,
|
||||
};
|
||||
|
||||
const char* label[] = {"C" ,
|
||||
"Na",
|
||||
"ClH asdasdasdas" ,
|
||||
"C" ,
|
||||
"C 666" ,
|
||||
"C" ,
|
||||
"H" ,
|
||||
"Ru",
|
||||
"H" ,
|
||||
"H 999asdasd" ,
|
||||
"H" ,
|
||||
"H" };
|
||||
|
||||
const char* sym = "B3U and some stuff";
|
||||
/*================= START OF TEST ==================*/
|
||||
|
||||
// open file in 'write' mode
|
||||
@ -72,11 +87,28 @@ int test_write(const char* file_name, const back_end_t backend) {
|
||||
rc = trexio_write_nucleus_coord(file,coord);
|
||||
assert (rc == TREXIO_SUCCESS);
|
||||
|
||||
rc = trexio_write_nucleus_label(file, label, 32);
|
||||
assert (rc == TREXIO_SUCCESS);
|
||||
rc = trexio_write_nucleus_point_group(file, sym, 32);
|
||||
assert (rc == TREXIO_SUCCESS);
|
||||
|
||||
// close current session
|
||||
rc = trexio_close(file);
|
||||
assert (rc == TREXIO_SUCCESS);
|
||||
|
||||
// reopen file in 'write' mode
|
||||
file = trexio_open(file_name, 'w', backend);
|
||||
assert (file != NULL);
|
||||
|
||||
// check if the written data exists in the file
|
||||
rc = trexio_has_nucleus_num(file);
|
||||
assert (rc == TREXIO_SUCCESS);
|
||||
rc = trexio_has_nucleus_coord(file);
|
||||
assert (rc == TREXIO_SUCCESS);
|
||||
rc = trexio_has_nucleus_label(file);
|
||||
assert (rc == TREXIO_SUCCESS);
|
||||
rc = trexio_has_nucleus_point_group(file);
|
||||
assert (rc == TREXIO_SUCCESS);
|
||||
|
||||
// should not work: try to overwrite the num variable
|
||||
rc = trexio_write_nucleus_num(file,25);
|
||||
@ -118,6 +150,8 @@ int test_read(const char* file_name, const back_end_t backend) {
|
||||
|
||||
int num;
|
||||
double* coord;
|
||||
char** label;
|
||||
char* point_group;
|
||||
|
||||
/*================= START OF TEST ==================*/
|
||||
|
||||
@ -137,6 +171,37 @@ int test_read(const char* file_name, const back_end_t backend) {
|
||||
|
||||
double x = coord[30] - 2.14171677;
|
||||
assert( x*x < 1.e-14);
|
||||
free(coord);
|
||||
|
||||
// read nucleus_label
|
||||
label = (char**) malloc(num*sizeof(char*));
|
||||
for (int i=0; i<num; i++){
|
||||
label[i] = (char*) malloc(32*sizeof(char));
|
||||
}
|
||||
|
||||
rc = trexio_read_nucleus_label(file, label, 2);
|
||||
assert (rc == TREXIO_SUCCESS);
|
||||
assert (strcmp(label[0], "C") == 0);
|
||||
assert (strcmp(label[1], "Na") == 0);
|
||||
|
||||
for (int i=0; i<num; i++){
|
||||
free(label[i]);
|
||||
}
|
||||
free(label);
|
||||
|
||||
point_group = (char*) malloc(32*sizeof(char));
|
||||
|
||||
rc = trexio_read_nucleus_point_group(file, point_group, 6);
|
||||
assert (rc == TREXIO_SUCCESS);
|
||||
|
||||
char * pch;
|
||||
pch = strtok(point_group, " ");
|
||||
assert (strcmp(pch, "B3U") == 0);
|
||||
/* alternative test when 3 symbols are read from the file to point_group */
|
||||
/*rc = trexio_read_nucleus_point_group(file, point_group, 3);
|
||||
assert (rc == TREXIO_SUCCESS);
|
||||
assert (strcmp(point_group, "B3U") == 0 );*/
|
||||
free(point_group);
|
||||
|
||||
// close current session
|
||||
rc = trexio_close(file);
|
||||
@ -151,7 +216,6 @@ int test_read(const char* file_name, const back_end_t backend) {
|
||||
|
||||
/*================= END OF TEST =====================*/
|
||||
|
||||
free(coord);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
215
tests/test_f.f90
215
tests/test_f.f90
@ -2,19 +2,19 @@ program test_trexio
|
||||
use trexio
|
||||
implicit none
|
||||
|
||||
call system('rm -rf trexio_test_fort')
|
||||
print *, 'call test_write(''trexio_test_fort'', TREXIO_TEXT)'
|
||||
call test_write('trexio_test_fort', TREXIO_TEXT)
|
||||
print *, 'call test_read(''trexio_test_fort'', TREXIO_TEXT)'
|
||||
call test_read('trexio_test_fort', TREXIO_TEXT)
|
||||
call system('rm -rf trexio_test_fort')
|
||||
call system('rm -rf test_write_f.dir')
|
||||
print *, 'call test_write(''test_write_f.dir'', TREXIO_TEXT)'
|
||||
call test_write('test_write_f.dir', TREXIO_TEXT)
|
||||
print *, 'call test_read(''test_write_f.dir'', TREXIO_TEXT)'
|
||||
call test_read('test_write_f.dir', TREXIO_TEXT)
|
||||
call system('rm -rf test_write_f.dir')
|
||||
|
||||
call system('rm -rf trexio_test_fort')
|
||||
print *, 'call test_write(''trexio_test_fort.h5'', TREXIO_HDF5)'
|
||||
call test_write('trexio_test_fort.h5', TREXIO_HDF5)
|
||||
print *, 'call test_read(''trexio_test_fort.h5'', TREXIO_HDF5)'
|
||||
call test_read('trexio_test_fort.h5', TREXIO_HDF5)
|
||||
call system('rm -rf trexio_test_fort.h5')
|
||||
call system('rm -rf test_write_f.h5')
|
||||
print *, 'call test_write(''test_write_f.h5'', TREXIO_HDF5)'
|
||||
call test_write('test_write_f.h5', TREXIO_HDF5)
|
||||
print *, 'call test_read(''test_write_f.h5'', TREXIO_HDF5)'
|
||||
call test_read('test_write_f.h5', TREXIO_HDF5)
|
||||
call system('rm -rf test_write_f.h5')
|
||||
|
||||
end program test_trexio
|
||||
|
||||
@ -23,22 +23,26 @@ subroutine test_write(file_name, back_end)
|
||||
! ============ Test write functionality =============== !
|
||||
|
||||
use trexio
|
||||
use, intrinsic :: iso_c_binding
|
||||
|
||||
implicit none
|
||||
|
||||
character*(*), intent(in) :: file_name
|
||||
integer(trexio_backend), intent(in) :: back_end
|
||||
integer, intent(in) :: back_end
|
||||
|
||||
integer(8) :: trex_file
|
||||
|
||||
integer :: rc = 1
|
||||
integer :: num
|
||||
character*(128) :: str
|
||||
|
||||
integer :: num
|
||||
|
||||
integer :: basis_nucleus_index(12)
|
||||
double precision :: charge(12)
|
||||
double precision :: coord(3,12)
|
||||
|
||||
character(len=:), allocatable :: sym_str
|
||||
character(len=:), allocatable :: label(:)
|
||||
|
||||
! parameters to be written
|
||||
num = 12
|
||||
charge = (/ 6., 6., 6., 6., 6., 6., 1., 1., 1., 1., 1., 1. /)
|
||||
@ -58,117 +62,56 @@ subroutine test_write(file_name, back_end)
|
||||
|
||||
basis_nucleus_index = (/ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 /)
|
||||
|
||||
label = [character(len=8) :: 'C', 'Na','C', 'C 66', 'C','C', 'H 99', 'Ru', 'H', 'H', 'H', 'H' ]
|
||||
|
||||
sym_str = 'B3U with some comments'
|
||||
|
||||
! ================= START OF TEST ===================== !
|
||||
|
||||
trex_file = trexio_open(file_name, 'w', back_end)
|
||||
|
||||
rc = trexio_has_nucleus_num(trex_file)
|
||||
if (rc == TREXIO_HAS_NOT) then
|
||||
write(*,*) 'SUCCESS HAS NOT 1'
|
||||
else
|
||||
call trexio_string_of_error(rc,str)
|
||||
print *, trim(str)
|
||||
call exit(1)
|
||||
endif
|
||||
call trexio_assert(rc, TREXIO_HAS_NOT, 'SUCCESS HAS NOT 1')
|
||||
|
||||
rc = trexio_has_nucleus_charge(trex_file)
|
||||
if (rc == TREXIO_HAS_NOT) then
|
||||
write(*,*) 'SUCCESS HAS NOT 2'
|
||||
else
|
||||
call trexio_string_of_error(rc,str)
|
||||
print *, trim(str)
|
||||
call exit(1)
|
||||
endif
|
||||
|
||||
call trexio_assert(rc, TREXIO_HAS_NOT, 'SUCCESS HAS NOT 2')
|
||||
|
||||
rc = trexio_write_nucleus_num(trex_file, num)
|
||||
if (rc == TREXIO_SUCCESS) then
|
||||
write(*,*) 'SUCCESS WRITE NUM'
|
||||
else
|
||||
call trexio_string_of_error(rc,str)
|
||||
print *, trim(str)
|
||||
call exit(1)
|
||||
endif
|
||||
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS WRITE NUM')
|
||||
|
||||
rc = trexio_write_nucleus_charge(trex_file, charge)
|
||||
if (rc == TREXIO_SUCCESS) then
|
||||
write(*,*) 'SUCCESS WRITE CHARGE'
|
||||
else
|
||||
call trexio_string_of_error(rc,str)
|
||||
print *, trim(str)
|
||||
call exit(1)
|
||||
endif
|
||||
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS WRITE CHARGE')
|
||||
|
||||
rc = trexio_write_nucleus_coord(trex_file, coord)
|
||||
if (rc == TREXIO_SUCCESS) then
|
||||
write(*,*) 'SUCCESS WRITE COORD'
|
||||
else
|
||||
call trexio_string_of_error(rc,str)
|
||||
print *, trim(str)
|
||||
call exit(1)
|
||||
endif
|
||||
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS WRITE COORD')
|
||||
|
||||
rc = trexio_has_nucleus_num(trex_file)
|
||||
if (rc == TREXIO_SUCCESS) then
|
||||
write(*,*) 'SUCCESS HAS 1'
|
||||
else
|
||||
call trexio_string_of_error(rc,str)
|
||||
print *, trim(str)
|
||||
call exit(1)
|
||||
endif
|
||||
rc = trexio_write_nucleus_label(trex_file, label, 5)
|
||||
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS WRITE LABEL')
|
||||
deallocate(label)
|
||||
|
||||
rc = trexio_write_nucleus_point_group(trex_file, sym_str, 32)
|
||||
deallocate(sym_str)
|
||||
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS WRITE POINT GROUP')
|
||||
|
||||
rc = trexio_has_nucleus_coord(trex_file)
|
||||
if (rc == TREXIO_SUCCESS) then
|
||||
write(*,*) 'SUCCESS HAS 2'
|
||||
else
|
||||
call trexio_string_of_error(rc,str)
|
||||
print *, trim(str)
|
||||
call exit(1)
|
||||
endif
|
||||
|
||||
rc = trexio_write_basis_nucleus_index(trex_file, basis_nucleus_index)
|
||||
if (rc == TREXIO_SUCCESS) then
|
||||
write(*,*) 'SUCCESS WRITE INDEX'
|
||||
else
|
||||
call trexio_string_of_error(rc,str)
|
||||
print *, trim(str)
|
||||
call exit(1)
|
||||
endif
|
||||
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS WRITE INDEX')
|
||||
|
||||
|
||||
rc = trexio_has_nucleus_num(trex_file)
|
||||
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS HAS 1')
|
||||
|
||||
rc = trexio_has_nucleus_coord(trex_file)
|
||||
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS HAS 2')
|
||||
|
||||
rc = trexio_close(trex_file)
|
||||
if (rc == TREXIO_SUCCESS) then
|
||||
write(*,*) 'SUCCESS CLOSE'
|
||||
else
|
||||
call trexio_string_of_error(rc,str)
|
||||
print *, trim(str)
|
||||
call exit(1)
|
||||
endif
|
||||
|
||||
|
||||
! ---------------------------------- !
|
||||
! to modify fields 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 == TREXIO_SUCCESS) write(*,*) 'SUCCESS MODIFY COORD'
|
||||
|
||||
! rc = trexio_close(trex_file)
|
||||
! if (rc == TREXIO_SUCCESS) write(*,*) 'SUCCESS CLOSE'
|
||||
call trexio_assert(rc, TREXIO_SUCCESS, 'SUCCESS CLOSE')
|
||||
|
||||
! ================= END OF TEST ===================== !
|
||||
|
||||
end subroutine test_write
|
||||
|
||||
|
||||
|
||||
|
||||
subroutine test_read(file_name, back_end)
|
||||
|
||||
! ============ Test read functionality =============== !
|
||||
@ -177,10 +120,11 @@ subroutine test_read(file_name, back_end)
|
||||
implicit none
|
||||
|
||||
character*(*), intent(in) :: file_name
|
||||
integer(trexio_backend), intent(in) :: back_end
|
||||
integer, intent(in) :: back_end
|
||||
|
||||
integer(8) :: trex_file
|
||||
|
||||
integer :: i, j, k, ind, offset, flag
|
||||
integer :: rc = 1
|
||||
integer :: num, num_read
|
||||
|
||||
@ -188,6 +132,12 @@ subroutine test_read(file_name, back_end)
|
||||
double precision :: charge(12)
|
||||
double precision :: coord(3,12)
|
||||
|
||||
character :: label_str(128)
|
||||
character(len=4) :: tmp_str
|
||||
character(len=4) :: label(12) ! also works with allocatable arrays
|
||||
|
||||
character(len=32) :: sym_str
|
||||
|
||||
character*(128) :: str
|
||||
|
||||
num = 12
|
||||
@ -196,56 +146,69 @@ subroutine test_read(file_name, back_end)
|
||||
|
||||
trex_file = trexio_open(file_name, 'r', back_end)
|
||||
|
||||
rc = trexio_read_nucleus_num(trex_file, num_read)
|
||||
|
||||
if (rc == TREXIO_SUCCESS .and. num_read == num) then
|
||||
rc = trexio_read_nucleus_num(trex_file, num_read)
|
||||
call trexio_assert(rc, TREXIO_SUCCESS)
|
||||
if (num_read == num) then
|
||||
write(*,*) 'SUCCESS READ NUM'
|
||||
else
|
||||
call trexio_string_of_error(rc,str)
|
||||
print *, trim(str)
|
||||
call exit(1)
|
||||
print *, 'FAILURE NUM CHECK'
|
||||
call exit(-1)
|
||||
endif
|
||||
|
||||
|
||||
rc = trexio_read_nucleus_charge(trex_file, charge)
|
||||
|
||||
if (rc == TREXIO_SUCCESS .and. (dabs(charge(11) - 1.d0) < 1.0D-8) ) then
|
||||
call trexio_assert(rc, TREXIO_SUCCESS)
|
||||
if (dabs(charge(11) - 1.d0) < 1.0D-8) then
|
||||
write(*,*) 'SUCCESS READ CHARGE'
|
||||
else
|
||||
call trexio_string_of_error(rc,str)
|
||||
print *, trim(str)
|
||||
print *, 'FAILURE CHARGE CHECK'
|
||||
call exit(-1)
|
||||
endif
|
||||
|
||||
|
||||
rc = trexio_read_nucleus_coord(trex_file, coord)
|
||||
|
||||
if (rc == TREXIO_SUCCESS .and. (dabs(coord(2,1) - 1.39250319d0) < 1.0D-8) ) then
|
||||
call trexio_assert(rc, TREXIO_SUCCESS)
|
||||
if (dabs(coord(2,1) - 1.39250319d0) < 1.0D-8) then
|
||||
write(*,*) 'SUCCESS READ COORD'
|
||||
else
|
||||
call trexio_string_of_error(rc,str)
|
||||
print *, trim(str)
|
||||
print *, 'FAILURE COORD CHECK'
|
||||
call exit(-1)
|
||||
endif
|
||||
|
||||
|
||||
rc = trexio_read_nucleus_label(trex_file, label, 2)
|
||||
call trexio_assert(rc, TREXIO_SUCCESS)
|
||||
if (trim(label(2)) == 'Na') then
|
||||
write(*,*) 'SUCCESS READ LABEL'
|
||||
else
|
||||
print *, 'FAILURE LABEL CHECK'
|
||||
call exit(-1)
|
||||
endif
|
||||
|
||||
|
||||
rc = trexio_read_basis_nucleus_index(trex_file, basis_nucleus_index)
|
||||
if (rc == TREXIO_SUCCESS .and. (basis_nucleus_index(12) == 12) ) then
|
||||
call trexio_assert(rc, TREXIO_SUCCESS)
|
||||
if (basis_nucleus_index(12) == 12) then
|
||||
write(*,*) 'SUCCESS READ INDEX'
|
||||
else
|
||||
call trexio_string_of_error(rc,str)
|
||||
print *, trim(str)
|
||||
print *, 'FAILURE INDEX CHECK'
|
||||
call exit(-1)
|
||||
endif
|
||||
|
||||
|
||||
rc = trexio_read_nucleus_point_group(trex_file, sym_str, 10)
|
||||
call trexio_assert(rc, TREXIO_SUCCESS)
|
||||
if (sym_str(1:3) == 'B3U') then
|
||||
write(*,*) 'SUCCESS READ POINT GROUP'
|
||||
else
|
||||
print *, 'FAILURE POINT GROUP CHECK'
|
||||
call exit(-1)
|
||||
endif
|
||||
|
||||
|
||||
rc = trexio_close(trex_file)
|
||||
if (rc == TREXIO_SUCCESS) then
|
||||
write(*,*) 'SUCCESS CLOSE'
|
||||
else
|
||||
call trexio_string_of_error(rc,str)
|
||||
print *, trim(str)
|
||||
call exit(1)
|
||||
endif
|
||||
|
||||
call trexio_assert(rc, TREXIO_SUCCESS)
|
||||
|
||||
! ================= END OF TEST ===================== !
|
||||
|
||||
|
@ -18,12 +18,15 @@ print('Strings I/O currently not supported')
|
||||
|
||||
# -------------------- GET ATTRIBUTES FROM THE CONFIGURATION ---------------- #
|
||||
group_dict = get_group_dict(trex_config)
|
||||
detailed_num = get_detailed_num_dict(trex_config)
|
||||
# helper dictionaries contain group, num or dset names as keys
|
||||
datasets = get_dset_dict(trex_config)
|
||||
detailed_dset_nostr, detailed_dset_str = split_dset_dict_detailed(datasets)
|
||||
detailed_nums = get_detailed_num_dict(trex_config)
|
||||
detailed_strs = get_detailed_str_dict(trex_config)
|
||||
# helper dictionaries that contain names of groups, nums or dsets as keys
|
||||
dsets = get_dset_dict(trex_config)
|
||||
detailed_dsets_nostr, detailed_dsets_str = split_dset_dict_detailed(dsets)
|
||||
detailed_dsets = detailed_dsets_nostr.copy()
|
||||
detailed_dsets.update(detailed_dsets_str)
|
||||
# consistency check for dimensioning variables
|
||||
check_dim_consistency(detailed_num, datasets)
|
||||
check_dim_consistency(detailed_nums, dsets)
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
# -------------------- GET TEMPLATED FILES TO BE POPULATED ------------------ #
|
||||
@ -40,18 +43,26 @@ files_todo = get_files_todo(source_files)
|
||||
|
||||
# populate files with iterative scheme, i.e. for unique functions
|
||||
for fname in files_todo['auxiliary']:
|
||||
iterative_populate_file(fname, template_paths, group_dict, detailed_dset_nostr, detailed_num)
|
||||
iterative_populate_file(fname, template_paths, group_dict, detailed_dsets, detailed_nums, detailed_strs)
|
||||
|
||||
# populate has/read/write_num functions with recursive scheme
|
||||
for fname in files_todo['num']:
|
||||
recursive_populate_file(fname, template_paths, detailed_num)
|
||||
recursive_populate_file(fname, template_paths, detailed_nums)
|
||||
|
||||
# populate has/read/write_dset functions with recursive scheme
|
||||
for fname in files_todo['dset']:
|
||||
recursive_populate_file(fname, template_paths, detailed_dset_nostr)
|
||||
# populate has/read/write_str functions with recursive scheme
|
||||
for fname in files_todo['attr_str']:
|
||||
recursive_populate_file(fname, template_paths, detailed_strs)
|
||||
|
||||
# populate has/read/write_dset (numerical) functions with recursive scheme
|
||||
for fname in files_todo['dset_data']:
|
||||
recursive_populate_file(fname, template_paths, detailed_dsets_nostr)
|
||||
|
||||
# populate has/read/write_dset (strings) functions with recursive scheme
|
||||
for fname in files_todo['dset_str']:
|
||||
recursive_populate_file(fname, template_paths, detailed_dsets_str)
|
||||
|
||||
# populate group-related functions with mixed (iterative+recursive) scheme [text backend]
|
||||
for fname in files_todo['group']:
|
||||
special_populate_text_group(fname, template_paths, group_dict, detailed_dset_nostr, detailed_num)
|
||||
special_populate_text_group(fname, template_paths, group_dict, detailed_dsets, detailed_nums, detailed_strs)
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
@ -39,11 +39,11 @@ def get_files_todo(source_files: dict) -> dict:
|
||||
files_todo = {}
|
||||
#files_todo['all'] = list(filter(lambda x: 'read' in x or 'write' in x or 'has' in x or 'hrw' in x or 'flush' in x or 'free' in x, all_files))
|
||||
files_todo['all'] = [f for f in all_files if 'read' in f or 'write' in f or 'has' in f or 'flush' in f or 'free' in f or 'hrw' in f]
|
||||
for key in ['dset', 'num', 'group']:
|
||||
for key in ['dset_data', 'dset_str', 'num', 'attr_str', 'group']:
|
||||
files_todo[key] = list(filter(lambda x: key in x, files_todo['all']))
|
||||
|
||||
files_todo['group'].append('struct_text_group_dset.h')
|
||||
# files that correspond to todo1 group (e.g. only iterative population within the function body)
|
||||
# files that correspond to iterative population (e.g. the code is repeated within the function body but the function itself is unique)
|
||||
files_todo['auxiliary'] = ['def_hdf5.c', 'basic_hdf5.c', 'basic_text_group.c', 'struct_hdf5.h', 'struct_text_group.h']
|
||||
|
||||
return files_todo
|
||||
@ -104,7 +104,7 @@ def recursive_populate_file(fname: str, paths: dict, detailed_source: dict) -> N
|
||||
'group_dset_f_dtype_default', 'group_dset_f_dtype_double', 'group_dset_f_dtype_single',
|
||||
'group_dset_dtype_default', 'group_dset_dtype_double', 'group_dset_dtype_single',
|
||||
'group_dset_rank', 'group_dset_dim_list', 'group_dset_f_dims',
|
||||
'group_dset', 'group_num', 'group']
|
||||
'group_dset', 'group_num', 'group_str', 'group']
|
||||
|
||||
for item in detailed_source.keys():
|
||||
with open(join(templ_path,fname), 'r') as f_in :
|
||||
@ -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:
|
||||
num_written.append(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
|
||||
templine += line_toadd
|
||||
|
||||
@ -168,7 +168,7 @@ def recursive_replace_line (input_line: str, triggers: list, source: dict) -> st
|
||||
return output_line
|
||||
|
||||
|
||||
def iterative_populate_file (filename: str, paths: dict, groups: dict, datasets: dict, numbers: dict) -> None:
|
||||
def iterative_populate_file (filename: str, paths: dict, groups: dict, datasets: dict, numbers: dict, strings: dict) -> None:
|
||||
"""
|
||||
Iteratively populate files with unique functions that contain templated variables.
|
||||
|
||||
@ -178,12 +178,13 @@ def iterative_populate_file (filename: str, paths: dict, groups: dict, datasets:
|
||||
groups (dict) : dictionary of groups
|
||||
datasets (dict) : dictionary of datasets with substitution details
|
||||
numbers (dict) : dictionary of numbers with substitution details
|
||||
strings (dict) : dictionary of strings with substitution details
|
||||
|
||||
Returns:
|
||||
None
|
||||
"""
|
||||
add_trigger = 'rc = trexio_text_free_$group$'
|
||||
triggers = [add_trigger, '$group_dset$', '$group_num$', '$group$']
|
||||
triggers = [add_trigger, '$group_dset$', '$group_num$', '$group_str$', '$group$']
|
||||
|
||||
templ_path = get_template_path(filename, paths)
|
||||
filename_out = join('populated',f'pop_{filename}')
|
||||
@ -197,7 +198,7 @@ def iterative_populate_file (filename: str, paths: dict, groups: dict, datasets:
|
||||
if id == 0:
|
||||
# special case for proper error handling when deallocting text groups
|
||||
error_handler = ' if (rc != TREXIO_SUCCESS) return rc;\n'
|
||||
populated_line = iterative_replace_line(line, triggers[3], groups, add_line=error_handler)
|
||||
populated_line = iterative_replace_line(line, '$group$', groups, add_line=error_handler)
|
||||
f_out.write(populated_line)
|
||||
elif id == 1:
|
||||
populated_line = iterative_replace_line(line, triggers[id], datasets, None)
|
||||
@ -206,6 +207,9 @@ def iterative_populate_file (filename: str, paths: dict, groups: dict, datasets:
|
||||
populated_line = iterative_replace_line(line, triggers[id], numbers, None)
|
||||
f_out.write(populated_line)
|
||||
elif id == 3:
|
||||
populated_line = iterative_replace_line(line, triggers[id], strings, None)
|
||||
f_out.write(populated_line)
|
||||
elif id == 4:
|
||||
populated_line = iterative_replace_line(line, triggers[id], groups, None)
|
||||
f_out.write(populated_line)
|
||||
else:
|
||||
@ -257,7 +261,7 @@ def check_triggers (input_line: str, triggers: list) -> int:
|
||||
return out_id
|
||||
|
||||
|
||||
def special_populate_text_group(fname: str, paths: dict, group_dict: dict, detailed_dset: dict, detailed_numbers: dict) -> None:
|
||||
def special_populate_text_group(fname: str, paths: dict, group_dict: dict, detailed_dset: dict, detailed_numbers: dict, detailed_strings: dict) -> None:
|
||||
"""
|
||||
Special population for group-related functions in the TEXT back end.
|
||||
|
||||
@ -267,6 +271,7 @@ def special_populate_text_group(fname: str, paths: dict, group_dict: dict, detai
|
||||
group_dict (dict) : dictionary of groups
|
||||
detailed_dset (dict) : dictionary of datasets with substitution details
|
||||
detailed_numbers (dict) : dictionary of numbers with substitution details
|
||||
detailed_strings (dict) : dictionary of string attributes with substitution details
|
||||
|
||||
Returns:
|
||||
None
|
||||
@ -275,7 +280,7 @@ def special_populate_text_group(fname: str, paths: dict, group_dict: dict, detai
|
||||
templ_path = get_template_path(fname, paths)
|
||||
|
||||
triggers = ['group_dset_dtype', 'group_dset_std_dtype_out', 'group_dset_std_dtype_in',
|
||||
'group_dset', 'group_num', 'group']
|
||||
'group_dset', 'group_num', 'group_str', 'group']
|
||||
|
||||
for group in group_dict.keys():
|
||||
|
||||
@ -286,13 +291,15 @@ def special_populate_text_group(fname: str, paths: dict, group_dict: dict, detai
|
||||
subloop_num = False
|
||||
loop_body = ''
|
||||
dset_allocated = []
|
||||
str_allocated = []
|
||||
|
||||
for line in f_in :
|
||||
|
||||
if 'START REPEAT GROUP_DSET' in line:
|
||||
subloop_dset = True
|
||||
continue
|
||||
elif 'START REPEAT GROUP_NUM' in line:
|
||||
# this can be merged in one later using something like START REPEAT GROUP_ATTR in line
|
||||
elif 'START REPEAT GROUP_NUM' in line or 'START REPEAT GROUP_ATTR_STR' in line:
|
||||
subloop_num = True
|
||||
continue
|
||||
|
||||
@ -302,6 +309,11 @@ def special_populate_text_group(fname: str, paths: dict, group_dict: dict, detai
|
||||
if group != detailed_dset[dset]['group']:
|
||||
continue
|
||||
|
||||
if ('REPEAT GROUP_DSET_STR' in line) and (detailed_dset[dset]['dtype'] != 'char*'):
|
||||
continue
|
||||
if ('REPEAT GROUP_DSET_NUM' in line) and (detailed_dset[dset]['dtype'] == 'char*'):
|
||||
continue
|
||||
|
||||
dset_allocated.append(dset)
|
||||
|
||||
if 'FREE($group$->$group_dset$)' in loop_body:
|
||||
@ -309,7 +321,7 @@ def special_populate_text_group(fname: str, paths: dict, group_dict: dict, detai
|
||||
for dset_alloc in dset_allocated:
|
||||
tmp_string += f'FREE({group}->{dset_alloc});\n '
|
||||
|
||||
tmp_body = loop_body.replace('FREE($group$->$group_dset$);',tmp_string)
|
||||
tmp_body = loop_body.replace('FREE($group$->$group_dset$);', tmp_string)
|
||||
|
||||
populated_body = recursive_replace_line(tmp_body, triggers, detailed_dset[dset])
|
||||
f_out.write(populated_body)
|
||||
@ -336,6 +348,33 @@ def special_populate_text_group(fname: str, paths: dict, group_dict: dict, detai
|
||||
loop_body = ''
|
||||
continue
|
||||
|
||||
elif 'END REPEAT GROUP_ATTR_STR' in line:
|
||||
for str in detailed_strings.keys():
|
||||
if group != detailed_strings[str]['group']:
|
||||
continue
|
||||
|
||||
str_allocated.append(str)
|
||||
|
||||
if 'FREE($group$->$group_str$)' in loop_body:
|
||||
tmp_string = ''
|
||||
for str_alloc in str_allocated:
|
||||
tmp_string += f'FREE({group}->{str_alloc});\n '
|
||||
|
||||
tmp_body = loop_body.replace('FREE($group$->$group_str$);', tmp_string)
|
||||
|
||||
populated_body = recursive_replace_line(tmp_body, triggers, detailed_strings[str])
|
||||
f_out.write(populated_body)
|
||||
else:
|
||||
save_body = loop_body
|
||||
populated_body = recursive_replace_line(save_body, triggers, detailed_strings[str])
|
||||
f_out.write(populated_body)
|
||||
|
||||
subloop_num = False
|
||||
loop_body = ''
|
||||
str_allocated = []
|
||||
|
||||
continue
|
||||
|
||||
if not subloop_num and not subloop_dset:
|
||||
# NORMAL CASE WITHOUT SUBLOOPS
|
||||
if '$group_dset' in line:
|
||||
@ -344,6 +383,12 @@ def special_populate_text_group(fname: str, paths: dict, group_dict: dict, detai
|
||||
continue
|
||||
populated_line = recursive_replace_line(line, triggers, detailed_dset[dset])
|
||||
f_out.write(populated_line)
|
||||
elif '$group_str' in line:
|
||||
for str in detailed_strings.keys():
|
||||
if group != detailed_strings[str]['group']:
|
||||
continue
|
||||
populated_line = recursive_replace_line(line, triggers, detailed_strings[str])
|
||||
f_out.write(populated_line)
|
||||
elif '$group_num$' in line:
|
||||
for dim in detailed_numbers.keys():
|
||||
if group != detailed_numbers[dim]['group']:
|
||||
@ -420,6 +465,31 @@ def get_detailed_num_dict (configuration: dict) -> dict:
|
||||
return num_dict
|
||||
|
||||
|
||||
def get_detailed_str_dict (configuration: dict) -> dict:
|
||||
"""
|
||||
Returns the dictionary of all `str`-like attributes.
|
||||
Keys are names, values are subdictionaries containing corresponding group and group_str names.
|
||||
|
||||
Parameters:
|
||||
configuration (dict) : configuration from `trex.json`
|
||||
|
||||
Returns:
|
||||
str_dict (dict) : dictionary of string attributes
|
||||
"""
|
||||
str_dict = {}
|
||||
for k1,v1 in configuration.items():
|
||||
for k2,v2 in v1.items():
|
||||
if len(v2[1]) == 0:
|
||||
tmp_str = f'{k1}_{k2}'
|
||||
if 'str' in v2[0]:
|
||||
tmp_dict = {}
|
||||
tmp_dict['group'] = k1
|
||||
tmp_dict['group_str'] = tmp_str
|
||||
str_dict[tmp_str] = tmp_dict
|
||||
|
||||
return str_dict
|
||||
|
||||
|
||||
def get_dset_dict (configuration: dict) -> dict:
|
||||
"""
|
||||
Returns the dictionary of datasets.
|
||||
@ -485,8 +555,12 @@ def split_dset_dict_detailed (datasets: dict) -> tuple:
|
||||
group_dset_std_dtype_out = '" PRId64 "'
|
||||
group_dset_std_dtype_in = '" SCNd64 "'
|
||||
elif v[0] == 'str':
|
||||
# TODO
|
||||
datatype = 'string'
|
||||
datatype = 'char*'
|
||||
group_dset_h5_dtype = 'c_s1'
|
||||
group_dset_f_dtype_default = 'character(len=*)'
|
||||
group_dset_dtype_default = 'char*'
|
||||
group_dset_std_dtype_out = 's'
|
||||
group_dset_std_dtype_in = 's'
|
||||
|
||||
# add the dset name for templates
|
||||
tmp_dict['group_dset'] = k
|
||||
@ -532,7 +606,7 @@ def split_dset_dict_detailed (datasets: dict) -> tuple:
|
||||
tmp_dict['group'] = v[2]
|
||||
|
||||
# split datasets in numeric- and string- based
|
||||
if (datatype == 'string'):
|
||||
if (datatype == 'char*'):
|
||||
dset_string_dict[k] = tmp_dict
|
||||
else:
|
||||
dset_numeric_dict[k] = tmp_dict
|
||||
|
Loading…
Reference in New Issue
Block a user