commit 3f62821b16cf6adfdd329cf1e41c98c683bc5195
parent b684e2be2d5a9e76636437c9e4ee855c127c0987
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Fri, 7 Jan 2022 11:00:52 +0100
Upd the profile of the smc_device_create function
The input arguments are now grouped together in the
smc_device_create_args structure rather than submitted separately as
function arguments. Thanks to this structure and its default values,
updating the input parameters should now marginally affect the calling
code.
In addition to the previous input arguments, the smc_device_create_args
structure has a new "verbose" member variable which controls the
verbosity level of the library. By default, the library is quiet.
Diffstat:
9 files changed, 166 insertions(+), 54 deletions(-)
diff --git a/src/smc.h b/src/smc.h
@@ -98,6 +98,19 @@ struct smc_integrator {
#define SMC_INTEGRATOR_NULL__ {NULL, NULL, 0, 0}
static const struct smc_integrator SMC_INTEGRATOR_NULL = SMC_INTEGRATOR_NULL__;
+struct smc_device_create_args {
+ struct mem_allocator* allocator; /* May NULL <=> Default allocator */
+ struct logger* logger; /* May NULL <=> default logger */
+ unsigned nthreads_hint; /* Hint on the number of threads to use */
+ enum ssp_rng_type rng_type; /* SSP_RNG_TYPE_NULL <=> use default RNG type */
+ int verbose; /* Verbosity level */
+};
+#define SMC_DEVICE_CREATE_ARGS_DEFAULT__ { \
+ NULL, NULL, SMC_NTHREADS_DEFAULT, SSP_RNG_TYPE_NULL, 0 \
+}
+static const struct smc_device_create_args SMC_DEVICE_CREATE_ARGS_DEFAULT =
+ SMC_DEVICE_CREATE_ARGS_DEFAULT__;
+
/* Forward declaration of opaque types */
struct smc_device; /* Entry point of the library */
struct smc_estimator; /* Estimator of an integrator */
@@ -130,10 +143,7 @@ SMC_API double* SMC_DOUBLEN(void* val);
******************************************************************************/
SMC_API res_T
smc_device_create
- (struct logger* logger, /* May be NULL <=> use default logger */
- struct mem_allocator* allocator, /* May be NULL <=> use default allocator */
- const unsigned nthreads_hint, /* Hint on the number of threads to use */
- const enum ssp_rng_type type, /* SSP_RNG_TYPE_NULL <=> use default RNG type */
+ (const struct smc_device_create_args* args,
struct smc_device** dev);
SMC_API res_T
diff --git a/src/smc_device.c b/src/smc_device.c
@@ -42,6 +42,26 @@
/*******************************************************************************
* Helper functions
******************************************************************************/
+static INLINE res_T
+check_device_create_args(const struct smc_device_create_args* args)
+{
+ if(!args || args->nthreads_hint == 0) return RES_BAD_ARG;
+ return RES_OK;
+}
+
+static INLINE void
+log_msg
+ (struct smc_device* smc,
+ const enum log_type stream,
+ const char* msg,
+ va_list vargs)
+{
+ ASSERT(smc && msg);
+ if(smc->verbose) {
+ CHK(logger_vprint(smc->logger, stream, msg, vargs) == RES_OK);
+ }
+}
+
static void
release_rngs(struct smc_device* dev)
{
@@ -79,21 +99,24 @@ device_release(ref_T* ref)
******************************************************************************/
res_T
smc_device_create
- (struct logger* logger,
- struct mem_allocator* mem_allocator,
- const unsigned nthreads_hint,
- const enum ssp_rng_type rng_type,
+ (const struct smc_device_create_args* args,
struct smc_device** out_dev)
{
struct smc_device* dev = NULL;
- struct mem_allocator* allocator;
+ struct mem_allocator* allocator = &mem_default_allocator;
+ struct logger* logger = LOGGER_DEFAULT;
+ enum ssp_rng_type rng_type = SSP_RNG_THREEFRY;
res_T res = RES_OK;
- if(!out_dev || !nthreads_hint) {
- res = RES_BAD_ARG;
- goto exit;
- }
- allocator = mem_allocator ? mem_allocator : &mem_default_allocator;
+ if(!out_dev) { res = RES_BAD_ARG; goto exit; }
+
+ res = check_device_create_args(args);
+ if(res != RES_OK) goto error;
+
+ if(args->allocator) allocator = args->allocator;
+ if(args->logger) logger = args->logger;
+ if(args->rng_type != SSP_RNG_TYPE_NULL) rng_type = args->rng_type;
+
dev = MEM_CALLOC(allocator, 1, sizeof(struct smc_device));
if(!dev) {
res = RES_MEM_ERR;
@@ -101,15 +124,14 @@ smc_device_create
}
ref_init(&dev->ref);
dev->allocator = allocator;
- dev->logger = logger ? logger : LOGGER_DEFAULT;
+ dev->logger = logger;
+ dev->verbose = args->verbose;
- dev->nthreads = MMIN(nthreads_hint, (unsigned)omp_get_num_procs());
+ dev->nthreads = MMIN(args->nthreads_hint, (unsigned)omp_get_num_procs());
omp_set_num_threads((int)dev->nthreads);
- res = smc_device_set_rng_type
- (dev, rng_type == SSP_RNG_TYPE_NULL ? SSP_RNG_THREEFRY : rng_type);
- if(res != RES_OK)
- goto error;
+ res = smc_device_set_rng_type(dev, rng_type);
+ if(res != RES_OK) goto error;
exit:
if(out_dev) *out_dev = dev;
@@ -204,3 +226,36 @@ smc_device_get_threads_count(const struct smc_device* dev, unsigned* nthreads)
return RES_OK;
}
+
+/*******************************************************************************
+ * Local functions
+ ******************************************************************************/
+void
+log_info(struct smc_device* smc, const char* msg, ...)
+{
+ va_list vargs_list;
+ ASSERT(smc && msg);
+ va_start(vargs_list, msg);
+ log_msg(smc, LOG_OUTPUT, msg, vargs_list);
+ va_end(vargs_list);
+}
+
+void
+log_err(struct smc_device* smc, const char* msg, ...)
+{
+ va_list vargs_list;
+ ASSERT(smc && msg);
+ va_start(vargs_list, msg);
+ log_msg(smc, LOG_ERROR, msg, vargs_list);
+ va_end(vargs_list);
+}
+
+void
+log_warn(struct smc_device* smc, const char* msg, ...)
+{
+ va_list vargs_list;
+ ASSERT(smc && msg);
+ va_start(vargs_list, msg);
+ log_msg(smc, LOG_WARNING, msg, vargs_list);
+ va_end(vargs_list);
+}
diff --git a/src/smc_device_c.h b/src/smc_device_c.h
@@ -35,14 +35,49 @@
#include <rsys/ref_count.h>
#include <rsys/stretchy_array.h>
+struct logger;
+struct mem_allocator;
+struct ssp_rng_proxy;
+struct ssp_rng;
+
struct smc_device {
struct ssp_rng_proxy* rng_proxy;
struct ssp_rng** rngs;
struct logger* logger;
struct mem_allocator* allocator;
size_t nthreads;
+ int verbose;
ref_T ref;
};
-#endif /* SMC_DEVICE_C_H */
+extern LOCAL_SYM void
+log_info
+ (struct smc_device* smc,
+ const char* msg,
+ ...)
+#ifdef COMPILER_GCC
+ __attribute((format(printf, 2, 3)))
+#endif
+ ;
+
+extern LOCAL_SYM void
+log_err
+ (struct smc_device* smc,
+ const char* msg,
+ ...)
+#ifdef COMPILER_GCC
+ __attribute((format(printf, 2, 3)))
+#endif
+ ;
+extern LOCAL_SYM void
+log_warn
+ (struct smc_device* smc,
+ const char* msg,
+ ...)
+#ifdef COMPILER_GCC
+ __attribute((format(printf, 2, 3)))
+#endif
+ ;
+
+#endif /* SMC_DEVICE_C_H */
diff --git a/src/smc_estimator.c b/src/smc_estimator.c
@@ -33,7 +33,6 @@
#include "smc_device_c.h"
#include "smc_type_c.h"
-#include <rsys/logger.h>
#include <rsys/mem_allocator.h>
#include <limits.h>
@@ -201,7 +200,7 @@ smc_solve
if(res != RES_OK) goto error;
/* Parallel evaluation of the simulation */
- logger_print(dev->logger, LOG_OUTPUT, "Solving: %3d%%\r", progress);
+ log_info(dev, "Solving: %3d%%\r", progress);
#pragma omp parallel for schedule(static)
for(i = 0; i < (int64_t)integrator->max_realisations; ++i) {
const int ithread = omp_get_thread_num();
@@ -237,10 +236,10 @@ smc_solve
#pragma omp critical
if(pcent > progress) {
progress = pcent;
- logger_print(dev->logger, LOG_OUTPUT, "Solving: %3d%%\r", progress);
+ log_info(dev, "Solving: %3d%%\r", progress);
}
}
- logger_print(dev->logger, LOG_OUTPUT, "Solving: %3d%%\n", progress);
+ log_info(dev, "Solving: %3d%%\n", progress);
/* Merge the parallel estimation into the final estimator */
FOR_EACH(i, 0, (int64_t)nthreads) {
@@ -318,7 +317,7 @@ smc_solve_N
}
/* Parallel estimation of N simulations */
- logger_print(dev->logger, LOG_OUTPUT, "Solving: %3d%%\r", progress);
+ log_info(dev, "Solving: %3d%%\r", progress);
#pragma omp parallel for schedule(static, 1)
for(i = 0; i < (int64_t)count; ++i) {
size_t istep;
@@ -359,11 +358,11 @@ smc_solve_N
#pragma omp critical
if(pcent > progress) {
progress = pcent;
- logger_print(dev->logger, LOG_OUTPUT, "Solving: %3d%%\r", progress);
+ log_info(dev, "Solving: %3d%%\r", progress);
}
}
- logger_print(dev->logger, LOG_OUTPUT, "Solving: %3d%%\n", progress);
+ log_info(dev, "Solving: %3d%%\n", progress);
exit:
if(vals) {
diff --git a/src/test_smc_device.c b/src/test_smc_device.c
@@ -49,14 +49,13 @@ main(int argc, char** argv)
struct logger logger;
struct mem_allocator allocator;
enum ssp_rng_type type;
+ struct smc_device_create_args args = SMC_DEVICE_CREATE_ARGS_DEFAULT;
struct smc_device* dev;
unsigned nthreads;
(void)argc, (void)argv;
- CHK(smc_device_create
- (NULL, NULL, SMC_NTHREADS_DEFAULT, SSP_RNG_TYPE_NULL, NULL) == RES_BAD_ARG);
- CHK(smc_device_create
- (NULL, NULL, SMC_NTHREADS_DEFAULT, SSP_RNG_TYPE_NULL, &dev) == RES_OK);
+ CHK(smc_device_create(&args, NULL) == RES_BAD_ARG);
+ CHK(smc_device_create(&args, &dev) == RES_OK);
CHK(smc_device_get_threads_count(NULL, NULL) == RES_BAD_ARG);
CHK(smc_device_get_threads_count(dev, NULL) == RES_BAD_ARG);
@@ -70,15 +69,16 @@ main(int argc, char** argv)
CHK(smc_device_ref_put(dev) == RES_OK);
CHK(smc_device_ref_put(dev) == RES_OK);
- CHK(smc_device_create(NULL, NULL, 0, SSP_RNG_TYPE_NULL, &dev) == RES_BAD_ARG);
+ args.nthreads_hint = 0;
+ CHK(smc_device_create(&args, &dev) == RES_BAD_ARG);
mem_init_proxy_allocator(&allocator, &mem_default_allocator);
-
CHK(MEM_ALLOCATED_SIZE(&allocator) == 0);
- CHK(smc_device_create
- (NULL, &allocator, 1, SSP_RNG_TYPE_NULL, NULL) == RES_BAD_ARG);
- CHK(smc_device_create
- (NULL, &allocator, 1, SSP_RNG_TYPE_NULL, &dev) == RES_OK);
+
+ args.nthreads_hint = 1;
+ args.allocator = &allocator;
+ CHK(smc_device_create(&args, NULL) == RES_BAD_ARG);
+ CHK(smc_device_create(&args, &dev) == RES_OK);
CHK(smc_device_ref_put(dev) == RES_OK);
CHK(MEM_ALLOCATED_SIZE(&allocator) == 0);
@@ -87,14 +87,18 @@ main(int argc, char** argv)
logger_set_stream(&logger, LOG_ERROR, log_stream, NULL);
logger_set_stream(&logger, LOG_WARNING, log_stream, NULL);
- CHK(smc_device_create(&logger, NULL, 1, SSP_RNG_TYPE_NULL, NULL) == RES_BAD_ARG);
- CHK(smc_device_create(&logger, NULL, 1, SSP_RNG_TYPE_NULL, &dev) == RES_OK);
+ args.logger = &logger;
+ args.allocator = NULL;
+ CHK(smc_device_create(&args, NULL) == RES_BAD_ARG);
+ CHK(smc_device_create(&args, &dev) == RES_OK);
CHK(smc_device_ref_put(dev) == RES_OK);
- CHK(smc_device_create
- (&logger, &allocator, 4, SSP_RNG_TYPE_NULL, NULL) == RES_BAD_ARG);
- CHK(smc_device_create
- (&logger, &allocator, 4, SSP_RNG_TYPE_NULL, &dev) == RES_OK);
+ args.logger = &logger;
+ args.allocator = &allocator;
+ args.nthreads_hint = SMC_NTHREADS_DEFAULT;
+
+ CHK(smc_device_create(&args, NULL) == RES_BAD_ARG);
+ CHK(smc_device_create(&args, &dev) == RES_OK);
CHK(smc_device_set_rng_type(NULL, SSP_RNG_TYPE_NULL) == RES_BAD_ARG);
CHK(smc_device_set_rng_type(dev, SSP_RNG_TYPE_NULL) == RES_BAD_ARG);
@@ -113,7 +117,8 @@ main(int argc, char** argv)
CHK(smc_device_ref_put(dev) == RES_OK);
- CHK(smc_device_create(&logger, &allocator, 4, SSP_RNG_RANLUX48, &dev) == RES_OK);
+ args.rng_type = SSP_RNG_RANLUX48;
+ CHK(smc_device_create(&args, &dev) == RES_OK);
CHK(smc_device_ref_put(dev) == RES_OK);
logger_release(&logger);
diff --git a/src/test_smc_doubleN.c b/src/test_smc_doubleN.c
@@ -67,6 +67,7 @@ main(int argc, char** argv)
{
struct mem_allocator allocator;
struct smc_device* dev;
+ struct smc_device_create_args args = SMC_DEVICE_CREATE_ARGS_DEFAULT;
struct smc_integrator integrator = SMC_INTEGRATOR_NULL;
struct smc_estimator* estimator;
struct smc_estimator_status status;
@@ -78,8 +79,8 @@ main(int argc, char** argv)
mem_init_proxy_allocator(&allocator, &mem_default_allocator);
- CHK(smc_device_create
- (NULL, &allocator, SMC_NTHREADS_DEFAULT, SSP_RNG_TYPE_NULL, &dev) == RES_OK);
+ args.allocator = &allocator;
+ CHK(smc_device_create(&args, &dev) == RES_OK);
integrator.integrand = cos_x;
integrator.type = &smc_doubleN;
diff --git a/src/test_smc_errors.c b/src/test_smc_errors.c
@@ -55,6 +55,7 @@ main(int argc, char** argv)
{
struct mem_allocator allocator;
struct smc_device* dev;
+ struct smc_device_create_args args = SMC_DEVICE_CREATE_ARGS_DEFAULT;
struct smc_integrator integrator = SMC_INTEGRATOR_NULL;
struct smc_estimator* estimator;
struct smc_estimator_status status;
@@ -62,8 +63,8 @@ main(int argc, char** argv)
mem_init_proxy_allocator(&allocator, &mem_default_allocator);
- SMC(device_create
- (NULL, &allocator, SMC_NTHREADS_DEFAULT, SSP_RNG_TYPE_NULL, &dev));
+ args.allocator = &allocator;
+ SMC(device_create(&args, &dev));
integrator.integrand = &compute_1;
integrator.type = &smc_double;
diff --git a/src/test_smc_light_path.c b/src/test_smc_light_path.c
@@ -318,12 +318,14 @@ main(int argc, char** argv)
{
struct mem_allocator allocator;
struct image img;
+ FILE* fp = NULL;
struct integrator_context* contexts;
struct s3d_device* dev;
struct s3d_scene* scn;
struct s3d_scene_view* view;
struct s3d_shape* shape;
struct s3d_vertex_data attrib;
+ struct smc_device_create_args args = SMC_DEVICE_CREATE_ARGS_DEFAULT;
struct smc_device* smc;
struct smc_integrator integrator = SMC_INTEGRATOR_NULL;
struct smc_estimator** estimators;
@@ -373,8 +375,9 @@ main(int argc, char** argv)
CHK(s3d_scene_view_create(scn, S3D_TRACE, &view) == RES_OK);
- CHK(smc_device_create
- (NULL, &allocator, SMC_NTHREADS_DEFAULT, SSP_RNG_TYPE_NULL, &smc) == RES_OK);
+ args.allocator = &allocator;
+ args.verbose = 1;
+ CHK(smc_device_create(&args, &smc) == RES_OK);
integrator.integrand = light_path_integrator;
integrator.type = &smc_float;
@@ -418,7 +421,9 @@ main(int argc, char** argv)
CHK(smc_estimator_ref_put(estimators[iestimator]) == RES_OK);
}}
- image_write_ppm_stream(&img, 0, stderr);
+ CHK(fp = fopen("image.ppm", "w"));
+ image_write_ppm_stream(&img, 0, fp);
+ CHK(fclose(fp) == 0);
CHK(image_release(&img) == RES_OK);
MEM_RM(&allocator, contexts);
diff --git a/src/test_smc_solve.c b/src/test_smc_solve.c
@@ -67,6 +67,7 @@ main(int argc, char** argv)
{
struct mem_allocator allocator;
struct smc_device* dev;
+ struct smc_device_create_args args = SMC_DEVICE_CREATE_ARGS_DEFAULT;
struct smc_integrator integrator = SMC_INTEGRATOR_NULL;
struct smc_estimator* estimator;
struct smc_estimator_status status;
@@ -74,8 +75,8 @@ main(int argc, char** argv)
mem_init_proxy_allocator(&allocator, &mem_default_allocator);
- CHK(smc_device_create
- (NULL, &allocator, SMC_NTHREADS_DEFAULT, SSP_RNG_TYPE_NULL, &dev) == RES_OK);
+ args.allocator = &allocator;
+ CHK(smc_device_create(&args, &dev) == RES_OK);
integrator.integrand = rcp_x;
integrator.type = &smc_double;