diff --git a/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/ConvertColorToGrayScale.cpp b/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/ConvertColorToGrayScale.cpp index c2b4de3ba9..e0f05669e6 100644 --- a/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/ConvertColorToGrayScale.cpp +++ b/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/ConvertColorToGrayScale.cpp @@ -2,6 +2,8 @@ #include "complex/Common/Array.hpp" #include "complex/Common/Range.hpp" +#include "complex/Core/Application.hpp" +#include "complex/Core/Preferences.hpp" #include "complex/DataStructure/DataArray.hpp" #include "complex/DataStructure/DataGroup.hpp" #include "complex/Utilities/ParallelDataAlgorithm.hpp" @@ -35,8 +37,8 @@ class LuminosityImpl for(size_t i = start; i < end; i++) { auto temp = static_cast( - roundf((m_ImageData[m_NumComp * i] * m_ColorWeights.getX()) + (m_ImageData[m_NumComp * i + 1] * m_ColorWeights.getY()) + (m_ImageData[m_NumComp * i + 2] * m_ColorWeights.getZ()))); - m_FlatImageData[i] = static_cast(temp); + roundf((m_ImageData.at(m_NumComp * i) * m_ColorWeights.getX()) + (m_ImageData.at(m_NumComp * i + 1) * m_ColorWeights.getY()) + (m_ImageData.at(m_NumComp * i + 2) * m_ColorWeights.getZ()))); + m_FlatImageData.setValue(i, static_cast(temp)); } } @@ -72,7 +74,7 @@ class LightnessImpl for(size_t i = start; i < end; i++) { auto minmax = std::minmax_element(m_ImageData.begin() + (i * m_NumComp), m_ImageData.begin() + (i * m_NumComp + 3)); - m_FlatImageData[i] = static_cast(roundf(static_cast(static_cast(*(minmax.first)) + static_cast(*(minmax.second))) / 2.0f)); + m_FlatImageData.setValue(i, static_cast(roundf(static_cast(static_cast(*(minmax.first)) + static_cast(*(minmax.second))) / 2.0f))); } } @@ -108,7 +110,7 @@ class SingleChannelImpl { for(size_t i = start; i < end; i++) { - m_FlatImageData[i] = static_cast((m_ImageData[m_NumComp * i + static_cast(m_Channel)])); + m_FlatImageData.setValue(i, static_cast((m_ImageData.at(m_NumComp * i + static_cast(m_Channel))))); } } @@ -198,9 +200,10 @@ Result<> ConvertColorToGrayScale::operator()() case ConversionType::Average: ParallelWrapper::Run(LuminosityImpl(inputColorData, outputGrayData, {0.3333f, 0.3333f, 0.3333f}, comp), totalPoints, algArrays); break; - case ConversionType::Lightness: + case ConversionType::Lightness: { ParallelWrapper::Run(LightnessImpl(inputColorData, outputGrayData, comp), totalPoints, algArrays); break; + } case ConversionType::SingleChannel: ParallelWrapper::Run(SingleChannelImpl(inputColorData, outputGrayData, comp, m_InputValues->ColorChannel), totalPoints, algArrays); break; diff --git a/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/FindArrayStatistics.cpp b/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/FindArrayStatistics.cpp index 9f675b5dc5..5136b50bb8 100644 --- a/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/FindArrayStatistics.cpp +++ b/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/FindArrayStatistics.cpp @@ -660,26 +660,42 @@ void FindStatistics(const DataArray& source, const Int32Array* featureIds, co auto* modalBinsArrayPtr = dynamic_cast*>(arrays[11]); auto* featureHasDataPtr = dynamic_cast(arrays[12]); -// #ifdef COMPLEX_ENABLE_MULTICORE -#if 0 - const tbb::simple_partitioner simplePartitioner; - const size_t grainSize = 500; - const tbb::blocked_range tbbRange(0, numFeatures, grainSize); - tbb::parallel_for(tbbRange, - FindArrayStatisticsByIndexImpl(inputValues->FindLength, inputValues->FindMin, inputValues->FindMax, inputValues->FindMean, inputValues->FindMode, - inputValues->FindStdDeviation, inputValues->FindSummation, inputValues->FindHistogram, inputValues->MinRange, inputValues->MaxRange, - inputValues->UseFullRange, inputValues->NumBins, inputValues->FindModalBinRanges, mask, featureIds, source, featureHasDataPtr, lengthArrayPtr, - minArrayPtr, maxArrayPtr, meanArrayPtr, modeArrayPtr, stdDevArrayPtr, summationArrayPtr, histArrayPtr, mostPopulatedBinPtr, modalBinsArrayPtr, - filter), - simplePartitioner); -#else - ParallelDataAlgorithm indexAlg; - indexAlg.setRange(0, numFeatures); - indexAlg.execute(FindArrayStatisticsByIndexImpl(inputValues->FindLength, inputValues->FindMin, inputValues->FindMax, inputValues->FindMean, inputValues->FindMode, inputValues->FindStdDeviation, - inputValues->FindSummation, inputValues->FindHistogram, inputValues->MinRange, inputValues->MaxRange, inputValues->UseFullRange, - inputValues->NumBins, inputValues->FindModalBinRanges, mask, featureIds, source, featureHasDataPtr, lengthArrayPtr, minArrayPtr, maxArrayPtr, - meanArrayPtr, modeArrayPtr, stdDevArrayPtr, summationArrayPtr, histArrayPtr, mostPopulatedBinPtr, modalBinsArrayPtr, filter)); - indexAlg.setParallelizationEnabled(false); + IParallelAlgorithm::AlgorithmArrays indexAlgArrays; + indexAlgArrays.push_back(&source); + indexAlgArrays.push_back(featureHasDataPtr); + indexAlgArrays.push_back(lengthArrayPtr); + indexAlgArrays.push_back(minArrayPtr); + indexAlgArrays.push_back(maxArrayPtr); + indexAlgArrays.push_back(meanArrayPtr); + indexAlgArrays.push_back(stdDevArrayPtr); + indexAlgArrays.push_back(summationArrayPtr); + indexAlgArrays.push_back(histArrayPtr); + indexAlgArrays.push_back(mostPopulatedBinPtr); + +#ifdef COMPLEX_ENABLE_MULTICORE + if(IParallelAlgorithm::CheckArraysInMemory(indexAlgArrays)) + { + const tbb::simple_partitioner simplePartitioner; + const size_t grainSize = 500; + const tbb::blocked_range tbbRange(0, numFeatures, grainSize); + tbb::parallel_for(tbbRange, + FindArrayStatisticsByIndexImpl(inputValues->FindLength, inputValues->FindMin, inputValues->FindMax, inputValues->FindMean, inputValues->FindMode, + inputValues->FindStdDeviation, inputValues->FindSummation, inputValues->FindHistogram, inputValues->MinRange, inputValues->MaxRange, + inputValues->UseFullRange, inputValues->NumBins, inputValues->FindModalBinRanges, mask, featureIds, source, featureHasDataPtr, lengthArrayPtr, + minArrayPtr, maxArrayPtr, meanArrayPtr, modeArrayPtr, stdDevArrayPtr, summationArrayPtr, histArrayPtr, mostPopulatedBinPtr, modalBinsArrayPtr, + filter), + simplePartitioner); + } + else + { + ParallelDataAlgorithm indexAlg; + indexAlg.setRange(0, numFeatures); + indexAlg.requireArraysInMemory(indexAlgArrays); + indexAlg.execute(FindArrayStatisticsByIndexImpl( + inputValues->FindLength, inputValues->FindMin, inputValues->FindMax, inputValues->FindMean, inputValues->FindMode, inputValues->FindStdDeviation, inputValues->FindSummation, + inputValues->FindHistogram, inputValues->MinRange, inputValues->MaxRange, inputValues->UseFullRange, inputValues->NumBins, inputValues->FindModalBinRanges, mask, featureIds, source, + featureHasDataPtr, lengthArrayPtr, minArrayPtr, maxArrayPtr, meanArrayPtr, modeArrayPtr, stdDevArrayPtr, summationArrayPtr, histArrayPtr, mostPopulatedBinPtr, modalBinsArrayPtr, filter)); + } #endif if(inputValues->FindMedian || inputValues->FindNumUniqueValues) @@ -689,8 +705,15 @@ void FindStatistics(const DataArray& source, const Int32Array* featureIds, co auto* medianArrayPtr = dynamic_cast(arrays[4]); auto* numUniqueValuesArrayPtr = dynamic_cast(arrays[9]); + IParallelAlgorithm::AlgorithmArrays medianAlgArrays; + medianAlgArrays.push_back(featureIds); + medianAlgArrays.push_back(&source); + medianAlgArrays.push_back(medianArrayPtr); + medianAlgArrays.push_back(numUniqueValuesArrayPtr); + medianAlgArrays.push_back(lengthArrayPtr); + ParallelDataAlgorithm medianDataAlg; - medianDataAlg.setParallelizationEnabled(false); + medianDataAlg.requireArraysInMemory(medianAlgArrays); medianDataAlg.setRange(0, numFeatures); medianDataAlg.execute( FindArrayMedianUniqueByIndexImpl(mask, featureIds, source, inputValues->FindMedian, inputValues->FindNumUniqueValues, medianArrayPtr, numUniqueValuesArrayPtr, lengthArrayPtr, filter)); diff --git a/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/PartitionGeometry.cpp b/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/PartitionGeometry.cpp index 93bf019250..f004f04d45 100644 --- a/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/PartitionGeometry.cpp +++ b/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/PartitionGeometry.cpp @@ -54,13 +54,13 @@ class PartitionCellBasedGeometryImpl auto partitionIndexResult = m_PSImageGeom.getIndex(coord[0], coord[1], coord[2]); if(partitionIndexResult.has_value()) { - // partitionIdsStore.setValue(index, static_cast(*partitionIndexResult) + m_StartingPartitionId); - partitionIdsStore[index] = static_cast(*partitionIndexResult) + m_StartingPartitionId; + partitionIdsStore.setValue(index, static_cast(*partitionIndexResult) + m_StartingPartitionId); + // partitionIdsStore[index] = static_cast(*partitionIndexResult) + m_StartingPartitionId; } else { - // partitionIdsStore.setValue(index, m_OutOfBoundsValue); - partitionIdsStore[index] = m_OutOfBoundsValue; + partitionIdsStore.setValue(index, m_OutOfBoundsValue); + // partitionIdsStore[index] = m_OutOfBoundsValue; } } } @@ -244,9 +244,12 @@ Result<> PartitionGeometry::partitionCellBasedGeometry(const IGridGeometry& inpu { SizeVec3 dims = inputGeometry.getDimensions(); + IParallelAlgorithm::AlgorithmArrays algArrays; + algArrays.push_back(&partitionIds); + ParallelData3DAlgorithm dataAlg; dataAlg.setRange(dims[0], dims[1], dims[2]); - dataAlg.setParallelizationEnabled(false); + dataAlg.requireArraysInMemory(algArrays); dataAlg.execute(PartitionCellBasedGeometryImpl(inputGeometry, partitionIds, psImageGeom, m_InputValues->StartingFeatureID, outOfBoundsValue, m_ShouldCancel)); return {}; @@ -258,9 +261,18 @@ Result<> PartitionGeometry::partitionCellBasedGeometry(const IGridGeometry& inpu Result<> PartitionGeometry::partitionNodeBasedGeometry(const IGeometry::SharedVertexList& vertexList, Int32Array& partitionIds, const ImageGeom& psImageGeom, int outOfBoundsValue, const std::optional& maskArrayOpt) { + IParallelAlgorithm::AlgorithmArrays algArrays; + algArrays.push_back(&vertexList); + algArrays.push_back(&partitionIds); + if(maskArrayOpt.has_value()) + { + algArrays.push_back(&(maskArrayOpt.value())); + } + // Allow data-based parallelization ParallelDataAlgorithm dataAlg; dataAlg.setRange(0, vertexList.getNumberOfTuples()); + dataAlg.requireArraysInMemory(algArrays); dataAlg.execute(PartitionNodeBasedGeometryImpl(vertexList, partitionIds, psImageGeom, m_InputValues->StartingFeatureID, outOfBoundsValue, maskArrayOpt, m_ShouldCancel)); return {}; diff --git a/src/complex/Utilities/IParallelAlgorithm.cpp b/src/complex/Utilities/IParallelAlgorithm.cpp index a964c76041..b3f1173164 100644 --- a/src/complex/Utilities/IParallelAlgorithm.cpp +++ b/src/complex/Utilities/IParallelAlgorithm.cpp @@ -5,6 +5,31 @@ namespace complex { +// ----------------------------------------------------------------------------- +bool IParallelAlgorithm::CheckArraysInMemory(const AlgorithmArrays& arrays) +{ + if(arrays.size() == 0) + { + true; + } + + for(const auto* array : arrays) + { + if(array == nullptr) + { + continue; + } + + if(array->getIDataStoreRef().getDataFormat().empty() == false) + { + return false; + } + } + + return true; +} + +// ----------------------------------------------------------------------------- IParallelAlgorithm::IParallelAlgorithm() { #ifdef COMPLEX_ENABLE_MULTICORE @@ -12,6 +37,8 @@ IParallelAlgorithm::IParallelAlgorithm() m_RunParallel = !Application::GetOrCreateInstance()->getPreferences()->useOocData(); #endif } + +// ----------------------------------------------------------------------------- IParallelAlgorithm::~IParallelAlgorithm() = default; // ----------------------------------------------------------------------------- @@ -23,29 +50,14 @@ bool IParallelAlgorithm::getParallelizationEnabled() const // ----------------------------------------------------------------------------- void IParallelAlgorithm::setParallelizationEnabled(bool doParallel) { +#ifdef COMPLEX_ENABLE_MULTICORE m_RunParallel = doParallel; +#endif } // ----------------------------------------------------------------------------- void IParallelAlgorithm::requireArraysInMemory(const AlgorithmArrays& arrays) { - if(arrays.size() == 0) - { - return; - } - - for(const auto* array : arrays) - { - if(array == nullptr) - { - continue; - } - - if(array->getIDataStoreRef().getDataFormat().empty() == false) - { - setParallelizationEnabled(false); - return; - } - } - setParallelizationEnabled(true); + bool inMemory = CheckArraysInMemory(arrays); + setParallelizationEnabled(!inMemory); } } // namespace complex diff --git a/src/complex/Utilities/IParallelAlgorithm.hpp b/src/complex/Utilities/IParallelAlgorithm.hpp index c4bde3c8bd..feea7739e4 100644 --- a/src/complex/Utilities/IParallelAlgorithm.hpp +++ b/src/complex/Utilities/IParallelAlgorithm.hpp @@ -13,6 +13,8 @@ class COMPLEX_EXPORT IParallelAlgorithm public: using AlgorithmArrays = std::vector; + static bool CheckArraysInMemory(const AlgorithmArrays& arrays); + IParallelAlgorithm(const IParallelAlgorithm&) = default; IParallelAlgorithm(IParallelAlgorithm&&) noexcept = default; IParallelAlgorithm& operator=(const IParallelAlgorithm&) = default;