stardis-solver

Solve coupled heat transfers
git clone git://git.meso-star.fr/stardis-solver.git
Log | Files | Refs | README | LICENSE

commit 329032fae3bce864d6d54500132597fab97d1c7d
parent 0e02fd25ee1af4ca480892785355ae2ccbcf02e0
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Mon, 14 Sep 2020 15:29:50 +0200

Write the scene hash during the green serialization

Use the hash to check that the scene used to de-serialised the green is
the same that the one used to estimate it.

Diffstat:
Mcmake/CMakeLists.txt | 2+-
Msrc/sdis_green.c | 107++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Msrc/sdis_green.h | 2+-
Msrc/sdis_scene.c | 96+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/sdis_scene_c.h | 6++++++
Msrc/sdis_solve_boundary_Xd.h | 2+-
Msrc/sdis_solve_medium_Xd.h | 2+-
Msrc/sdis_solve_probe_Xd.h | 2+-
Msrc/sdis_solve_probe_boundary_Xd.h | 2+-
9 files changed, 171 insertions(+), 50 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -34,7 +34,7 @@ find_package(Star3D 0.7 REQUIRED) find_package(StarSP 0.8 REQUIRED) find_package(StarEnc2D 0.5 REQUIRED) find_package(StarEnc3D 0.5 REQUIRED) -find_package(RSys 0.8.1 REQUIRED) +find_package(RSys 0.10 REQUIRED) find_package(OpenMP 2.0 REQUIRED) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${RCMAKE_SOURCE_DIR}) diff --git a/src/sdis_green.c b/src/sdis_green.c @@ -291,7 +291,7 @@ struct sdis_green_function { FILE* rng_state; ref_T ref; - struct sdis_device* dev; + struct sdis_scene* scn; }; /******************************************************************************* @@ -462,7 +462,7 @@ green_function_solve_path if(time_curr <= 0 || (path->limit_type == SDIS_VERTEX && time_curr <= medium_get_t0(medium))) { - log_err(green->dev, + log_err(green->scn->dev, "%s: invalid observation time \"%g\": the initial condition is reached " "while instationary system are not supported by the green function.\n", FUNC_NAME, time); @@ -560,9 +560,9 @@ read_media(struct sdis_green_function* green, FILE* stream) READ(&id); READ(&mdm_type); - name = flist_name_get(&green->dev->media_names, id); + name = flist_name_get(&green->scn->dev->media_names, id); if(!name) { - log_err(green->dev, "%s: a Stardis medium is missing.\n", + log_err(green->scn->dev, "%s: a Stardis medium is missing.\n", FUNC_NAME); res = RES_BAD_ARG; goto error; @@ -571,7 +571,7 @@ read_media(struct sdis_green_function* green, FILE* stream) mdm = name->mem; if(mdm_type != mdm->type) { - log_err(green->dev, "%s: inconsistency between the a Stardis medium " + log_err(green->scn->dev, "%s: inconsistency between the a Stardis medium " "and its serialised data.\n", FUNC_NAME); res = RES_BAD_ARG; goto error; @@ -664,23 +664,23 @@ read_interfaces(struct sdis_green_function* green, FILE* stream) READ(&mdm_back_id); READ(&mdm_back_type); - name = flist_name_get(&green->dev->interfaces_names, id); + name = flist_name_get(&green->scn->dev->interfaces_names, id); if(!name) { - log_err(green->dev, "%s: a Stardis interface is missing.\n", + log_err(green->scn->dev, "%s: a Stardis interface is missing.\n", FUNC_NAME); res = RES_BAD_ARG; goto error; } interf = name->mem; - mdm_front = flist_name_get(&green->dev->media_names, mdm_front_id)->mem; - mdm_back = flist_name_get(&green->dev->media_names, mdm_back_id)->mem; + mdm_front = flist_name_get(&green->scn->dev->media_names, mdm_front_id)->mem; + mdm_back = flist_name_get(&green->scn->dev->media_names, mdm_back_id)->mem; if(mdm_front != interf->medium_front || mdm_back != interf->medium_back || mdm_front_type != interf->medium_front->type || mdm_back_type != interf->medium_back->type) { - log_err(green->dev, "%s: inconsistency between the a Stardis interface " + log_err(green->scn->dev, "%s: inconsistency between the a Stardis interface " "and its serialised data.\n", FUNC_NAME); res = RES_BAD_ARG; goto error; @@ -804,18 +804,18 @@ green_function_clear(struct sdis_green_function* green) static void green_function_release(ref_T* ref) { - struct sdis_device* dev; + struct sdis_scene* scn; struct sdis_green_function* green; ASSERT(ref); green = CONTAINER_OF(ref, struct sdis_green_function, ref); - dev = green->dev; + scn = green->scn; green_function_clear(green); htable_medium_release(&green->media); htable_interf_release(&green->interfaces); darray_green_path_release(&green->paths); if(green->rng_state) fclose(green->rng_state); - MEM_RM(dev->allocator, green); - SDIS(device_ref_put(dev)); + MEM_RM(scn->dev->allocator, green); + SDIS(scene_ref_put(scn)); } /******************************************************************************* @@ -858,7 +858,7 @@ sdis_green_function_solve goto error; } - res = ssp_rng_create(green->dev->allocator, &green->rng_type, &rng); + res = ssp_rng_create(green->scn->dev->allocator, &green->rng_type, &rng); if(res != RES_OK) goto error; /* Avoid correlation by defining the RNG state from the final state of the @@ -870,7 +870,7 @@ sdis_green_function_solve npaths = darray_green_path_size_get(&green->paths); /* Create the estimator */ - res = estimator_create(green->dev, SDIS_ESTIMATOR_TEMPERATURE, &estimator); + res = estimator_create(green->scn->dev, SDIS_ESTIMATOR_TEMPERATURE, &estimator); if(res != RES_OK) goto error; /* Solve the green function */ @@ -910,6 +910,7 @@ sdis_green_function_write(struct sdis_green_function* green, FILE* stream) { struct ssp_rng* rng = NULL; enum rng_type rng_type = RNG_UNKNOWN; + hash256_T hash; res_T res = RES_OK; if(!green || !stream) { @@ -917,8 +918,8 @@ sdis_green_function_write(struct sdis_green_function* green, FILE* stream) goto error; } - #define WRITE(Var) { \ - if(fwrite((Var), sizeof(*(Var)), 1, stream) != 1) { \ + #define WRITE(Var, Nb) { \ + if(fwrite((Var), sizeof(*(Var)), (Nb), stream) != (Nb)) { \ res = RES_IO_ERR; \ goto error; \ } \ @@ -926,14 +927,18 @@ sdis_green_function_write(struct sdis_green_function* green, FILE* stream) rng_type = get_rng_type_enum(&green->rng_type); if(rng_type == RNG_UNKNOWN) { - log_err(green->dev, + log_err(green->scn->dev, "%s: could not function a green function with an unknown RNG type.\n", FUNC_NAME); res = RES_BAD_ARG; goto error; } - WRITE(&SDIS_GREEN_FUNCTION_VERSION); + WRITE(&SDIS_GREEN_FUNCTION_VERSION, 1); + + res = scene_compute_hash(green->scn, hash); + if(res != RES_OK) goto error; + WRITE(hash, sizeof(hash256_T)); res = write_media(green, stream); if(res != RES_OK) goto error; @@ -942,14 +947,14 @@ sdis_green_function_write(struct sdis_green_function* green, FILE* stream) res = write_paths_list(green, stream); if(res != RES_OK) goto error; - WRITE(&green->npaths_valid); - WRITE(&green->npaths_invalid); - WRITE(&green->realisation_time); - WRITE(&rng_type); + WRITE(&green->npaths_valid, 1); + WRITE(&green->npaths_invalid, 1); + WRITE(&green->realisation_time, 1); + WRITE(&rng_type, 1); #undef WRITE /* Create a temporary RNG used to serialise the RNG state */ - res = ssp_rng_create(green->dev->allocator, &green->rng_type, &rng); + res = ssp_rng_create(green->scn->dev->allocator, &green->rng_type, &rng); if(res != RES_OK) goto error; rewind(green->rng_state); res = ssp_rng_read(rng, green->rng_state); @@ -970,6 +975,7 @@ sdis_green_function_create_from_stream FILE* stream, struct sdis_green_function** out_green) { + hash256_T hash0, hash1; struct sdis_green_function* green = NULL; struct ssp_rng* rng = NULL; enum rng_type rng_type = RNG_UNKNOWN; @@ -981,11 +987,11 @@ sdis_green_function_create_from_stream goto error; } - res = green_function_create(scn->dev, &green); + res = green_function_create(scn, &green); if(res != RES_OK) goto error; - #define READ(Var) { \ - if(fread((Var), sizeof(*(Var)), 1, stream) != 1) { \ + #define READ(Var, Nb) { \ + if(fread((Var), sizeof(*(Var)), (Nb), stream) != (Nb)) { \ if(feof(stream)) { \ res = RES_BAD_ARG; \ } else if(ferror(stream)) { \ @@ -997,15 +1003,28 @@ sdis_green_function_create_from_stream } \ } (void)0 - READ(&version); + READ(&version, 1); if(version != SDIS_GREEN_FUNCTION_VERSION) { - log_err(green->dev, "%s: unexpected green function version %d. Expecting a " - "green function in version %d.\n", + log_err(green->scn->dev, + "%s: unexpected green function version %d. Expecting a green function " + "in version %d.\n", FUNC_NAME, version, SDIS_GREEN_FUNCTION_VERSION); res = RES_BAD_ARG; goto error; } + res = scene_compute_hash(green->scn, hash0); + if(res != RES_OK) goto error; + + READ(hash1, sizeof(hash256_T)); + if(!hash256_eq(hash0, hash1)) { + log_err(green->scn->dev, + "%s: the submitted scene does not match scene used to estimate the green " + "function.\n", FUNC_NAME); + res = RES_BAD_ARG; + goto error; + } + res = read_media(green, stream); if(res != RES_OK) goto error; res = read_interfaces(green, stream); @@ -1013,16 +1032,16 @@ sdis_green_function_create_from_stream res = read_paths_list(green, stream); if(res != RES_OK) goto error; - READ(&green->npaths_valid); - READ(&green->npaths_invalid); - READ(&green->realisation_time); - READ(&rng_type); + READ(&green->npaths_valid, 1); + READ(&green->npaths_invalid, 1); + READ(&green->realisation_time, 1); + READ(&rng_type, 1); #undef READ get_rng_type_ssp(rng_type, &green->rng_type); /* Create a temporary RNG used to deserialise the RNG state */ - res = ssp_rng_create(green->dev->allocator, &green->rng_type, &rng); + res = ssp_rng_create(green->scn->dev->allocator, &green->rng_type, &rng); if(res != RES_OK) goto error; res = ssp_rng_read(rng, stream); if(res != RES_OK) goto error; @@ -1267,23 +1286,23 @@ error: ******************************************************************************/ res_T green_function_create - (struct sdis_device* dev, struct sdis_green_function** out_green) + (struct sdis_scene* scn, struct sdis_green_function** out_green) { struct sdis_green_function* green = NULL; res_T res = RES_OK; - ASSERT(dev && out_green); + ASSERT(scn && out_green); - green = MEM_CALLOC(dev->allocator, 1, sizeof(*green)); + green = MEM_CALLOC(scn->dev->allocator, 1, sizeof(*green)); if(!green) { res = RES_MEM_ERR; goto error; } ref_init(&green->ref); - SDIS(device_ref_get(dev)); - green->dev = dev; - htable_medium_init(dev->allocator, &green->media); - htable_interf_init(dev->allocator, &green->interfaces); - darray_green_path_init(dev->allocator, &green->paths); + SDIS(scene_ref_get(scn)); + green->scn = scn; + htable_medium_init(scn->dev->allocator, &green->media); + htable_interf_init(scn->dev->allocator, &green->interfaces); + darray_green_path_init(scn->dev->allocator, &green->paths); green->npaths_valid = SIZE_MAX; green->npaths_invalid = SIZE_MAX; diff --git a/src/sdis_green.h b/src/sdis_green.h @@ -39,7 +39,7 @@ static const struct green_path_handle GREEN_PATH_HANDLE_NULL = extern LOCAL_SYM res_T green_function_create - (struct sdis_device* dev, + (struct sdis_scene* scn, struct sdis_green_function** green); /* Merge `src' into `dst' an clear `src' */ diff --git a/src/sdis_scene.c b/src/sdis_scene.c @@ -13,6 +13,10 @@ * 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 "sdis_scene_Xd.h" /* Generate the Generic functions of the scene */ @@ -22,10 +26,12 @@ #include "sdis_scene_Xd.h" #include "sdis.h" +#include "sdis_interface_c.h" #include "sdis_scene_c.h" #include <float.h> #include <limits.h> +#include <sys/mman.h> /******************************************************************************* * Helper function @@ -390,3 +396,93 @@ scene_get_medium_in_closed_boundaries : scene_get_medium_in_closed_boundaries_3d(scn, pos, out_medium); } +res_T +scene_compute_hash(const struct sdis_scene* scn, hash256_T hash) +{ + void* data = NULL; + FILE* stream = NULL; + size_t iprim, nprims; + size_t len; + res_T res = RES_OK; + ASSERT(scn && hash); + + stream = tmpfile(); + if(!stream) { + res = RES_IO_ERR; + goto error; + } + + #define WRITE(Var, Nb) \ + if(fwrite((Var), sizeof(*(Var)), Nb, stream) != (Nb)) { \ + res = RES_IO_ERR; \ + goto error; \ + } (void)0 + if(scene_is_2d(scn)) { + S2D(scene_view_primitives_count(scn->s2d_view, &nprims)); + } else { + S3D(scene_view_primitives_count(scn->s3d_view, &nprims)); + } + FOR_EACH(iprim, 0, nprims) { + struct sdis_interface* interf = NULL; + size_t ivert; + + if(scene_is_2d(scn)) { + struct s2d_primitive prim; + S2D(scene_view_get_primitive(scn->s2d_view, (unsigned)iprim, &prim)); + FOR_EACH(ivert, 0, 2) { + struct s2d_attrib attr; + S2D(segment_get_vertex_attrib(&prim, ivert, S2D_POSITION, &attr)); + WRITE(attr.value, 2); + } + } else { + struct s3d_primitive prim; + S3D(scene_view_get_primitive(scn->s3d_view, (unsigned)iprim, &prim)); + FOR_EACH(ivert, 0, 3) { + struct s3d_attrib attr; + S3D(triangle_get_vertex_attrib(&prim, ivert, S3D_POSITION, &attr)); + WRITE(attr.value, 3); + } + } + + interf = scene_get_interface(scn, (unsigned)iprim); + WRITE(&interf->medium_front->type, 1); + WRITE(&interf->medium_front->id, 1); + WRITE(&interf->medium_back->type, 1); + WRITE(&interf->medium_back->id, 1); + } + #undef WRITE + + len = (size_t)ftell(stream); + rewind(stream); +#ifdef COMPILER_GCC + data = mmap(NULL, len, PROT_READ, MAP_PRIVATE|MAP_POPULATE, fileno(stream), 0); + if(data == MAP_FAILED) { + res = RES_IO_ERR; + goto error; + } +#else + data = MEM_ALLOC_ALIGNED(scn->dev->allocator, len, 16); + if(!data) { + res = RES_MEM_ERR; + goto error; + } + if(fread(data, len, 1, stream) != 1) { + res = RES_IO_ERR; + goto error; + } +#endif + + res = hash_sha256(scn->dev->allocator, data, len, hash); + if(res != RES_OK) goto error; + +exit: +#ifdef COMPILER_GCC + if(data) munmap(data, len); +#else + if(data) MEM_RM(scn->dev->allocator, data); +#endif + if(stream) fclose(stream); + return res; +error: + goto exit; +} diff --git a/src/sdis_scene_c.h b/src/sdis_scene_c.h @@ -20,6 +20,7 @@ #include <star/s3d.h> #include <rsys/dynamic_array_uint.h> +#include <rsys/hash.h> #include <rsys/hash_table.h> #include <rsys/ref_count.h> @@ -248,6 +249,11 @@ scene_get_medium_in_closed_boundaries const double position[], struct sdis_medium** medium); +extern LOCAL_SYM res_T +scene_compute_hash + (const struct sdis_scene* scn, + hash256_T hash); + static INLINE void scene_get_enclosure_ids (const struct sdis_scene* scn, diff --git a/src/sdis_solve_boundary_Xd.h b/src/sdis_solve_boundary_Xd.h @@ -214,7 +214,7 @@ XD(solve_boundary) greens = MEM_CALLOC(scn->dev->allocator, scn->dev->nthreads, sizeof(*greens)); if(!greens) { res = RES_MEM_ERR; goto error; } FOR_EACH(i, 0, scn->dev->nthreads) { - res = green_function_create(scn->dev, &greens[i]); + res = green_function_create(scn, &greens[i]); if(res != RES_OK) goto error; } } diff --git a/src/sdis_solve_medium_Xd.h b/src/sdis_solve_medium_Xd.h @@ -284,7 +284,7 @@ XD(solve_medium) greens = MEM_CALLOC(scn->dev->allocator, scn->dev->nthreads, sizeof(*greens)); if(!greens) { res = RES_MEM_ERR; goto error; } FOR_EACH(i, 0, scn->dev->nthreads) { - res = green_function_create(scn->dev, &greens[i]); + res = green_function_create(scn, &greens[i]); if(res != RES_OK) goto error; } } diff --git a/src/sdis_solve_probe_Xd.h b/src/sdis_solve_probe_Xd.h @@ -115,7 +115,7 @@ XD(solve_probe) greens = MEM_CALLOC(scn->dev->allocator, scn->dev->nthreads, sizeof(*greens)); if(!greens) { res = RES_MEM_ERR; goto error; } FOR_EACH(i, 0, scn->dev->nthreads) { - res = green_function_create(scn->dev, &greens[i]); + res = green_function_create(scn, &greens[i]); if(res != RES_OK) goto error; } } diff --git a/src/sdis_solve_probe_boundary_Xd.h b/src/sdis_solve_probe_boundary_Xd.h @@ -150,7 +150,7 @@ XD(solve_probe_boundary) greens = MEM_CALLOC(scn->dev->allocator, scn->dev->nthreads, sizeof(*greens)); if(!greens) { res = RES_MEM_ERR; goto error; } FOR_EACH(i, 0, scn->dev->nthreads) { - res = green_function_create(scn->dev, &greens[i]); + res = green_function_create(scn, &greens[i]); if(res != RES_OK) goto error; } }