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:
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 */
}
}
}