commit 2060dfe39b71247612b73b589649ef0281e95dd9
parent 95659ffe274e1922538b0920f2c227fe1485f07b
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Mon, 3 Jun 2019 14:47:11 +0200
At the end of the simulation, save the RNG state against the estimator
Add the ssol_estimator_get_rng_state function to retrieve the saved
state.
Diffstat:
4 files changed, 83 insertions(+), 1 deletion(-)
diff --git a/src/ssol.h b/src/ssol.h
@@ -1140,6 +1140,12 @@ ssol_estimator_get_mc_sampled
const struct ssol_instance* samp_instance,
struct ssol_mc_sampled* sampled);
+/* Retrieve the RNG state at the end of the simulation */
+SSOL_API res_T
+ssol_estimator_get_rng_state
+ (const struct ssol_estimator* estimator,
+ const struct ssp_rng** rng_state);
+
/*******************************************************************************
* Tracked paths
******************************************************************************/
diff --git a/src/ssol_estimator.c b/src/ssol_estimator.c
@@ -25,6 +25,8 @@
#include <rsys/ref_count.h>
#include <rsys/rsys.h>
+#include <star/ssp.h>
+
#include <math.h>
/*******************************************************************************
@@ -81,6 +83,7 @@ estimator_release(ref_T* ref)
htable_receiver_release(&estimator->mc_receivers);
htable_sampled_release(&estimator->mc_sampled);
darray_path_release(&estimator->paths);
+ if(estimator->rng) SSP(rng_ref_put(estimator->rng));
ASSERT(dev && dev->allocator);
MEM_RM(dev->allocator, estimator);
SSOL(device_ref_put(dev));
@@ -255,6 +258,15 @@ ssol_estimator_get_mc_sampled
}
res_T
+ssol_estimator_get_rng_state
+ (const struct ssol_estimator* estimator, const struct ssp_rng** rng_state)
+{
+ if(!estimator || !rng_state) return RES_BAD_ARG;
+ *rng_state = estimator->rng;
+ return RES_OK;
+}
+
+res_T
ssol_estimator_get_tracked_paths_count
(const struct ssol_estimator* estimator, size_t* npaths)
{
@@ -344,7 +356,6 @@ estimator_create
exit:
if(out_estimator) *out_estimator = estimator;
return res;
-
error:
if(estimator) {
SSOL(estimator_ref_put(estimator));
@@ -353,3 +364,55 @@ error:
goto exit;
}
+res_T
+estimator_save_rng_state
+ (struct ssol_estimator* estimator, const struct ssp_rng_proxy* proxy)
+{
+ struct ssp_rng_type rng_type;
+ FILE* stream = NULL;
+ res_T res = RES_OK;
+ ASSERT(estimator && proxy);
+
+ /* Release the previous rng state */
+ if(estimator->rng) {
+ SSP(rng_ref_put(estimator->rng));
+ estimator->rng = NULL;
+ }
+
+ stream = tmpfile();
+ if(!stream) {
+ log_error(estimator->dev,
+ "Could not open a stream to store the proxy RNG state.\n");
+ res = RES_IO_ERR;
+ goto error;
+ }
+
+ SSP(rng_proxy_get_type(proxy, &rng_type));
+ res = ssp_rng_create(estimator->dev->allocator, &rng_type, &estimator->rng);
+ if(res != RES_OK) {
+ log_error(estimator->dev,
+ "Could not create the RNG to save the proxy RNG state.\n");
+ goto error;
+ }
+
+ res = ssp_rng_proxy_write(proxy, stream);
+ if(res != RES_OK) {
+ log_error(estimator->dev, "Could not serialize the proxy RNG state.\n");
+ goto error;
+ }
+
+ rewind(stream);
+ res = ssp_rng_read(estimator->rng, stream);
+ if(res != RES_OK) {
+ log_error(estimator->dev, "Could not save the proxy RNG state.\n");
+ goto error;
+ }
+
+exit:
+ if(stream) fclose(stream);
+ return res;
+error:
+ if(estimator->rng) SSP(rng_ref_put(estimator->rng));
+ goto exit;
+}
+
diff --git a/src/ssol_estimator_c.h b/src/ssol_estimator_c.h
@@ -26,6 +26,7 @@
/* Forward declaration */
struct mem_allocator;
struct ssol_instance;
+struct ssp_rng_proxy;
/* Monte carlo data */
struct mc_data {
@@ -569,6 +570,9 @@ struct ssol_estimator {
* geometry */
double sampled_area;
+ /* State of the RNG after the simulation */
+ struct ssp_rng* rng;
+
struct ssol_device* dev;
ref_T ref;
};
@@ -579,6 +583,11 @@ estimator_create
struct ssol_scene* scene,
struct ssol_estimator** estimator);
+extern LOCAL_SYM res_T
+estimator_save_rng_state
+ (struct ssol_estimator* estimator,
+ const struct ssp_rng_proxy* proxy);
+
static FINLINE res_T
get_mc_receiver_1side
(struct htable_receiver* receivers,
diff --git a/src/ssol_solver.c b/src/ssol_solver.c
@@ -1320,6 +1320,10 @@ ssol_solve
}
estimator->sampled_area = scn->sampled_area;
+
+ res = estimator_save_rng_state(estimator, rng_proxy);
+ if(res != RES_OK) goto error;
+
if(mt_res != RES_OK) res = (res_T)mt_res;
#ifndef NDEBUG