From f29f3d4263d701251275d7dc59df287fc443c10b Mon Sep 17 00:00:00 2001 From: q-posev Date: Wed, 10 Mar 2021 14:51:15 +0100 Subject: [PATCH] added templator for frontend --- src/templates_front/templator_front.org | 624 ++++++++++++++++++++++++ 1 file changed, 624 insertions(+) create mode 100644 src/templates_front/templator_front.org diff --git a/src/templates_front/templator_front.org b/src/templates_front/templator_front.org new file mode 100644 index 0000000..e209ffe --- /dev/null +++ b/src/templates_front/templator_front.org @@ -0,0 +1,624 @@ +#+Title: Templator for frontend + +* Constant file prefixes (not used by generator) :noxport: + +** Prefixes + + #+NAME:header + #+begin_src c +/* This file was generated from the trexio.org org-mode file. + To generate it, open trexio.org in Emacs and execute + M-x org-babel-tangle +*/ + + #+end_src + + #+begin_src c :tangle prefix_front.h :noweb yes +<
> +#ifndef _TREXIO_H +#define _TREXIO_H + +#include + + #+end_src + + #+begin_src c :tangle prefix_front.c :noweb yes +<
> +#include +#include +#include +#include +#include + +#include "trexio.h" +#include "trexio_s.h" +#include "trexio_text.h" +#include "trexio_hdf5.h" +/* +#include "trexio_json.h" +,*/ + + #+end_src + + #+begin_src c :tangle prefix_s_front.h :noweb yes +<
> +#ifndef _TREXIO_S_H +#define _TREXIO_S_H + +#include "trexio.h" +#include +#include + #+end_src + +** Error handling + #+begin_src c :tangle prefix_front.h +typedef int32_t trexio_exit_code; + +#define TREXIO_FAILURE ( (trexio_exit_code) -1 ) +#define TREXIO_SUCCESS ( (trexio_exit_code) 0 ) +#define TREXIO_INVALID_ARG_1 ( (trexio_exit_code) 1 ) +#define TREXIO_INVALID_ARG_2 ( (trexio_exit_code) 2 ) +#define TREXIO_INVALID_ARG_3 ( (trexio_exit_code) 3 ) +#define TREXIO_INVALID_ARG_4 ( (trexio_exit_code) 4 ) +#define TREXIO_INVALID_ARG_5 ( (trexio_exit_code) 5 ) +#define TREXIO_END ( (trexio_exit_code) 10 ) +#define TREXIO_READONLY ( (trexio_exit_code) 11 ) +#define TREXIO_ERRNO ( (trexio_exit_code) 12 ) +#define TREXIO_INVALID_ID ( (trexio_exit_code) 20 ) +#define TREXIO_INVALID_NUM ( (trexio_exit_code) 21 ) + #+end_src + +** Back ends + + #+begin_src c :tangle prefix_front.h +typedef int32_t back_end_t; + +#define TREXIO_HDF5 ( (back_end_t) 0 ) +#define TREXIO_TEXT ( (back_end_t) 1 ) +#define TREXIO_JSON ( (back_end_t) 2 ) +#define TREXIO_INVALID_BACK_END ( (back_end_t) 3 ) + #+end_src + +** Read/write behavior + + Every time a reading function is called, the data is read from the + disk. If data needs to be cached, this is left to the user of the + library. + + Writing to TREXIO files is done with transactions (all-or-nothing + effect) in a per-group fashion. File writes are attempted by + calling explicitly the flush function, or when the TREXIO file is + closed. If writing is impossible because the data is not valid, no + data is written. + + The order in which the data is written is not necessarily consistent + with the order in which the function calls were made. + + The TREXIO files are supposed to be opened by only one program at a + time: if the same TREXIO file is modified simultaneously by multiple + concurrent programs, the behavior is not specified. + +** TREXIO file type + + ~trexio_s~ is the the main type for TREXIO files, visible to the users + of the library. This type is kept opaque, and all modifications to + the files will be necessarily done through the use of functions, + taking such a type as argument. + + File creation and opening functions will return /TREXIO file handles/, + namely pointers to ~trexio_s~ types. All functions accessing to the + TREXIO files will have as a first argument the TREXIO file handle. + + #+begin_src c :tangle prefix_front.h +typedef struct trexio_s trexio_t; + #+end_src + + #+begin_src c :tangle prefix_s_front.h +struct trexio_s { + char* file_name; + pthread_mutex_t thread_lock; + back_end_t back_end; + char mode; + char padding[7]; /* Ensures the proper alignment of back-ends */ +}; + #+end_src + +** Polymorphism of the file handle + + Polymorphism of the ~trexio_t~ type is handled by ensuring that the + corresponding types for all back ends can be safely casted to + ~trexio_t~. This is done by making the back end structs start with + ~struct trexio_s~: + + #+begin_src c +struct trexio_back_end_s { + trexio_t parent ; + /* add below specific back end data */ +} + #+end_src + +** File opening + + #+begin_src c :tangle prefix_front.h +trexio_t* trexio_open(const char* file_name, const char mode, const back_end_t back_end); + #+end_src + + #+begin_src c :tangle prefix_front.c +trexio_t* trexio_open(const char* file_name, const char mode, const back_end_t back_end) { + + if (file_name == NULL) return NULL; + if (file_name[0] == '\0') return NULL; + + if (back_end < 0) return NULL; + if (back_end >= TREXIO_INVALID_BACK_END) return NULL; + + if (mode != 'r' && mode != 'w' && mode != 'a') return NULL; + + trexio_t* result = NULL; + + /* Allocate data structures */ + switch (back_end) { + + case TREXIO_TEXT: + result = (trexio_t*) malloc (sizeof(trexio_text_t)); + break; + + case TREXIO_HDF5: + result = (trexio_t*) malloc (sizeof(trexio_hdf5_t)); + break; +/* + case TREXIO_JSON: + result = (trexio_t*) malloc (sizeof(trexio_json_t)); + break; +,*/ + } + + assert (result != NULL); /* TODO: Error handling */ + + + /* Data for the parent type */ + + result->file_name = (char*) calloc(strlen(file_name)+1,sizeof(char)); + strcpy(result->file_name, file_name); + result->back_end = back_end; + result->mode = mode; + int irc = pthread_mutex_init ( &(result->thread_lock), NULL); + assert (irc == 0); + + trexio_exit_code rc; + + /* Back end initialization */ + + rc = TREXIO_FAILURE; + + switch (back_end) { + + case TREXIO_TEXT: + rc = trexio_text_init(result); + break; + + case TREXIO_HDF5: + rc = trexio_hdf5_init(result); + break; +/* + case TREXIO_JSON: + rc = trexio_json_init(result); + break; +,*/ + } + + if (rc != TREXIO_SUCCESS) { + free(result->file_name); + free(result); + return NULL; + } + + /* File locking */ + + rc = TREXIO_FAILURE; + + switch (back_end) { + + case TREXIO_TEXT: + rc = trexio_text_lock(result); + break; + + case TREXIO_HDF5: + rc = TREXIO_SUCCESS; + break; +/* + case TREXIO_JSON: + rc = trexio_json_lock(result); + break; +*/ + } + + if (rc != TREXIO_SUCCESS) { + free(result->file_name); + free(result); + return NULL; + } + + return result; +} + #+end_src + +** File closing + + #+begin_src c :tangle prefix_front.h +trexio_exit_code trexio_close(trexio_t* file); + #+end_src + + #+begin_src c :tangle prefix_front.c +trexio_exit_code trexio_close(trexio_t* file) { + + if (file == NULL) return TREXIO_FAILURE; + + trexio_exit_code rc; + + /* Terminate the back end */ + switch (file->back_end) { + + case TREXIO_TEXT: + rc = trexio_text_finalize(file); + break; + + case TREXIO_HDF5: + rc = trexio_hdf5_finalize(file); + break; +/* + case TREXIO_JSON: + rc = trexio_json_finalize(file); + break; +,*/ + default: + assert (1 == 0); /* Impossible case */ + } + + if (rc != TREXIO_SUCCESS) { + free(file->file_name); + free(file); + return TREXIO_FAILURE; + } + + /* File unlocking */ + + rc = TREXIO_FAILURE; + + switch (file->back_end) { + + case TREXIO_TEXT: + rc = trexio_text_unlock(file); + break; + + case TREXIO_HDF5: + rc = TREXIO_SUCCESS; + break; +/* + case TREXIO_JSON: + rc = trexio_json_unlock(file); + break; +*/ + } + + /* Terminate front end */ + + free(file->file_name); + file->file_name = NULL; + + int irc = pthread_mutex_destroy( &(file->thread_lock) ); + + free(file); + + if (irc != 0) return TREXIO_ERRNO; + if (rc != TREXIO_SUCCESS) return TREXIO_FAILURE; + + return TREXIO_SUCCESS; +} + #+end_src + + +* Front end + +** Template for frontend read/write a number + + #+begin_src c :tangle rw_num_front.h +trexio_exit_code trexio_read_$group_num$(trexio_t* file, int64_t* num); +trexio_exit_code trexio_write_$group_num$(trexio_t* file, const int64_t num); + #+end_src + + #+begin_src c :tangle read_num_front.c +trexio_exit_code trexio_read_$group_num$(trexio_t* file, int64_t* num) { + if (file == NULL) return TREXIO_INVALID_ARG_1; + + uint64_t u_num = 0; + trexio_exit_code rc = TREXIO_FAILURE; + + 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 = (int64_t) u_num; + return TREXIO_SUCCESS; +} + #+end_src + + #+begin_src c :tangle write_num_front.c + +trexio_exit_code trexio_write_$group_num$(trexio_t* file, const int64_t num) { + if (file == NULL) return TREXIO_INVALID_ARG_1; + if (num < 0 ) return TREXIO_INVALID_ARG_2; + + trexio_exit_code rc = TREXIO_FAILURE; + + switch (file->back_end) { + + case TREXIO_TEXT: + rc = trexio_text_write_$group_num$(file, (uint64_t) num); + break; + + case TREXIO_HDF5: + rc = trexio_hdf5_write_$group_num$(file, (uint64_t) num); + break; +/* + case TREXIO_JSON: + rc = trexio_json_write_$group_num$(file, (uint64_t) num); + break; +,*/ + } + if (rc != TREXIO_SUCCESS) return rc; + + return TREXIO_SUCCESS; +} + #+end_src + + +** Template for frontend read/write a dataset + + #+begin_src c :tangle rw_dset_front.h +trexio_exit_code trexio_read_$group$_$group_dset$(trexio_t* file, $group_dset_dtype$* $group_dset$); +trexio_exit_code trexio_write_$group$_$group_dset$(trexio_t* file, const $group_dset_dtype$* $group_dset$); + #+end_src + + #+begin_src c :tangle read_dset_front.c +trexio_exit_code trexio_read_$group$_$group_dset$(trexio_t* file, $group_dset_dtype$* $group_dset$) { + if (file == NULL) return TREXIO_INVALID_ARG_1; + if (coord == NULL) return TREXIO_INVALID_ARG_2; + + trexio_exit_code rc; + uint64_t $group_dset_dim$ = -1; + // 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; + + int64_t dim_total = nucleus_num*3; + if (dim_total < 0) return TREXIO_FAILURE; + + uint32_t rank = $group_dset_rank$; + uint64_t dims[$group_dset_rank$] = {$group_dset_dim_list$}; + + switch (file->back_end) { + + case TREXIO_TEXT: + return trexio_text_read_$group$_$group_dset$(file, $group_dset$, (uint64_t) dim_total); + break; + + case TREXIO_HDF5: + return trexio_hdf5_read_$group$_$group_dset$(file, $group_dset$, rank, dims); + break; +/* + case TREXIO_JSON: + return trexio_json_read_$group$_$group_dset$(file, $group_dset$); + break; +,*/ + default: + return TREXIO_FAILURE; /* Impossible case */ + } +} + #+end_src + + #+begin_src c :tangle write_dset_front.c + +trexio_exit_code trexio_write_$group$_$group_dset$(trexio_t* file, const $group_dset_dtype$* $group_dset$) { + if (file == NULL) return TREXIO_INVALID_ARG_1; + if (coord == NULL) return TREXIO_INVALID_ARG_2; + + trexio_exit_code rc; + uint64_t $group_dset_dim$ = -1; + // 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; + + int64_t dim_total = nucleus_num*3; + if (dim_total < 0) return TREXIO_FAILURE; + + uint32_t rank = $group_dset_rank$; + uint64_t dims[$group_dset_rank$] = {$group_dset_dim_list$}; + + switch (file->back_end) { + + case TREXIO_TEXT: + return trexio_text_write_$group$_$group_dset$(file, $group_dset$, (uint64_t) dim_total); + break; + + case TREXIO_HDF5: + return trexio_hdf5_write_$group$_$group_dset$(file, $group_dset$, rank, dims); + break; +/* + case TREXIO_JSON: + return trexio_json_write_$group$_$group_dset$(file, $group_dset$); + break; +,*/ + default: + return TREXIO_FAILURE; /* Impossible case */ + } +} + #+end_src + + ## *** rdm +**** one_e + #+begin_src c :tangle trexio.h +trexio_exit_code trexio_read_rdm_one_e(trexio_t* file, double* one_e); +trexio_exit_code trexio_write_rdm_one_e(trexio_t* file, const double* one_e); + #+end_src + + #+begin_src c :tangle trexio.c +trexio_exit_code trexio_read_rdm_one_e(trexio_t* file, double* one_e) { + if (file == NULL) return TREXIO_INVALID_ARG_1; + if (one_e == NULL) return TREXIO_INVALID_ARG_2; + + int64_t dim_one_e = -1; + trexio_exit_code rc = trexio_read_nucleus_num(file, &dim_one_e); /* This dimension is wrong. Should be mo_num */ + if (rc != TREXIO_SUCCESS) return rc; + if (dim_one_e < 0) return TREXIO_FAILURE; + + switch (file->back_end) { + + case TREXIO_TEXT: + return trexio_text_read_rdm_one_e(file, one_e, (uint64_t) dim_one_e); + break; +/* + case TREXIO_HDF5: + return trexio_hdf5_read_rdm_one_e(file, one_e); + break; + + case TREXIO_JSON: + return trexio_json_read_rdm_one_e(file, one_e); + break; +,*/ + default: + return TREXIO_FAILURE; /* Impossible case */ + } +} + +trexio_exit_code trexio_write_rdm_one_e(trexio_t* file, const double* one_e) { + if (file == NULL) return TREXIO_INVALID_ARG_1; + if (one_e == NULL) return TREXIO_INVALID_ARG_2; + + int64_t nucleus_num = -1; + trexio_exit_code rc = trexio_read_nucleus_num(file, &nucleus_num); + if (rc != TREXIO_SUCCESS) return rc; + + int64_t dim_one_e = nucleus_num * nucleus_num; /* This dimension is wrong. Should be mo_num */ + if (dim_one_e < 0) return TREXIO_FAILURE; + + switch (file->back_end) { + + case TREXIO_TEXT: + return trexio_text_write_rdm_one_e(file, one_e, (uint64_t) dim_one_e); + break; +/* + case TREXIO_HDF5: + return trexio_hdf5_write_rdm_one_e(file, one_e); + break; + + case TREXIO_JSON: + return trexio_json_write_rdm_one_e(file, one_e); + break; +,*/ + default: + return TREXIO_FAILURE; /* Impossible case */ + } +} + #+end_src + +**** two_e + + ~buffered_read~ functions return ~TREXIO_SUCCESS~ if the complete + buffer was read or written. If the read data is smaller than the + buffer because the end is reached, the function returns ~TREXIO_END~. + + #+begin_src c :tangle trexio.h +trexio_exit_code trexio_buffered_read_rdm_two_e(trexio_t* file, const int64_t offset, const int64_t size, int64_t* index, double* value); +trexio_exit_code trexio_buffered_write_rdm_two_e(trexio_t* file, const int64_t offset, const int64_t size, const int64_t* index, const double* value); + #+end_src + + #+begin_src c :tangle trexio.c +trexio_exit_code trexio_buffered_read_rdm_two_e(trexio_t* file, const int64_t offset, const int64_t size, int64_t* index, double* value) { + if (file == NULL) return TREXIO_INVALID_ARG_1; + if (offset <= 0 ) return TREXIO_INVALID_ARG_2; + if (size <= 0 ) return TREXIO_INVALID_ARG_3; + if (index == NULL) return TREXIO_INVALID_ARG_4; + if (value == NULL) return TREXIO_INVALID_ARG_5; + + switch (file->back_end) { + + case TREXIO_TEXT: + return trexio_text_buffered_read_rdm_two_e(file, (uint64_t) offset, (uint64_t) size, index, value); + break; +/* + case TREXIO_HDF5: + return trexio_hdf5_buffered_read_rdm_two_e(file, size); + break; + + case TREXIO_JSON: + return trexio_json_buffered_read_rdm_two_e(file, size); + break; +,*/ + default: + return TREXIO_FAILURE; /* Impossible case */ + } +} + +trexio_exit_code trexio_buffered_write_rdm_two_e(trexio_t* file, const int64_t offset, const int64_t size, const int64_t* index, const double* value) { + if (file == NULL) return TREXIO_INVALID_ARG_1; + if (offset <= 0 ) return TREXIO_INVALID_ARG_2; + if (size <= 0 ) return TREXIO_INVALID_ARG_3; + if (index == NULL) return TREXIO_INVALID_ARG_4; + if (value == NULL) return TREXIO_INVALID_ARG_5; + + switch (file->back_end) { + + case TREXIO_TEXT: + return trexio_text_buffered_write_rdm_two_e(file, (uint64_t) offset, (uint64_t) size, index, value); + break; +/* + case TREXIO_HDF5: + return trexio_hdf5_buffered_write_rdm_two_e(file, size); + break; + + case TREXIO_JSON: + return trexio_json_buffered_write_rdm_two_e(file, size); + break; +,*/ + default: + return TREXIO_FAILURE; /* Impossible case */ + } +} + #+end_src + + +* Back ends + + TREXIO has multiple possible back ends: + + - HDF5: The most efficient back-end, by default + - Text files: not to be used for production, but useful for debugging + - JSON: for portability + +* File suffixes :noxport: + + #+begin_src c :tangle suffix_front.h +#endif + #+end_src + + #+begin_src c :tangle suffix_s_front.h +#endif + #+end_src + + +