diff --git a/CMakeLists.txt b/CMakeLists.txt index a645402..e9abc7e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) project( ViennaRay LANGUAGES CXX - VERSION 4.2.0) + VERSION 4.3.0) # -------------------------------------------------------------------------------------------------------- # Library switches @@ -51,13 +51,13 @@ endif() add_library(${PROJECT_NAME} INTERFACE) -target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_17) +target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_20) target_compile_definitions(${PROJECT_NAME} INTERFACE VIENNARAY_EMBREE_VERSION=${VIENNARAY_EMBREE_VERSION}) set_target_properties( ${PROJECT_NAME} - PROPERTIES CXX_STANDARD 17 + PROPERTIES CXX_STANDARD 20 CXX_EXTENSIONS OFF CXX_STANDARD_REQUIRED ON WINDOWS_EXPORT_ALL_SYMBOLS ON) @@ -98,7 +98,7 @@ include("cmake/cpm.cmake") CPMAddPackage( NAME ViennaCore - VERSION 2.1.2 + VERSION 2.2.1 GIT_REPOSITORY "https://github.com/ViennaTools/ViennaCore" OPTIONS "VIENNACORE_USE_GPU ${VIENNARAY_USE_GPU}") diff --git a/README.md b/README.md index 4ee04ec..13e1ea8 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ We recommend using [CPM.cmake](https://github.com/cpm-cmake/CPM.cmake) to consum * Installation with CPM ```cmake - CPMAddPackage("gh:viennatools/viennaray@4.2.0") # Use the latest release version + CPMAddPackage("gh:viennatools/viennaray@4.3.0") # Use the latest release version ``` * With a local installation diff --git a/examples/disk2D/disk2D.cpp b/examples/disk2D/disk2D.cpp index 8fda7c6..6d5daf0 100644 --- a/examples/disk2D/disk2D.cpp +++ b/examples/disk2D/disk2D.cpp @@ -58,7 +58,7 @@ int main() { std::cout << "Tracing time: " << timer.currentDuration / 1e9 << " s\n"; // Extract the normalized hit counts for each geometry point - auto &flux = rayTracer.getLocalData().getVectorData("flux"); + auto flux = *rayTracer.getLocalData().getScalarData("flux"); rayTracer.normalizeFlux(flux, NormalizationType::SOURCE); rayTracer.smoothFlux(flux, 1); diff --git a/examples/disk3D/disk3D.cpp b/examples/disk3D/disk3D.cpp index ac19bb7..51fce43 100644 --- a/examples/disk3D/disk3D.cpp +++ b/examples/disk3D/disk3D.cpp @@ -60,7 +60,7 @@ int main() { std::cout << "Tracing time: " << timer.currentDuration / 1e9 << " s\n"; // Extract the normalized hit counts for each geometry point - auto &flux = rayTracer.getLocalData().getVectorData("flux"); + auto &flux = *rayTracer.getLocalData().getScalarData("flux"); rayTracer.normalizeFlux(flux, NormalizationType::SOURCE); rayTracer.smoothFlux(flux); diff --git a/examples/triangle2D/triangle2D.cpp b/examples/triangle2D/triangle2D.cpp index 45cd968..68c46b8 100644 --- a/examples/triangle2D/triangle2D.cpp +++ b/examples/triangle2D/triangle2D.cpp @@ -36,11 +36,10 @@ int main() { std::cout << "Tracing time: " << timer.currentDuration / 1e9 << " s\n"; - auto &localData = tracer.getLocalData(); - tracer.normalizeFlux(localData.getVectorData(0), NormalizationType::SOURCE); + auto flux = *tracer.getLocalData().getScalarData("flux"); + tracer.normalizeFlux(flux, NormalizationType::SOURCE); auto triMesh = convertLinesToTriangles(lineMesh); rayInternal::writeVTP("lineGeometryOutput.vtp", triMesh.nodes, - triMesh.triangles, - localData.getVectorData(0)); + triMesh.triangles, flux); } \ No newline at end of file diff --git a/examples/triangle3D/triangle3D.cpp b/examples/triangle3D/triangle3D.cpp index 0cec1aa..bb87cb0 100644 --- a/examples/triangle3D/triangle3D.cpp +++ b/examples/triangle3D/triangle3D.cpp @@ -36,9 +36,9 @@ int main() { std::cout << "Tracing time: " << timer.currentDuration / 1e9 << " s\n"; - auto &localData = tracer.getLocalData(); - tracer.normalizeFlux(localData.getVectorData(0), NormalizationType::SOURCE); + auto flux = *tracer.getLocalData().getScalarData("flux"); + tracer.normalizeFlux(flux, NormalizationType::SOURCE); rayInternal::writeVTP("triangleGeometryOutput.vtp", points, - triangles, localData.getVectorData(0)); + triangles, flux); } \ No newline at end of file diff --git a/gpu/tests/boundaries/TestPipelineTriangle.cu b/gpu/tests/boundaries/TestPipelineTriangle.cu index 5b439f5..eb79d38 100644 --- a/gpu/tests/boundaries/TestPipelineTriangle.cu +++ b/gpu/tests/boundaries/TestPipelineTriangle.cu @@ -131,8 +131,9 @@ extern "C" __global__ void __raygen__() { // the values we store the PRD pointer in: uint32_t u0, u1; packPointer((void *)&prd, u0, u1); + const float initialRayWeight = prd.rayWeight; - while (continueRay(launchParams, prd)) { + while (continueRay(launchParams, prd, initialRayWeight)) { printf("Tracing ray %u from pos (%f, %f, %f) in dir (%f, %f, %f)\n", linearLaunchIndex, prd.pos[0], prd.pos[1], prd.pos[2], prd.dir[0], prd.dir[1], prd.dir[2]); diff --git a/include/viennaray/rayParticle.hpp b/include/viennaray/rayParticle.hpp index 51a6b18..c218a2c 100644 --- a/include/viennaray/rayParticle.hpp +++ b/include/viennaray/rayParticle.hpp @@ -4,10 +4,11 @@ #include #include -#include +#include #include #include +#include #define VIENNARAY_PARTICLE_STOP \ std::pair> { \ @@ -44,7 +45,7 @@ template class AbstractParticle { surfaceReflection(NumericType rayWeight, const Vec3D &rayDir, const Vec3D &geomNormal, const unsigned int primId, const int materialId, - const TracingData *globalData, + const PointData *globalData, RNG &rngState) = 0; /// Surface collision. This function gets called whenever an intersection of @@ -55,14 +56,15 @@ template class AbstractParticle { /// primId: ID fo the hit disc; /// materialId: ID of material at hit disc; /// localData: user-defined data; - /// globalData: constant user-defined data; + /// globalData: constant user-defined data; (can be nullptr if no global data + /// is provided) /// Rng: thread-safe random number generator (standard library conform); virtual void surfaceCollision(NumericType rayWeight, const Vec3D &rayDir, const Vec3D &geomNormal, const unsigned int primID, const int materialId, - TracingData &localData, - const TracingData *globalData, + PointData &localData, + const PointData *globalData, RNG &rngState) = 0; /// Set the power of the cosine source distribution for this particle. @@ -96,7 +98,7 @@ class Particle : public AbstractParticle { surfaceReflection(NumericType rayWeight, const Vec3D &rayDir, const Vec3D &geomNormal, const unsigned int primId, const int materialId, - const TracingData *globalData, + const PointData *globalData, RNG &rngState) override { // return the sticking probability and direction after reflection for this // hit @@ -105,8 +107,8 @@ class Particle : public AbstractParticle { void surfaceCollision(NumericType rayWeight, const Vec3D &rayDir, const Vec3D &geomNormal, const unsigned int primID, const int materialId, - TracingData &localData, - const TracingData *globalData, + PointData &localData, + const PointData *globalData, RNG &rngState) override { // collect data for this hit } NumericType getSourceDistributionPower() const override { return 1.; } @@ -138,7 +140,7 @@ class DiffuseParticle surfaceReflection(NumericType rayWeight, const Vec3D &rayDir, const Vec3D &geomNormal, const unsigned int primID, const int materialId, - const TracingData *globalData, + const PointData *globalData, RNG &rngState) final { auto direction = ReflectionDiffuse(geomNormal, rngState); return std::pair>{stickingProbability_, @@ -148,11 +150,11 @@ class DiffuseParticle void surfaceCollision(NumericType rayWeight, const Vec3D &rayDir, const Vec3D &geomNormal, const unsigned int primID, const int materialId, - TracingData &localData, - const TracingData *globalData, + PointData &localData, + const PointData *globalData, RNG &rngState) final { // collect data for this hit - localData.getVectorData(0)[primID] += rayWeight; + localData.addToScalarData(0, primID, rayWeight); } NumericType getSourceDistributionPower() const final { return 1.; } @@ -179,7 +181,7 @@ class SpecularParticle surfaceReflection(NumericType rayWeight, const Vec3D &rayDir, const Vec3D &geomNormal, const unsigned int primID, const int materialId, - const TracingData *globalData, + const PointData *globalData, RNG &rngState) final { auto direction = ReflectionSpecular(rayDir, geomNormal); return std::pair>{stickingProbability_, @@ -189,11 +191,11 @@ class SpecularParticle void surfaceCollision(NumericType rayWeight, const Vec3D &rayDir, const Vec3D &geomNormal, const unsigned int primID, const int materialId, - TracingData &localData, - const TracingData *globalData, + PointData &localData, + const PointData *globalData, RNG &rngState) final { // collect data for this hit - localData.getVectorData(0)[primID] += rayWeight; + localData.addToScalarData(0, primID, rayWeight); } NumericType getSourceDistributionPower() const final { return sourcePower_; } diff --git a/include/viennaray/rayTrace.hpp b/include/viennaray/rayTrace.hpp index 1c75745..f5a657a 100644 --- a/include/viennaray/rayTrace.hpp +++ b/include/viennaray/rayTrace.hpp @@ -132,13 +132,13 @@ template class Trace { virtual void smoothFlux(std::vector &flux, int numNeighbors = 1) = 0; - [[nodiscard]] TracingData &getLocalData() { return localData_; } + [[nodiscard]] PointData &getLocalData() { return localData_; } - [[nodiscard]] TracingData *getGlobalData() { - return pGlobalData_; - } + [[nodiscard]] auto getGlobalData() { return pGlobalData_; } - void setGlobalData(TracingData &data) { pGlobalData_ = &data; } + void setGlobalData(SmartPointer> data) { + pGlobalData_ = data; + } [[nodiscard]] TraceInfo getRayTraceInfo() const { return RTInfo_; } @@ -173,8 +173,8 @@ template class Trace { rayInternal::KernelConfig config_; - TracingData localData_; - TracingData *pGlobalData_ = nullptr; + PointData localData_; + SmartPointer> pGlobalData_ = nullptr; TraceInfo RTInfo_; DataLog dataLog_; }; diff --git a/include/viennaray/rayTraceDisk.hpp b/include/viennaray/rayTraceDisk.hpp index 38766c0..bc370c8 100644 --- a/include/viennaray/rayTraceDisk.hpp +++ b/include/viennaray/rayTraceDisk.hpp @@ -39,17 +39,16 @@ class TraceDisk final : public Trace { auto localDataLabels = this->pParticle_->getLocalDataLabels(); if (!localDataLabels.empty()) { - this->localData_.setNumberOfVectorData(localDataLabels.size()); auto numPoints = geometry_.getNumPrimitives(); - for (int i = 0; i < localDataLabels.size(); ++i) { - this->localData_.setVectorData(i, numPoints, 0., localDataLabels[i]); + for (const auto &label : localDataLabels) { + this->localData_.insertReplaceScalarData(numPoints, 0., label); } } rayInternal::TraceKernel tracer( this->device_, geometry_, boundary, this->pSource_, this->pParticle_, this->config_, this->dataLog_, this->RTInfo_); - tracer.setTracingData(&this->localData_, this->pGlobalData_); + tracer.setTracingData(&this->localData_, this->pGlobalData_.get()); tracer.apply(); ++this->config_.runNumber; diff --git a/include/viennaray/rayTraceKernel.hpp b/include/viennaray/rayTraceKernel.hpp index 6473563..62581cc 100644 --- a/include/viennaray/rayTraceKernel.hpp +++ b/include/viennaray/rayTraceKernel.hpp @@ -66,7 +66,7 @@ template class TraceKernel { #endif // thread local data storage - std::vector> threadLocalData(numThreads); + std::vector> threadLocalData(numThreads); for (auto &data : threadLocalData) { data = *pLocalData_; } @@ -344,66 +344,11 @@ template class TraceKernel { for (int i = 0; i < numThreads; ++i) { dataLog_.merge(threadLocalDataLog[i]); } - // merge local data - if (!pLocalData_->getVectorData().empty()) { - // merge vector data -#pragma omp parallel for - for (int i = 0; i < pLocalData_->getVectorData().size(); ++i) { - switch (pLocalData_->getVectorMergeType(i)) { - case TracingDataMergeEnum::SUM: { - for (size_t j = 0; j < pLocalData_->getVectorData(i).size(); ++j) { - for (int k = 0; k < numThreads; ++k) { - pLocalData_->getVectorData(i)[j] += - threadLocalData[k].getVectorData(i)[j]; - } - } - break; - } - - case TracingDataMergeEnum::APPEND: { - pLocalData_->getVectorData(i).clear(); - for (int k = 0; k < numThreads; ++k) { - pLocalData_->appendVectorData(i, - threadLocalData[k].getVectorData(i)); - } - break; - } - - default: { - VIENNACORE_LOG_WARNING("Invalid merge type in local vector data."); - break; - } - } - } - } - if (!pLocalData_->getScalarData().empty()) { - // merge scalar data - for (int i = 0; i < pLocalData_->getScalarData().size(); ++i) { - switch (pLocalData_->getScalarMergeType(i)) { - case TracingDataMergeEnum::SUM: { - for (int j = 0; j < numThreads; ++j) { - pLocalData_->getScalarData(i) += - threadLocalData[j].getScalarData(i); - } - break; - } - - case TracingDataMergeEnum::AVERAGE: { - for (int j = 0; j < numThreads; ++j) { - pLocalData_->getScalarData(i) += - threadLocalData[j].getScalarData(i); - } - pLocalData_->getScalarData(i) /= static_cast(numThreads); - break; - } - - default: { - VIENNACORE_LOG_WARNING("Invalid merge type in local scalar data."); - break; - } - } - } + // merge local data + for (int i = 0; i < numThreads; ++i) { + pLocalData_->mergeScalarData(threadLocalData[i], + std::plus()); } traceInfo_.numRays = numRays; @@ -425,8 +370,8 @@ template class TraceKernel { rtcReleaseScene(rtcScene); } - void setTracingData(TracingData *pLocalData, - const TracingData *pGlobalData) { + void setTracingData(PointData *pLocalData, + const PointData *pGlobalData) { pLocalData_ = pLocalData; pGlobalData_ = pGlobalData; } @@ -520,8 +465,8 @@ template class TraceKernel { const KernelConfig config_; - TracingData *pLocalData_ = nullptr; - TracingData const *pGlobalData_ = nullptr; + PointData *pLocalData_ = nullptr; + PointData const *pGlobalData_ = nullptr; TraceInfo &traceInfo_; DataLog &dataLog_; }; diff --git a/include/viennaray/rayTraceTriangle.hpp b/include/viennaray/rayTraceTriangle.hpp index 0ca8666..0805105 100644 --- a/include/viennaray/rayTraceTriangle.hpp +++ b/include/viennaray/rayTraceTriangle.hpp @@ -43,17 +43,16 @@ class TraceTriangle final : public Trace { auto localDataLabels = this->pParticle_->getLocalDataLabels(); if (!localDataLabels.empty()) { - this->localData_.setNumberOfVectorData(localDataLabels.size()); auto numPoints = geometry_.getNumPrimitives(); - for (int i = 0; i < localDataLabels.size(); ++i) { - this->localData_.setVectorData(i, numPoints, 0., localDataLabels[i]); + for (const auto &label : localDataLabels) { + this->localData_.insertReplaceScalarData(numPoints, 0., label); } } rayInternal::TraceKernel tracer( this->device_, geometry_, boundary, this->pSource_, this->pParticle_, this->config_, this->dataLog_, this->RTInfo_); - tracer.setTracingData(&this->localData_, this->pGlobalData_); + tracer.setTracingData(&this->localData_, this->pGlobalData_.get()); tracer.apply(); ++this->config_.runNumber; diff --git a/tests/diskAreas/diskAreas.cpp b/tests/diskAreas/diskAreas.cpp index 459a8d3..9dcdaa5 100644 --- a/tests/diskAreas/diskAreas.cpp +++ b/tests/diskAreas/diskAreas.cpp @@ -22,8 +22,8 @@ int main() { auto device = rtcNewDevice(""); - auto localData = TracingData(); - const auto globalData = TracingData(); + auto localData = PointData(); + const auto globalData = PointData(); GeometryDisk geometry; auto diskRadius = gridDelta * rayInternal::DiskFactor; @@ -46,9 +46,10 @@ int main() { DiffuseParticle particle(1.0, "hitFlux"); auto cp = particle.clone(); - localData.setNumberOfVectorData(cp->getLocalDataLabels().size()); auto numPoints = geometry.getNumPrimitives(); - localData.resizeAllVectorData(numPoints, 0.); + for (const auto &label : particle.getLocalDataLabels()) { + localData.insertReplaceScalarData(numPoints, 0., label); + } DataLog log; TraceInfo info; diff --git a/tests/rngSeed/rngSeed.cpp b/tests/rngSeed/rngSeed.cpp index 956ff69..ed03988 100644 --- a/tests/rngSeed/rngSeed.cpp +++ b/tests/rngSeed/rngSeed.cpp @@ -30,7 +30,7 @@ int main() { rayTracer.apply(); - flux1 = rayTracer.getLocalData().getVectorData(0); + flux1 = *rayTracer.getLocalData().getScalarData("hitFlux"); } { @@ -42,7 +42,7 @@ int main() { rayTracer.apply(); - flux2 = rayTracer.getLocalData().getVectorData(0); + flux2 = *rayTracer.getLocalData().getScalarData("hitFlux"); } VC_TEST_ASSERT(flux1.size() == flux2.size()); diff --git a/tests/traceInterface/traceInterface.cpp b/tests/traceInterface/traceInterface.cpp index eb8a15d..6a00164 100644 --- a/tests/traceInterface/traceInterface.cpp +++ b/tests/traceInterface/traceInterface.cpp @@ -56,7 +56,7 @@ int main() { rayTracer.apply(); - auto flux = rayTracer.getLocalData().getVectorData(0); + auto flux = *rayTracer.getLocalData().getScalarData("hitFlux"); VC_TEST_ASSERT(flux.size() == points.size()); rayTracer.normalizeFlux(flux); diff --git a/tests/tracingData/tracingData.cpp b/tests/tracingData/tracingData.cpp index 9676f60..039ed8a 100644 --- a/tests/tracingData/tracingData.cpp +++ b/tests/tracingData/tracingData.cpp @@ -1,36 +1,23 @@ -#include +#include #include -using namespace viennaray; +using namespace viennacore; int main() { using NumericType = float; - TracingData defaultData; - defaultData.setNumberOfScalarData(1); - defaultData.setNumberOfVectorData(1); + PointData defaultData; - VC_TEST_ASSERT(defaultData.getScalarDataLabel(0) == "scalarData"); - VC_TEST_ASSERT(defaultData.getVectorDataLabel(0) == "vectorData"); + defaultData.insertNextScalarData(1000, 0, "zeroData"); - defaultData.setVectorData(0, 1000, 0, "zeroData"); + VC_TEST_ASSERT(defaultData.getScalarDataLabel(0) == "zeroData"); + VC_TEST_ASSERT(defaultData.getScalarData("zeroData")->size() == 1000); - VC_TEST_ASSERT(defaultData.getVectorDataLabel(0) == "zeroData"); - VC_TEST_ASSERT(defaultData.getVectorData("zeroData").size() == 1000); + defaultData.insertNextScalarData(1, 0, "oneData"); - defaultData.setScalarData(0, 1, "oneData"); + VC_TEST_ASSERT(defaultData.getScalarDataLabel(1) == "oneData"); + VC_TEST_ASSERT(defaultData.getScalarData("oneData")->size() == 1); - VC_TEST_ASSERT(defaultData.getScalarDataLabel(0) == "oneData"); - VC_TEST_ASSERT(defaultData.getScalarData("oneData") == 1); - - defaultData.resizeAllVectorData(10, 0.5); - int counter = 0; - for (const auto v : defaultData.getVectorData(0)) { - VC_TEST_ASSERT(v == 0.5); - counter++; - } - VC_TEST_ASSERT(counter == 10) - - TracingData movedData = std::move(defaultData); + PointData movedData = std::move(defaultData); VC_TEST_ASSERT(defaultData.getScalarData().data() == nullptr); VC_TEST_ASSERT(defaultData.getVectorData().data() == nullptr);