commit adf0b3137f54dbba6d35d965c64fc984323c5369
parent 70b4beb0a8c71f6eaa748623f9cb60909a2b5f7a
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Tue, 23 Jan 2018 10:36:27 +0100
Merge branch 'release_0.4'
Diffstat:
18 files changed, 255 insertions(+), 708 deletions(-)
diff --git a/README.md b/README.md
@@ -20,9 +20,21 @@ RCMake package, the RSys and the Star-Sampling libraries, respectively. The
generated project can be edited, built, tested and installed as any CMake
project.
+## Release notes
+
+### Version 0.4
+
+- Remove the raw integration functionality.
+- Rename the `max_steps` integrator attribute in `max_realisation`.
+- Update the profile of the integrand function of the integrator: the
+ identifier of the thread that invokes the integrand is provided has an input
+ parameter.
+- Add the `smc_device_get_threads_count` function that returns the maximum
+ number of threads used by the device.
+
## License
-Star-MC is Copyright (C) |Meso|Star> 2015-2016 (<contact@meso-star.com>). It is
+Star-MC is Copyright (C) |Meso|Star> 2015-2018 (<contact@meso-star.com>). It is
a free software released under the [OSI](http://opensource.org)-approved CeCILL
license. You are welcome to redistribute it under certain conditions; refer to
the COPYING files for details.
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (C) |Meso|Star> 2015-2016 (contact@meso-star.com)
+# Copyright (C) |Meso|Star> 2015-2018 (contact@meso-star.com)
#
# This software is a computer program whose purpose is to generate files
# used to build the Star-MC library.
@@ -40,10 +40,10 @@ option(NO_TEST "Disable the test" OFF)
# Check dependencies
################################################################################
find_package(RCMake 0.3 REQUIRED)
-find_package(RSys 0.4 REQUIRED)
-find_package(StarSP 0.4 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")
@@ -59,12 +59,11 @@ include(rcmake_runtime)
# Configure and define targets
################################################################################
set(VERSION_MAJOR 0)
-set(VERSION_MINOR 3)
-set(VERSION_PATCH 1)
+set(VERSION_MINOR 4)
+set(VERSION_PATCH 0)
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
set(SMC_FILES_SRC
- smc_accumulator.c
smc_device.c
smc_doubleN.c
smc_estimator.c
@@ -88,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)
@@ -125,9 +122,12 @@ if(NOT NO_TEST)
new_test(test_smc_device)
new_test(test_smc_solve ${MATH_LIB})
new_test(test_smc_doubleN ${MATH_LIB})
- new_test(test_smc_integrate ${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
@@ -1,4 +1,4 @@
-/* Copyright (C) |Meso|Star> 2015-2016 (contact@meso-star.com)
+/* Copyright (C) |Meso|Star> 2015-2018 (contact@meso-star.com)
*
* This software is a computer program whose purpose is to manage the
* statistical estimation of a function.
@@ -75,15 +75,6 @@ struct smc_type {
void (*sqrt)(void* result, const void* value);
};
-/* Type for raw integration, i.e. whithout estimator. Experiment results are
- * simply accumulated */
-struct smc_type_accum {
- void* (*create)(struct mem_allocator* allocator, void* ctx);
- void (*destroy)(struct mem_allocator*, void* accum);
- void (*clear)(void* accum);
- void (*add)(void* result, const void* op0, const void* op1);
-};
-
static const struct smc_type SMC_TYPE_NULL =
{ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
@@ -95,37 +86,20 @@ struct smc_estimator_status {
size_t NF; /* Failed samples count */
};
-struct smc_accumulator_status {
- void* value; /* Accumulated value */
- size_t N; /* Samples count */
-};
-
struct smc_integrator {
- res_T (*integrand)(void* value, struct ssp_rng* rng, void* ctx);
+ res_T (*integrand)
+ (void* value, struct ssp_rng* rng, const unsigned ithread, void* ctx);
const struct smc_type* type;
- size_t max_steps; /* Maximum # of experiments */
+ size_t max_realisations; /* Maximum # of realisations */
size_t max_failures; /* Cancel integration past # failed samples */
};
static const struct smc_integrator SMC_INTEGRATOR_NULL =
{ NULL, NULL, SIZE_MAX, SIZE_MAX };
-#define SMC_AUTO_CANCEL_OFF SIZE_MAX
-
-struct smc_integrator_accum {
- res_T (*integrand)(void* accum, struct ssp_rng* rng, void* ctx);
- const struct smc_type_accum* type;
- size_t max_steps; /* Maximum # of accumulation */
- size_t max_failures; /* Cancel integration past # failed samples */
-};
-
-static const struct smc_integrator_accum SMC_INTEGRATOR_ACCUM_NULL =
-{ NULL, NULL, SIZE_MAX, SIZE_MAX };
-
/* Forward declaration of opaque types */
struct smc_device; /* Entry point of the library */
struct smc_estimator; /* Estimator of an integrator */
-struct smc_accumulator; /* Accumulated values of a integration */
BEGIN_DECLS
@@ -176,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
******************************************************************************/
@@ -208,31 +188,6 @@ smc_estimator_get_status
(struct smc_estimator* estimator,
struct smc_estimator_status* status);
-/*******************************************************************************
- * Accumulation API
- ******************************************************************************/
-/* Raw integration.
- * The realisations must be accumulated by the user defined integrand */
-SMC_API res_T
-smc_integrate
- (struct smc_device* dev,
- struct smc_integrator_accum* integrator,
- void* ctx,
- struct smc_accumulator** accumulator);
-
-SMC_API res_T
-smc_accumulator_ref_get
- (struct smc_accumulator* accumulator);
-
-SMC_API res_T
-smc_accumulator_ref_put
- (struct smc_accumulator* accumulator);
-
-SMC_API res_T
-smc_accumulator_get_status
- (struct smc_accumulator* accumulator,
- struct smc_accumulator_status* status);
-
END_DECLS
#endif /* SMC_H */
diff --git a/src/smc_accumulator.c b/src/smc_accumulator.c
@@ -1,237 +0,0 @@
-/* Copyright (C) |Meso|Star> 2015-2016 (contact@meso-star.com)
- *
- * This software is a computer program whose purpose is to manage the
- * statistical estimation of a function.
- *
- * This software is governed by the CeCILL license under French law and
- * abiding by the rules of distribution of free software. You can use,
- * modify and/or redistribute the software under the terms of the CeCILL
- * license as circulated by CEA, CNRS and INRIA at the following URL
- * "http://www.cecill.info".
- *
- * As a counterpart to the access to the source code and rights to copy,
- * modify and redistribute granted by the license, users are provided only
- * with a limited warranty and the software's author, the holder of the
- * economic rights, and the successive licensors have only limited
- * liability.
- *
- * In this respect, the user's attention is drawn to the risks associated
- * with loading, using, modifying and/or developing or reproducing the
- * software by the user in light of its specific status of free software,
- * that may mean that it is complicated to manipulate, and that also
- * therefore means that it is reserved for developers and experienced
- * professionals having in-depth computer knowledge. Users are therefore
- * encouraged to load and test the software's suitability as regards their
- * requirements in conditions enabling the security of their systems and/or
- * data to be ensured and, more generally, to use and operate it in the
- * same conditions as regards security.
- *
- * The fact that you are presently reading this means that you have had
- * knowledge of the CeCILL license and that you accept its terms. */
-
-#include "smc.h"
-#include "smc_device_c.h"
-#include "smc_type_c.h"
-
-#include <rsys/mem_allocator.h>
-
-#include <omp.h>
-
-struct smc_accumulator {
- struct smc_type_accum type;
- struct smc_accumulator_status status;
- struct smc_device* dev;
- ref_T ref;
-};
-
-/*******************************************************************************
- * Helper functions
- ******************************************************************************/
-static res_T
-accumulator_create
- (struct smc_device* dev,
- const struct smc_type_accum* type,
- void* ctx,
- struct smc_accumulator** out_accum)
-{
- struct smc_accumulator* accum = NULL;
- res_T res = RES_OK;
- ASSERT(out_accum && dev && type);
-
- accum = MEM_CALLOC(dev->allocator, 1, sizeof(struct smc_accumulator));
- if(!accum) {
- res = RES_MEM_ERR;
- goto error;
- }
- SMC(device_ref_get(dev));
- accum->dev = dev;
- ref_init(&accum->ref);
-
- accum->status.value = type->create(dev->allocator, ctx);
- if(!accum->status.value) {
- res = RES_MEM_ERR;
- goto error;
- }
- type->clear(accum->status.value);
-
- accum->status.N = 0;
- accum->type = *type;
-
-exit:
- *out_accum = accum;
- return res;
-error:
- if(accum) {
- SMC(accumulator_ref_put(accum));
- accum = NULL;
- }
- goto exit;
-}
-
-static char
-check_integrator_accum(struct smc_integrator_accum* integrator)
-{
- ASSERT(integrator);
- return integrator->integrand
- && integrator->type
- && integrator->max_steps
- && check_type_accum(integrator->type);
-}
-
-static void
-accumulator_release(ref_T* ref)
-{
- struct smc_accumulator* accum;
- struct smc_device* dev;
- ASSERT(ref);
-
- accum = CONTAINER_OF(ref, struct smc_accumulator, ref);
- dev = accum->dev;
- if(accum->status.value)
- accum->type.destroy(dev->allocator, accum->status.value);
- MEM_RM(dev->allocator, accum);
- SMC(device_ref_put(dev));
-}
-
-/*******************************************************************************
- * Exported functions
- ******************************************************************************/
-res_T
-smc_integrate
- (struct smc_device* dev,
- struct smc_integrator_accum* integrator,
- void* ctx,
- struct smc_accumulator** out_accum)
-{
- struct smc_accumulator* accum = NULL;
- int64_t i;
- size_t nthreads = 0;
- void** accums = NULL;
- size_t* nsamples = NULL;
- res_T res = RES_OK;
- size_t nfailed = 0;
- int cancel = 0;
-
- if(!dev || !integrator || !out_accum || !check_integrator_accum(integrator)) {
- res = RES_BAD_ARG;
- goto error;
- }
- nthreads = device_get_threads_count(dev);
-
- /* Create and initialize per thread memory variables */
- nsamples = MEM_CALLOC(dev->allocator, nthreads, sizeof(size_t));
- if(!nsamples) {
- res = RES_MEM_ERR;
- goto error;
- }
-
- accums = MEM_CALLOC(dev->allocator, nthreads, sizeof(void*));
- if(!accums) {
- res = RES_MEM_ERR;
- goto error;
- }
-
- FOR_EACH(i, 0, (int64_t)nthreads) {
- accums[i] = integrator->type->create(dev->allocator, ctx);
- if(!accums[i]) {
- res = RES_MEM_ERR;
- goto error;
- }
- integrator->type->clear(accums[i]);
- }
-
- /* Create the accumulator */
- res = accumulator_create(dev, integrator->type, ctx, &accum);
- if(res != RES_OK) goto error;
-
- /* Parallel evaluation of the integrator */
- #pragma omp parallel shared(cancel, nfailed)
- {
- const int ithread = omp_get_thread_num();
- #pragma omp for schedule(static)
- for(i=0; i < (int64_t)integrator->max_steps; ++i) {
- if(!cancel) {
- if(integrator->integrand(accums[ithread], dev->rngs[ithread], ctx) == RES_OK) {
- /* call succeded */
- ++nsamples[ithread];
- } else {
- #pragma omp atomic
- ++nfailed;
- if (nfailed > integrator->max_failures) {
- cancel = 1;
- }
- }
- }
- }
- }
-
- /* Merge the parallel estimation into the final estimator */
- FOR_EACH(i, 0, (int64_t)nthreads) {
- accum->status.N += nsamples[i];
- integrator->type->add(accum->status.value, accum->status.value, accums[i]);
- }
-
-exit:
- if(nsamples) MEM_RM(dev->allocator, nsamples);
- if(accums) {
- FOR_EACH(i, 0, (int64_t)nthreads)
- if(accums[i]) integrator->type->destroy(dev->allocator, accums[i]);
- MEM_RM(dev->allocator, accums);
- }
- if(out_accum) *out_accum = accum;
- return res;
-
-error:
- if(accum) {
- SMC(accumulator_ref_put(accum));
- accum = NULL;
- }
- goto exit;
-}
-
-res_T
-smc_accumulator_ref_get(struct smc_accumulator* accum)
-{
- if(!accum) return RES_BAD_ARG;
- ref_get(&accum->ref);
- return RES_OK;
-}
-
-res_T
-smc_accumulator_ref_put(struct smc_accumulator* accum)
-{
- if(!accum) return RES_BAD_ARG;
- ref_put(&accum->ref, accumulator_release);
- return RES_OK;
-}
-
-res_T
-smc_accumulator_get_status
- (struct smc_accumulator* accum,
- struct smc_accumulator_status* status)
-{
- if(!accum || !status) return RES_BAD_ARG;
- *status = accum->status;
- return RES_OK;
-}
-
diff --git a/src/smc_device.c b/src/smc_device.c
@@ -1,4 +1,4 @@
-/* Copyright (C) |Meso|Star> 2015-2016 (contact@meso-star.com)
+/* Copyright (C) |Meso|Star> 2015-2018 (contact@meso-star.com)
*
* This software is a computer program whose purpose is to manage the
* statistical estimation of a function.
@@ -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
@@ -1,4 +1,4 @@
-/* Copyright (C) |Meso|Star> 2015-2016 (contact@meso-star.com)
+/* Copyright (C) |Meso|Star> 2015-2018 (contact@meso-star.com)
*
* This software is a computer program whose purpose is to manage the
* statistical estimation of a function.
@@ -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_doubleN.c b/src/smc_doubleN.c
@@ -1,4 +1,4 @@
-/* Copyright (C) |Meso|Star> 2015-2016 (contact@meso-star.com)
+/* Copyright (C) |Meso|Star> 2015-2018 (contact@meso-star.com)
*
* This software is a computer program whose purpose is to manage the
* statistical estimation of a function.
diff --git a/src/smc_estimator.c b/src/smc_estimator.c
@@ -1,4 +1,4 @@
-/* Copyright (C) |Meso|Star> 2015-2016 (contact@meso-star.com)
+/* Copyright (C) |Meso|Star> 2015-2018 (contact@meso-star.com)
*
* This software is a computer program whose purpose is to manage the
* statistical estimation of a function.
@@ -112,7 +112,7 @@ check_integrator(struct smc_integrator* integrator)
ASSERT(integrator);
return integrator->integrand
&& integrator->type
- && integrator->max_steps
+ && integrator->max_realisations
&& check_type(integrator->type);
}
@@ -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));
@@ -202,9 +202,11 @@ smc_solve
{
const int ithread = omp_get_thread_num();
#pragma omp for schedule(static)
- for(i = 0; i < (int64_t)integrator->max_steps; ++i) {
+ for(i = 0; i < (int64_t)integrator->max_realisations; ++i) {
if(!cancel) {
- if(integrator->integrand(vals[ithread], dev->rngs[ithread], ctx) == RES_OK) {
+ const res_T res_local = integrator->integrand
+ (vals[ithread], dev->rngs[ithread], (unsigned)ithread, ctx);
+ if(res_local == RES_OK) {
/* call succeded */
integrator->type->add(accums[ithread], accums[ithread], vals[ithread]);
integrator->type->mul(vals[ithread], vals[ithread], vals[ithread]);
@@ -260,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;
@@ -283,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
@@ -301,11 +303,12 @@ smc_solve_N
#pragma omp for schedule(static, 1)
for(i = 0; i < (int64_t)count; ++i) {
size_t istep;
- FOR_EACH(istep, 0, integrator->max_steps) {
+ FOR_EACH(istep, 0, integrator->max_realisations) {
if(!cancel) {
- if(integrator->integrand
- (vals[ithread], dev->rngs[ithread], (char*)ctx + (size_t)i*sizeof_ctx)
- == RES_OK) {
+ const res_T res_local = integrator->integrand
+ (vals[ithread], dev->rngs[ithread], (unsigned)ithread,
+ (char*)ctx + (size_t)i*sizeof_ctx);
+ if(res_local == RES_OK) {
/* call succeded */
integrator->type->add
(estimators[i]->value, estimators[i]->value, vals[ithread]);
diff --git a/src/smc_type.c b/src/smc_type.c
@@ -1,4 +1,4 @@
-/* Copyright (C) |Meso|Star> 2015-2016 (contact@meso-star.com)
+/* Copyright (C) |Meso|Star> 2015-2018 (contact@meso-star.com)
*
* This software is a computer program whose purpose is to manage the
* statistical estimation of a function.
diff --git a/src/smc_type_c.h b/src/smc_type_c.h
@@ -1,4 +1,4 @@
-/* Copyright (C) |Meso|Star> 2015-2016 (contact@meso-star.com)
+/* Copyright (C) |Meso|Star> 2015-2018 (contact@meso-star.com)
*
* This software is a computer program whose purpose is to manage the
* statistical estimation of a function.
@@ -49,15 +49,5 @@ check_type(const struct smc_type* type)
&& type->sqrt != NULL;
}
-static INLINE char
-check_type_accum(const struct smc_type_accum* type)
-{
- ASSERT(type);
- return type->create != NULL
- && type->destroy != NULL
- && type->clear != NULL
- && type->add != NULL;
-}
-
#endif /* SMC_TYPE_C_H */
diff --git a/src/smc_type_real.h b/src/smc_type_real.h
@@ -1,4 +1,4 @@
-/* Copyright (C) |Meso|Star> 2015-2016 (contact@meso-star.com)
+/* Copyright (C) |Meso|Star> 2015-2018 (contact@meso-star.com)
*
* This software is a computer program whose purpose is to manage the
* statistical estimation of a function.
diff --git a/src/test_smc_device.c b/src/test_smc_device.c
@@ -1,4 +1,4 @@
-/* Copyright (C) |Meso|Star> 2015-2016 (contact@meso-star.com)
+/* Copyright (C) |Meso|Star> 2015-2018 (contact@meso-star.com)
*
* This software is governed by the CeCILL license under French law and
* abiding by the rules of distribution of free software. You can use,
@@ -33,6 +33,8 @@
#include <star/ssp.h>
+#include <omp.h>
+
static void
log_stream(const char* msg, void* ctx)
{
@@ -48,62 +50,69 @@ main(int argc, char** argv)
struct mem_allocator allocator;
struct ssp_rng_type type;
struct smc_device* dev;
+ unsigned nthreads;
(void)argc, (void)argv;
- CHECK(smc_device_create(NULL, NULL, SMC_NTHREADS_DEFAULT, NULL, NULL), RES_BAD_ARG);
- CHECK(smc_device_create(NULL, NULL, SMC_NTHREADS_DEFAULT, NULL, &dev), RES_OK);
+ 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());
- CHECK(smc_device_ref_get(NULL), RES_BAD_ARG);
- CHECK(smc_device_ref_get(dev), RES_OK);
- CHECK(smc_device_ref_put(NULL), RES_BAD_ARG);
- CHECK(smc_device_ref_put(dev), RES_OK);
- CHECK(smc_device_ref_put(dev), RES_OK);
+ 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);
+ CHK(smc_device_ref_put(dev) == RES_OK);
+ CHK(smc_device_ref_put(dev) == RES_OK);
- CHECK(smc_device_create(NULL, NULL, 0, NULL, &dev), RES_BAD_ARG);
+ CHK(smc_device_create(NULL, NULL, 0, NULL, &dev) == RES_BAD_ARG);
mem_init_proxy_allocator(&allocator, &mem_default_allocator);
- CHECK(MEM_ALLOCATED_SIZE(&allocator), 0);
- CHECK(smc_device_create(NULL, &allocator, 1, NULL, NULL), RES_BAD_ARG);
- CHECK(smc_device_create(NULL, &allocator, 1, NULL, &dev), RES_OK);
- CHECK(smc_device_ref_put(dev), RES_OK);
- CHECK(MEM_ALLOCATED_SIZE(&allocator), 0);
+ CHK(MEM_ALLOCATED_SIZE(&allocator) == 0);
+ CHK(smc_device_create(NULL, &allocator, 1, NULL, NULL) == RES_BAD_ARG);
+ CHK(smc_device_create(NULL, &allocator, 1, NULL, &dev) == RES_OK);
+ CHK(smc_device_ref_put(dev) == RES_OK);
+ CHK(MEM_ALLOCATED_SIZE(&allocator) == 0);
- CHECK(logger_init(&allocator, &logger), RES_OK);
+ CHK(logger_init(&allocator, &logger) == RES_OK);
logger_set_stream(&logger, LOG_OUTPUT, log_stream, NULL);
logger_set_stream(&logger, LOG_ERROR, log_stream, NULL);
logger_set_stream(&logger, LOG_WARNING, log_stream, NULL);
- CHECK(smc_device_create(&logger, NULL, 1, NULL, NULL), RES_BAD_ARG);
- CHECK(smc_device_create(&logger, NULL, 1, NULL, &dev), RES_OK);
- CHECK(smc_device_ref_put(dev), RES_OK);
+ CHK(smc_device_create(&logger, NULL, 1, NULL, NULL) == RES_BAD_ARG);
+ CHK(smc_device_create(&logger, NULL, 1, NULL, &dev) == RES_OK);
+ CHK(smc_device_ref_put(dev) == RES_OK);
- CHECK(smc_device_create(&logger, &allocator, 4, NULL, NULL), RES_BAD_ARG);
- CHECK(smc_device_create(&logger, &allocator, 4, NULL, &dev), RES_OK);
+ CHK(smc_device_create(&logger, &allocator, 4, NULL, NULL) == RES_BAD_ARG);
+ CHK(smc_device_create(&logger, &allocator, 4, NULL, &dev) == RES_OK);
- CHECK(smc_device_set_rng_type(NULL, NULL), RES_BAD_ARG);
- CHECK(smc_device_set_rng_type(dev, NULL), RES_BAD_ARG);
- CHECK(smc_device_set_rng_type(NULL, &ssp_rng_ranlux48), RES_BAD_ARG);
- CHECK(smc_device_set_rng_type(dev, &ssp_rng_ranlux48), RES_OK);
+ CHK(smc_device_set_rng_type(NULL, NULL) == RES_BAD_ARG);
+ CHK(smc_device_set_rng_type(dev, NULL) == RES_BAD_ARG);
+ CHK(smc_device_set_rng_type(NULL, &ssp_rng_ranlux48) == RES_BAD_ARG);
+ CHK(smc_device_set_rng_type(dev, &ssp_rng_ranlux48) == RES_OK);
- CHECK(smc_device_get_rng_type(NULL, NULL), RES_BAD_ARG);
- CHECK(smc_device_get_rng_type(dev, NULL), RES_BAD_ARG);
- CHECK(smc_device_get_rng_type(NULL, &type), RES_BAD_ARG);
- CHECK(smc_device_get_rng_type(dev, &type), RES_OK);
- CHECK(ssp_rng_type_eq(&type, &ssp_rng_ranlux48), 1);
+ CHK(smc_device_get_rng_type(NULL, NULL) == RES_BAD_ARG);
+ CHK(smc_device_get_rng_type(dev, NULL) == RES_BAD_ARG);
+ CHK(smc_device_get_rng_type(NULL, &type) == RES_BAD_ARG);
+ CHK(smc_device_get_rng_type(dev, &type) == RES_OK);
+ CHK(ssp_rng_type_eq(&type, &ssp_rng_ranlux48) == 1);
- CHECK(smc_device_set_rng_type(dev, &ssp_rng_kiss), RES_OK);
- CHECK(smc_device_get_rng_type(dev, &type), RES_OK);
- CHECK(ssp_rng_type_eq(&type, &ssp_rng_kiss), 1);
+ CHK(smc_device_set_rng_type(dev, &ssp_rng_kiss) == RES_OK);
+ CHK(smc_device_get_rng_type(dev, &type) == RES_OK);
+ CHK(ssp_rng_type_eq(&type, &ssp_rng_kiss) == 1);
- CHECK(smc_device_ref_put(dev), RES_OK);
+ CHK(smc_device_ref_put(dev) == RES_OK);
- CHECK(smc_device_create(&logger, &allocator, 4, &ssp_rng_ranlux48, &dev), RES_OK);
- CHECK(smc_device_ref_put(dev), RES_OK);
+ CHK(smc_device_create(&logger, &allocator, 4, &ssp_rng_ranlux48, &dev) == RES_OK);
+ CHK(smc_device_ref_put(dev) == RES_OK);
logger_release(&logger);
check_memory_allocator(&allocator);
mem_shutdown_proxy_allocator(&allocator);
- CHECK(mem_allocated_size(), 0);
+ CHK(mem_allocated_size() == 0);
return 0;
}
diff --git a/src/test_smc_doubleN.c b/src/test_smc_doubleN.c
@@ -1,4 +1,4 @@
-/* Copyright (C) |Meso|Star> 2015-2016 (contact@meso-star.com)
+/* Copyright (C) |Meso|Star> 2015-2018 (contact@meso-star.com)
*
* This software is a computer program whose purpose is to manage the
* statistical estimation of a function.
@@ -45,20 +45,19 @@ enum {
struct alpha { double value; };
static res_T
-cos_x(void* value, struct ssp_rng* rng, void* context)
+cos_x(void* value, struct ssp_rng* rng, const unsigned ithread, void* context)
{
double* result = SMC_DOUBLEN(value);
double samp;
struct smc_doubleN_context* ctx = context;
const struct alpha* alpha = ctx->integrand_data;
- NCHECK(value, NULL);
- NCHECK(rng, NULL);
+ (void)ithread;
+ CHK(value != NULL);
+ CHK(rng != NULL);
samp = ssp_rng_uniform_double(rng, -PI/4.0, PI/4.0);
- result[WEIGHT] =
- cos(alpha->value*samp) * PI / 2.0;
- result[WEIGHT_SENSIBILITY_ALPHA] =
- -samp * sin(alpha->value*samp) * PI/2.0;
+ result[WEIGHT] = cos(alpha->value*samp) * PI / 2.0;
+ result[WEIGHT_SENSIBILITY_ALPHA] = -samp * sin(alpha->value*samp) * PI/2.0;
return RES_OK;
}
@@ -79,22 +78,21 @@ main(int argc, char** argv)
mem_init_proxy_allocator(&allocator, &mem_default_allocator);
- CHECK(smc_device_create(NULL, &allocator, SMC_NTHREADS_DEFAULT, NULL, &dev),
- RES_OK);
+ CHK(smc_device_create(NULL, &allocator, SMC_NTHREADS_DEFAULT, NULL, &dev) == RES_OK);
integrator.integrand = cos_x;
integrator.type = &smc_doubleN;
- integrator.max_steps = 100000;
+ integrator.max_realisations = 100000;
alpha.value = a;
ctx.count = WEIGHTS_COUNT;
ctx.integrand_data = α
- CHECK(smc_solve(dev, &integrator, NULL, &estimator), RES_MEM_ERR);
+ CHK(smc_solve(dev, &integrator, NULL, &estimator) == RES_MEM_ERR);
ctx.count = 0;
- CHECK(smc_solve(dev, &integrator, &ctx, &estimator), RES_MEM_ERR);
+ CHK(smc_solve(dev, &integrator, &ctx, &estimator) == RES_MEM_ERR);
ctx.count = WEIGHTS_COUNT;
- CHECK(smc_solve(dev, &integrator, &ctx, &estimator), RES_OK);
- CHECK(smc_estimator_get_status(estimator, &status), RES_OK);
+ CHK(smc_solve(dev, &integrator, &ctx, &estimator) == RES_OK);
+ CHK(smc_estimator_get_status(estimator, &status) == RES_OK);
/* Check the estimated result */
result = 2*sin(a*PI/4.0) / a;
@@ -102,10 +100,10 @@ main(int argc, char** argv)
a, result,
SMC_DOUBLEN(status.E)[WEIGHT],
SMC_DOUBLEN(status.SE)[WEIGHT]);
- CHECK(eq_eps
+ CHK(eq_eps
(result,
SMC_DOUBLEN(status.E)[WEIGHT],
- SMC_DOUBLEN(status.SE)[WEIGHT]), 1);
+ SMC_DOUBLEN(status.SE)[WEIGHT]));
/* Check the estimated sensibility in alpha */
result = 2*(a*PI/4.0*cos(a*PI/4.0) - sin(a*PI/4.0)) / (a*a);
@@ -113,16 +111,16 @@ main(int argc, char** argv)
a, result,
SMC_DOUBLEN(status.E)[WEIGHT_SENSIBILITY_ALPHA],
SMC_DOUBLEN(status.SE)[WEIGHT_SENSIBILITY_ALPHA]);
- CHECK(eq_eps
+ CHK(eq_eps
(result,
SMC_DOUBLEN(status.E)[WEIGHT_SENSIBILITY_ALPHA],
- SMC_DOUBLEN(status.SE)[WEIGHT_SENSIBILITY_ALPHA]), 1);
+ SMC_DOUBLEN(status.SE)[WEIGHT_SENSIBILITY_ALPHA]));
- CHECK(smc_estimator_ref_put(estimator), RES_OK);
- CHECK(smc_device_ref_put(dev), RES_OK);
+ CHK(smc_estimator_ref_put(estimator) == RES_OK);
+ CHK(smc_device_ref_put(dev) == RES_OK);
check_memory_allocator(&allocator);
mem_shutdown_proxy_allocator(&allocator);
- CHECK(mem_allocated_size(), 0);
+ CHK(mem_allocated_size() == 0);
return 0;
}
diff --git a/src/test_smc_errors.c b/src/test_smc_errors.c
@@ -1,4 +1,4 @@
-/* Copyright (C) |Meso|Star> 2015-2016 (contact@meso-star.com)
+/* Copyright (C) |Meso|Star> 2015-2018 (contact@meso-star.com)
*
* This software is a computer program whose purpose is to manage the
* statistical estimation of a function.
@@ -35,17 +35,17 @@
#include <star/ssp.h>
static res_T
-compute_1(void* value, struct ssp_rng* rng, 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;
- if (ok)
- /* weight is 1 */
- SMC_DOUBLE(value) = 1;
- else
- /* clear weight */
- SMC_DOUBLE(value) = 0;
+ (void)context, (void)ithread;
+ if(ok) {
+ SMC_DOUBLE(value) = 1; /* weight is 1 */
+ } else {
+ SMC_DOUBLE(value) = 0; /* clear weight */
+ }
/* a realization has been carried out only if ok */
return ok ? RES_OK : RES_BAD_ARG;
}
@@ -66,16 +66,14 @@ main(int argc, char** argv)
integrator.integrand = &compute_1;
integrator.type = &smc_double;
- integrator.max_steps = 10000;
- /* set auto cancel OFF */
- integrator.max_failures = SMC_AUTO_CANCEL_OFF;
+ integrator.max_realisations = 10000;
SMC(solve(dev, &integrator, NULL, &estimator));
SMC(estimator_get_status(estimator, &status));
/* result must be 1 with std err = 0 */
- CHECK(SMC_DOUBLE(status.E), 1);
- CHECK(SMC_DOUBLE(status.SE), 0);
+ CHK(SMC_DOUBLE(status.E) == 1);
+ CHK(SMC_DOUBLE(status.SE) == 0);
printf("OK realizations = %lu; KO realizations = %lu\n",
(unsigned long)status.N, (unsigned long)status.NF);
@@ -83,18 +81,18 @@ main(int argc, char** argv)
SMC(estimator_ref_put(estimator));
/* set auto cancel ON */
- integrator.max_failures = integrator.max_steps / 1000;
+ integrator.max_failures = integrator.max_realisations / 1000;
SMC(solve(dev, &integrator, NULL, &estimator));
SMC(estimator_get_status(estimator, &status));
/* it is expected that solve was auto-canceled */
- NCHECK(integrator.max_steps, status.N);
- CHECK(status.NF >= integrator.max_failures + 1, 1);
+ CHK(integrator.max_realisations != status.N);
+ CHK(status.NF >= integrator.max_failures + 1);
/* result must be 1 with std err = 0 */
- CHECK(SMC_DOUBLE(status.E), 1);
- CHECK(SMC_DOUBLE(status.SE), 0);
+ CHK(SMC_DOUBLE(status.E) == 1);
+ CHK(SMC_DOUBLE(status.SE) == 0);
printf("OK realizations = %lu; KO realizations = %lu\n",
(unsigned long)status.N, (unsigned long)status.NF);
@@ -104,7 +102,7 @@ main(int argc, char** argv)
check_memory_allocator(&allocator);
mem_shutdown_proxy_allocator(&allocator);
- CHECK(mem_allocated_size(), 0);
+ CHK(mem_allocated_size() == 0);
return 0;
}
diff --git a/src/test_smc_integrate.c b/src/test_smc_integrate.c
@@ -1,182 +0,0 @@
-/* Copyright (C) |Meso|Star> 2015-2016 (contact@meso-star.com)
- *
- * This software is governed by the CeCILL license under French law and
- * abiding by the rules of distribution of free software. You can use,
- * modify and/or redistribute the software under the terms of the CeCILL
- * license as circulated by CEA, CNRS and INRIA at the following URL
- * "http://www.cecill.info".
- *
- * As a counterpart to the access to the source code and rights to copy,
- * modify and redistribute granted by the license, users are provided only
- * with a limited warranty and the software's author, the holder of the
- * economic rights, and the successive licensors have only limited
- * liability.
- *
- * In this respect, the user's attention is drawn to the risks associated
- * with loading, using, modifying and/or developing or reproducing the
- * software by the user in light of its specific status of free software,
- * that may mean that it is complicated to manipulate, and that also
- * therefore means that it is reserved for developers and experienced
- * professionals having in-depth computer knowledge. Users are therefore
- * encouraged to load and test the software's suitability as regards their
- * requirements in conditions enabling the security of their systems and/or
- * data to be ensured and, more generally, to use and operate it in the
- * same conditions as regards security.
- *
- * The fact that you are presently reading this means that you have had
- * knowledge of the CeCILL license and that you accept its terms. */
-
-#include "smc.h"
-#include "test_smc_utils.h"
-
-#include <star/ssp.h>
-
-#include <math.h>
-
-static void*
-dbl2_create(struct mem_allocator* allocator, void* ctx)
-{
- NCHECK(allocator, NULL);
- CHECK(ctx, (void*)0xC0DE);
- return MEM_CALLOC(allocator, 2, sizeof(double));
-}
-
-static void
-dbl2_destroy(struct mem_allocator* allocator, void* data)
-{
- NCHECK(allocator, NULL);
- NCHECK(data, NULL);
- MEM_RM(allocator, data);
-}
-
-static void
-dbl2_clear(void* data)
-{
- ((double*)data)[0] = ((double*)data)[1] = 0.0;
-}
-
-static void
-dbl2_add(void* result, const void* op0, const void* op1)
-{
- int i;
- FOR_EACH(i, 0, 2) {
- ((double*)result)[i] = ((double*)op0)[i] + ((double*)op1)[i];
- }
-}
-
-static const struct smc_type_accum smc_accum_dbl2 = {
- dbl2_create,
- dbl2_destroy,
- dbl2_clear,
- dbl2_add
-};
-
-static res_T
-rcp_x(void* value, struct ssp_rng* rng, void* ctx)
-{
- double* result = value;
- double samp;
- double val;
- NCHECK(value, NULL);
- NCHECK(rng, NULL);
- CHECK(ctx, (void*)0xC0DE);
- samp = ssp_rng_uniform_double(rng, 1.0, 4.0);
- val = 1.0 / samp * 3;
- result[0] += val;
- result[1] += val*val;
- return RES_OK;
-}
-
-static res_T
-cos_x(void* value, struct ssp_rng* rng, void* ctx)
-{
- double* result = value;
- double samp;
- double val;
- NCHECK(value, NULL);
- NCHECK(rng, NULL);
- CHECK(ctx, (void*)0xC0DE);
- samp = ssp_rng_uniform_double(rng, -PI/4.0, PI/4.0);
- val = cos(samp) * PI / 2.0;
- result[0] += val;
- result[1] += val*val;
- return RES_OK;
-}
-
-int
-main(int argc, char** argv)
-{
- struct mem_allocator allocator;
- struct smc_device* dev;
- struct smc_integrator_accum integrator = SMC_INTEGRATOR_ACCUM_NULL;
- struct smc_accumulator* accum;
- struct smc_accumulator_status status;
- double* val;
- double E, V, SE;
- (void)argc, (void)argv;
-
- mem_init_proxy_allocator(&allocator, &mem_default_allocator);
- CHECK(smc_device_create(NULL, &allocator, SMC_NTHREADS_DEFAULT, NULL, &dev),
- RES_OK);
-
- integrator.integrand = rcp_x;
- integrator.type = &smc_accum_dbl2;
- integrator.max_steps = 10000;
-
- CHECK(smc_integrate(NULL, NULL, (void*)0xC0DE, NULL), RES_BAD_ARG);
- CHECK(smc_integrate(dev, NULL, (void*)0xC0DE, NULL), RES_BAD_ARG);
- CHECK(smc_integrate(NULL, &integrator, (void*)0xC0DE, NULL), RES_BAD_ARG);
- CHECK(smc_integrate(dev, &integrator, (void*)0xC0DE, NULL), RES_BAD_ARG);
- CHECK(smc_integrate(NULL, NULL, (void*)0xC0DE, &accum), RES_BAD_ARG);
- CHECK(smc_integrate(dev, NULL, (void*)0xC0DE, &accum), RES_BAD_ARG);
- CHECK(smc_integrate(NULL, &integrator, (void*)0xC0DE, &accum), RES_BAD_ARG);
- CHECK(smc_integrate(dev, &integrator, (void*)0xC0DE, &accum), RES_OK);
-
- CHECK(smc_accumulator_get_status(NULL, NULL), RES_BAD_ARG);
- CHECK(smc_accumulator_get_status(accum, NULL), RES_BAD_ARG);
- CHECK(smc_accumulator_get_status(NULL, &status), RES_BAD_ARG);
- CHECK(smc_accumulator_get_status(accum, &status), RES_OK);
-
- val = status.value;
- E = val[0] / (double)status.N;
- V = val[1] / (double)status.N - (val[0]*val[0]) / (double)(status.N * status.N);
- SE = sqrt(V / (double)status.N);
-
- printf("Integral[1, 4] 1/x dx = %g; E = %g; SE = %g\n",
- log(4.0) - log(1.0), E, SE);
- CHECK(eq_eps(log(4.0) - log(1.0), E, 2.0 * SE), 1);
-
- CHECK(smc_accumulator_ref_get(NULL), RES_BAD_ARG);
- CHECK(smc_accumulator_ref_get(accum), RES_OK);
- CHECK(smc_accumulator_ref_put(NULL), RES_BAD_ARG);
- CHECK(smc_accumulator_ref_put(accum), RES_OK);
- CHECK(smc_accumulator_ref_put(accum), RES_OK);
-
- integrator.type = NULL;
- CHECK(smc_integrate(dev, &integrator, NULL, &accum), RES_BAD_ARG);
- integrator.type = &smc_accum_dbl2;
- integrator.integrand = NULL;
- CHECK(smc_integrate(dev, &integrator, NULL, &accum), RES_BAD_ARG);
-
- integrator.integrand = cos_x;
- CHECK(smc_integrate(dev, &integrator, (void*)0xC0DE, &accum), RES_OK);
- CHECK(smc_accumulator_get_status(accum, &status), RES_OK);
-
- val = status.value;
- E = val[0] / (double)status.N;
- V = val[1] / (double)status.N - (val[0]*val[0]) / (double)(status.N * status.N);
- SE = sqrt(V / (double)status.N);
-
- printf("Integral[-PI/4, PI/4] cos(x) dx = %g; E = %g; SE = %g\n",
- 2*sin(PI/4.0), E, SE);
- CHECK(eq_eps(2*sin(PI/4.0), E, 2 * SE), 1);
-
- CHECK(smc_accumulator_ref_put(accum), RES_OK);
- CHECK(smc_device_ref_put(dev), RES_OK);
-
- check_memory_allocator(&allocator);
- mem_shutdown_proxy_allocator(&allocator);
- CHECK(mem_allocated_size(), 0);
- return 0;
-}
-
diff --git a/src/test_smc_light_path.c b/src/test_smc_light_path.c
@@ -1,4 +1,4 @@
-/* Copyright (C) |Meso|Star> 2015-2016 (contact@meso-star.com)
+/* Copyright (C) |Meso|Star> 2015-2018 (contact@meso-star.com)
*
* This software is governed by the CeCILL license under French law and
* abiding by the rules of distribution of free software. You can use,
@@ -129,7 +129,7 @@ cbox_get_ids(const unsigned itri, unsigned ids[3], void* data)
{
const unsigned id = itri * 3;
struct cbox_desc* desc = data;
- NCHECK(desc, NULL);
+ CHK(desc != NULL);
ids[0] = desc->indices[id + 0];
ids[1] = desc->indices[id + 1];
ids[2] = desc->indices[id + 2];
@@ -139,7 +139,7 @@ static INLINE void
cbox_get_position(const unsigned ivert, float position[3], void* data)
{
struct cbox_desc* desc = data;
- NCHECK(desc, NULL);
+ CHK(desc != NULL);
position[0] = desc->vertices[ivert*3 + 0];
position[1] = desc->vertices[ivert*3 + 1];
position[2] = desc->vertices[ivert*3 + 2];
@@ -165,9 +165,9 @@ camera_init(struct camera* cam)
ASSERT(cam);
f3_set(cam->pos, pos);
- f = f3_normalize(cam->z, f3_sub(cam->z, tgt, pos)); NCHECK(f, 0);
- f = f3_normalize(cam->x, f3_cross(cam->x, cam->z, up)); NCHECK(f, 0);
- f = f3_normalize(cam->y, f3_cross(cam->y, cam->z, cam->x)); NCHECK(f, 0);
+ f = f3_normalize(cam->z, f3_sub(cam->z, tgt, pos)); CHK(f != 0);
+ f = f3_normalize(cam->x, f3_cross(cam->x, cam->z, up)); CHK(f != 0);
+ f = f3_normalize(cam->y, f3_cross(cam->y, cam->z, cam->x)); CHK(f != 0);
f3_divf(cam->z, cam->z, (float)tan(fov_x*0.5f));
f3_divf(cam->y, cam->y, proj_ratio);
}
@@ -185,7 +185,7 @@ camera_ray
f3_mulf(x, cam->x, pixel[0]*2.f - 1.f);
f3_mulf(y, cam->y, pixel[1]*2.f - 1.f);
f3_add(dir, f3_add(dir, x, y), cam->z);
- f = f3_normalize(dir, dir); NCHECK(f, 0);
+ f = f3_normalize(dir, dir); CHK(f != 0);
f3_set(org, cam->pos);
}
@@ -211,10 +211,10 @@ direct_lighting
float wi[3];
float range[2];
- NCHECK(view, NULL);
- NCHECK(pos, NULL);
- NCHECK(N, NULL);
- CHECK(f3_is_normalized(N), 1);
+ CHK(view != NULL);
+ CHK(pos != NULL);
+ CHK(N != NULL);
+ CHK(f3_is_normalized(N) == 1);
f3_sub(wi, light_pos, pos);
len = f3_normalize(wi, wi);
@@ -222,7 +222,7 @@ direct_lighting
/* Trace shadow ray */
range[0] = EPSILON;
range[1] = len;
- CHECK(s3d_scene_view_trace_ray(view, pos, wi, range, NULL, &hit), RES_OK);
+ CHK(s3d_scene_view_trace_ray(view, pos, wi, range, NULL, &hit) == RES_OK);
if(!S3D_HIT_NONE(&hit)) return 0.f; /* Light is occluded */
len *= 0.01f; /* Transform len from centimer to meter */
@@ -239,13 +239,14 @@ skydome_lighting(const float wi[3])
const float sky_irradiance = 12.0f;
float u;
- NCHECK(wi, NULL);
+ CHK(wi != NULL);
u = CLAMP(wi[2], 0.f, 0.05f) * 1.f;
return u * sky_irradiance + (1.f - u) * ground_irradiance;
}
static res_T
-light_path_integrator(void* value, struct ssp_rng* rng, void* data)
+light_path_integrator
+ (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 */
@@ -255,9 +256,11 @@ light_path_integrator(void* value, struct ssp_rng* rng, void* data)
float throughput = 1.f;
int idepth;
- NCHECK(value, NULL);
- NCHECK(rng, NULL);
- NCHECK(data, NULL);
+ (void)ithread;
+
+ CHK(value != NULL);
+ CHK(rng != NULL);
+ CHK(data != NULL);
/* Compute the pixel bound */
pix_lower[0] = (float)ctx->ipixel[0] / (float)IMG_WIDTH;
@@ -275,15 +278,13 @@ light_path_integrator(void* value, struct ssp_rng* rng, void* data)
FOR_EACH(idepth, 0, LIGHT_PATH_DEPTH) {
struct s3d_hit hit = S3D_HIT_NULL;
- double Nd[3];
- double sample[4];
float cos_theta;
float pdf;
float pos[3];
float N[3] = {0, 0, 0};
- CHECK(s3d_scene_view_trace_ray
- (ctx->view, ray_org, ray_dir, ray_range, NULL, &hit), RES_OK);
+ CHK(s3d_scene_view_trace_ray
+ (ctx->view, ray_org, ray_dir, ray_range, NULL, &hit) == RES_OK);
if(S3D_HIT_NONE(&hit)) { /* Skydome lighting */
L += throughput * skydome_lighting(ray_dir);
@@ -299,12 +300,9 @@ light_path_integrator(void* value, struct ssp_rng* rng, void* data)
L += throughput * direct_lighting(ctx->view, pos, N);
/* New ray */
- d3_normalize(Nd, d3_set_f3(Nd, N));
- ssp_ran_hemisphere_cos(rng, Nd, sample);
- pdf = (float)sample[3];
- cos_theta = (float)d3_dot(Nd, sample);
+ ssp_ran_hemisphere_cos_float(rng, N, ray_dir, &pdf);
+ cos_theta = f3_dot(N, ray_dir);
f3_set(ray_org, pos);
- f3_normalize(ray_dir, f3_set_d3(ray_dir, sample));
ray_range[0] = EPSILON;
throughput *= (float)(ALBEDO / PI) / pdf * cos_theta;
}
@@ -336,58 +334,58 @@ main(int argc, char** argv)
mem_init_proxy_allocator(&allocator, &mem_default_allocator);
- CHECK(image_init(&allocator, &img), RES_OK);
- CHECK(image_setup
- (&img, IMG_WIDTH, IMG_HEIGHT, 3*IMG_WIDTH, IMAGE_RGB8, NULL), RES_OK);
+ CHK(image_init(&allocator, &img) == RES_OK);
+ CHK(image_setup
+ (&img, IMG_WIDTH, IMG_HEIGHT, 3*IMG_WIDTH, IMAGE_RGB8, NULL) == RES_OK);
- CHECK(s3d_device_create(NULL, &allocator, 0, &dev), RES_OK);
- CHECK(s3d_scene_create(dev, &scn), RES_OK);
+ CHK(s3d_device_create(NULL, &allocator, 0, &dev) == RES_OK);
+ CHK(s3d_scene_create(dev, &scn) == RES_OK);
attrib.usage = S3D_POSITION;
attrib.type = S3D_FLOAT3;
attrib.get = cbox_get_position;
- CHECK(s3d_shape_create_mesh(dev, &shape), RES_OK);
- CHECK(s3d_mesh_setup_indexed_vertices(shape, cbox_walls_ntris, cbox_get_ids,
- cbox_walls_nverts, &attrib, 1, &cbox_walls_desc), RES_OK);
- CHECK(s3d_scene_attach_shape(scn, shape), RES_OK);
- CHECK(s3d_shape_ref_put(shape), RES_OK);
+ CHK(s3d_shape_create_mesh(dev, &shape) == RES_OK);
+ CHK(s3d_mesh_setup_indexed_vertices(shape, cbox_walls_ntris, cbox_get_ids,
+ cbox_walls_nverts, &attrib, 1, &cbox_walls_desc) == RES_OK);
+ CHK(s3d_scene_attach_shape(scn, shape) == RES_OK);
+ CHK(s3d_shape_ref_put(shape) == RES_OK);
- CHECK(s3d_shape_create_mesh(dev, &shape), RES_OK);
- CHECK(s3d_mesh_setup_indexed_vertices(shape, cbox_block_ntris, cbox_get_ids,
- cbox_short_block_nverts, &attrib, 1, &cbox_short_block_desc), RES_OK);
- CHECK(s3d_scene_attach_shape(scn, shape), RES_OK);
- CHECK(s3d_shape_ref_put(shape), RES_OK);
+ CHK(s3d_shape_create_mesh(dev, &shape) == RES_OK);
+ CHK(s3d_mesh_setup_indexed_vertices(shape, cbox_block_ntris, cbox_get_ids,
+ cbox_short_block_nverts, &attrib, 1, &cbox_short_block_desc) == RES_OK);
+ CHK(s3d_scene_attach_shape(scn, shape) == RES_OK);
+ CHK(s3d_shape_ref_put(shape) == RES_OK);
- CHECK(s3d_shape_create_mesh(dev, &shape), RES_OK);
- CHECK(s3d_mesh_setup_indexed_vertices(shape, cbox_block_ntris, cbox_get_ids,
- cbox_tall_block_nverts, &attrib, 1, &cbox_tall_block_desc), RES_OK);
- CHECK(s3d_scene_attach_shape(scn, shape), RES_OK);
- CHECK(s3d_shape_ref_put(shape), RES_OK);
+ CHK(s3d_shape_create_mesh(dev, &shape) == RES_OK);
+ CHK(s3d_mesh_setup_indexed_vertices(shape, cbox_block_ntris, cbox_get_ids,
+ cbox_tall_block_nverts, &attrib, 1, &cbox_tall_block_desc) == RES_OK);
+ CHK(s3d_scene_attach_shape(scn, shape) == RES_OK);
+ CHK(s3d_shape_ref_put(shape) == RES_OK);
- CHECK(s3d_scene_instantiate(scn, &shape), RES_OK);
- CHECK(s3d_scene_ref_put(scn), RES_OK);
- CHECK(s3d_instance_set_position(shape, f3(pos, -100.f, 0.f, -2.f)), RES_OK);
+ CHK(s3d_scene_instantiate(scn, &shape) == RES_OK);
+ CHK(s3d_scene_ref_put(scn) == RES_OK);
+ CHK(s3d_instance_set_position(shape, f3(pos, -100.f, 0.f, -2.f)) == RES_OK);
- CHECK(s3d_scene_create(dev, &scn), RES_OK);
- CHECK(s3d_scene_attach_shape(scn, shape), RES_OK);
- CHECK(s3d_shape_ref_put(shape), RES_OK);
+ CHK(s3d_scene_create(dev, &scn) == RES_OK);
+ CHK(s3d_scene_attach_shape(scn, shape) == RES_OK);
+ CHK(s3d_shape_ref_put(shape) == RES_OK);
- CHECK(s3d_scene_view_create(scn, S3D_TRACE, &view), RES_OK);
+ CHK(s3d_scene_view_create(scn, S3D_TRACE, &view) == RES_OK);
- CHECK(smc_device_create(NULL, &allocator, SMC_NTHREADS_DEFAULT, NULL, &smc),
- RES_OK);
+ CHK(smc_device_create(NULL, &allocator, SMC_NTHREADS_DEFAULT, NULL, &smc)
+ == RES_OK);
integrator.integrand = light_path_integrator;
integrator.type = &smc_float;
- integrator.max_steps = 4;
+ integrator.max_realisations = 4;
contexts = MEM_CALLOC
(&allocator, IMG_WIDTH*IMG_HEIGHT, sizeof(struct integrator_context));
- NCHECK(contexts, NULL);
+ CHK(contexts != NULL);
estimators = MEM_CALLOC
(&allocator, IMG_WIDTH*IMG_HEIGHT, sizeof(struct smc_estimator*));
- NCHECK(estimators, NULL);
+ CHK(estimators != NULL);
camera_init(&cam);
@@ -402,8 +400,8 @@ main(int argc, char** argv)
contexts[ictx].ipixel[1] = iy;
}}
- CHECK(smc_solve_N(smc, &integrator, IMG_WIDTH * IMG_HEIGHT, contexts,
- sizeof(struct integrator_context), estimators), RES_OK);
+ CHK(smc_solve_N(smc, &integrator, IMG_WIDTH * IMG_HEIGHT, contexts,
+ sizeof(struct integrator_context), estimators) == RES_OK);
FOR_EACH(iy, 0, IMG_HEIGHT) {
FOR_EACH(ix, 0, IMG_WIDTH) {
@@ -413,27 +411,27 @@ main(int argc, char** argv)
float col;
unsigned char colu;
- CHECK(smc_estimator_get_status(estimators[iestimator], &status), RES_OK);
+ CHK(smc_estimator_get_status(estimators[iestimator], &status) == RES_OK);
col = (float)pow(SMC_FLOAT(status.E), 1.0/GAMMA); /* Gamma correction */
colu = (uint8_t)(CLAMP(col, 0.f, 1.f) * 255.f); /* Float to U8 */
pix[0] = pix[1] = pix[2] = colu;
- CHECK(smc_estimator_ref_put(estimators[iestimator]), RES_OK);
+ CHK(smc_estimator_ref_put(estimators[iestimator]) == RES_OK);
}}
image_write_ppm_stream(&img, 0, stdout);
- CHECK(image_release(&img), RES_OK);
+ CHK(image_release(&img) == RES_OK);
MEM_RM(&allocator, contexts);
MEM_RM(&allocator, estimators);
- CHECK(s3d_scene_view_ref_put(view), RES_OK);
+ CHK(s3d_scene_view_ref_put(view) == RES_OK);
- CHECK(s3d_device_ref_put(dev), RES_OK);
- CHECK(s3d_scene_ref_put(scn), RES_OK);
- CHECK(smc_device_ref_put(smc), RES_OK);
+ CHK(s3d_device_ref_put(dev) == RES_OK);
+ CHK(s3d_scene_ref_put(scn) == RES_OK);
+ CHK(smc_device_ref_put(smc) == RES_OK);
check_memory_allocator(&allocator);
mem_shutdown_proxy_allocator(&allocator);
- CHECK(mem_allocated_size(), 0);
+ CHK(mem_allocated_size() == 0);
return 0;
}
diff --git a/src/test_smc_solve.c b/src/test_smc_solve.c
@@ -1,4 +1,4 @@
-/* Copyright (C) |Meso|Star> 2015-2016 (contact@meso-star.com)
+/* Copyright (C) |Meso|Star> 2015-2018 (contact@meso-star.com)
*
* This software is governed by the CeCILL license under French law and
* abiding by the rules of distribution of free software. You can use,
@@ -35,26 +35,28 @@
#include <math.h>
static res_T
-rcp_x(void* value, struct ssp_rng* rng, void* ctx)
+rcp_x(void* value, struct ssp_rng* rng, const unsigned ithread, void* ctx)
{
double* result = value;
double samp;
- NCHECK(value, NULL);
- NCHECK(rng, NULL);
- CHECK(ctx, NULL);
+ (void)ithread;
+ CHK(value != NULL);
+ CHK(rng != NULL);
+ CHK(ctx == NULL);
samp = ssp_rng_uniform_double(rng, 1.0, 4.0);
*result = 1.0 / samp * 3;
return RES_OK;
}
static res_T
-cos_x(void* value, struct ssp_rng* rng, void* ctx)
+cos_x(void* value, struct ssp_rng* rng, const unsigned ithread, void* ctx)
{
float* result = value;
double samp;
- NCHECK(value, NULL);
- NCHECK(rng, NULL);
- CHECK(ctx, (void*)0xC0DE);
+ (void)ithread;
+ CHK(value != NULL);
+ CHK(rng != NULL);
+ CHK(ctx == (void*)0xC0DE);
samp = ssp_rng_uniform_double(rng, -PI/4.0, PI/4.0);
*result = (float)(cos(samp) * PI / 2.0);
return RES_OK;
@@ -72,53 +74,52 @@ main(int argc, char** argv)
mem_init_proxy_allocator(&allocator, &mem_default_allocator);
- CHECK(smc_device_create(NULL, &allocator, SMC_NTHREADS_DEFAULT, NULL, &dev),
- RES_OK);
+ CHK(smc_device_create(NULL, &allocator, SMC_NTHREADS_DEFAULT, NULL, &dev) == RES_OK);
integrator.integrand = rcp_x;
integrator.type = &smc_double;
- integrator.max_steps = 10000;
-
- CHECK(smc_solve(NULL, NULL, NULL, NULL), RES_BAD_ARG);
- CHECK(smc_solve(dev, NULL, NULL, NULL), RES_BAD_ARG);
- CHECK(smc_solve(NULL, &integrator, NULL, NULL), RES_BAD_ARG);
- CHECK(smc_solve(dev, &integrator, NULL, NULL), RES_BAD_ARG);
- CHECK(smc_solve(NULL, NULL, NULL, &estimator), RES_BAD_ARG);
- CHECK(smc_solve(dev, NULL, NULL, &estimator), RES_BAD_ARG);
- CHECK(smc_solve(NULL, &integrator, NULL, &estimator), RES_BAD_ARG);
- CHECK(smc_solve(dev, &integrator, NULL, &estimator), RES_OK);
-
- CHECK(smc_estimator_get_status(NULL, NULL), RES_BAD_ARG);
- CHECK(smc_estimator_get_status(estimator, NULL), RES_BAD_ARG);
- CHECK(smc_estimator_get_status(NULL, &status), RES_BAD_ARG);
- CHECK(smc_estimator_get_status(estimator, &status), RES_OK);
+ integrator.max_realisations = 10000;
+
+ CHK(smc_solve(NULL, NULL, NULL, NULL) == RES_BAD_ARG);
+ CHK(smc_solve(dev, NULL, NULL, NULL) == RES_BAD_ARG);
+ CHK(smc_solve(NULL, &integrator, NULL, NULL) == RES_BAD_ARG);
+ CHK(smc_solve(dev, &integrator, NULL, NULL) == RES_BAD_ARG);
+ CHK(smc_solve(NULL, NULL, NULL, &estimator) == RES_BAD_ARG);
+ CHK(smc_solve(dev, NULL, NULL, &estimator) == RES_BAD_ARG);
+ CHK(smc_solve(NULL, &integrator, NULL, &estimator) == RES_BAD_ARG);
+ CHK(smc_solve(dev, &integrator, NULL, &estimator) == RES_OK);
+
+ CHK(smc_estimator_get_status(NULL, NULL) == RES_BAD_ARG);
+ CHK(smc_estimator_get_status(estimator, NULL) == RES_BAD_ARG);
+ CHK(smc_estimator_get_status(NULL, &status) == RES_BAD_ARG);
+ CHK(smc_estimator_get_status(estimator, &status) == RES_OK);
printf("Integral[1, 4] 1/x dx = %g; E = %g; SE = %g\n",
log(4.0) - log(1.0), SMC_DOUBLE(status.E), SMC_DOUBLE(status.SE));
- CHECK(eq_eps
- (log(4.0) - log(1.0), SMC_DOUBLE(status.E), 2.0 * SMC_DOUBLE(status.SE)), 1);
- CHECK(smc_estimator_ref_put(estimator), RES_OK);
+ CHK(eq_eps
+ (log(4.0) - log(1.0), SMC_DOUBLE(status.E), 2.0 * SMC_DOUBLE(status.SE)));
+ CHK(smc_estimator_ref_put(estimator) == RES_OK);
integrator.type = NULL;
- CHECK(smc_solve(dev, &integrator, NULL, &estimator), RES_BAD_ARG);
+ CHK(smc_solve(dev, &integrator, NULL, &estimator) == RES_BAD_ARG);
integrator.type = &smc_double;
integrator.integrand = NULL;
- CHECK(smc_solve(dev, &integrator, NULL, &estimator), RES_BAD_ARG);
+ CHK(smc_solve(dev, &integrator, NULL, &estimator) == RES_BAD_ARG);
integrator.integrand = cos_x;
integrator.type = &smc_float;
- CHECK(smc_solve(dev, &integrator, (void*)0xC0DE, &estimator), RES_OK);
- CHECK(smc_estimator_get_status(estimator, &status), RES_OK);
+ CHK(smc_solve(dev, &integrator, (void*)0xC0DE, &estimator) == RES_OK);
+ CHK(smc_estimator_get_status(estimator, &status) == RES_OK);
printf("Integral[-PI/4, PI/4] cos(x) dx = %f; E = %f; SE = %f\n",
2*sin(PI/4.0), SMC_FLOAT(status.E), SMC_FLOAT(status.SE));
- CHECK(eq_eps
- ((float)2*sin(PI/4.0), SMC_FLOAT(status.E), 2 * SMC_FLOAT(status.SE)), 1);
- CHECK(smc_device_ref_put(dev), RES_OK);
+ CHK(eq_eps
+ ((float)2*sin(PI/4.0), SMC_FLOAT(status.E), 2 * SMC_FLOAT(status.SE)));
+ CHK(smc_device_ref_put(dev) == RES_OK);
- CHECK(smc_estimator_ref_put(estimator), RES_OK);
+ CHK(smc_estimator_ref_put(estimator) == RES_OK);
check_memory_allocator(&allocator);
mem_shutdown_proxy_allocator(&allocator);
- CHECK(mem_allocated_size(), 0);
+ CHK(mem_allocated_size() == 0);
return 0;
}
diff --git a/src/test_smc_utils.h b/src/test_smc_utils.h
@@ -1,4 +1,4 @@
-/* Copyright (C) |Meso|Star> 2015-2016 (contact@meso-star.com)
+/* Copyright (C) |Meso|Star> 2015-2018 (contact@meso-star.com)
*
* This software is governed by the CeCILL license under French law and
* abiding by the rules of distribution of free software. You can use,