commit ffa619c03bdc20702c18b88f70942b3304b7bbb9
parent 3183e8d4e009991c685e3e9889bc25b7485babde
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Fri, 3 Mar 2023 15:43:52 +0100
Add the signature of the green function
The caller can provide a signature to an estimated green function that
is serialized with its data. When a green function is de-serialized, the
saved signature is compared to the one submitted to the de-serialization
function. If the signatures differ, the function returns an error.
This signature allows the caller to check that a green function is the
expected function against the caller's constraints that the green
function cannot check by itself.
For example, the green function cannot guarantee that the 'deltas' used
by the conductive subpaths sampled during the estimation of the green
function are the same as those defined in the scene to which the green
function currently refers. Although this precondition must be ensured to
guarantee that the green function matches the scene, it is impossible to
verify that it is actually true since these 'delta' parameters are
defined on the caller side. So until now, we simply assumed that this
constraint was respected since we could not detect such an
inconsistency. Now, the caller can incorporate these parameters into the
signature of the green function which, when reloaded, can be compared
with the signature of the current scene to ensure that the deltas are
indeed the same.
Diffstat:
11 files changed, 164 insertions(+), 37 deletions(-)
diff --git a/src/sdis.c b/src/sdis.c
@@ -192,6 +192,9 @@ gather_green_functions_from_non_master_process
(struct sdis_scene* scn,
struct sdis_green_function* greens[])
{
+ struct sdis_green_function_create_from_stream_args green_args =
+ SDIS_GREEN_FUNCTION_CREATE_FROM_STREAM_ARGS_DEFAULT;
+
void* data = NULL; /* Pointer to gathered serialized green function data */
FILE* stream = NULL; /* Temp file that stores the serialized green function */
int iproc;
@@ -254,7 +257,9 @@ gather_green_functions_from_non_master_process
* iterate over the indices of non master processes in [1, #procs],
* the index the green function to deserialized is iproc - 1 */
rewind(stream);
- res = sdis_green_function_create_from_stream(scn, stream, &greens[iproc-1]);
+ green_args.scene = scn;
+ green_args.stream = stream;
+ res = sdis_green_function_create_from_stream(&green_args, &greens[iproc-1]);
if(res != RES_OK) {
log_err(scn->dev,
"Error deserializing the green function sent by the process %d -- %s.\n",
@@ -364,6 +369,7 @@ release_per_thread_rng(struct sdis_device* dev, struct ssp_rng* rngs[])
res_T
create_per_thread_green_function
(struct sdis_scene* scn,
+ const hash256_T signature,
struct sdis_green_function** out_greens[])
{
struct sdis_green_function** greens = NULL;
@@ -380,7 +386,7 @@ create_per_thread_green_function
}
FOR_EACH(i, 0, scn->dev->nthreads) {
- res = green_function_create(scn, &greens[i]);
+ res = green_function_create(scn, signature, &greens[i]);
if(res != RES_OK) goto error;
}
diff --git a/src/sdis.h b/src/sdis.h
@@ -18,6 +18,7 @@
#include <star/ssp.h>
+#include <rsys/hash.h>
#include <rsys/rsys.h>
#include <float.h>
@@ -394,7 +395,7 @@ struct sdis_ambient_radiative_temperature {
};
#define SDIS_AMBIENT_RADIATIVE_TEMPERATURE_NULL__ {-1, -1}
static const struct sdis_ambient_radiative_temperature
-SDIS_AMBIENT_RADIATIVE_TEMPERATURE_NULL =
+SDIS_AMBIENT_RADIATIVE_TEMPERATURE_NULL =
SDIS_AMBIENT_RADIATIVE_TEMPERATURE_NULL__;
struct sdis_scene_create_args {
@@ -445,6 +446,12 @@ struct sdis_solve_probe_args {
int register_paths; /* Combination of enum sdis_heat_path_flag */
struct ssp_rng* rng_state; /* Initial RNG state. May be NULL */
enum ssp_rng_type rng_type; /* RNG type to use if `rng_state' is NULL */
+
+ /* Signature of the estimated green function. The signature is ignored in an
+ * ordinary probe estimation. The signature of the green function can be
+ * queried to verify that it is the expected one with respect to the caller's
+ * constraints that the green function cannot otherwise ensure */
+ hash256_T signature;
};
#define SDIS_SOLVE_PROBE_ARGS_DEFAULT__ { \
10000, /* #realisations */ \
@@ -453,7 +460,8 @@ struct sdis_solve_probe_args {
1, /* Picard order */ \
SDIS_HEAT_PATH_NONE, /* Register paths mask */ \
NULL, /* RNG state */ \
- SSP_RNG_THREEFRY /* RNG type */ \
+ SSP_RNG_THREEFRY, /* RNG type */ \
+ {0} /* Signature */ \
}
static const struct sdis_solve_probe_args SDIS_SOLVE_PROBE_ARGS_DEFAULT =
SDIS_SOLVE_PROBE_ARGS_DEFAULT__;
@@ -474,6 +482,12 @@ struct sdis_solve_probe_boundary_args {
int register_paths; /* Combination of enum sdis_heat_path_flag */
struct ssp_rng* rng_state; /* Initial RNG state. May be NULL */
enum ssp_rng_type rng_type; /* RNG type to use if `rng_state' is NULL */
+
+ /* Signature of the estimated green function. The signature is ignored in an
+ * ordinary probe estimation. The signature of the green function can be
+ * queried to verify that it is the expected one with respect to the caller's
+ * constraints that the green function cannot otherwise ensure */
+ hash256_T signature;
};
#define SDIS_SOLVE_PROBE_BOUNDARY_ARGS_DEFAULT__ { \
10000, /* #realisations */ \
@@ -484,7 +498,8 @@ struct sdis_solve_probe_boundary_args {
SDIS_SIDE_NULL__, \
SDIS_HEAT_PATH_NONE, \
NULL, /* RNG state */ \
- SSP_RNG_THREEFRY /* RNG type */ \
+ SSP_RNG_THREEFRY, /* RNG type */ \
+ {0} /* Signature */ \
}
static const struct sdis_solve_probe_boundary_args
SDIS_SOLVE_PROBE_BOUNDARY_ARGS_DEFAULT =
@@ -505,6 +520,12 @@ struct sdis_solve_boundary_args {
int register_paths; /* Combination of enum sdis_heat_path_flag */
struct ssp_rng* rng_state; /* Initial RNG state. May be NULL */
enum ssp_rng_type rng_type; /* RNG type to use if `rng_state' is NULL */
+
+ /* Signature of the estimated green function. The signature is ignored in an
+ * ordinary probe estimation. The signature of the green function can be
+ * queried to verify that it is the expected one with respect to the caller's
+ * constraints that the green function cannot otherwise ensure */
+ hash256_T signature;
};
#define SDIS_SOLVE_BOUNDARY_ARGS_DEFAULT__ { \
10000, /* #realisations */ \
@@ -515,7 +536,8 @@ struct sdis_solve_boundary_args {
1, /* Picard order */ \
SDIS_HEAT_PATH_NONE, \
NULL, /* RNG state */ \
- SSP_RNG_THREEFRY /* RNG type */ \
+ SSP_RNG_THREEFRY, /* RNG type */ \
+ {0} /* Signature */ \
}
static const struct sdis_solve_boundary_args SDIS_SOLVE_BOUNDARY_ARGS_DEFAULT =
SDIS_SOLVE_BOUNDARY_ARGS_DEFAULT__;
@@ -533,6 +555,12 @@ struct sdis_solve_medium_args {
int register_paths; /* Combination of enum sdis_heat_path_flag */
struct ssp_rng* rng_state; /* Initial RNG state. May be NULL */
enum ssp_rng_type rng_type; /* RNG type to use if `rng_state' is NULL */
+
+ /* Signature of the estimated green function. The signature is ignored in an
+ * ordinary probe estimation. The signature of the green function can be
+ * queried to verify that it is the expected one with respect to the caller's
+ * constraints that the green function cannot otherwise ensure */
+ hash256_T signature;
};
#define SDIS_SOLVE_MEDIUM_ARGS_DEFAULT__ { \
10000, /* #realisations */ \
@@ -541,7 +569,8 @@ struct sdis_solve_medium_args {
1, /* Picard order */ \
SDIS_HEAT_PATH_NONE, \
NULL, /* RNG state */ \
- SSP_RNG_THREEFRY /* RNG type */ \
+ SSP_RNG_THREEFRY, /* RNG type */ \
+ {0} /* Signature */ \
}
static const struct sdis_solve_medium_args SDIS_SOLVE_MEDIUM_ARGS_DEFAULT =
SDIS_SOLVE_MEDIUM_ARGS_DEFAULT__;
@@ -646,6 +675,23 @@ struct sdis_compute_power_args {
static const struct sdis_compute_power_args
SDIS_COMPUTE_POWER_ARGS_DEFAULT = SDIS_COMPUTE_POWER_ARGS_DEFAULT__;
+struct sdis_green_function_create_from_stream_args {
+ struct sdis_scene* scene; /* Scene from which the green was evaluated */
+ FILE* stream; /* Stream from which the green function is deserialized */
+
+ /* This signature is compared to the one serialized with the green function.
+ * An error is returned if they differ */
+ hash256_T signature;
+};
+#define SDIS_GREEN_FUNCTION_CREATE_FROM_STREAM_ARGS_DEFAULT__ { \
+ NULL, /* Scene */ \
+ NULL, /* Stream */ \
+ {0} /* Signature */ \
+}
+static const struct sdis_green_function_create_from_stream_args
+SDIS_GREEN_FUNCTION_CREATE_FROM_STREAM_ARGS_DEFAULT =
+ SDIS_GREEN_FUNCTION_CREATE_FROM_STREAM_ARGS_DEFAULT__;
+
BEGIN_DECLS
/*******************************************************************************
@@ -1152,8 +1198,7 @@ sdis_green_function_write
SDIS_API res_T
sdis_green_function_create_from_stream
- (struct sdis_scene* scn, /* Scene from which the green was evaluated */
- FILE* stream, /* Stream into which the green was serialized */
+ (struct sdis_green_function_create_from_stream_args* args,
struct sdis_green_function** green);
/* Retrieve the scene used to compute the green function */
@@ -1176,6 +1221,11 @@ sdis_green_function_get_invalid_paths_count
(const struct sdis_green_function* green,
size_t* nfails);
+SDIS_API res_T
+sdis_green_function_get_signature
+ (const struct sdis_green_function* green,
+ hash256_T signature);
+
/* Iterate over all valid green function paths */
SDIS_API res_T
sdis_green_function_for_each_path
diff --git a/src/sdis_c.h b/src/sdis_c.h
@@ -17,6 +17,7 @@
#define SDIS_C_H
#include <star/ssp.h>
+#include <rsys/hash.h>
#include <rsys/rsys.h>
/* Id of the messages sent between processes */
@@ -61,6 +62,7 @@ release_per_thread_rng
extern LOCAL_SYM res_T
create_per_thread_green_function
(struct sdis_scene* scene,
+ const hash256_T signature,
struct sdis_green_function** greens[]);
extern LOCAL_SYM void
diff --git a/src/sdis_green.c b/src/sdis_green.c
@@ -300,6 +300,7 @@ struct sdis_green_function {
size_t npaths_valid;
size_t npaths_invalid;
+ hash256_T signature;
struct accum realisation_time; /* Time per realisation */
@@ -313,6 +314,15 @@ struct sdis_green_function {
/*******************************************************************************
* Helper functions
******************************************************************************/
+static INLINE res_T
+check_sdis_green_function_create_from_stream_args
+ (const struct sdis_green_function_create_from_stream_args* args)
+{
+ if(!args || !args->scene || !args->stream)
+ return RES_BAD_ARG;
+ return RES_OK;
+}
+
static res_T
ensure_medium_registration
(struct sdis_green_function* green,
@@ -892,7 +902,9 @@ sdis_green_function_write(struct sdis_green_function* green, FILE* stream)
res = scene_compute_hash(green->scn, hash);
if(res != RES_OK) goto error;
+
WRITE(hash, sizeof(hash256_T));
+ WRITE(green->signature, sizeof(hash256_T));
res = write_media(green, stream);
if(res != RES_OK) goto error;
@@ -925,8 +937,7 @@ error:
res_T
sdis_green_function_create_from_stream
- (struct sdis_scene* scn,
- FILE* stream,
+ (struct sdis_green_function_create_from_stream_args* args,
struct sdis_green_function** out_green)
{
hash256_T hash0, hash1;
@@ -935,19 +946,18 @@ sdis_green_function_create_from_stream
int version = 0;
res_T res = RES_OK;
- if(!scn || !stream || !out_green) {
- res = RES_BAD_ARG;
- goto error;
- }
+ if(!out_green) { res = RES_BAD_ARG; goto error; }
+ res = check_sdis_green_function_create_from_stream_args(args);
+ if(res != RES_OK) goto error;
- res = green_function_create(scn, &green);
+ res = green_function_create(args->scene, args->signature, &green);
if(res != RES_OK) goto error;
#define READ(Var, Nb) { \
- if(fread((Var), sizeof(*(Var)), (Nb), stream) != (Nb)) { \
- if(feof(stream)) { \
+ if(fread((Var), sizeof(*(Var)), (Nb), args->stream) != (Nb)) { \
+ if(feof(args->stream)) { \
res = RES_BAD_ARG; \
- } else if(ferror(stream)) { \
+ } else if(ferror(args->stream)) { \
res = RES_IO_ERR; \
} else { \
res = RES_UNKNOWN_ERR; \
@@ -978,11 +988,20 @@ sdis_green_function_create_from_stream
goto error;
}
- res = read_media(green, stream);
+ READ(hash1, sizeof(hash256_T));
+ if(!hash256_eq(hash1, green->signature)) {
+ log_err(green->scn->dev,
+ "%s: the input signature does not match the saved signature\n",
+ FUNC_NAME);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ res = read_media(green, args->stream);
if(res != RES_OK) goto error;
- res = read_interfaces(green, stream);
+ res = read_interfaces(green, args->stream);
if(res != RES_OK) goto error;
- res = read_paths_list(green, stream);
+ res = read_paths_list(green, args->stream);
if(res != RES_OK) goto error;
READ(&green->npaths_valid, 1);
@@ -994,7 +1013,7 @@ sdis_green_function_create_from_stream
/* Create a temporary RNG used to deserialise the RNG state */
res = ssp_rng_create(green->scn->dev->allocator, green->rng_type, &rng);
if(res != RES_OK) goto error;
- res = ssp_rng_read(rng, stream);
+ res = ssp_rng_read(rng, args->stream);
if(res != RES_OK) goto error;
res = ssp_rng_write(rng, green->rng_state);
if(res != RES_OK) goto error;
@@ -1043,6 +1062,15 @@ sdis_green_function_get_invalid_paths_count
}
res_T
+sdis_green_function_get_signature
+ (const struct sdis_green_function* green, hash256_T signature)
+{
+ if(!green || !signature) return RES_BAD_ARG;
+ memcpy(signature, green->signature, sizeof(hash256_T));
+ return RES_OK;
+}
+
+res_T
sdis_green_function_for_each_path
(struct sdis_green_function* green,
sdis_process_green_path_T func,
@@ -1329,7 +1357,9 @@ error:
******************************************************************************/
res_T
green_function_create
- (struct sdis_scene* scn, struct sdis_green_function** out_green)
+ (struct sdis_scene* scn,
+ const hash256_T signature,
+ struct sdis_green_function** out_green)
{
struct sdis_green_function* green = NULL;
res_T res = RES_OK;
@@ -1348,6 +1378,7 @@ green_function_create
darray_green_path_init(scn->dev->allocator, &green->paths);
green->npaths_valid = SIZE_MAX;
green->npaths_invalid = SIZE_MAX;
+ memcpy(green->signature, signature, sizeof(hash256_T));
/* TODO replace the tmpfile. tmpfile can only be called a limited number of
* times while one could create a huge amount of green functions at the same
diff --git a/src/sdis_green.h b/src/sdis_green.h
@@ -16,12 +16,13 @@
#ifndef SDIS_GREEN_H
#define SDIS_GREEN_H
+#include <rsys/hash.h>
#include <rsys/rsys.h>
/* Current version the green function data structure. One should increment it
* and perform a version management onto serialized data when the gren function
* data structure is updated. */
-static const int SDIS_GREEN_FUNCTION_VERSION = 1;
+static const int SDIS_GREEN_FUNCTION_VERSION = 2;
/* Forward declaration */
struct accum;
@@ -40,6 +41,7 @@ static const struct green_path_handle GREEN_PATH_HANDLE_NULL =
extern LOCAL_SYM res_T
green_function_create
(struct sdis_scene* scn,
+ const hash256_T signature,
struct sdis_green_function** green);
/* Merge `src' into `dst' an clear `src' */
diff --git a/src/sdis_solve_boundary_Xd.h b/src/sdis_solve_boundary_Xd.h
@@ -298,7 +298,8 @@ XD(solve_boundary)
/* Create the per thread green function */
if(out_green) {
- res = create_per_thread_green_function(scn, &per_thread_green);
+ res = create_per_thread_green_function
+ (scn, args->signature, &per_thread_green);
if(res != RES_OK) goto error;
}
diff --git a/src/sdis_solve_medium_Xd.h b/src/sdis_solve_medium_Xd.h
@@ -355,7 +355,8 @@ XD(solve_medium)
if(res != RES_OK) goto error;
if(out_green) {
- res = create_per_thread_green_function(scn, &per_thread_green);
+ res = create_per_thread_green_function
+ (scn, args->signature, &per_thread_green);
if(res != RES_OK) goto error;
}
diff --git a/src/sdis_solve_probe_Xd.h b/src/sdis_solve_probe_Xd.h
@@ -157,7 +157,8 @@ XD(solve_probe)
/* Create the per thread green function */
if(out_green) {
- res = create_per_thread_green_function(scn, &per_thread_green);
+ res = create_per_thread_green_function
+ (scn, args->signature, &per_thread_green);
if(res != RES_OK) goto error;
}
diff --git a/src/sdis_solve_probe_boundary_Xd.h b/src/sdis_solve_probe_boundary_Xd.h
@@ -197,7 +197,8 @@ XD(solve_probe_boundary)
/* Create the per thread green function */
if(out_green) {
- res = create_per_thread_green_function(scn, &per_thread_green);
+ res = create_per_thread_green_function
+ (scn, args->signature, &per_thread_green);
if(res != RES_OK) goto error;
}
diff --git a/src/test_sdis_solve_probe.c b/src/test_sdis_solve_probe.c
@@ -19,6 +19,8 @@
#include <star/ssp.h>
#include <rsys/math.h>
+#include <string.h>
+
/*
* The scene is composed of a solid cube with unknown temperature. The
* surrounding fluid has a fixed constant temperature.
@@ -280,6 +282,8 @@ main(int argc, char** argv)
struct sdis_green_function* green = NULL;
const struct sdis_heat_path* path = NULL;
struct sdis_device_create_args dev_args = SDIS_DEVICE_CREATE_ARGS_DEFAULT;
+ struct sdis_green_function_create_from_stream_args green_args =
+ SDIS_GREEN_FUNCTION_CREATE_FROM_STREAM_ARGS_DEFAULT;
struct sdis_scene_create_args scn_args = SDIS_SCENE_CREATE_ARGS_DEFAULT;
struct sdis_fluid_shader fluid_shader = DUMMY_FLUID_SHADER;
struct sdis_solid_shader solid_shader = DUMMY_SOLID_SHADER;
@@ -498,7 +502,7 @@ main(int argc, char** argv)
OK(sdis_green_function_solve(green, &estimator2));
check_green_function(green);
check_estimator_eq(estimator, estimator2);
-
+
stream = tmpfile();
CHK(stream);
BA(sdis_green_function_write(NULL, stream));
@@ -512,22 +516,46 @@ main(int argc, char** argv)
OK(sdis_green_function_ref_put(green));
rewind(stream);
- BA(sdis_green_function_create_from_stream(NULL, stream, &green));
- BA(sdis_green_function_create_from_stream(scn, NULL, &green));
- BA(sdis_green_function_create_from_stream(scn, stream, NULL));
- OK(sdis_green_function_create_from_stream(scn, stream, &green));
+ green_args.scene = NULL;
+ green_args.stream = stream;
+ BA(sdis_green_function_create_from_stream(&green_args, &green));
+ green_args.scene = scn;
+ green_args.stream = NULL;
+ BA(sdis_green_function_create_from_stream(&green_args, &green));
+ green_args.scene = scn;
+ green_args.stream = stream;
+ BA(sdis_green_function_create_from_stream(&green_args, NULL));
+ OK(sdis_green_function_create_from_stream(&green_args, &green));
CHK(!fclose(stream));
OK(sdis_green_function_solve(green, &estimator3));
-
check_green_function(green);
check_estimator_eq_strict(estimator2, estimator3);
+ OK(sdis_green_function_ref_put(green));
+ OK(sdis_estimator_ref_put(estimator3));
+ CHK(stream = tmpfile());
+ hash_sha256("Hello, world!", strlen("Hello, world!"), solve_args.signature);
+ OK(sdis_solve_probe_green_function(scn, &solve_args, &green));
+ OK(sdis_green_function_write(green, stream));
OK(sdis_green_function_ref_put(green));
+ green_args.scene = scn;
+ green_args.stream = stream;
+ rewind(stream);
+ BA(sdis_green_function_create_from_stream(&green_args, &green));
+ memcpy(green_args.signature, solve_args.signature, sizeof(hash256_T));
+ rewind(stream);
+ OK(sdis_green_function_create_from_stream(&green_args, &green));
+ CHK(!fclose(stream));
+
+ OK(sdis_green_function_solve(green, &estimator3));
+ check_estimator_eq_strict(estimator2, estimator3);
+ OK(sdis_green_function_ref_put(green));
+ OK(sdis_estimator_ref_put(estimator3));
+
OK(sdis_estimator_ref_put(estimator));
OK(sdis_estimator_ref_put(estimator2));
- OK(sdis_estimator_ref_put(estimator3));
OK(sdis_solve_probe(scn, &solve_args, &estimator));
BA(sdis_estimator_get_paths_count(NULL, &n));
diff --git a/src/test_sdis_utils.c b/src/test_sdis_utils.c
@@ -455,6 +455,8 @@ check_green_serialization
(struct sdis_green_function* green,
struct sdis_scene* scn)
{
+ struct sdis_green_function_create_from_stream_args args =
+ SDIS_GREEN_FUNCTION_CREATE_FROM_STREAM_ARGS_DEFAULT;
FILE* stream = NULL;
struct sdis_estimator *e1 = NULL;
struct sdis_estimator *e2 = NULL;
@@ -467,7 +469,9 @@ check_green_serialization
OK(sdis_green_function_write(green, stream));
rewind(stream);
- OK(sdis_green_function_create_from_stream(scn, stream, &green2));
+ args.scene = scn;
+ args.stream = stream;
+ OK(sdis_green_function_create_from_stream(&args, &green2));
CHK(!fclose(stream));
check_green_function(green2);