star-ck

Describe the radiative properties of gas mixtures
git clone git://git.meso-star.fr/star-ck.git
Log | Files | Refs | README | LICENSE

commit 36e6495a6ce4a902804fd304167ea5e925ba0d5b
parent 95e48a5dec4e525da8745148506868086a5ce7a6
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Fri, 30 Oct 2020 14:57:10 +0100

Add the load procedures

Diffstat:
Mdoc/atrck | 8++++----
Msrc/atrck.c | 283++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Msrc/atrck.h | 11+++++++++++
Msrc/atrck_c.h | 105+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 402 insertions(+), 5 deletions(-)

diff --git a/doc/atrck b/doc/atrck @@ -11,12 +11,12 @@ --- <bands-list> ::= <band> [ <band> ... ] -<band> ::= <band-id> <band-center> <band-size> <#quad-pts> +<band> ::= <band-id> <band-low> <band-upp> <#quad-pts> <quad-pts-list> <band-id> ::= INT64 -<band-center> ::= DOUBLE -<band-size> ::= DOUBLE +<band-low> ::= DOUBLE +<band-upp> ::= DOUBLE <#quad-pts> ::= INT64 --- @@ -33,5 +33,5 @@ <padding> [ <ka-list> ... ] <ka-list> ::= <ka> [ <ka> ... ] -<ka> ::= DOUBLE +<ka> ::= FLOAT diff --git a/src/atrck.c b/src/atrck.c @@ -13,22 +13,253 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#define _POSIX_C_SOURCE 200809L /* mmap support */ +#define _DEFAULT_SOURCE 1 /* MAP_POPULATE support */ +#define _BSD_SOURCE 1 /* MAP_POPULATE for glibc < 2.19 */ + #include "atrck.h" #include "atrck_c.h" #include "atrck_log.h" -#include <unistd.h> +#include <unistd.h> /* sysconf support */ + +#include <errno.h> +#include <string.h> +#include <sys/mman.h> /* mmap */ /******************************************************************************* * Helper functions ******************************************************************************/ static void +reset_atrck(struct atrck* atrck) +{ + ASSERT(atrck); + atrck->pagesize = 0; + atrck->nnodes = 0; + darray_band_purge(&atrck->bands); +} + +static res_T +read_quad_pt + (struct atrck* atrck, + struct quad_pt* quad_pt, + FILE* stream, + const char* stream_name, + size_t iband, + size_t iquad_pt) +{ + res_T res = RES_OK; + ASSERT(atrck && quad_pt && stream_name); + + #define READ(Var, Name) { \ + if(fread((Var), sizeof(*(Var)), 1, stream) != 1) { \ + log_err(atrck, \ + "%s: band %lu: quadrature point %lu: could not read the %s.\n", \ + stream_name, iband, iquad_pt, Name); \ + res = RES_IO_ERR; \ + goto error; \ + } \ + } (void)0 + READ(&quad_pt->absissa, "quadrature point absissa"); + READ(&quad_pt->weight, "quadrature point weight"); + #undef READ + + quad_pt->ka_list = NULL; + +exit: + return res; +error: + goto exit; +} + +static res_T +read_band + (struct atrck* atrck, + struct band* band, + FILE* stream, + const char* stream_name) +{ + double cumul; + size_t iquad_pt; + uint64_t nquad_pts; + res_T res = RES_OK; + ASSERT(atrck && band && stream_name); + + /* Read band definition */ + #define READ(Var, Name) { \ + if(fread((Var), sizeof(*(Var)), 1, stream) != 1) { \ + log_err(atrck, "%s: band %lu: could not read the %s.\n", \ + stream_name, (unsigned long)band->id, (Name)); \ + res = RES_IO_ERR; \ + goto error; \ + } \ + } (void)0 + READ(&band->id, "band identifier"); + READ(&band->low, "band lower bound"); + READ(&band->upp, "band upper bound"); + READ(&nquad_pts, "#quadrature points"); + #undef READ + + /* Check band description */ + if(band->low < 0 || band->low > band->upp) { + log_err(atrck, + "%s: band %lu: invalid band range [%g, %g].\n", + stream_name, (unsigned long)band->id, band->low, band->upp); + res = RES_BAD_ARG; + goto error; + } + if(nquad_pts == 0) { + log_err(atrck, + "%s: band %lu: invalid number fo quadrature points (#points=%lu).\n", + stream_name, (unsigned long)band->id, (unsigned long)nquad_pts); + res = RES_BAD_ARG; + goto error; + } + + /* Allocate the list of quadrature points */ + res = darray_quad_pt_resize(&band->quad_pts, nquad_pts); + if(res != RES_OK) { + log_err(atrck, + "%s: band %lu: could not allocate the list of quadrature points " + "(#points=%lu).\n", + stream_name, (unsigned long)band->id, (unsigned long)nquad_pts); + goto error; + } + + /* Allocate the cumulative used to sample the quadrature points */ + res = darray_double_resize(&band->quad_pts_cumul, nquad_pts); + if(res != RES_OK) { + log_err(atrck, + "%s: band %lu: could not allocate the cumulative of quadrature points " + "(#points=%lu).\n", + stream_name, (unsigned long)band->id, (unsigned long)nquad_pts); + goto error; + } + + /* Read the data of the quadrature points of the band */ + cumul = 0; + FOR_EACH(iquad_pt, 0, nquad_pts) { + struct quad_pt* quad_pt = darray_quad_pt_data_get(&band->quad_pts)+iquad_pt; + + /* Read current quadrature point */ + res = read_quad_pt(atrck, quad_pt, stream, stream_name, band->id, iquad_pt); + if(res != RES_OK) goto error; + + /* Compute the quadrature point cumulative */ + cumul += quad_pt->weight; + darray_double_data_get(&band->quad_pts_cumul)[iquad_pt] = cumul; + } + +exit: + return res; +error: + goto exit; +} + +static res_T +load_stream(struct atrck* atrck, FILE* stream, const char* stream_name) +{ + size_t map_len; + size_t iband; + uint64_t nbands; + res_T res = RES_OK; + ASSERT(atrck && stream && stream_name); + + reset_atrck(atrck); + + /* Read file header */ + #define READ(Var, Name) { \ + if(fread((Var), sizeof(*(Var)), 1, stream) != 1) { \ + log_err(atrck, "%s: could not read the %s.\n", stream_name, (Name)); \ + res = RES_IO_ERR; \ + goto error; \ + } \ + } (void)0 + READ(&atrck->pagesize, "page size"); + READ(&nbands, "number of bands"); + READ(&atrck->nnodes, "number of nodes"); + #undef READ + + /* Check band description */ + if(!IS_POW2(atrck->pagesize)) { + log_err(atrck, "%s: invalid pagesize %lu.\n", + stream_name, (unsigned long)atrck->pagesize); + res = RES_BAD_ARG; + goto error; + } + if(!nbands) { + log_err(atrck, "%s: invalid number of bands %lu.\n", + stream_name, (unsigned long)nbands); + res = RES_BAD_ARG; + goto error; + } + if(!atrck->nnodes) { + log_err(atrck, "%s: invalid number of nodes %lu.\n", + stream_name, (unsigned long)atrck->nnodes); + res = RES_BAD_ARG; + goto error; + } + + /* Allocate the bands */ + res = darray_band_resize(&atrck->bands, nbands); + if(res != RES_OK) { + log_err(atrck, "%s: could not allocate the list of bands (#bands=%lu).\n", + stream_name, (unsigned long)nbands); + goto error; + } + + /* Read the band description */ + FOR_EACH(iband, 0, nbands) { + struct band* band = darray_band_data_get(&atrck->bands) + iband; + res = read_band(atrck, band, stream, stream_name); + if(res != RES_OK) goto error; + } + + /* Compute the length in bytes of the ka to map for each quadrature point */ + map_len = ALIGN_SIZE(atrck->nnodes * sizeof(double), atrck->pagesize); + + /* Load the per band, per quadrature point and per node correlated K */ + FOR_EACH(iband, 0, nbands) { + struct band* band = darray_band_data_get(&atrck->bands) + iband; + size_t iquad_pt; + FOR_EACH(iquad_pt, 0, darray_quad_pt_size_get(&band->quad_pts)) { + struct quad_pt* quad_pt = NULL; + off_t offset = 0; + + quad_pt = darray_quad_pt_data_get(&band->quad_pts)+iquad_pt; + offset = (off_t)ALIGN_SIZE((uint64_t)ftell(stream), atrck->pagesize); + quad_pt->map_len = map_len; + quad_pt->ka_list = mmap(NULL, quad_pt->map_len, PROT_READ, + MAP_PRIVATE|MAP_POPULATE, fileno(stream), offset); + if(quad_pt->ka_list == MAP_FAILED) { + log_err(atrck, + "%s: band %lu: quadrature point %lu: coult not map the correlated K " + "-- %s.\n", + stream_name, + (unsigned long)band->id, + (unsigned long)iquad_pt, + strerror(errno)); + res = RES_IO_ERR; + goto error; + } + } + } + +exit: + return res; +error: + reset_atrck(atrck); + goto exit; +} + +static void release_atrck(ref_T* ref) { struct atrck* atrck; ASSERT(ref); atrck = CONTAINER_OF(ref, struct atrck, ref); if(atrck->logger == &atrck->logger__) logger_release(&atrck->logger__); + darray_band_release(&atrck->bands); MEM_RM(atrck->allocator, atrck); } @@ -70,6 +301,7 @@ atrck_create atrck->allocator = allocator; atrck->verbose = verbose; atrck->pagesize_os = (size_t)sysconf(_SC_PAGESIZE); + darray_band_init(allocator, &atrck->bands); if(logger) { atrck->logger = logger; } else { @@ -103,3 +335,52 @@ atrck_ref_put(struct atrck* atrck) return RES_OK; } +res_T +atrck_load(struct atrck* atrck, const char* path) +{ + FILE* file = NULL; + res_T res = RES_OK; + + if(!atrck || !path) { + res = RES_BAD_ARG; + goto error; + } + + file = fopen(path, "r"); + if(!file) { + log_err(atrck, "%s: error opening file `%s'.\n", FUNC_NAME, path); + res = RES_IO_ERR; + goto error; + } + + res = load_stream(atrck, file, path); + if(res != RES_OK) goto error; + +exit: + if(file) fclose(file); + return res; +error: + goto exit; +} + +res_T +atrck_load_stream + (struct atrck* atrck, + FILE* stream, + const char* stream_name) +{ + if(!atrck || !stream) return RES_BAD_ARG; + return load_stream(atrck, stream, stream_name ? stream_name : "<stream>"); +} + + +/******************************************************************************* + * Local functions + ******************************************************************************/ +void +quad_pt_release(struct quad_pt* quad_pt) +{ + ASSERT(quad_pt); + if(quad_pt->ka_list && quad_pt->ka_list != MAP_FAILED) + munmap(quad_pt->ka_list, quad_pt->map_len); +} diff --git a/src/atrck.h b/src/atrck.h @@ -63,6 +63,17 @@ ATRCK_API res_T atrck_ref_put (struct atrck* atrck); +ATRCK_API res_T +atrck_load + (struct atrck* atrck, + const char* path); + +ATRCK_API res_T +atrck_load_stream + (struct atrck* atrck, + FILE* stream, + const char* stream_name); /* Can be NULL */ + END_DECLS #endif /* ATRCK_H */ diff --git a/src/atrck_c.h b/src/atrck_c.h @@ -16,12 +16,117 @@ #ifndef ATRCK_C_H #define ATRCK_C_H +#include <rsys/dynamic_array_double.h> #include <rsys/logger.h> #include <rsys/ref_count.h> struct mem_allocator; +struct quad_pt { + double* ka_list; /* Per node ka */ + size_t map_len; + double absissa; + double weight; +}; + +static INLINE void +quad_pt_init(struct mem_allocator* allocator, struct quad_pt* quad) +{ + ASSERT(quad); + (void)allocator; + quad->ka_list = NULL; + quad->map_len = 0;; + quad->absissa = 0; + quad->weight = 0; +} + +extern LOCAL_SYM INLINE void +quad_pt_release + (struct quad_pt* quad); + +/* Define the dynamic array of quadrature points */ +#define DARRAY_NAME quad_pt +#define DARRAY_DATA struct quad_pt +#include <rsys/dynamic_array.h> + +struct band { + uint64_t id; + double low; /* Lower bound in cm^-1 */ + double upp; /* Upper bound in cm^-1 */ + struct darray_quad_pt quad_pts; + struct darray_double quad_pts_cumul; +}; + +static INLINE void +band_init(struct mem_allocator* allocator, struct band* band) +{ + ASSERT(band); + band->id = UINT64_MAX; + band->low = DBL_MAX; + band->upp =-DBL_MAX; + darray_quad_pt_init(allocator, &band->quad_pts); + darray_double_init(allocator, &band->quad_pts_cumul); +} + +static INLINE void +band_release(struct band* band) +{ + ASSERT(band); + darray_quad_pt_release(&band->quad_pts); + darray_double_release(&band->quad_pts_cumul); +} + +static INLINE res_T +band_copy(struct band* dst, const struct band* src) +{ + res_T res = RES_OK; + ASSERT(dst && src); + + dst->id = src->id; + dst->low = src->low; + dst->upp = src->upp; + res = darray_quad_pt_copy(&dst->quad_pts, &src->quad_pts); + if(res != RES_OK) return res; + res = darray_double_copy(&dst->quad_pts_cumul, &src->quad_pts_cumul); + if(res != RES_OK) return res; + return RES_OK; +} + +static INLINE res_T +band_copy_and_release(struct band* dst, struct band* src) +{ + res_T res = RES_OK; + ASSERT(dst && src); + + dst->id = src->id; + dst->low = src->low; + dst->upp = src->upp; + res = darray_quad_pt_copy_and_release(&dst->quad_pts, &src->quad_pts); + if(res != RES_OK) return res; + res = darray_double_copy_and_release + (&dst->quad_pts_cumul, &src->quad_pts_cumul); + if(res != RES_OK) return res; + return RES_OK; + +} + +/* Define the dynamic array of bands */ +#define DARRAY_NAME band +#define DARRAY_DATA struct band +#define DARRAY_FUNCTOR_INIT band_init +#define DARRAY_FUNCTOR_RELEASE band_release +#define DARRAY_FUNCTOR_COPY band_copy +#define DARRAY_FUNCTOR_COPY_AND_RELEASE band_copy_and_release +#include <rsys/dynamic_array.h> + +struct mem_allocator; + struct atrck { + /* Loaded data */ + uint64_t pagesize; + uint64_t nnodes; + struct darray_band bands; + size_t pagesize_os; struct mem_allocator* allocator;