star-aerosol

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

commit 3da21deaf0f1cbda2f8e360e34a72d93c9b81239
parent 22a35fcfe6e58cbb1bf044bea3da763e6c3b513f
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed, 31 Aug 2022 11:28:24 +0200

Update file format and fix memory unmapping

Diffstat:
Mdoc/sars.5.scd | 16+++++++---------
Msrc/sars.c | 35+++++++++++++++++------------------
Msrc/sars.h | 19++++++++++++++++---
Msrc/sars_c.h | 20++++++++++++++++++--
Msrc/test_sars_load.c | 20++++++++------------
5 files changed, 66 insertions(+), 44 deletions(-)

diff --git a/doc/sars.5.scd b/doc/sars.5.scd @@ -19,7 +19,7 @@ sars(5) sars - Star AeoRoSol file format -# DESCRIPTION +# DESCRIPTION *sars* is a binary file format for storing the radiative properties of an aerosol. The volumetric mesh to which the CKs are attached is _not_ described @@ -47,10 +47,10 @@ Fill bytes follow the list of spectral bands to ensure alignment of the radiative coefficients on _pagesize_. By aligning data on _pagesize_, and depending on system requirements, memory mapping can be used to automatically load/unload the radiative coefficients on demand (see *mmap*(2)). For each band, -the diffusion coefficients are then listed before the list of absorption -coefficients. Each list is followed by a _padding_, which is a list of bytes -that provides memory alignment of the following data to _pagesize_. Bands are -sorted according to the order in which they were previously declared. +the absorption coefficient and diffusion coefficient are listed per node. This +list is followed by a _padding_, which is a list of bytes that provides memory +alignment of the following data to _pagesize_. Bands are sorted according to the +order in which they were previously declared. # BINARY FILE FORMAT @@ -82,11 +82,9 @@ significant bytes are stored first. <rad-coefs> ::= <per-band-k> [ <per-band-k> ... ] -<per-band-k> ::= <ks-list> - <ka-list> +<per-band-k> ::= <ka-ks> [ <ka-ks> ... ] <padding> -<ka-list> ::= <ka> [ <ka> ... ] <padding> -<ks-list> ::= <ks> [ <ks> ... ] <padding> +<ka-ks> ::= <ka> <ks> <ka> ::= FLOAT # in m^-1 <ks> ::= FLOAT # in m^-1 ``` diff --git a/src/sars.c b/src/sars.c @@ -164,7 +164,7 @@ load_stream(struct sars* sars, FILE* stream, const char* stream_name) } /* Compute the length in bytes of the k to map for each band/quadrature point */ - map_len = ALIGN_SIZE(sars->nnodes * sizeof(float), sars->pagesize); + map_len = ALIGN_SIZE(sars->nnodes * sizeof(float)*2, sars->pagesize); /* Compute the offset toward the 1st list of radiative coefficients */ offset = ftell(stream); @@ -177,23 +177,11 @@ load_stream(struct sars* sars, FILE* stream, const char* stream_name) band->map_len = map_len; /* Map the per band scattering coefficient */ - band->ks_list = mmap(NULL, band->map_len, PROT_READ, + band->k_list = mmap(NULL, band->map_len, PROT_READ, MAP_PRIVATE|MAP_POPULATE, fileno(stream), offset); - if(band->ks_list == MAP_FAILED) { + if(band->k_list == MAP_FAILED) { log_err(sars, - "%s: band %lu: could not map the scattering coefficients -- %s\n", - stream_name, (unsigned long)iband, strerror(errno)); - res = RES_IO_ERR; - goto error; - } - offset = (off_t)((size_t)offset + map_len); - - /* Map the per band absorption coefficient */ - band->ka_list = mmap(NULL, band->map_len, PROT_READ, - MAP_PRIVATE|MAP_POPULATE, fileno(stream), offset); - if(band->ks_list == MAP_FAILED) { - log_err(sars, - "%s: band %lu: could not map the absorption coefficients -- %s\n", + "%s: band %lu: could not map the radiative coefficients -- %s\n", stream_name, (unsigned long)iband, strerror(errno)); res = RES_IO_ERR; goto error; @@ -380,8 +368,7 @@ sars_get_band sars_band->lower = band->low; sars_band->upper = band->upp; sars_band->id = iband; - sars_band->ks_list = band->ks_list; - sars_band->ka_list = band->ka_list; + sars_band->k_list = band->k_list; exit: return res; @@ -446,3 +433,15 @@ exit: error: goto exit; } + +/******************************************************************************* + * Local functions + ******************************************************************************/ +void +band_release(struct band* band) +{ + ASSERT(band); + if(band->k_list && band->k_list != MAP_FAILED) { + munmap(band->k_list, band->map_len); + } +} diff --git a/src/sars.h b/src/sars.h @@ -54,10 +54,9 @@ struct sars_band { double upper; /* Upper band wavelength in nm (exclusive) */ size_t id; - float* ks_list; /* Per node ks */ - float* ka_list; /* Per node ka */ + float* k_list; /* Per node radiative coefficients */ }; -#define SARS_BAND_NULL__ {0, 0, 0, NULL, NULL} +#define SARS_BAND_NULL__ {0, 0, 0, NULL} static const struct sars_band SARS_BAND_NULL = SARS_BAND_NULL__; /* Forward declaration of opaque data types */ @@ -113,4 +112,18 @@ sars_find_bands const double range[2], /* In nm. Limits are inclusive */ size_t ibands[2]); /* Range of overlaped bands. Limits are inclusive */ +static INLINE float +sars_band_get_ka(const struct sars_band* band, const size_t inode) +{ + ASSERT(band); + return band->k_list[inode*2 + 0]; +} + +static INLINE float +sars_band_get_ks(const struct sars_band* band, const size_t inode) +{ + ASSERT(band); + return band->k_list[inode*2 + 1]; +} + #endif /* SARS_H */ diff --git a/src/sars_c.h b/src/sars_c.h @@ -24,13 +24,29 @@ struct band { double low; /* Lower bound in nm (inclusive) */ double upp; /* Upper bound in nm (exclusive) */ size_t map_len; - float* ka_list; - float* ks_list; + float* k_list; /* List of float[2] (ka, ks) */ }; +static INLINE void +band_init(struct mem_allocator* allocator, struct band* band) +{ + ASSERT(band); + (void)allocator; + band->low = DBL_MAX; + band->upp =-DBL_MAX; + band->map_len = 0; + band->k_list = NULL; +} + +extern LOCAL_SYM void +band_release + (struct band* band); + /* Generate 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 #include <rsys/dynamic_array.h> struct mem_allocator; diff --git a/src/test_sars_load.c b/src/test_sars_load.c @@ -56,8 +56,8 @@ check_sars_load FOR_EACH(inode, 0, nnodes) { const float ks = (float)(iband*2000 + inode); const float ka = (float)(iband*1000 + inode); - CHK(band.ks_list[inode] == ks); - CHK(band.ka_list[inode] == ka); + CHK(sars_band_get_ks(&band, inode) == ks); + CHK(sars_band_get_ka(&band, inode) == ka); } } } @@ -94,16 +94,10 @@ write_sars CHK(fseek(fp, (long)ALIGN_SIZE((size_t)ftell(fp), pagesize), SEEK_SET)==0); FOR_EACH(inode, 0, nnodes) { - const float ks = (float)(iband*2000 + inode); - CHK(fwrite(&ks, sizeof(ks), 1, fp) == 1); - } - - /* Padding */ - CHK(fseek(fp, (long)ALIGN_SIZE((size_t)ftell(fp), pagesize), SEEK_SET)==0); - - FOR_EACH(inode, 0, nnodes) { const float ka = (float)(iband*1000 + inode); + const float ks = (float)(iband*2000 + inode); CHK(fwrite(&ka, sizeof(ka), 1, fp) == 1); + CHK(fwrite(&ks, sizeof(ks), 1, fp) == 1); } } @@ -250,8 +244,10 @@ test_load_files(struct sars* sars, int argc, char** argv) CHK(band.lower < band.upper); FOR_EACH(inode, 0, nnodes) { - CHK(band.ks_list[inode] == band.ks_list[inode]); /* !NaN */ - CHK(band.ka_list[inode] == band.ka_list[inode]); /* !NaN */ + const float ka = sars_band_get_ka(&band, inode); + const float ks = sars_band_get_ks(&band, inode); + CHK(ka == ka); /* !NaN */ + CHK(ks == ks); /* !NaN */ } } }