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:
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);