1
0
mirror of https://github.com/TREX-CoE/trexio.git synced 2025-01-03 10:06:01 +01:00

Merge pull request #59 from TREX-CoE/general-attributes

General numerical attributes (float, int, dim types)
This commit is contained in:
Evgeny Posenitskiy 2021-09-22 13:33:43 +02:00 committed by GitHub
commit b7dc5fc49f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 15659 additions and 530 deletions

File diff suppressed because one or more lines are too long

View File

@ -28,12 +28,15 @@
Useful when working with C pointers
*/
%include typemaps.i
/* Redefine the int32_t* and int64_t* num to be output
/* Redefine the [int32_t*, int64_t*, float*, double*] num
pattern to be appended to the output tuple.
Useful for TREXIO read_num functions where the
num variable is modified by address
*/
%apply int *OUTPUT { int32_t* const num};
%apply int *OUTPUT { int64_t* const num};
%apply float *OUTPUT { float* const num};
%apply float *OUTPUT { double* const num};
/* Does not work for arrays (SIGSEGV) */
@ -66,23 +69,23 @@ import_array();
%numpy_typemaps(int32_t, NPY_INT32, int64_t)
%numpy_typemaps(int64_t, NPY_INT64, int64_t)
/* Enable write|read_safe functions to convert numpy arrays from/to double arrays */
%apply (double* ARGOUT_ARRAY1, int64_t DIM1) {(double * const dset_out, const int64_t dim_out)};
%apply (double* IN_ARRAY1, int64_t DIM1) {(const double * dset_in, const int64_t dim_in)};
%apply (double* ARGOUT_ARRAY1, int64_t DIM1) {(double* const dset_out, const int64_t dim_out)};
%apply (double* IN_ARRAY1, int64_t DIM1) {(const double* dset_in, const int64_t dim_in)};
/* Enable write|read_safe functions to convert numpy arrays from/to float arrays */
%apply (float* ARGOUT_ARRAY1, int64_t DIM1) {(float * const dset_out, const int64_t dim_out)};
%apply (float* IN_ARRAY1, int64_t DIM1) {(const float * dset_in, const int64_t dim_in)};
%apply (float* ARGOUT_ARRAY1, int64_t DIM1) {(float* const dset_out, const int64_t dim_out)};
%apply (float* IN_ARRAY1, int64_t DIM1) {(const float* dset_in, const int64_t dim_in)};
/* Enable write|read_safe functions to convert numpy arrays from/to int32 arrays */
%apply (int32_t* ARGOUT_ARRAY1, int64_t DIM1) {(int32_t * const dset_out, const int64_t dim_out)};
%apply (int32_t* IN_ARRAY1, int64_t DIM1) {(const int32_t * dset_in, const int64_t dim_in)};
%apply (int32_t* ARGOUT_ARRAY1, int64_t DIM1) {(int32_t* const dset_out, const int64_t dim_out)};
%apply (int32_t* IN_ARRAY1, int64_t DIM1) {(const int32_t* dset_in, const int64_t dim_in)};
/* Enable write|read_safe functions to convert numpy arrays from/to int64 arrays */
%apply (int64_t* ARGOUT_ARRAY1, int64_t DIM1) {(int64_t * const dset_out, const int64_t dim_out)};
%apply (int64_t* IN_ARRAY1, int64_t DIM1) {(const int64_t * dset_in, const int64_t dim_in)};
%apply (int64_t* ARGOUT_ARRAY1, int64_t DIM1) {(int64_t* const dset_out, const int64_t dim_out)};
%apply (int64_t* IN_ARRAY1, int64_t DIM1) {(const int64_t* dset_in, const int64_t dim_in)};
/* This tells SWIG to treat char ** dset_in pattern as a special case
Enables access to trexio_[...]_write_dset_str set of functions directly, i.e.
by converting input list of strings from Python into char ** of C
*/
%typemap(in) char ** dset_in {
%typemap(in) char** dset_in {
/* Check if is a list */
if (PyList_Check($input)) {
int size = PyList_Size($input);
@ -105,7 +108,7 @@ import_array();
}
}
/* This cleans up the char ** array we malloc-ed before */
%typemap(freearg) char ** dset_in {
%typemap(freearg) char** dset_in {
free((char *) $1);
}

View File

@ -164,7 +164,7 @@ __trexio_path__ = None
| ~TREXIO_INVALID_ID~ | 9 | 'Invalid ID' |
| ~TREXIO_ALLOCATION_FAILED~ | 10 | 'Allocation failed' |
| ~TREXIO_HAS_NOT~ | 11 | 'Element absent' |
| ~TREXIO_INVALID_NUM~ | 12 | 'Invalid dimensions' |
| ~TREXIO_INVALID_NUM~ | 12 | 'Invalid (negative or 0) dimension' |
| ~TREXIO_ATTR_ALREADY_EXISTS~ | 13 | 'Attribute already exists' |
| ~TREXIO_DSET_ALREADY_EXISTS~ | 14 | 'Dataset already exists' |
| ~TREXIO_OPEN_ERROR~ | 15 | 'Error opening file' |
@ -389,7 +389,7 @@ return '\n'.join(result)
return "Element absent";
break;
case TREXIO_INVALID_NUM:
return "Invalid dimensions";
return "Invalid (negative or 0) dimension";
break;
case TREXIO_ATTR_ALREADY_EXISTS:
return "Attribute already exists";
@ -1054,6 +1054,7 @@ def close(trexio_file):
, "charge" : [ "float", [ "nucleus.num" ] ]
, "coord" : [ "float", [ "nucleus.num", "3" ] ]
, "label" : [ "str" , [ "nucleus.num" ] ]
, "point_group" : [ "str" , [ ] ]
}
}
#+end_src
@ -1066,32 +1067,38 @@ def close(trexio_file):
All templates presented below use the ~$var$~ notation to indicate
the variable, which will be replaced by the
~generator.py~. Sometimes the upper case is used, i.e. ~$VAR$~ (for
~generator.py~. Sometimes the upper case is used, i.e. ~$VAR$~ (for
example, in ~#define~ statements). More detailed description of
each variable can be found below:
| Template variable | Description | Example |
|--------------------------------+-----------------------------------------------------+----------------------|
| ~$group$~ | Name of the group | ~nucleus~ |
| ~$group_num$~ | Name of the dimensioning variable (scalar) | ~nucleus_num~ |
| ~$group_dset$~ | Name of the dataset (vector/matrix/tensor) | ~nucleus_coord~ |
| ~$group_dset_rank$~ | Rank of the dataset | ~2~ |
| ~$group_dset_dim$~ | Selected dimension of the dataset | ~nucleus_num~ |
| ~$group_dset_dim_list$~ | All dimensions of the dataset | ~{nucleus_num, 3}~ |
| ~$group_dset_dtype$~ | Basic type of the dataset (int/float/char) | ~float~ |
| ~$group_dset_h5_dtype$~ | Type of the dataset in HDF5 | ~double~ |
| ~$group_dset_std_dtype_in$~ | Input type of the dataset in TEXT [fscanf] | ~%lf~ |
| ~$group_dset_std_dtype_out$~ | Output type of the dataset in TEXT [fprintf] | ~%24.16e~ |
| ~$group_dset_dtype_default$~ | Default datatype of the dataset [C] | ~double/int32_t~ |
| ~$group_dset_dtype_single$~ | Single precision datatype of the dataset [C] | ~float/int32_t~ |
| ~$group_dset_dtype_double$~ | Double precision datatype of the dataset [C] | ~double/int64_t~ |
| ~$default_prec$~ | Default precision for read/write without suffix [C] | ~64/32~ |
| ~$group_dset_f_dtype_default$~ | Default datatype of the dataset [Fortran] | ~real(8)/integer(4)~ |
| ~$group_dset_f_dtype_single$~ | Single precision datatype of the dataset [Fortran] | ~real(4)/integer(4)~ |
| ~$group_dset_f_dtype_double$~ | Double precision datatype of the dataset [Fortran] | ~real(8)/integer(8)~ |
| ~$group_dset_f_dims$~ | Dimensions in Fortran | ~(:,:)~ |
| ~$group_dset_py_dtype$~ | Standard datatype of the dataset [Python] | ~float/int~ |
| Template variable | Description | Example |
|--------------------------------+-----------------------------------------------------+-----------------------|
| ~$group$~ | Name of the group | ~nucleus~ |
| ~$group_num$~ | Name of the numerical attribute (scalar) | ~nucleus_num~ |
| ~$group_str$~ | Name of the string attribute (scalar) | ~nucleus_point_group~ |
| ~$group_dset$~ | Name of the dataset (vector/matrix/tensor) | ~nucleus_coord~ |
| ~$group_dset_rank$~ | Rank of the dataset | ~2~ |
| ~$group_dset_dim$~ | Selected dimension of the dataset | ~nucleus_num~ |
| ~$group_dset_dim_list$~ | All dimensions of the dataset | ~{nucleus_num, 3}~ |
| ~$group_dset_dtype$~ | Basic type of the dataset (int/float/char) | ~float~ |
| ~$group_dset_h5_dtype$~ | Type of the dataset in HDF5 | ~double~ |
| ~$group_dset_std_dtype_in$~ | Input type of the dataset in TEXT [fscanf] | ~%lf~ |
| ~$group_dset_std_dtype_out$~ | Output type of the dataset in TEXT [fprintf] | ~%24.16e~ |
| ~$group_dset_dtype_default$~ | Default datatype of the dataset [C] | ~double/int32_t~ |
| ~$group_dset_dtype_single$~ | Single precision datatype of the dataset [C] | ~float/int32_t~ |
| ~$group_dset_dtype_double$~ | Double precision datatype of the dataset [C] | ~double/int64_t~ |
| ~$group_dset_f_dtype_default$~ | Default datatype of the dataset [Fortran] | ~real(8)/integer(4)~ |
| ~$group_dset_f_dtype_single$~ | Single precision datatype of the dataset [Fortran] | ~real(4)/integer(4)~ |
| ~$group_dset_f_dtype_double$~ | Double precision datatype of the dataset [Fortran] | ~real(8)/integer(8)~ |
| ~$group_dset_f_dims$~ | Dimensions in Fortran | ~(:,:)~ |
| ~$group_dset_py_dtype$~ | Standard datatype of the dataset [Python] | ~float/int~ |
| ~$default_prec$~ | Default precision for read/write without suffix [C] | ~64/32~ |
| ~$is_index$~ | Expands to ~true~ if dataset has a type ~index~ [C] | ~true/false~ |
Some of the aforementioned template variables with ~group_dset~ prefix are duplicated with ~group_num~ prefix,
e.g. you might find $group_num_dtype_double$ in the templates corresponding to numerical attributes.
The expanding values are the same as for ~group_dset~ and thus are not listed in the table above.
Note: parent group name is always added to the child objects upon
construction of TREXIO (e.g. ~num~ of ~nucleus~ group becomes
@ -1102,27 +1109,33 @@ def close(trexio_file):
object) levels of =trex.json= . The parsed data is divided in 2
parts:
1) Dimensioning variables (contain ~num~ in their names). These are always scalar integers.
1) Single attributes. These can be numerical values or strings.
2) Datasets. These can be vectors, matrices or tensors. The types are indicated in =trex.json=.
Currently supported types: int, float and strings.
Currently supported data types: int, float and strings.
For each of the aforementioned objects, TREXIO provides *has*,
*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 single dimensioning variable
*Note:* single integer attributes that contain ~num~ in their name (e.g. ~nucleus_num~) are
considered dimensioning variables and cannot be negative or 0. An attempt to write negative or 0
value will result in ~TREXIO_INVALID_ARG_2~ exit code.
This section concerns API calls related to dimensioning variables.
** Templates for front end has/read/write a single numerical attribute
*** Introduction
| Function name | Description | Precision |
|-------------------------------+---------------------------------------------------+-----------|
| ~trexio_has_$group_num$~ | Check if a dimensioning variable exists in a file | --- |
| ~trexio_read_$group_num$~ | Read a dimensioning variable | Single |
| ~trexio_write_$group_num$~ | Write a dimensioning variable | Single |
| ~trexio_read_$group_num$_32~ | Read a dimensioning variable | Single |
| ~trexio_write_$group_num$_32~ | Write a dimensioning variable | Single |
| ~trexio_read_$group_num$_64~ | Read a dimensioning variable | Double |
| ~trexio_write_$group_num$_64~ | Write a dimensioning variable | Double |
This section concerns API calls related to numerical attributes,
namely single value of int/float types.
| Function name | Description | Precision |
|-------------------------------+----------------------------------------+-----------|
| ~trexio_has_$group_num$~ | Check if an attribute exists in a file | --- |
| ~trexio_read_$group_num$~ | Read a attribute | Single |
| ~trexio_write_$group_num$~ | Write a attribute | Single |
| ~trexio_read_$group_num$_32~ | Read a attribute | Single |
| ~trexio_write_$group_num$_32~ | Write a attribute | Single |
| ~trexio_read_$group_num$_64~ | Read a attribute | Double |
| ~trexio_write_$group_num$_64~ | Write a attribute | Double |
*** C templates for front end
@ -1135,70 +1148,39 @@ def close(trexio_file):
(non-suffixed) API call on dimensioning variables deals with single
precision (see Table above).
**** Function declarations
#+begin_src c :tangle hrw_num_front.h :exports none
#+begin_src c :tangle hrw_attr_num_front.h :exports none
trexio_exit_code trexio_has_$group_num$(trexio_t* const file);
trexio_exit_code trexio_read_$group_num$(trexio_t* const file, int32_t* const num);
trexio_exit_code trexio_write_$group_num$(trexio_t* const file, const int32_t num);
trexio_exit_code trexio_read_$group_num$_32(trexio_t* const file, int32_t* const num);
trexio_exit_code trexio_write_$group_num$_32(trexio_t* const file, const int32_t num);
trexio_exit_code trexio_read_$group_num$_64(trexio_t* const file, int64_t* const num);
trexio_exit_code trexio_write_$group_num$_64(trexio_t* const file, const int64_t num);
trexio_exit_code trexio_read_$group_num$(trexio_t* const file, $group_num_dtype_default$* const num);
trexio_exit_code trexio_write_$group_num$(trexio_t* const file, const $group_num_dtype_default$ num);
trexio_exit_code trexio_read_$group_num$_32(trexio_t* const file, $group_num_dtype_single$* const num);
trexio_exit_code trexio_write_$group_num$_32(trexio_t* const file, const $group_num_dtype_single$ num);
trexio_exit_code trexio_read_$group_num$_64(trexio_t* const file, $group_num_dtype_double$* const num);
trexio_exit_code trexio_write_$group_num$_64(trexio_t* const file, const $group_num_dtype_double$ num);
#+end_src
#+begin_src c :tangle read_num_64_front.c
**** Source code for double precision functions
#+begin_src c :tangle read_attr_num_64_front.c
trexio_exit_code
trexio_read_$group_num$_64 (trexio_t* const file, int64_t* const num)
trexio_read_$group_num$_64 (trexio_t* const file, $group_num_dtype_double$* const num)
{
if (file == NULL) return TREXIO_INVALID_ARG_1;
if (trexio_has_$group_num$(file) != TREXIO_SUCCESS) return TREXIO_ATTR_MISSING;
uint64_t u_num = 0;
trexio_exit_code rc = TREXIO_GROUP_READ_ERROR;
switch (file->back_end) {
case TREXIO_TEXT:
rc = trexio_text_read_$group_num$(file, &u_num);
return trexio_text_read_$group_num$(file, num);
break;
case TREXIO_HDF5:
rc = trexio_hdf5_read_$group_num$(file, &u_num);
return trexio_hdf5_read_$group_num$(file, num);
break;
/*
case TREXIO_JSON:
rc =trexio_json_read_$group_num$(file, &u_num);
break;
,*/
}
if (rc != TREXIO_SUCCESS) return rc;
*num = (int64_t) u_num;
return TREXIO_SUCCESS;
}
#+end_src
#+begin_src c :tangle write_num_64_front.c
trexio_exit_code
trexio_write_$group_num$_64 (trexio_t* const file, const int64_t num)
{
if (file == NULL) return TREXIO_INVALID_ARG_1;
if (num < 0 ) return TREXIO_INVALID_ARG_2;
if (trexio_has_$group_num$(file) == TREXIO_SUCCESS) return TREXIO_ATTR_ALREADY_EXISTS;
switch (file->back_end) {
case TREXIO_TEXT:
return trexio_text_write_$group_num$(file, (int64_t) num);
break;
case TREXIO_HDF5:
return trexio_hdf5_write_$group_num$(file, (int64_t) num);
break;
/*
case TREXIO_JSON:
return trexio_json_write_$group_num$(file, (int64_t) num);
return trexio_json_read_$group_num$(file, num);
break;
,*/
}
@ -1207,60 +1189,26 @@ trexio_write_$group_num$_64 (trexio_t* const file, const int64_t num)
}
#+end_src
#+begin_src c :tangle read_num_32_front.c
#+begin_src c :tangle write_attr_num_64_front.c
trexio_exit_code
trexio_read_$group_num$_32 (trexio_t* const file, int32_t* const num)
trexio_write_$group_num$_64 (trexio_t* const file, const $group_num_dtype_double$ num)
{
if (file == NULL) return TREXIO_INVALID_ARG_1;
if (trexio_has_$group_num$(file) != TREXIO_SUCCESS) return TREXIO_ATTR_MISSING;
uint64_t u_num = 0;
trexio_exit_code rc = TREXIO_GROUP_READ_ERROR;
switch (file->back_end) {
case TREXIO_TEXT:
rc = trexio_text_read_$group_num$(file, &u_num);
break;
case TREXIO_HDF5:
rc = trexio_hdf5_read_$group_num$(file, &u_num);
break;
/*
case TREXIO_JSON:
rc =trexio_json_read_$group_num$(file, &u_num);
break;
,*/
}
if (rc != TREXIO_SUCCESS) return rc;
*num = (int32_t) u_num;
return TREXIO_SUCCESS;
}
#+end_src
#+begin_src c :tangle write_num_32_front.c
trexio_exit_code
trexio_write_$group_num$_32 (trexio_t* const file, const int32_t num)
{
if (file == NULL) return TREXIO_INVALID_ARG_1;
if (num < 0 ) return TREXIO_INVALID_ARG_2;
//if (num <= 0L) return TREXIO_INVALID_NUM; /* this line is uncommented by the generator for dimensioning variables; do NOT remove! */
if (trexio_has_$group_num$(file) == TREXIO_SUCCESS) return TREXIO_ATTR_ALREADY_EXISTS;
switch (file->back_end) {
case TREXIO_TEXT:
return trexio_text_write_$group_num$(file, (int64_t) num);
break;
case TREXIO_HDF5:
return trexio_hdf5_write_$group_num$(file, (int64_t) num);
break;
/*
case TREXIO_JSON:
return trexio_json_write_$group_num$(file, (int64_t) num);
return trexio_text_write_$group_num$(file, num);
break;
case TREXIO_HDF5:
return trexio_hdf5_write_$group_num$(file, num);
break;
/*
case TREXIO_JSON:
return trexio_json_write_$group_num$(file, num);
break;
,*/
}
@ -1269,23 +1217,89 @@ trexio_write_$group_num$_32 (trexio_t* const file, const int32_t num)
}
#+end_src
#+begin_src c :tangle read_num_def_front.c
**** Source code for single precision functions
#+begin_src c :tangle read_attr_num_32_front.c
trexio_exit_code
trexio_read_$group_num$ (trexio_t* const file, int32_t* const num)
trexio_read_$group_num$_32 (trexio_t* const file, $group_num_dtype_single$* const num)
{
return trexio_read_$group_num$_32(file, num);
if (file == NULL) return TREXIO_INVALID_ARG_1;
if (trexio_has_$group_num$(file) != TREXIO_SUCCESS) return TREXIO_ATTR_MISSING;
$group_num_dtype_double$ num_64 = 0;
trexio_exit_code rc = TREXIO_GROUP_READ_ERROR;
switch (file->back_end) {
case TREXIO_TEXT:
rc = trexio_text_read_$group_num$(file, &num_64);
break;
case TREXIO_HDF5:
rc = trexio_hdf5_read_$group_num$(file, &num_64);
break;
/*
case TREXIO_JSON:
rc =trexio_json_read_$group_num$(file, &num_64);
break;
,*/
}
if (rc != TREXIO_SUCCESS) return rc;
*num = ($group_num_dtype_single$) num_64;
return TREXIO_SUCCESS;
}
#+end_src
#+begin_src c :tangle write_num_def_front.c
#+begin_src c :tangle write_attr_num_32_front.c
trexio_exit_code
trexio_write_$group_num$ (trexio_t* const file, const int32_t num)
trexio_write_$group_num$_32 (trexio_t* const file, const $group_num_dtype_single$ num)
{
return trexio_write_$group_num$_32(file, num);
if (file == NULL) return TREXIO_INVALID_ARG_1;
//if (num <= 0) return TREXIO_INVALID_NUM; /* this line is uncommented by the generator for dimensioning variables; do NOT remove! */
if (trexio_has_$group_num$(file) == TREXIO_SUCCESS) return TREXIO_ATTR_ALREADY_EXISTS;
switch (file->back_end) {
case TREXIO_TEXT:
return trexio_text_write_$group_num$(file, ($group_num_dtype_double$) num);
break;
case TREXIO_HDF5:
return trexio_hdf5_write_$group_num$(file, ($group_num_dtype_double$) num);
break;
/*
case TREXIO_JSON:
return trexio_json_write_$group_num$(file, ($group_num_dtype_double$) num);
break;
,*/
}
return TREXIO_FAILURE;
}
#+end_src
#+begin_src c :tangle has_num_front.c
**** Source code for default functions
#+begin_src c :tangle read_attr_num_def_front.c
trexio_exit_code
trexio_read_$group_num$ (trexio_t* const file, $group_num_dtype_default$* const num)
{
return trexio_read_$group_num$_$default_prec$(file, num);
}
#+end_src
#+begin_src c :tangle write_attr_num_def_front.c
trexio_exit_code
trexio_write_$group_num$ (trexio_t* const file, const $group_num_dtype_default$ num)
{
return trexio_write_$group_num$_$default_prec$(file, num);
}
#+end_src
#+begin_src c :tangle has_attr_num_front.c
trexio_exit_code
trexio_has_$group_num$ (trexio_t* const file)
{
@ -1319,67 +1333,67 @@ trexio_has_$group_num$ (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_num_64_front_fortran.f90
#+begin_src f90 :tangle write_attr_num_64_front_fortran.f90
interface
integer function trexio_write_$group_num$_64 (trex_file, num) bind(C)
use, intrinsic :: iso_c_binding
integer(8), intent(in), value :: trex_file
integer(8), intent(in), value :: num
$group_num_f_dtype_double$, intent(in), value :: num
end function trexio_write_$group_num$_64
end interface
#+end_src
#+begin_src f90 :tangle read_num_64_front_fortran.f90
#+begin_src f90 :tangle read_attr_num_64_front_fortran.f90
interface
integer function trexio_read_$group_num$_64 (trex_file, num) bind(C)
use, intrinsic :: iso_c_binding
integer(8), intent(in), value :: trex_file
integer(8), intent(out) :: num
$group_num_f_dtype_double$, intent(out) :: num
end function trexio_read_$group_num$_64
end interface
#+end_src
#+begin_src f90 :tangle write_num_32_front_fortran.f90
#+begin_src f90 :tangle write_attr_num_32_front_fortran.f90
interface
integer function trexio_write_$group_num$_32 (trex_file, num) bind(C)
use, intrinsic :: iso_c_binding
integer(8), intent(in), value :: trex_file
integer(4), intent(in), value :: num
$group_num_f_dtype_single$, intent(in), value :: num
end function trexio_write_$group_num$_32
end interface
#+end_src
#+begin_src f90 :tangle read_num_32_front_fortran.f90
#+begin_src f90 :tangle read_attr_num_32_front_fortran.f90
interface
integer function trexio_read_$group_num$_32 (trex_file, num) bind(C)
use, intrinsic :: iso_c_binding
integer(8), intent(in), value :: trex_file
integer(4), intent(out) :: num
$group_num_f_dtype_single$, intent(out) :: num
end function trexio_read_$group_num$_32
end interface
#+end_src
#+begin_src f90 :tangle write_num_def_front_fortran.f90
#+begin_src f90 :tangle write_attr_num_def_front_fortran.f90
interface
integer function trexio_write_$group_num$ (trex_file, num) bind(C)
use, intrinsic :: iso_c_binding
integer(8), intent(in), value :: trex_file
integer(4), intent(in), value :: num
$group_num_f_dtype_default$, intent(in), value :: num
end function trexio_write_$group_num$
end interface
#+end_src
#+begin_src f90 :tangle read_num_def_front_fortran.f90
#+begin_src f90 :tangle read_attr_num_def_front_fortran.f90
interface
integer function trexio_read_$group_num$ (trex_file, num) bind(C)
use, intrinsic :: iso_c_binding
integer(8), intent(in), value :: trex_file
integer(4), intent(out) :: num
$group_num_f_dtype_default$, intent(out) :: num
end function trexio_read_$group_num$
end interface
#+end_src
#+begin_src f90 :tangle has_num_front_fortran.f90
#+begin_src f90 :tangle has_attr_num_front_fortran.f90
interface
integer function trexio_has_$group_num$ (trex_file) bind(C)
use, intrinsic :: iso_c_binding
@ -1390,8 +1404,8 @@ end interface
*** Python templates for front end
#+begin_src python :tangle write_num_front.py
def write_$group_num$(trexio_file, num_w: int) -> None:
#+begin_src python :tangle write_attr_num_front.py
def write_$group_num$(trexio_file, num_w: $group_num_py_dtype$) -> None:
"""Write the $group_num$ variable in the TREXIO file.
Parameters:
@ -1415,8 +1429,8 @@ def write_$group_num$(trexio_file, num_w: int) -> None:
raise
#+end_src
#+begin_src python :tangle read_num_front.py
def read_$group_num$(trexio_file) -> int:
#+begin_src python :tangle read_attr_num_front.py
def read_$group_num$(trexio_file) -> $group_num_py_dtype$:
"""Read the $group_num$ variable from the TREXIO file.
Parameter is a ~TREXIO File~ object that has been created by a call to ~open~ function.
@ -1440,7 +1454,7 @@ def read_$group_num$(trexio_file) -> int:
return num_r
#+end_src
#+begin_src python :tangle has_num_front.py
#+begin_src python :tangle has_attr_num_front.py
def has_$group_num$(trexio_file) -> bool:
"""Check that $group_num$ variable exists in the TREXIO file.
@ -1468,6 +1482,7 @@ def has_$group_num$(trexio_file) -> bool:
#+end_src
** Templates for front end has/read/write a dataset of numerical data
*** Introduction
This section concerns API calls related to datasets.
@ -2324,6 +2339,7 @@ trexio_read_chunk_ao_2e_int_eri_value_64(trexio_t* const file,
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).
**** Function declarations
#+begin_src c :tangle hrw_dset_str_front.h :exports none
trexio_exit_code trexio_has_$group_dset$(trexio_t* const file);
@ -2333,6 +2349,8 @@ trexio_exit_code trexio_read_$group_dset$(trexio_t* const file, char** dset_out,
trexio_exit_code trexio_write_$group_dset$(trexio_t* const file, const char** dset_in, const int32_t max_str_len);
#+end_src
**** Source code for default functions
#+begin_src c :tangle read_dset_str_front.c
trexio_exit_code
trexio_read_$group_dset$_low (trexio_t* const file, char* dset_out, const int32_t max_str_len)
@ -2776,6 +2794,7 @@ def has_$group_dset$(trexio_file) -> bool:
| ~trexio_write_$group_str$~ | Write a string attribute |
*** C templates for front end
**** Function declarations
#+begin_src c :tangle hrw_attr_str_front.h :exports none
trexio_exit_code trexio_has_$group_str$(trexio_t* const file);
@ -2783,6 +2802,8 @@ trexio_exit_code trexio_read_$group_str$(trexio_t* const file, char* const str_o
trexio_exit_code trexio_write_$group_str$(trexio_t* const file, const char* str, const int32_t max_str_len);
#+end_src
**** Source code for default functions
#+begin_src c :tangle read_attr_str_front.c
trexio_exit_code
trexio_read_$group_str$ (trexio_t* const file, char* const str_out, const int32_t max_str_len)

View File

@ -152,18 +152,18 @@ trexio_hdf5_deinit (trexio_t* const file)
}
#+end_src
** Template for HDF5 has/read/write a single dimensioning variable
** Template for HDF5 has/read/write the numerical attribute
#+begin_src c :tangle hrw_num_hdf5.h :exports none
#+begin_src c :tangle hrw_attr_num_hdf5.h :exports none
trexio_exit_code trexio_hdf5_has_$group_num$ (trexio_t* const file);
trexio_exit_code trexio_hdf5_read_$group_num$ (trexio_t* const file, uint64_t* const num);
trexio_exit_code trexio_hdf5_write_$group_num$(trexio_t* const file, const uint64_t num);
trexio_exit_code trexio_hdf5_read_$group_num$ (trexio_t* const file, $group_num_dtype_double$* const num);
trexio_exit_code trexio_hdf5_write_$group_num$(trexio_t* const file, const $group_num_dtype_double$ num);
#+end_src
#+begin_src c :tangle read_num_hdf5.c
#+begin_src c :tangle read_attr_num_hdf5.c
trexio_exit_code
trexio_hdf5_read_$group_num$ (trexio_t* const file, uint64_t* const num)
trexio_hdf5_read_$group_num$ (trexio_t* const file, $group_num_dtype_double$* const num)
{
if (file == NULL) return TREXIO_INVALID_ARG_1;
@ -177,7 +177,7 @@ trexio_hdf5_read_$group_num$ (trexio_t* const file, uint64_t* const num)
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);
const herr_t status = H5Aread(num_id, H5T_$GROUP_NUM_H5_DTYPE$, num);
H5Aclose(num_id);
@ -189,66 +189,44 @@ trexio_hdf5_read_$group_num$ (trexio_t* const file, uint64_t* const num)
#+end_src
#+begin_src c :tangle write_num_hdf5.c
#+begin_src c :tangle write_attr_num_hdf5.c
trexio_exit_code
trexio_hdf5_write_$group_num$ (trexio_t* const file, const uint64_t num)
trexio_hdf5_write_$group_num$ (trexio_t* const file, const $group_num_dtype_double$ num)
{
if (file == NULL) return TREXIO_INVALID_ARG_1;
if (num == 0L ) return TREXIO_INVALID_ARG_2;
trexio_hdf5_t* const f = (trexio_hdf5_t*) file;
if (H5Aexists(f->$group$_group, $GROUP_NUM$_NAME) == 0) {
/* Write the dimensioning variables */
const hid_t dtype = H5Tcopy(H5T_NATIVE_UINT64);
const hid_t dspace = H5Screate(H5S_SCALAR);
const hid_t num_id = H5Acreate(f->$group$_group, $GROUP_NUM$_NAME, dtype, dspace,
H5P_DEFAULT, H5P_DEFAULT);
if (num_id <= 0) {
H5Sclose(dspace);
H5Tclose(dtype);
return TREXIO_INVALID_ID;
}
const herr_t status = H5Awrite(num_id, dtype, &(num));
if (status < 0) {
H5Aclose(num_id);
H5Sclose(dspace);
H5Tclose(dtype);
return TREXIO_FAILURE;
}
/* Write the dimensioning variables */
const hid_t dtype = H5Tcopy(H5T_$GROUP_NUM_H5_DTYPE$);
const hid_t dspace = H5Screate(H5S_SCALAR);
const hid_t num_id = H5Acreate(f->$group$_group, $GROUP_NUM$_NAME,
dtype, dspace, H5P_DEFAULT, H5P_DEFAULT);
if (num_id <= 0) {
H5Sclose(dspace);
H5Aclose(num_id);
H5Tclose(dtype);
return TREXIO_SUCCESS;
} else {
uint64_t infile_num;
trexio_exit_code rc = trexio_hdf5_read_$group_num$(file, &(infile_num));
if (rc != TREXIO_SUCCESS) return rc;
const hid_t dtype = H5Tcopy(H5T_NATIVE_UINT64);
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 = H5Awrite(num_id, dtype, &(num));
if (status < 0) return TREXIO_FAILURE;
H5Aclose(num_id);
H5Tclose(dtype);
return TREXIO_SUCCESS;
return TREXIO_INVALID_ID;
}
const herr_t status = H5Awrite(num_id, dtype, &(num));
if (status < 0) {
H5Aclose(num_id);
H5Sclose(dspace);
H5Tclose(dtype);
return TREXIO_FAILURE;
}
H5Sclose(dspace);
H5Aclose(num_id);
H5Tclose(dtype);
return TREXIO_SUCCESS;
}
#+end_src
#+begin_src c :tangle has_num_hdf5.c
#+begin_src c :tangle has_attr_num_hdf5.c
trexio_exit_code
trexio_hdf5_has_$group_num$ (trexio_t* const file)
{
@ -270,7 +248,7 @@ trexio_hdf5_has_$group_num$ (trexio_t* const file)
}
#+end_src
** Template for HDF5 has/read/write a dataset of numerical data
** Template for HDF5 has/read/write the dataset of numerical data
#+begin_src c :tangle hrw_dset_data_hdf5.h :exports none
trexio_exit_code trexio_hdf5_has_$group_dset$(trexio_t* const file);
@ -341,12 +319,6 @@ trexio_hdf5_write_$group_dset$ (trexio_t* const file, const $group_dset_dtype$*
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;
if ( H5LTfind_dataset(f->$group$_group, $GROUP_DSET$_NAME) != 1 ) {
@ -400,7 +372,7 @@ trexio_hdf5_has_$group_dset$ (trexio_t* const file)
}
#+end_src
** Template for HDF5 has/read/write a dataset of strings
** Template for HDF5 has/read/write the 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);
@ -523,12 +495,6 @@ trexio_hdf5_write_$group_dset$ (trexio_t* const file, const char** $group_dset$,
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;
@ -612,7 +578,7 @@ trexio_hdf5_has_$group_dset$ (trexio_t* const file)
}
#+end_src
** Template for HDF5 has/read/write a single string attribute
** Template for HDF5 has/read/write the 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);

View File

@ -19,19 +19,19 @@ cat populated/pop_flush_group_text.h >> trexio_text.h
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_has_attr_num_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_read_attr_num_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_write_attr_num_text.c >> trexio_text.c
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_num_text.h >> trexio_text.h
cat populated/pop_hrw_attr_str_text.h >> trexio_text.h
cat rdm_text.c >> trexio_text.c

View File

@ -46,6 +46,7 @@
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <stdbool.h>
#+end_src
@ -78,7 +79,8 @@
#+begin_src c :tangle struct_text_group_dset.h
typedef struct $group$_s {
uint64_t $group_num$;
$group_num_dtype_double$ $group_num$;
bool $group_num$_isSet;
$group_dset_dtype$* $group_dset$;
uint32_t rank_$group_dset$;
uint32_t to_flush;
@ -346,18 +348,21 @@ trexio_text_read_$group$ (trexio_text_t* const file)
}
// END REPEAT GROUP_DSET_ALL
unsigned int local_isSet;
// START REPEAT GROUP_NUM
/* Read data */
rc = fscanf(f, "%1023s", buffer);
assert(!((rc != 1) || (strcmp(buffer, "$group_num$") != 0)));
if ((rc != 1) || (strcmp(buffer, "$group_num$") != 0)) {
assert(!((rc != 1) || (strcmp(buffer, "$group_num$_isSet") != 0)));
if ((rc != 1) || (strcmp(buffer, "$group_num$_isSet") != 0)) {
FREE(buffer);
fclose(f);
FREE($group$);
return NULL;
}
rc = fscanf(f, "%" SCNu64 "", &($group$->$group_num$));
/* additional parameter local_isSet is needed to suppress warning when fscanf into bool variable using %u or %d */
rc = fscanf(f, "%u", &(local_isSet));
$group$->$group_num$_isSet = (bool) local_isSet;
assert(!(rc != 1));
if (rc != 1) {
FREE(buffer);
@ -365,6 +370,26 @@ trexio_text_read_$group$ (trexio_text_t* const file)
FREE($group$);
return NULL;
}
if ($group$->$group_num$_isSet == true) {
rc = fscanf(f, "%1023s", buffer);
assert(!((rc != 1) || (strcmp(buffer, "$group_num$") != 0)));
if ((rc != 1) || (strcmp(buffer, "$group_num$") != 0)) {
FREE(buffer);
fclose(f);
FREE($group$);
return NULL;
}
rc = fscanf(f, "%$group_num_std_dtype_in$", &($group$->$group_num$));
assert(!(rc != 1));
if (rc != 1) {
FREE(buffer);
fclose(f);
FREE($group$);
return NULL;
}
}
// END REPEAT GROUP_NUM
// START REPEAT GROUP_ATTR_STR
@ -458,49 +483,51 @@ trexio_text_read_$group$ (trexio_text_t* const file)
// 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);
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;
if(size_$group_dset$ != 0) {
$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$;
tmp_$group_dset$ = CALLOC(size_$group_dset$*32, char);
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;
}
size_t tmp_$group_dset$_len = strlen($group$->$group_dset$[i]);
tmp_$group_dset$ += tmp_$group_dset$_len + 1;
}
size_t tmp_$group_dset$_len = strlen($group$->$group_dset$[i]);
tmp_$group_dset$ += tmp_$group_dset$_len + 1;
}
// END REPEAT GROUP_DSET_STR
@ -555,7 +582,8 @@ trexio_text_flush_$group$ (trexio_text_t* const file)
// END REPEAT GROUP_DSET_ALL
// START REPEAT GROUP_NUM
fprintf(f, "$group_num$ %" PRIu64 "\n", $group$->$group_num$);
fprintf(f, "$group_num$_isSet %u \n", $group$->$group_num$_isSet);
if ($group$->$group_num$_isSet == true) fprintf(f, "$group_num$ %$group_num_std_dtype_out$ \n", $group$->$group_num$);
// END REPEAT GROUP_NUM
// START REPEAT GROUP_ATTR_STR
@ -624,17 +652,17 @@ trexio_text_free_$group$ (trexio_text_t* const file)
}
#+end_src
** Template for has/read/write the num attribute
** Template for has/read/write the numerical attribute
#+begin_src c :tangle hrw_num_text.h :exports none
#+begin_src c :tangle hrw_attr_num_text.h :exports none
trexio_exit_code trexio_text_has_$group_num$ (trexio_t* const file);
trexio_exit_code trexio_text_read_$group_num$ (trexio_t* const file, uint64_t* const num);
trexio_exit_code trexio_text_write_$group_num$(trexio_t* const file, const uint64_t num);
trexio_exit_code trexio_text_read_$group_num$ (trexio_t* const file, $group_num_dtype_double$* const num);
trexio_exit_code trexio_text_write_$group_num$(trexio_t* const file, const $group_num_dtype_double$ num);
#+end_src
#+begin_src c :tangle read_num_text.c
#+begin_src c :tangle read_attr_num_text.c
trexio_exit_code
trexio_text_read_$group_num$ (trexio_t* const file, uint64_t* const num)
trexio_text_read_$group_num$ (trexio_t* const file, $group_num_dtype_double$* const num)
{
if (file == NULL) return TREXIO_INVALID_ARG_1;
@ -650,9 +678,9 @@ trexio_text_read_$group_num$ (trexio_t* const file, uint64_t* const num)
}
#+end_src
#+begin_src c :tangle write_num_text.c
#+begin_src c :tangle write_attr_num_text.c
trexio_exit_code
trexio_text_write_$group_num$ (trexio_t* const file, const uint64_t num)
trexio_text_write_$group_num$ (trexio_t* const file, const $group_num_dtype_double$ num)
{
if (file == NULL) return TREXIO_INVALID_ARG_1;
@ -662,6 +690,7 @@ trexio_text_write_$group_num$ (trexio_t* const file, const uint64_t num)
if ($group$ == NULL) return TREXIO_FAILURE;
$group$->$group_num$ = num;
$group$->$group_num$_isSet = true;
$group$->to_flush = 1;
return TREXIO_SUCCESS;
@ -669,7 +698,7 @@ trexio_text_write_$group_num$ (trexio_t* const file, const uint64_t num)
}
#+end_src
#+begin_src c :tangle has_num_text.c
#+begin_src c :tangle has_attr_num_text.c
trexio_exit_code
trexio_text_has_$group_num$ (trexio_t* const file)
{
@ -678,7 +707,7 @@ trexio_text_has_$group_num$ (trexio_t* const file)
$group$_t* $group$ = trexio_text_read_$group$((trexio_text_t*) file);
if ($group$ == NULL) return TREXIO_FAILURE;
if ($group$->$group_num$ > 0L){
if ($group$->$group_num$_isSet == true){
return TREXIO_SUCCESS;
} else {
return TREXIO_HAS_NOT;

View File

@ -27,6 +27,14 @@ static int test_write_num (const char* file_name, const back_end_t backend) {
rc = trexio_write_nucleus_num(file, num);
assert (rc == TREXIO_SUCCESS);
// attempt to write 0 as dimensioning variable in an empty file; should FAIL and return TREXIO_INVALID_ARG_2
rc = trexio_write_mo_num(file, 0);
assert (rc == TREXIO_INVALID_NUM);
// write numerical attribute ao_cartesian as 0
rc = trexio_write_ao_cartesian(file, 0);
assert (rc == TREXIO_SUCCESS);
// close current session
rc = trexio_close(file);
assert (rc == TREXIO_SUCCESS);
@ -77,6 +85,7 @@ static int test_read_num (const char* file_name, const back_end_t backend) {
// parameters to be read
int num;
int cartesian;
/*================= START OF TEST ==================*/
@ -89,6 +98,15 @@ static int test_read_num (const char* file_name, const back_end_t backend) {
assert (rc == TREXIO_SUCCESS);
assert (num == 12);
// read non-existing numerical attribute from the file
rc = trexio_read_mo_num(file, &num);
assert (rc == TREXIO_ATTR_MISSING);
// read ao_cartesian (zero) value from the file
rc = trexio_read_ao_cartesian(file, &cartesian);
assert (rc == TREXIO_SUCCESS);
assert (cartesian == 0);
// close current session
rc = trexio_close(file);
assert (rc == TREXIO_SUCCESS);

View File

@ -27,6 +27,14 @@ static int test_write_num (const char* file_name, const back_end_t backend) {
rc = trexio_write_nucleus_num(file, num);
assert (rc == TREXIO_SUCCESS);
// attempt to write 0 as dimensioning variable in an empty file; should FAIL and return TREXIO_INVALID_ARG_2
rc = trexio_write_mo_num(file, 0);
assert (rc == TREXIO_INVALID_NUM);
// write numerical attribute ao_cartesian as 0
rc = trexio_write_ao_cartesian(file, 0);
assert (rc == TREXIO_SUCCESS);
// close current session
rc = trexio_close(file);
assert (rc == TREXIO_SUCCESS);
@ -77,6 +85,7 @@ static int test_read_num (const char* file_name, const back_end_t backend) {
// parameters to be read
int num;
int cartesian;
/*================= START OF TEST ==================*/
@ -89,6 +98,15 @@ static int test_read_num (const char* file_name, const back_end_t backend) {
assert (rc == TREXIO_SUCCESS);
assert (num == 12);
// read non-existing numerical attribute from the file
rc = trexio_read_mo_num(file, &num);
assert (rc == TREXIO_ATTR_MISSING);
// read ao_cartesian (zero) value from the file
rc = trexio_read_ao_cartesian(file, &cartesian);
assert (rc == TREXIO_SUCCESS);
assert (cartesian == 0);
// close current session
rc = trexio_close(file);
assert (rc == TREXIO_SUCCESS);

View File

@ -41,7 +41,7 @@ for fname in files_todo['auxiliary']:
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']:
for fname in files_todo['attr_num']:
recursive_populate_file(fname, template_paths, detailed_nums)
# populate has/read/write_str functions with recursive scheme

View File

@ -39,7 +39,7 @@ 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_data', 'dset_str', 'num', 'attr_str', 'group']:
for key in ['dset_data', 'dset_str', 'attr_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')
@ -100,10 +100,13 @@ def recursive_populate_file(fname: str, paths: dict, detailed_source: dict) -> N
fname_new = join('populated',f'pop_{fname}')
templ_path = get_template_path(fname, paths)
triggers = ['group_dset_dtype', 'group_dset_py_dtype', 'group_dset_h5_dtype', 'default_prec', 'is_index',
'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',
triggers = ['group_dset_dtype', 'group_dset_py_dtype', 'group_dset_h5_dtype', 'default_prec', 'is_index',
'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_num_f_dtype_default', 'group_num_f_dtype_double', 'group_num_f_dtype_single',
'group_num_dtype_default', 'group_num_dtype_double', 'group_num_dtype_single',
'group_num_h5_dtype', 'group_num_py_dtype',
'group_dset', 'group_num', 'group_str', 'group']
for item in detailed_source.keys():
@ -126,6 +129,12 @@ def recursive_populate_file(fname: str, paths: dict, detailed_source: dict) -> N
f_out.write(templine)
num_written = []
continue
# special case to uncomment check for positive dimensioning variables in templates
elif 'uncommented by the generator for dimensioning' in line:
# only uncomment and write the line if `num` is in the name
if 'dim' in detailed_source[item]['trex_json_int_type']:
templine = line.replace('//', '')
f_out.write(templine)
# general case of recursive replacement of inline triggers
else:
populated_line = recursive_replace_line(line, triggers, detailed_source[item])
@ -284,6 +293,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_num_dtype_double', 'group_num_std_dtype_out', 'group_num_std_dtype_in',
'group_dset', 'group_num', 'group_str', 'group']
for group in group_dict.keys():
@ -455,7 +465,7 @@ def get_detailed_num_dict (configuration: dict) -> dict:
configuration (dict) : configuration from `trex.json`
Returns:
num_dict (dict) : dictionary of num-suffixed variables
num_dict (dict) : dictionary of all numerical attributes (of types int, float, dim)
"""
num_dict = {}
for k1,v1 in configuration.items():
@ -468,6 +478,35 @@ def get_detailed_num_dict (configuration: dict) -> dict:
tmp_dict['group_num'] = tmp_num
num_dict[tmp_num] = tmp_dict
# TODO the arguments below are almost the same as for group_dset (except for trex_json_int_type) and can be exported from somewhere
if v2[0] == 'float':
tmp_dict['datatype'] = 'double'
tmp_dict['group_num_h5_dtype'] = 'native_double'
tmp_dict['group_num_f_dtype_default']= 'real(8)'
tmp_dict['group_num_f_dtype_double'] = 'real(8)'
tmp_dict['group_num_f_dtype_single'] = 'real(4)'
tmp_dict['group_num_dtype_default']= 'double'
tmp_dict['group_num_dtype_double'] = 'double'
tmp_dict['group_num_dtype_single'] = 'float'
tmp_dict['default_prec'] = '64'
tmp_dict['group_num_std_dtype_out'] = '24.16e'
tmp_dict['group_num_std_dtype_in'] = 'lf'
tmp_dict['group_num_py_dtype'] = 'float'
elif v2[0] in ['int', 'dim']:
tmp_dict['datatype'] = 'int64_t'
tmp_dict['group_num_h5_dtype'] = 'native_int64'
tmp_dict['group_num_f_dtype_default']= 'integer(4)'
tmp_dict['group_num_f_dtype_double'] = 'integer(8)'
tmp_dict['group_num_f_dtype_single'] = 'integer(4)'
tmp_dict['group_num_dtype_default']= 'int32_t'
tmp_dict['group_num_dtype_double'] = 'int64_t'
tmp_dict['group_num_dtype_single'] = 'int32_t'
tmp_dict['default_prec'] = '32'
tmp_dict['group_num_std_dtype_out'] = '" PRId64 "'
tmp_dict['group_num_std_dtype_in'] = '" SCNd64 "'
tmp_dict['group_num_py_dtype'] = 'int'
tmp_dict['trex_json_int_type'] = v2[0]
return num_dict
@ -634,7 +673,7 @@ def check_dim_consistency(num: dict, dset: dict) -> None:
Consistency check to make sure that each dimensioning variable exists as a num attribute of some group.
Parameters:
num (dict) : dictionary of num-suffixed variables
num (dict) : dictionary of numerical attributes
dset (dict) : dictionary of datasets
Returns:
@ -647,6 +686,8 @@ def check_dim_consistency(num: dict, dset: dict) -> None:
if dim not in dim_tocheck:
dim_tocheck.append(dim)
num_onlyDim = [attr_name for attr_name, specs in num.items() if specs['trex_json_int_type']=='dim']
for dim in dim_tocheck:
if not dim in num.keys():
if not dim in num_onlyDim:
raise ValueError(f"Dimensioning variable {dim} is not a num attribute of any group.\n")

144
trex.org
View File

@ -16,6 +16,14 @@ column-major order (as in Fortran), and the ordering of the dimensions
is reversed in the produced ~trex.json~ configuration file as the library is
written in C.
TREXIO currently supports ~int~, ~float~ and ~str~ types for both single attributes and arrays.
Note, that some attributes might have ~dim~ type (e.g. ~num~ of the ~nucleus~ group).
This type is treated exactly the same as ~int~ with the only difference that ~dim~ variables
cannot be negative or zero. This additional constraint is required because ~dim~ attributes
are used internally to allocate memory and to check array boundaries in the memory-safe API.
Most of the times, the ~dim~ variables contain ~num~ suffix.
In Fortran, the arrays are 1-based and in most other languages the
arrays are 0-based. Hence, we introduce the ~index~ type which is an
1-based ~int~ in the Fortran interface and 0-based otherwise.
@ -35,9 +43,9 @@ arrays are 0-based. Hence, we introduce the ~index~ type which is an
#+NAME: metadata
| Variable | Type | Dimensions (for arrays) | Description |
|-------------------+-------+-------------------------+------------------------------------------|
| ~code_num~ | ~int~ | | Number of codes used to produce the file |
| ~code_num~ | ~dim~ | | Number of codes used to produce the file |
| ~code~ | ~str~ | ~(metadata.code_num)~ | Names of the codes used |
| ~author_num~ | ~int~ | | Number of authors of the file |
| ~author_num~ | ~dim~ | | Number of authors of the file |
| ~author~ | ~str~ | ~(metadata.author_num)~ | Names of the authors of the file |
| ~package_version~ | ~str~ | | TREXIO version used to produce the file |
| ~description~ | ~str~ | | Text describing the content of file |
@ -47,9 +55,9 @@ arrays are 0-based. Hence, we introduce the ~index~ type which is an
:RESULTS:
#+begin_src python :tangle trex.json
"metadata": {
"code_num" : [ "int", [] ]
"code_num" : [ "dim", [] ]
, "code" : [ "str", [ "metadata.code_num" ] ]
, "author_num" : [ "int", [] ]
, "author_num" : [ "dim", [] ]
, "author" : [ "str", [ "metadata.author_num" ] ]
, "package_version" : [ "str", [] ]
, "description" : [ "str", [] ]
@ -65,19 +73,19 @@ arrays are 0-based. Hence, we introduce the ~index~ type which is an
#+NAME:electron
| Variable | Type | Dimensions | Description |
|----------+-------+------------+-------------------------------------|
| ~up_num~ | ~int~ | | Number of \uparrow-spin electrons |
| ~dn_num~ | ~int~ | | Number of \downarrow-spin electrons |
| ~up_num~ | ~dim~ | | Number of \uparrow-spin electrons |
| ~dn_num~ | ~dim~ | | Number of \downarrow-spin electrons |
#+CALL: json(data=electron, title="electron")
#+RESULTS:
:results:
:RESULTS:
#+begin_src python :tangle trex.json
"electron": {
"up_num" : [ "int", [] ]
, "dn_num" : [ "int", [] ]
"up_num" : [ "dim", [] ]
, "dn_num" : [ "dim", [] ]
} ,
#+end_src
:end:
:END:
* Nucleus (nucleus group)
@ -87,7 +95,7 @@ arrays are 0-based. Hence, we introduce the ~index~ type which is an
#+NAME: nucleus
| Variable | Type | Dimensions | Description |
|---------------+---------+-------------------+--------------------------|
| ~num~ | ~int~ | | Number of nuclei |
| ~num~ | ~dim~ | | Number of nuclei |
| ~charge~ | ~float~ | ~(nucleus.num)~ | Charges of the nuclei |
| ~coord~ | ~float~ | ~(3,nucleus.num)~ | Coordinates of the atoms |
| ~label~ | ~str~ | ~(nucleus.num)~ | Atom labels |
@ -95,17 +103,17 @@ arrays are 0-based. Hence, we introduce the ~index~ type which is an
#+CALL: json(data=nucleus, title="nucleus")
#+RESULTS:
:results:
:RESULTS:
#+begin_src python :tangle trex.json
"nucleus": {
"num" : [ "int" , [] ]
, "charge" : [ "float", [ "nucleus.num" ] ]
, "coord" : [ "float", [ "nucleus.num", "3" ] ]
, "label" : [ "str" , [ "nucleus.num" ] ]
, "point_group" : [ "str" , [] ]
"num" : [ "dim" , [] ]
, "charge" : [ "float", [ "nucleus.num" ] ]
, "coord" : [ "float", [ "nucleus.num", "3" ] ]
, "label" : [ "str" , [ "nucleus.num" ] ]
, "point_group" : [ "str" , [] ]
} ,
#+end_src
:end:
:END:
* Effective core potentials (ecp group)
@ -135,12 +143,12 @@ arrays are 0-based. Hence, we introduce the ~index~ type which is an
| ~lmax_plus_1~ | ~int~ | ~(nucleus.num)~ | $\ell_{\max} + 1$, one higher than the maximum angular momentum in the removed core orbitals |
| ~z_core~ | ~float~ | ~(nucleus.num)~ | Charges to remove |
| ~local_n~ | ~int~ | ~(nucleus.num)~ | Number of local functions $N_{q \ell}$ |
| ~local_num_n_max~ | ~int~ | | Maximum value of ~local_n~, used for dimensioning arrays |
| ~local_exponent~ | ~float~ | ~(ecp.local_num_n_max, nucleus.num)~ | $\alpha_{A q \ell_{\max}}$ |
| ~local_coef~ | ~float~ | ~(ecp.local_num_n_max, nucleus.num)~ | $\beta_{A q \ell_{\max}}$ |
| ~local_num_n_max~ | ~dim~ | | Maximum value of ~local_n~, used for dimensioning arrays |
| ~local_exponent~ | ~float~ | ~(ecp.local_num_n_max, nucleus.num)~ | $\alpha_{A q \ell_{\max}}$ |
| ~local_coef~ | ~float~ | ~(ecp.local_num_n_max, nucleus.num)~ | $\beta_{A q \ell_{\max}}$ |
| ~local_power~ | ~int~ | ~(ecp.local_num_n_max, nucleus.num)~ | $n_{A q \ell_{\max}}$ |
| ~non_local_n~ | ~int~ | ~(nucleus.num)~ | $N_{q \ell_{\max}}$ |
| ~non_local_num_n_max~ | ~int~ | | Maximum value of ~non_local_n~, used for dimensioning arrays |
| ~non_local_num_n_max~ | ~dim~ | | Maximum value of ~non_local_n~, used for dimensioning arrays |
| ~non_local_exponent~ | ~float~ | ~(ecp.non_local_num_n_max, nucleus.num)~ | $\alpha_{A q \ell}$ |
| ~non_local_coef~ | ~float~ | ~(ecp.non_local_num_n_max, nucleus.num)~ | $\beta_{A q \ell}$ |
| ~non_local_power~ | ~int~ | ~(ecp.non_local_num_n_max, nucleus.num)~ | $n_{A q \ell}$ |
@ -148,24 +156,24 @@ arrays are 0-based. Hence, we introduce the ~index~ type which is an
#+CALL: json(data=ecp, title="ecp")
#+RESULTS:
:results:
:RESULTS:
#+begin_src python :tangle trex.json
"ecp": {
"lmax_plus_1" : [ "int" , [ "nucleus.num" ] ]
, "z_core" : [ "float", [ "nucleus.num" ] ]
, "local_n" : [ "int" , [ "nucleus.num" ] ]
, "local_num_n_max" : [ "int" , [] ]
, "local_exponent" : [ "float", [ "nucleus.num", "ecp.local_num_n_max" ] ]
, "local_coef" : [ "float", [ "nucleus.num", "ecp.local_num_n_max" ] ]
, "local_power" : [ "int" , [ "nucleus.num", "ecp.local_num_n_max" ] ]
, "non_local_n" : [ "int" , [ "nucleus.num" ] ]
, "non_local_num_n_max" : [ "int" , [] ]
, "non_local_exponent" : [ "float", [ "nucleus.num", "ecp.non_local_num_n_max" ] ]
, "non_local_coef" : [ "float", [ "nucleus.num", "ecp.non_local_num_n_max" ] ]
, "non_local_power" : [ "int" , [ "nucleus.num", "ecp.non_local_num_n_max" ] ]
"lmax_plus_1" : [ "int" , [ "nucleus.num" ] ]
, "z_core" : [ "float", [ "nucleus.num" ] ]
, "local_n" : [ "int" , [ "nucleus.num" ] ]
, "local_num_n_max" : [ "dim" , [] ]
, "local_exponent" : [ "float", [ "nucleus.num", "ecp.local_num_n_max" ] ]
, "local_coef" : [ "float", [ "nucleus.num", "ecp.local_num_n_max" ] ]
, "local_power" : [ "int" , [ "nucleus.num", "ecp.local_num_n_max" ] ]
, "non_local_n" : [ "int" , [ "nucleus.num" ] ]
, "non_local_num_n_max" : [ "dim" , [] ]
, "non_local_exponent" : [ "float", [ "nucleus.num", "ecp.non_local_num_n_max" ] ]
, "non_local_coef" : [ "float", [ "nucleus.num", "ecp.non_local_num_n_max" ] ]
, "non_local_power" : [ "int" , [ "nucleus.num", "ecp.non_local_num_n_max" ] ]
} ,
#+end_src
:end:
:END:
* Basis set (basis group)
@ -210,8 +218,8 @@ arrays are 0-based. Hence, we introduce the ~index~ type which is an
| Variable | Type | Dimensions | Description |
|---------------------+---------+--------------------+----------------------------------------------------------|
| ~type~ | ~str~ | | Type of basis set: "Gaussian" or "Slater" |
| ~num~ | ~int~ | | Total Number of shells |
| ~prim_num~ | ~int~ | | Total number of primitives |
| ~num~ | ~dim~ | | Total Number of shells |
| ~prim_num~ | ~dim~ | | Total number of primitives |
| ~nucleus_index~ | ~index~ | ~(nucleus.num)~ | Index of the first shell of each nucleus ($A$) |
| ~nucleus_shell_num~ | ~int~ | ~(nucleus.num)~ | Number of shells for each nucleus |
| ~shell_ang_mom~ | ~int~ | ~(basis.num)~ | Angular momentum ~0:S, 1:P, 2:D, ...~ |
@ -225,24 +233,24 @@ arrays are 0-based. Hence, we introduce the ~index~ type which is an
#+CALL: json(data=basis, title="basis")
#+RESULTS:
:results:
:RESULTS:
#+begin_src python :tangle trex.json
"basis": {
"type" : [ "str" , [] ]
, "num" : [ "int" , [] ]
, "prim_num" : [ "int" , [] ]
, "nucleus_index" : [ "index", [ "nucleus.num" ] ]
, "nucleus_shell_num" : [ "int" , [ "nucleus.num" ] ]
, "shell_ang_mom" : [ "int" , [ "basis.num" ] ]
, "shell_prim_num" : [ "int" , [ "basis.num" ] ]
, "shell_factor" : [ "float", [ "basis.num" ] ]
, "shell_prim_index" : [ "index", [ "basis.num" ] ]
, "exponent" : [ "float", [ "basis.prim_num" ] ]
, "coefficient" : [ "float", [ "basis.prim_num" ] ]
, "prim_factor" : [ "float", [ "basis.prim_num" ] ]
"type" : [ "str" , [] ]
, "num" : [ "dim" , [] ]
, "prim_num" : [ "dim" , [] ]
, "nucleus_index" : [ "index", [ "nucleus.num" ] ]
, "nucleus_shell_num" : [ "int" , [ "nucleus.num" ] ]
, "shell_ang_mom" : [ "int" , [ "basis.num" ] ]
, "shell_prim_num" : [ "int" , [ "basis.num" ] ]
, "shell_factor" : [ "float", [ "basis.num" ] ]
, "shell_prim_index" : [ "index", [ "basis.num" ] ]
, "exponent" : [ "float", [ "basis.prim_num" ] ]
, "coefficient" : [ "float", [ "basis.prim_num" ] ]
, "prim_factor" : [ "float", [ "basis.prim_num" ] ]
} ,
#+end_src
:end:
:END:
For example, consider H_2 with the following basis set (in GAMESS
format), where both the AOs and primitives are considered normalized:
@ -348,23 +356,23 @@ prim_factor =
| Variable | Type | Dimensions | Description |
|-----------------+---------+------------+---------------------------------|
| ~cartesian~ | ~int~ | | ~1~: true, ~0~: false |
| ~num~ | ~int~ | | Total number of atomic orbitals |
| ~num~ | ~dim~ | | Total number of atomic orbitals |
| ~shell~ | ~index~ | ~(ao.num)~ | basis set shell for each AO |
| ~normalization~ | ~float~ | ~(ao.num)~ | Normalization factors |
#+CALL: json(data=ao, title="ao")
#+RESULTS:
:results:
:RESULTS:
#+begin_src python :tangle trex.json
"ao": {
"cartesian" : [ "int" , [] ]
, "num" : [ "int" , [] ]
, "shell" : [ "index", [ "ao.num" ] ]
, "normalization" : [ "float", [ "ao.num" ] ]
"cartesian" : [ "int" , [] ]
, "num" : [ "dim" , [] ]
, "shell" : [ "index", [ "ao.num" ] ]
, "normalization" : [ "float", [ "ao.num" ] ]
} ,
#+end_src
:end:
:END:
** One-electron integrals (~ao_1e_int~ group)
:PROPERTIES:
@ -453,7 +461,7 @@ prim_factor =
| Variable | Type | Dimensions | Description |
|---------------+---------+--------------------+--------------------------------------------------------------------------|
| ~type~ | ~str~ | | Free text to identify the set of MOs (HF, Natural, Local, CASSCF, /etc/) |
| ~num~ | ~int~ | | Number of MOs |
| ~num~ | ~dim~ | | Number of MOs |
| ~coefficient~ | ~float~ | ~(ao.num, mo.num)~ | MO coefficients |
| ~class~ | ~str~ | ~(mo.num)~ | Choose among: Core, Inactive, Active, Virtual, Deleted |
| ~symmetry~ | ~str~ | ~(mo.num)~ | Symmetry in the point group |
@ -462,18 +470,18 @@ prim_factor =
#+CALL: json(data=mo, title="mo")
#+RESULTS:
:results:
:RESULTS:
#+begin_src python :tangle trex.json
"mo": {
"type" : [ "str" , [] ]
, "num" : [ "int" , [] ]
, "coefficient" : [ "float", [ "mo.num", "ao.num" ] ]
, "class" : [ "str" , [ "mo.num" ] ]
, "symmetry" : [ "str" , [ "mo.num" ] ]
, "occupation" : [ "float", [ "mo.num" ] ]
"type" : [ "str" , [] ]
, "num" : [ "dim" , [] ]
, "coefficient" : [ "float", [ "mo.num", "ao.num" ] ]
, "class" : [ "str" , [ "mo.num" ] ]
, "symmetry" : [ "str" , [ "mo.num" ] ]
, "occupation" : [ "float", [ "mo.num" ] ]
} ,
#+end_src
:end:
:END:
** One-electron integrals (~mo_1e_int~ group)