star-mc

Parallel estimation of Monte Carlo integrators
git clone git://git.meso-star.fr/star-mc.git
Log | Files | Refs | README | LICENSE

commit e074851ac2387d5ea4d29cb5207634bebd9711d7
parent 69081f544c04670e187387dd2b0d142ab1add76d
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Mon, 22 Jan 2018 16:05:55 +0100

Implement the smc_device_get_theads_count function

Diffstat:
Mcmake/CMakeLists.txt | 14++++++++------
Msrc/smc.h | 9++++++++-
Msrc/smc_device.c | 9+++++++++
Msrc/smc_device_c.h | 7-------
Msrc/smc_estimator.c | 12++++++------
Msrc/test_smc_device.c | 9+++++++++
Msrc/test_smc_doubleN.c | 2+-
Msrc/test_smc_errors.c | 6+++---
Msrc/test_smc_light_path.c | 5+++--
Msrc/test_smc_solve.c | 8++++----
10 files changed, 51 insertions(+), 30 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -42,8 +42,8 @@ option(NO_TEST "Disable the test" OFF) find_package(RCMake 0.3 REQUIRED) find_package(RSys 0.6 REQUIRED) find_package(StarSP 0.5 REQUIRED) +find_package(OpenMP 1.2 REQUIRED) find_package(Star3D 0.4) -find_package(OpenMP) if(NOT OPENMP_FOUND) message(STATUS "No OpenMP support: muti-threading is disabled") @@ -87,11 +87,9 @@ set_target_properties(smc PROPERTIES VERSION ${VERSION} SOVERSION ${VERSION_MAJOR}) -if(OPENMP_FOUND) - set_target_properties(smc PROPERTIES COMPILE_FLAGS ${OpenMP_C_FLAGS}) - if(CMAKE_COMPILER_IS_GNUCC) - set_target_properties(smc PROPERTIES LINK_FLAGS ${OpenMP_C_FLAGS}) - endif() +set_target_properties(smc PROPERTIES COMPILE_FLAGS ${OpenMP_C_FLAGS}) +if(CMAKE_COMPILER_IS_GNUCC) + set_target_properties(smc PROPERTIES LINK_FLAGS ${OpenMP_C_FLAGS}) endif() target_link_libraries(smc RSys StarSP) @@ -126,6 +124,10 @@ if(NOT NO_TEST) new_test(test_smc_doubleN ${MATH_LIB}) new_test(test_smc_errors) + set_target_properties(test_smc_device PROPERTIES + COMPILE_FLAGS ${OpenMP_C_FLAGS} + LINK_FLAGS ${OpenMP_C_FLAGS}) + if(NOT TARGET Star3D) rcmake_copy_runtime_libraries(test_smc_solve) message(STATUS diff --git a/src/smc.h b/src/smc.h @@ -87,7 +87,8 @@ struct smc_estimator_status { }; struct smc_integrator { - res_T (*integrand)(void* val, struct ssp_rng*, const int ithread, void* ctx); + res_T (*integrand) + (void* value, struct ssp_rng* rng, const unsigned ithread, void* ctx); const struct smc_type* type; size_t max_realisations; /* Maximum # of realisations */ size_t max_failures; /* Cancel integration past # failed samples */ @@ -149,6 +150,12 @@ smc_device_get_rng_type (struct smc_device* dev, struct ssp_rng_type* type); +/* Return the maximum number of threads internally used by the device */ +SMC_API res_T +smc_device_get_threads_count + (const struct smc_device* dev, + unsigned* nthreads); + /******************************************************************************* * Integration API ******************************************************************************/ diff --git a/src/smc_device.c b/src/smc_device.c @@ -194,3 +194,12 @@ smc_device_get_rng_type(struct smc_device* dev, struct ssp_rng_type* type) return ssp_rng_proxy_get_type(dev->rng_proxy, type); } +res_T +smc_device_get_threads_count(const struct smc_device* dev, unsigned* nthreads) +{ + if(!dev || !nthreads) return RES_BAD_ARG; + ASSERT(dev->nthreads <= UINT_MAX); + *nthreads = (unsigned)dev->nthreads; + return RES_OK; +} + diff --git a/src/smc_device_c.h b/src/smc_device_c.h @@ -44,12 +44,5 @@ struct smc_device { ref_T ref; }; -static FINLINE size_t -device_get_threads_count(const struct smc_device* dev) -{ - ASSERT(dev); - return sa_size(dev->rngs); -} - #endif /* SMC_DEVICE_C_H */ diff --git a/src/smc_estimator.c b/src/smc_estimator.c @@ -151,7 +151,7 @@ smc_solve { struct smc_estimator* estimator = NULL; int64_t i; - size_t nthreads = 0; + unsigned nthreads = 0; char* raw = NULL; void** vals = NULL; void** accums = NULL; @@ -165,7 +165,7 @@ smc_solve res = RES_BAD_ARG; goto error; } - nthreads = device_get_threads_count(dev); + SMC(device_get_threads_count(dev, &nthreads)); /* Create per thread temporary variables */ raw = MEM_CALLOC(dev->allocator, nthreads, sizeof(void*)*3 + sizeof(size_t)); @@ -205,7 +205,7 @@ smc_solve for(i = 0; i < (int64_t)integrator->max_realisations; ++i) { if(!cancel) { const res_T res_local = integrator->integrand - (vals[ithread], dev->rngs[ithread], ithread, ctx); + (vals[ithread], dev->rngs[ithread], (unsigned)ithread, ctx); if(res_local == RES_OK) { /* call succeded */ integrator->type->add(accums[ithread], accums[ithread], vals[ithread]); @@ -262,7 +262,7 @@ smc_solve_N { res_T res = RES_OK; int64_t i; - size_t nthreads = 0; + unsigned nthreads = 0; void** vals = NULL; int cancel = 0; @@ -285,7 +285,7 @@ smc_solve_N } /* Create the per thread temporary variables */ - nthreads = device_get_threads_count(dev); + SMC(device_get_threads_count(dev, &nthreads)); vals = MEM_CALLOC(dev->allocator, nthreads, sizeof(void*)); FOR_EACH(i, 0, (int64_t)nthreads) { vals[i] = integrator->type->create @@ -306,7 +306,7 @@ smc_solve_N FOR_EACH(istep, 0, integrator->max_realisations) { if(!cancel) { const res_T res_local = integrator->integrand - (vals[ithread], dev->rngs[ithread], ithread, + (vals[ithread], dev->rngs[ithread], (unsigned)ithread, (char*)ctx + (size_t)i*sizeof_ctx); if(res_local == RES_OK) { /* call succeded */ diff --git a/src/test_smc_device.c b/src/test_smc_device.c @@ -33,6 +33,8 @@ #include <star/ssp.h> +#include <omp.h> + static void log_stream(const char* msg, void* ctx) { @@ -48,11 +50,18 @@ main(int argc, char** argv) struct mem_allocator allocator; struct ssp_rng_type type; struct smc_device* dev; + unsigned nthreads; (void)argc, (void)argv; CHK(smc_device_create(NULL, NULL, SMC_NTHREADS_DEFAULT, NULL, NULL) == RES_BAD_ARG); CHK(smc_device_create(NULL, NULL, SMC_NTHREADS_DEFAULT, NULL, &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); + CHK(smc_device_get_threads_count(NULL, &nthreads) == RES_BAD_ARG); + CHK(smc_device_get_threads_count(dev, &nthreads) == RES_OK); + CHK(nthreads == (unsigned)omp_get_num_procs()); + CHK(smc_device_ref_get(NULL) == RES_BAD_ARG); CHK(smc_device_ref_get(dev) == RES_OK); CHK(smc_device_ref_put(NULL) == RES_BAD_ARG); diff --git a/src/test_smc_doubleN.c b/src/test_smc_doubleN.c @@ -45,7 +45,7 @@ enum { struct alpha { double value; }; static res_T -cos_x(void* value, struct ssp_rng* rng, const int ithread, void* context) +cos_x(void* value, struct ssp_rng* rng, const unsigned ithread, void* context) { double* result = SMC_DOUBLEN(value); double samp; diff --git a/src/test_smc_errors.c b/src/test_smc_errors.c @@ -35,12 +35,12 @@ #include <star/ssp.h> static res_T -compute_1(void* value, struct ssp_rng* rng, const int ithread, void* context) +compute_1 + (void* value, struct ssp_rng* rng, const unsigned ithread, void* context) { /* pretend that 10% of the realizations fail */ int ok = ssp_rng_canonical(rng) > 0.1; - (void)context; - CHK(ithread >= 0); + (void)context, (void)ithread; if(ok) { SMC_DOUBLE(value) = 1; /* weight is 1 */ } else { diff --git a/src/test_smc_light_path.c b/src/test_smc_light_path.c @@ -246,7 +246,7 @@ skydome_lighting(const float wi[3]) static res_T light_path_integrator - (void* value, struct ssp_rng* rng, const int ithread, void* data) + (void* value, struct ssp_rng* rng, const unsigned ithread, void* data) { struct integrator_context* ctx = data; float pix_lower[2], pix_upper[2]; /* Pixel AABB */ @@ -256,9 +256,10 @@ light_path_integrator float throughput = 1.f; int idepth; + (void)ithread; + CHK(value != NULL); CHK(rng != NULL); - CHK(ithread >= 0); CHK(data != NULL); /* Compute the pixel bound */ diff --git a/src/test_smc_solve.c b/src/test_smc_solve.c @@ -35,13 +35,13 @@ #include <math.h> static res_T -rcp_x(void* value, struct ssp_rng* rng, const int ithread, void* ctx) +rcp_x(void* value, struct ssp_rng* rng, const unsigned ithread, void* ctx) { double* result = value; double samp; + (void)ithread; CHK(value != NULL); CHK(rng != NULL); - CHK(ithread >= 0); CHK(ctx == NULL); samp = ssp_rng_uniform_double(rng, 1.0, 4.0); *result = 1.0 / samp * 3; @@ -49,13 +49,13 @@ rcp_x(void* value, struct ssp_rng* rng, const int ithread, void* ctx) } static res_T -cos_x(void* value, struct ssp_rng* rng, const int ithread, void* ctx) +cos_x(void* value, struct ssp_rng* rng, const unsigned ithread, void* ctx) { float* result = value; double samp; + (void)ithread; CHK(value != NULL); CHK(rng != NULL); - CHK(ithread >= 0); CHK(ctx == (void*)0xC0DE); samp = ssp_rng_uniform_double(rng, -PI/4.0, PI/4.0); *result = (float)(cos(samp) * PI / 2.0);