diff --git a/src/trexio.c b/src/trexio.c index 2d940d4..042ddb3 100644 --- a/src/trexio.c +++ b/src/trexio.c @@ -81,8 +81,12 @@ trexio_t* trexio_open(const char* file_name, const char mode, const back_end_t b break; */ } - if (rc != TREXIO_SUCCESS) return NULL; - + + if (rc != TREXIO_SUCCESS) { + free(result->file_name); + free(result); + return NULL; + } /* File locking */ @@ -96,18 +100,20 @@ trexio_t* trexio_open(const char* file_name, const char mode, const back_end_t b case TREXIO_HDF5: rc = TREXIO_SUCCESS; -/* - rc = trexio_hdf5_lock(result); break; - +/* case TREXIO_JSON: rc = trexio_json_lock(result); break; */ } - if (rc != TREXIO_SUCCESS) return NULL; - + if (rc != TREXIO_SUCCESS) { + free(result->file_name); + free(result); + return NULL; + } + return result; } @@ -137,9 +143,10 @@ trexio_exit_code trexio_close(trexio_t* file) { } if (rc != TREXIO_SUCCESS) { + free(file->file_name); + free(file); return TREXIO_FAILURE; } - /* File unlocking */ @@ -153,17 +160,13 @@ trexio_exit_code trexio_close(trexio_t* file) { case TREXIO_HDF5: rc = TREXIO_SUCCESS; -/* - rc = trexio_hdf5_unlock(file); break; - +/* case TREXIO_JSON: rc = trexio_json_unlock(file); break; */ } - if (rc != TREXIO_SUCCESS) return TREXIO_FAILURE; - /* Terminate front end */ @@ -171,11 +174,12 @@ trexio_exit_code trexio_close(trexio_t* file) { 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; } @@ -244,6 +248,9 @@ trexio_exit_code trexio_read_nucleus_coord(trexio_t* file, double* coord) { int64_t dim_coord = nucleus_num*3; if (dim_coord < 0) return TREXIO_FAILURE; + uint32_t rank = 2; + uint64_t dims[2] = {nucleus_num, 3}; + switch (file->back_end) { case TREXIO_TEXT: @@ -251,7 +258,7 @@ trexio_exit_code trexio_read_nucleus_coord(trexio_t* file, double* coord) { break; case TREXIO_HDF5: - return trexio_hdf5_read_nucleus_coord(file, coord); + return trexio_hdf5_read_nucleus_coord(file, coord, rank, dims); break; /* case TREXIO_JSON: @@ -274,6 +281,9 @@ trexio_exit_code trexio_write_nucleus_coord(trexio_t* file, const double* coord) int64_t dim_coord = nucleus_num*3; if (dim_coord < 0) return TREXIO_FAILURE; + uint32_t rank = 2; + uint64_t dims[2] = {nucleus_num, 3}; + switch (file->back_end) { case TREXIO_TEXT: @@ -281,7 +291,7 @@ trexio_exit_code trexio_write_nucleus_coord(trexio_t* file, const double* coord) break; case TREXIO_HDF5: - return trexio_hdf5_write_nucleus_coord(file, coord); + return trexio_hdf5_write_nucleus_coord(file, coord, rank, dims); break; /* case TREXIO_JSON: diff --git a/src/trexio.h b/src/trexio.h index 26aad39..f36285f 100644 --- a/src/trexio.h +++ b/src/trexio.h @@ -22,6 +22,8 @@ typedef int32_t trexio_exit_code; #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 ) typedef int32_t back_end_t; diff --git a/src/trexio.org b/src/trexio.org index 0bc5bac..874585f 100644 --- a/src/trexio.org +++ b/src/trexio.org @@ -79,6 +79,8 @@ typedef int32_t trexio_exit_code; #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 @@ -219,8 +221,12 @@ trexio_t* trexio_open(const char* file_name, const char mode, const back_end_t b break; ,*/ } - if (rc != TREXIO_SUCCESS) return NULL; - + + if (rc != TREXIO_SUCCESS) { + free(result->file_name); + free(result); + return NULL; + } /* File locking */ @@ -234,18 +240,20 @@ trexio_t* trexio_open(const char* file_name, const char mode, const back_end_t b case TREXIO_HDF5: rc = TREXIO_SUCCESS; -/* - rc = trexio_hdf5_lock(result); break; - +/* case TREXIO_JSON: rc = trexio_json_lock(result); break; -,*/ +*/ + } + + if (rc != TREXIO_SUCCESS) { + free(result->file_name); + free(result); + return NULL; } - if (rc != TREXIO_SUCCESS) return NULL; - return result; } #+end_src @@ -283,9 +291,10 @@ trexio_exit_code trexio_close(trexio_t* file) { } if (rc != TREXIO_SUCCESS) { + free(file->file_name); + free(file); return TREXIO_FAILURE; } - /* File unlocking */ @@ -299,17 +308,13 @@ trexio_exit_code trexio_close(trexio_t* file) { case TREXIO_HDF5: rc = TREXIO_SUCCESS; -/* - rc = trexio_hdf5_unlock(file); break; - +/* case TREXIO_JSON: rc = trexio_json_unlock(file); break; -,*/ +*/ } - if (rc != TREXIO_SUCCESS) return TREXIO_FAILURE; - /* Terminate front end */ @@ -317,11 +322,12 @@ trexio_exit_code trexio_close(trexio_t* file) { 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 @@ -407,6 +413,9 @@ trexio_exit_code trexio_read_nucleus_coord(trexio_t* file, double* coord) { int64_t dim_coord = nucleus_num*3; if (dim_coord < 0) return TREXIO_FAILURE; + uint32_t rank = 2; + uint64_t dims[2] = {nucleus_num, 3}; + switch (file->back_end) { case TREXIO_TEXT: @@ -414,7 +423,7 @@ trexio_exit_code trexio_read_nucleus_coord(trexio_t* file, double* coord) { break; case TREXIO_HDF5: - return trexio_hdf5_read_nucleus_coord(file, coord); + return trexio_hdf5_read_nucleus_coord(file, coord, rank, dims); break; /* case TREXIO_JSON: @@ -437,6 +446,9 @@ trexio_exit_code trexio_write_nucleus_coord(trexio_t* file, const double* coord) int64_t dim_coord = nucleus_num*3; if (dim_coord < 0) return TREXIO_FAILURE; + uint32_t rank = 2; + uint64_t dims[2] = {nucleus_num, 3}; + switch (file->back_end) { case TREXIO_TEXT: @@ -444,7 +456,7 @@ trexio_exit_code trexio_write_nucleus_coord(trexio_t* file, const double* coord) break; case TREXIO_HDF5: - return trexio_hdf5_write_nucleus_coord(file, coord); + return trexio_hdf5_write_nucleus_coord(file, coord, rank, dims); break; /* case TREXIO_JSON: diff --git a/src/trexio_hdf5.c b/src/trexio_hdf5.c index 8c46932..62c72bf 100644 --- a/src/trexio_hdf5.c +++ b/src/trexio_hdf5.c @@ -402,43 +402,88 @@ trexio_exit_code trexio_hdf5_write_nucleus_num(const trexio_t* file, const uint6 return TREXIO_SUCCESS; } -trexio_exit_code trexio_hdf5_read_nucleus_coord(const trexio_t* file, double* coord) { - - assert (file != NULL); - assert (coord != NULL); - - h5nucleus_t* nucleus = trexio_hdf5_read_nucleus((trexio_hdf5_t*) file); - - if (nucleus == NULL) return TREXIO_FAILURE; - assert (nucleus->coord != NULL); - - for (size_t i=0 ; i<3*nucleus->num ; i++) { - coord[i] = nucleus->coord[i]; - } - - trexio_hdf5_free_nucleus(nucleus); - return TREXIO_SUCCESS; -} - - -trexio_exit_code trexio_hdf5_write_nucleus_coord(const trexio_t* file, const double* coord) { +trexio_exit_code trexio_hdf5_read_nucleus_coord(const trexio_t* file, double* coord, const uint32_t rank, const uint64_t* dims) { assert (file != NULL); assert (coord != NULL); - h5nucleus_t* nucleus = trexio_hdf5_read_nucleus((trexio_hdf5_t*) file); - - if (nucleus == NULL) return TREXIO_FAILURE; - assert (nucleus->coord != NULL); - - for (size_t i=0 ; i<3*nucleus->num ; i++) { - nucleus->coord[i] = coord[i]; - } + trexio_hdf5_t* f = (trexio_hdf5_t*) file; - trexio_exit_code rc = trexio_hdf5_write_nucleus((trexio_hdf5_t*) file, nucleus); - assert (rc == TREXIO_SUCCESS); + herr_t status; + int rrank; + // get the rank of the dataset in a file + status = H5LTget_dataset_ndims (f->nucleus_group, NUCLEUS_COORD_NAME, + &rrank); - trexio_hdf5_free_nucleus(nucleus); + if (status < 0) return TREXIO_FAILURE; + + if (rrank != (int) rank) return TREXIO_INVALID_ARG_3; + + // open the dataset to get its dimensions + hid_t dset_id = H5Dopen(f->nucleus_group, NUCLEUS_COORD_NAME, H5P_DEFAULT); + if (dset_id <= 0) return TREXIO_INVALID_ID; + + // allocate space for the dimensions to be read + hsize_t* ddims = (hsize_t*) calloc( (int) rank, sizeof(hsize_t)); + if (ddims == NULL) return TREXIO_FAILURE; + + // read dimensions from the existing dataset + status = H5LDget_dset_dims(dset_id, ddims); + + H5Dclose(dset_id); + if (status < 0) { + free(ddims); + return TREXIO_FAILURE; + } + + for (uint32_t i=0; inucleus_group, + NUCLEUS_COORD_NAME, + coord); + if (status < 0) return TREXIO_FAILURE; + + return TREXIO_SUCCESS; +} + + +trexio_exit_code trexio_hdf5_write_nucleus_coord(const trexio_t* file, const double* coord, const uint32_t rank, const uint64_t* dims) { + + assert (file != NULL); + assert (coord != NULL); + + uint64_t nucleus_num; + trexio_exit_code rc = trexio_hdf5_read_nucleus_num(file, &(nucleus_num)); + if (rc != TREXIO_SUCCESS) return rc; + if (nucleus_num <= 0L) return TREXIO_INVALID_NUM; + + trexio_hdf5_t* f = (trexio_hdf5_t*) file; + + herr_t status; + if ( H5LTfind_dataset(f->nucleus_group, NUCLEUS_COORD_NAME) != 1) { + + status = H5LTmake_dataset_double (f->nucleus_group, NUCLEUS_COORD_NAME, + (int) rank, (hsize_t*) dims, coord); + if (status < 0) return TREXIO_FAILURE; + + } else { + + hid_t dset_id = H5Dopen(f->nucleus_group, NUCLEUS_COORD_NAME, H5P_DEFAULT); + if (dset_id <= 0) return TREXIO_INVALID_ID; + + status = H5Dwrite(dset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, coord); + + H5Dclose(dset_id); + if (status < 0) return TREXIO_FAILURE; + + } return TREXIO_SUCCESS; } diff --git a/src/trexio_hdf5.h b/src/trexio_hdf5.h index 1689cf8..f71360c 100644 --- a/src/trexio_hdf5.h +++ b/src/trexio_hdf5.h @@ -91,7 +91,7 @@ typedef struct four_index_s { trexio_exit_code trexio_hdf5_read_nucleus_num(const trexio_t* file, uint64_t* num); trexio_exit_code trexio_hdf5_write_nucleus_num(const trexio_t* file, const uint64_t num); -trexio_exit_code trexio_hdf5_read_nucleus_coord(const trexio_t* file, double* coord); -trexio_exit_code trexio_hdf5_write_nucleus_coord(const trexio_t* file, const double* coord); +trexio_exit_code trexio_hdf5_read_nucleus_coord(const trexio_t* file, double* coord, const uint32_t rank, const uint64_t* dims); +trexio_exit_code trexio_hdf5_write_nucleus_coord(const trexio_t* file, const double* coord, const uint32_t rank, const uint64_t* dims); #endif diff --git a/src/trexio_hdf5.org b/src/trexio_hdf5.org index d146d3a..cda15ba 100644 --- a/src/trexio_hdf5.org +++ b/src/trexio_hdf5.org @@ -36,7 +36,7 @@ #include "trexio_hdf5.h" #+end_src - + * HDF5 Back end ** HDF5 definitions @@ -560,49 +560,94 @@ trexio_exit_code trexio_hdf5_write_nucleus_num(const trexio_t* file, const uint6 The ~coord~ array is assumed allocated with the appropriate size. #+begin_src c :tangle trexio_hdf5.h -trexio_exit_code trexio_hdf5_read_nucleus_coord(const trexio_t* file, double* coord); -trexio_exit_code trexio_hdf5_write_nucleus_coord(const trexio_t* file, const double* coord); +trexio_exit_code trexio_hdf5_read_nucleus_coord(const trexio_t* file, double* coord, const uint32_t rank, const uint64_t* dims); +trexio_exit_code trexio_hdf5_write_nucleus_coord(const trexio_t* file, const double* coord, const uint32_t rank, const uint64_t* dims); #+end_src #+begin_src c :tangle trexio_hdf5.c -trexio_exit_code trexio_hdf5_read_nucleus_coord(const trexio_t* file, double* coord) { +trexio_exit_code trexio_hdf5_read_nucleus_coord(const trexio_t* file, double* coord, const uint32_t rank, const uint64_t* dims) { assert (file != NULL); assert (coord != NULL); - - h5nucleus_t* nucleus = trexio_hdf5_read_nucleus((trexio_hdf5_t*) file); - - if (nucleus == NULL) return TREXIO_FAILURE; - assert (nucleus->coord != NULL); - for (size_t i=0 ; i<3*nucleus->num ; i++) { - coord[i] = nucleus->coord[i]; + trexio_hdf5_t* f = (trexio_hdf5_t*) file; + + herr_t status; + int rrank; + // get the rank of the dataset in a file + status = H5LTget_dataset_ndims (f->nucleus_group, NUCLEUS_COORD_NAME, + &rrank); + + if (status < 0) return TREXIO_FAILURE; + + if (rrank != (int) rank) return TREXIO_INVALID_ARG_3; + + // open the dataset to get its dimensions + hid_t dset_id = H5Dopen(f->nucleus_group, NUCLEUS_COORD_NAME, H5P_DEFAULT); + if (dset_id <= 0) return TREXIO_INVALID_ID; + + // allocate space for the dimensions to be read + hsize_t* ddims = (hsize_t*) calloc( (int) rank, sizeof(hsize_t)); + if (ddims == NULL) return TREXIO_FAILURE; + + // read dimensions from the existing dataset + status = H5LDget_dset_dims(dset_id, ddims); + + H5Dclose(dset_id); + if (status < 0) { + free(ddims); + return TREXIO_FAILURE; } - trexio_hdf5_free_nucleus(nucleus); + for (uint32_t i=0; inucleus_group, + NUCLEUS_COORD_NAME, + coord); + if (status < 0) return TREXIO_FAILURE; + return TREXIO_SUCCESS; } -trexio_exit_code trexio_hdf5_write_nucleus_coord(const trexio_t* file, const double* coord) { +trexio_exit_code trexio_hdf5_write_nucleus_coord(const trexio_t* file, const double* coord, const uint32_t rank, const uint64_t* dims) { assert (file != NULL); assert (coord != NULL); - - h5nucleus_t* nucleus = trexio_hdf5_read_nucleus((trexio_hdf5_t*) file); + + uint64_t nucleus_num; + trexio_exit_code rc = trexio_hdf5_read_nucleus_num(file, &(nucleus_num)); + if (rc != TREXIO_SUCCESS) return rc; + if (nucleus_num <= 0L) return TREXIO_INVALID_NUM; + + trexio_hdf5_t* f = (trexio_hdf5_t*) file; + + herr_t status; + if ( H5LTfind_dataset(f->nucleus_group, NUCLEUS_COORD_NAME) != 1) { + + status = H5LTmake_dataset_double (f->nucleus_group, NUCLEUS_COORD_NAME, + (int) rank, (hsize_t*) dims, coord); + if (status < 0) return TREXIO_FAILURE; + + } else { + + hid_t dset_id = H5Dopen(f->nucleus_group, NUCLEUS_COORD_NAME, H5P_DEFAULT); + if (dset_id <= 0) return TREXIO_INVALID_ID; + + status = H5Dwrite(dset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, coord); + + H5Dclose(dset_id); + if (status < 0) return TREXIO_FAILURE; - if (nucleus == NULL) return TREXIO_FAILURE; - assert (nucleus->coord != NULL); - - for (size_t i=0 ; i<3*nucleus->num ; i++) { - nucleus->coord[i] = coord[i]; } - trexio_exit_code rc = trexio_hdf5_write_nucleus((trexio_hdf5_t*) file, nucleus); - assert (rc == TREXIO_SUCCESS); - - trexio_hdf5_free_nucleus(nucleus); - return TREXIO_SUCCESS; } diff --git a/src/trexio_text.c b/src/trexio_text.c index d18dc3b..3dd4529 100644 --- a/src/trexio_text.c +++ b/src/trexio_text.c @@ -448,7 +448,7 @@ rdm_t* trexio_text_read_rdm(trexio_text_t* file) { if (file->parent.mode == 'w') { rdm->file = fopen(file_name,"a"); } else { - rdm->file = fopen(file_name,""); + rdm->file = fopen(file_name,"r"); } free(file_name); file->rdm = rdm ; diff --git a/src/trexio_text.org b/src/trexio_text.org index 649309d..310fd88 100644 --- a/src/trexio_text.org +++ b/src/trexio_text.org @@ -99,6 +99,7 @@ typedef struct trexio_text_s { #+end_src +*** Init/deinit functions #+begin_src c :tangle trexio_text.h trexio_exit_code trexio_text_init(trexio_t* file); @@ -634,7 +635,7 @@ rdm_t* trexio_text_read_rdm(trexio_text_t* file) { if (file->parent.mode == 'w') { rdm->file = fopen(file_name,"a"); } else { - rdm->file = fopen(file_name,""); + rdm->file = fopen(file_name,"r"); } free(file_name); file->rdm = rdm ;