diff --git a/CMakeLists.txt b/CMakeLists.txt index 79e76b4eb8..b1629264e2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -465,7 +465,9 @@ set(COMPLEX_HDRS ${COMPLEX_SOURCE_DIR}/Utilities/FilterUtilities.hpp ${COMPLEX_SOURCE_DIR}/Utilities/GeometryUtilities.hpp ${COMPLEX_SOURCE_DIR}/Utilities/GeometryHelpers.hpp + ${COMPLEX_SOURCE_DIR}/Utilities/MemoryUtilities.hpp ${COMPLEX_SOURCE_DIR}/Utilities/StringUtilities.hpp + ${COMPLEX_SOURCE_DIR}/Utilities/IParallelAlgorithm.hpp ${COMPLEX_SOURCE_DIR}/Utilities/ParallelDataAlgorithm.hpp ${COMPLEX_SOURCE_DIR}/Utilities/ParallelData2DAlgorithm.hpp ${COMPLEX_SOURCE_DIR}/Utilities/ParallelData3DAlgorithm.hpp @@ -661,6 +663,8 @@ set(COMPLEX_SRCS ${COMPLEX_SOURCE_DIR}/Utilities/TooltipRowItem.cpp ${COMPLEX_SOURCE_DIR}/Utilities/DataArrayUtilities.cpp ${COMPLEX_SOURCE_DIR}/Utilities/DataGroupUtilities.cpp + ${COMPLEX_SOURCE_DIR}/Utilities/MemoryUtilities.cpp + ${COMPLEX_SOURCE_DIR}/Utilities/IParallelAlgorithm.cpp ${COMPLEX_SOURCE_DIR}/Utilities/ParallelDataAlgorithm.cpp ${COMPLEX_SOURCE_DIR}/Utilities/ParallelData2DAlgorithm.cpp ${COMPLEX_SOURCE_DIR}/Utilities/ParallelData3DAlgorithm.cpp diff --git a/docs/Porting_Filters.md b/docs/Porting_Filters.md index 9de3892ab2..88d2cf12f1 100644 --- a/docs/Porting_Filters.md +++ b/docs/Porting_Filters.md @@ -78,7 +78,8 @@ Example of getting an array and summing the values using range based for loop. ```c++ // Let's sum up all the areas. - Float64Array& faceAreas = dataGraph.getDataRefAs(triangleAreasDataPath); + Float64Array& faceAreasArray = dataGraph.getDataRefAs(triangleAreasDataPath); + AbstractFloat64DataStore& faceAreas = faceAreasArray.getDataStoreRef(); double sumOfAreas = 0.0; for(const auto& area : faceAreas) { @@ -86,7 +87,13 @@ Example of getting an array and summing the values using range based for loop. } ``` -## Chaining Together DataPath + String to form new DataPath +## DataArray Performance + +* When iterating over values, either to read or write, use the reference returned by DataArray::getDataStoreRef(). +* When writing values in a multi-threaded function, use the getValue and setValue methods in AbstractDataStore to ensure that values being both read and written at the same time. The [] operators are not capable of protecting against data corruption. + * In situation where values are only being read from the array, the [] operators are both safe and faster to use. + +## Chaining Together DataPath + String to form new DataPath ## ```c++ DataPath triangleAreasDataPath = geometryPath.createChildPath(triangleFaceDataGroupName).createChildPath("Triangle Areas"); diff --git a/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/ComputeFeatureRect.cpp b/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/ComputeFeatureRect.cpp index 27e937cf04..3490a8a16a 100644 --- a/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/ComputeFeatureRect.cpp +++ b/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/ComputeFeatureRect.cpp @@ -36,7 +36,7 @@ Result<> ComputeFeatureRect::operator()() { const auto& featureIds = m_DataStructure.getDataRefAs(m_InputValues->FeatureIdsArrayPath); auto& corners = m_DataStructure.getDataRefAs(m_InputValues->FeatureRectArrayPath); - auto& cornersDataStore = corners.getIDataStoreRefAs(); + auto& cornersDataStore = corners.getDataStoreRef(); // Create corners array, which stores pixel coordinates for the top-left and bottom-right coordinates of each feature object for(usize i = 0; i < corners.getNumberOfTuples(); i++) diff --git a/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/ConvertColorToGrayScale.cpp b/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/ConvertColorToGrayScale.cpp index 4b42aeafd5..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))))); } } @@ -134,10 +136,11 @@ class ParallelWrapper ParallelWrapper& operator=(ParallelWrapper&&) = delete; // Move Assignment Not Implemented template - static void Run(T impl, size_t totalPoints) + static void Run(T impl, size_t totalPoints, typename IParallelAlgorithm::AlgorithmArrays algArrays) { ParallelDataAlgorithm dataAlg; dataAlg.setRange(0, totalPoints); + dataAlg.requireArraysInMemory(algArrays); dataAlg.execute(impl); } @@ -185,19 +188,24 @@ Result<> ConvertColorToGrayScale::operator()() size_t comp = inputColorData.getNumberOfComponents(); size_t totalPoints = inputColorData.getNumberOfTuples(); + typename IParallelAlgorithm::AlgorithmArrays algArrays; + algArrays.push_back(&inputColorData); + algArrays.push_back(&outputGrayData); + switch(convType) { case ConversionType::Luminosity: - ParallelWrapper::Run(LuminosityImpl(inputColorData, outputGrayData, m_InputValues->ColorWeights, comp), totalPoints); + ParallelWrapper::Run(LuminosityImpl(inputColorData, outputGrayData, m_InputValues->ColorWeights, comp), totalPoints, algArrays); break; case ConversionType::Average: - ParallelWrapper::Run(LuminosityImpl(inputColorData, outputGrayData, {0.3333f, 0.3333f, 0.3333f}, comp), totalPoints); + ParallelWrapper::Run(LuminosityImpl(inputColorData, outputGrayData, {0.3333f, 0.3333f, 0.3333f}, comp), totalPoints, algArrays); break; - case ConversionType::Lightness: - ParallelWrapper::Run(LightnessImpl(inputColorData, outputGrayData, comp), totalPoints); + 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); + ParallelWrapper::Run(SingleChannelImpl(inputColorData, outputGrayData, comp, m_InputValues->ColorChannel), totalPoints, algArrays); break; } } diff --git a/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/ConvertData.cpp b/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/ConvertData.cpp index 1e2c5df91f..b648e63320 100644 --- a/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/ConvertData.cpp +++ b/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/ConvertData.cpp @@ -2,89 +2,128 @@ #include "complex/DataStructure/DataArray.hpp" #include "complex/DataStructure/DataGroup.hpp" +#include "complex/Utilities/ParallelDataAlgorithm.hpp" using namespace complex; namespace Detail { template -void ConvertData(DataArray& inputArray, DataArray& outputArray) +class ConvertDataAlg { - size_t size = inputArray.getSize(); - for(size_t v = 0; v < size; ++v) +public: + using InputStoreType = AbstractDataStore; + using OutputStoreType = AbstractDataStore; + + ConvertDataAlg(InputStoreType& inputStore, OutputStoreType& outputStore) + : m_InputStore(inputStore) + , m_OutputStore(outputStore) { - if constexpr(std::is_same::value) - { - // inputArray and destination arrays have the same type - outputArray[v] = inputArray[v]; - } - else if constexpr(std::is_same::value) - { - // inputArray array is a boolean array - outputArray[v] = (inputArray[v] ? 1 : 0); - } - else if constexpr(std::is_same::value) - { - // Destination array is a boolean array - outputArray[v] = (inputArray[v] != 0); - } - else + } + + void convert(size_t start, size_t end) const + { + // std::cout << "\tConvertDataAlg: " << start << " to " << end << std::endl; + + for(size_t v = start; v < end; ++v) { - // All other cases - outputArray[v] = static_cast(inputArray[v]); + // std::cout << "\tConvertDataAlg: index " << v << std::endl; + + if constexpr(std::is_same::value) + { + // inputArray and destination arrays have the same type + m_OutputStore.setValue(v, m_InputStore.getValue(v)); + } + else if constexpr(std::is_same::value) + { + // inputArray array is a boolean array + m_OutputStore.setValue(v, (m_InputStore.getValue(v) ? 1 : 0)); + } + else if constexpr(std::is_same::value) + { + // Destination array is a boolean array + m_OutputStore.setValue(v, (m_InputStore.getValue(v) != 0)); + } + else + { + // All other cases + m_OutputStore.setValue(v, static_cast(m_InputStore.getValue(v))); + } } } -} + + /** + * @brief operator () This is called from the TBB stye of code + * @param range The range to compute the values + */ + void operator()(const Range& range) const + { + convert(range.min(), range.max()); + } + +private: + InputStoreType& m_InputStore; + OutputStoreType& m_OutputStore; +}; template Result<> ConvertData(DataStructure& dataStructure, const ConvertDataInputValues* inputValues) { DataArray& inputArray = dataStructure.getDataRefAs>(inputValues->SelectedArrayPath); + AbstractDataStore& inputStore = inputArray.getDataStoreRef(); + + typename IParallelAlgorithm::AlgorithmArrays algArrays; + algArrays.push_back(&inputArray); + algArrays.push_back(dataStructure.getDataAs(inputValues->OutputArrayName)); + + ParallelDataAlgorithm dataAlg; + dataAlg.setRange(0, inputArray.size()); + dataAlg.requireArraysInMemory(algArrays); switch(inputValues->ScalarType) { case DataType::int8: { - ConvertData(inputArray, dataStructure.getDataRefAs(inputValues->OutputArrayName)); + dataAlg.execute(ConvertDataAlg(inputStore, dataStructure.getDataRefAs(inputValues->OutputArrayName).getDataStoreRef())); break; } case DataType::uint8: { - ConvertData(inputArray, dataStructure.getDataRefAs(inputValues->OutputArrayName)); + dataAlg.execute(ConvertDataAlg(inputStore, dataStructure.getDataRefAs(inputValues->OutputArrayName).getDataStoreRef())); break; } case DataType::int16: { - ConvertData(inputArray, dataStructure.getDataRefAs(inputValues->OutputArrayName)); + dataAlg.execute(ConvertDataAlg(inputStore, dataStructure.getDataRefAs(inputValues->OutputArrayName).getDataStoreRef())); break; } case DataType::uint16: { - ConvertData(inputArray, dataStructure.getDataRefAs(inputValues->OutputArrayName)); + dataAlg.execute(ConvertDataAlg(inputStore, dataStructure.getDataRefAs(inputValues->OutputArrayName).getDataStoreRef())); break; } case DataType::int32: { - ConvertData(inputArray, dataStructure.getDataRefAs(inputValues->OutputArrayName)); + dataAlg.execute(ConvertDataAlg(inputStore, dataStructure.getDataRefAs(inputValues->OutputArrayName).getDataStoreRef())); break; } case DataType::uint32: { - ConvertData(inputArray, dataStructure.getDataRefAs(inputValues->OutputArrayName)); + dataAlg.execute(ConvertDataAlg(inputStore, dataStructure.getDataRefAs(inputValues->OutputArrayName).getDataStoreRef())); break; } case DataType::int64: { - ConvertData(inputArray, dataStructure.getDataRefAs(inputValues->OutputArrayName)); + dataAlg.execute(ConvertDataAlg(inputStore, dataStructure.getDataRefAs(inputValues->OutputArrayName).getDataStoreRef())); break; } case DataType::uint64: { - ConvertData(inputArray, dataStructure.getDataRefAs(inputValues->OutputArrayName)); + dataAlg.execute(ConvertDataAlg(inputStore, dataStructure.getDataRefAs(inputValues->OutputArrayName).getDataStoreRef())); break; } case DataType::float32: { - ConvertData(inputArray, dataStructure.getDataRefAs(inputValues->OutputArrayName)); + dataAlg.execute(ConvertDataAlg(inputStore, dataStructure.getDataRefAs(inputValues->OutputArrayName).getDataStoreRef())); break; } case DataType::float64: { - ConvertData(inputArray, dataStructure.getDataRefAs(inputValues->OutputArrayName)); + dataAlg.execute(ConvertDataAlg(inputStore, dataStructure.getDataRefAs(inputValues->OutputArrayName).getDataStoreRef())); break; } case DataType::boolean: { - ConvertData(inputArray, dataStructure.getDataRefAs(inputValues->OutputArrayName)); + dataAlg.execute(ConvertDataAlg(inputStore, dataStructure.getDataRefAs(inputValues->OutputArrayName).getDataStoreRef())); break; } default: { diff --git a/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/FindArrayStatistics.cpp b/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/FindArrayStatistics.cpp index 56bdd1b080..5136b50bb8 100644 --- a/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/FindArrayStatistics.cpp +++ b/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/FindArrayStatistics.cpp @@ -428,6 +428,8 @@ class FindArrayMedianUniqueByIndexImpl featureSources[featureSourceIndex].reserve(m_LengthArray->operator[](featureSourceIndex + start)); } const usize numTuples = m_Source.getNumberOfTuples(); + const auto& featureIds = m_FeatureIds->getDataStoreRef(); + const auto& source = m_Source.getDataStoreRef(); for(usize tupleIndex = 0; tupleIndex < numTuples; tupleIndex++) { @@ -437,25 +439,28 @@ class FindArrayMedianUniqueByIndexImpl continue; } // Is the featureId within our range that we care about - const int32 featureId = (*m_FeatureIds)[tupleIndex]; + const int32 featureId = featureIds[tupleIndex]; if(featureId < start || featureId >= end) { continue; } - featureSources[featureId - start].push_back(m_Source[tupleIndex]); + featureSources[featureId - start].push_back(source[tupleIndex]); } + auto& medianArray = m_MedianArray->getDataStoreRef(); + auto& numUniqueValuesArray = m_NumUniqueValuesArray->getDataStoreRef(); + for(usize featureSourceIndex = 0; featureSourceIndex < numFeatureSources; featureSourceIndex++) { if(m_FindMedian) { const float32 val = StatisticsCalculations::findMedian(featureSources[featureSourceIndex]); - m_MedianArray->operator[](featureSourceIndex + start) = val; + medianArray.setValue(featureSourceIndex + start, val); } if(m_FindNumUniqueValues) { const auto val = StatisticsCalculations::findNumUniqueValues(featureSources[featureSourceIndex]); - m_NumUniqueValuesArray->operator[](featureSourceIndex + start) = val; + numUniqueValuesArray.setValue(featureSourceIndex + start, val); } } } @@ -655,23 +660,42 @@ void FindStatistics(const DataArray& source, const Int32Array* featureIds, co auto* modalBinsArrayPtr = dynamic_cast*>(arrays[11]); auto* featureHasDataPtr = dynamic_cast(arrays[12]); + 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 - 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 - auto impl = 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, - mask, featureIds, source, featureHasDataPtr, lengthArrayPtr, minArrayPtr, maxArrayPtr, meanArrayPtr, modeArrayPtr, stdDevArrayPtr, summationArrayPtr, - histArrayPtr, mostPopulatedBinPtr, filter); - impl.compute(0, numFeatures); + 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) @@ -681,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)); @@ -710,7 +741,6 @@ void FindStatistics(const DataArray& source, const Int32Array* featureIds, co } else { - // compute the statistics for the entire array FindStatisticsImpl, T>(source, arrays, inputValues); } @@ -719,9 +749,15 @@ void FindStatistics(const DataArray& source, const Int32Array* featureIds, co // ----------------------------------------------------------------------------- template -void StandardizeDataByIndex(const DataArray& data, bool useMask, const std::unique_ptr& mask, const Int32Array* featureIds, const Float32Array& mu, const Float32Array& sig, - Float32Array& standardized) +void StandardizeDataByIndex(const DataArray& dataArray, bool useMask, const std::unique_ptr& mask, const Int32Array* featureIdsArray, const Float32Array& muArray, + const Float32Array& sigArray, Float32Array& standardizedArray) { + auto& data = dataArray.getDataStoreRef(); + auto& standardized = standardizedArray.getDataStoreRef(); + const auto& featureIds = featureIdsArray->getDataStoreRef(); + const auto& mu = muArray.getDataStoreRef(); + const auto& sig = sigArray.getDataStoreRef(); + const usize numTuples = data.getNumberOfTuples(); for(usize i = 0; i < numTuples; i++) { @@ -729,20 +765,25 @@ void StandardizeDataByIndex(const DataArray& data, bool useMask, const std::u { if(mask->isTrue(i)) { - standardized[i] = (static_cast(data[i]) - mu[featureIds->at(i)]) / sig[featureIds->at(i)]; + standardized.setValue(i, (static_cast(data[i]) - mu[featureIds.at(i)]) / sig[featureIds.at(i)]); } } else { - standardized[i] = (static_cast(data[i]) - mu[featureIds->at(i)]) / sig[featureIds->at(i)]; + standardized.setValue(i, (static_cast(data[i]) - mu[featureIds.at(i)]) / sig[featureIds.at(i)]); } } } // ----------------------------------------------------------------------------- template -void StandardizeData(const DataArray& data, bool useMask, const std::unique_ptr& mask, const Float32Array& mu, const Float32Array& sig, Float32Array& standardized) +void StandardizeData(const DataArray& dataArray, bool useMask, const std::unique_ptr& mask, const Float32Array& muArray, const Float32Array& sigArray, Float32Array& standardizedArray) { + auto& data = dataArray.getDataStoreRef(); + auto& standardized = standardizedArray.getDataStoreRef(); + const auto& mu = muArray.getDataStoreRef(); + const auto& sig = sigArray.getDataStoreRef(); + const usize numTuples = data.getNumberOfTuples(); for(usize i = 0; i < numTuples; i++) @@ -751,12 +792,12 @@ void StandardizeData(const DataArray& data, bool useMask, const std::unique_p { if(mask->isTrue(i)) { - standardized[i] = (static_cast(data[i]) - mu[0]) / sig[0]; + standardized.setValue(i, (static_cast(data[i]) - mu[0]) / sig[0]); } } else { - standardized[i] = (static_cast(data[i]) - mu[0]) / sig[0]; + standardized.setValue(i, (static_cast(data[i]) - mu[0]) / sig[0]); } } } diff --git a/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/FindFeatureCentroids.cpp b/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/FindFeatureCentroids.cpp index e7239cb8f5..439b03ae15 100644 --- a/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/FindFeatureCentroids.cpp +++ b/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/FindFeatureCentroids.cpp @@ -20,7 +20,7 @@ class FindFeatureCentroidsImpl1 , m_Count(count) , m_Dims(dims) , m_ImageGeom(imageGeom) - , m_FeatureIds(featureIds) + , m_FeatureIds(featureIds.getDataStoreRef()) { } ~FindFeatureCentroidsImpl1() = default; @@ -82,7 +82,7 @@ class FindFeatureCentroidsImpl1 size_t m_TotalFeatures = 0; std::array m_Dims = {0, 0, 0}; const complex::ImageGeom& m_ImageGeom; - const Int32Array& m_FeatureIds; + const Int32AbstractDataStore& m_FeatureIds; }; } // namespace @@ -112,12 +112,13 @@ Result<> FindFeatureCentroids::operator()() const auto& featureIds = m_DataStructure.getDataRefAs(m_InputValues->FeatureIdsArrayPath); // Output Feature Data - auto& centroids = m_DataStructure.getDataRefAs(m_InputValues->CentroidsArrayPath); + auto& centroidsArray = m_DataStructure.getDataRefAs(m_InputValues->CentroidsArrayPath); + auto& centroids = centroidsArray.getDataStoreRef(); // Required Geometry const auto& imageGeom = m_DataStructure.getDataRefAs(m_InputValues->ImageGeometryPath); - size_t totalFeatures = centroids.getNumberOfTuples(); + size_t totalFeatures = centroidsArray.getNumberOfTuples(); size_t xPoints = imageGeom.getNumXCells(); size_t yPoints = imageGeom.getNumYCells(); @@ -146,13 +147,13 @@ Result<> FindFeatureCentroids::operator()() centroids[featureId_idx] = static_cast(sum[featureId_idx] / static_cast(count[featureId_idx])); } - featureId_idx = static_cast(featureId * 3 + 1); + featureId_idx++; // featureId * 3 + 1 if(static_cast(count[featureId_idx]) > 0.0f) { centroids[featureId_idx] = static_cast(sum[featureId_idx] / static_cast(count[featureId_idx])); } - featureId_idx = static_cast(featureId * 3 + 2); + featureId_idx++; // featureId * 3 + 2 if(static_cast(count[featureId_idx]) > 0.0f) { centroids[featureId_idx] = static_cast(sum[featureId_idx] / static_cast(count[featureId_idx])); diff --git a/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/PartitionGeometry.cpp b/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/PartitionGeometry.cpp index f739d2a1c4..f004f04d45 100644 --- a/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/PartitionGeometry.cpp +++ b/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/PartitionGeometry.cpp @@ -55,10 +55,12 @@ class PartitionCellBasedGeometryImpl if(partitionIndexResult.has_value()) { 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; } } } @@ -242,8 +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.requireArraysInMemory(algArrays); dataAlg.execute(PartitionCellBasedGeometryImpl(inputGeometry, partitionIds, psImageGeom, m_InputValues->StartingFeatureID, outOfBoundsValue, m_ShouldCancel)); return {}; @@ -255,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/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/ScalarSegmentFeatures.cpp b/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/ScalarSegmentFeatures.cpp index 5772796031..dac8bd6432 100644 --- a/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/ScalarSegmentFeatures.cpp +++ b/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/ScalarSegmentFeatures.cpp @@ -75,11 +75,13 @@ class TSpecificCompareFunctor : public SegmentFeatures::CompareFunctor CX_DEFAULT_CONSTRUCTORS(TSpecificCompareFunctor) using DataArrayType = DataArray; + using DataStoreType = AbstractDataStore; + TSpecificCompareFunctor(IDataArray* data, int64 length, T tolerance, AbstractDataStore* featureIds) : m_Length(length) , m_Tolerance(tolerance) , m_FeatureIdsArray(featureIds) - , m_Data(dynamic_cast(data)) + , m_Data(dynamic_cast(data)->getDataStoreRef()) { } ~TSpecificCompareFunctor() override = default; @@ -92,9 +94,9 @@ class TSpecificCompareFunctor : public SegmentFeatures::CompareFunctor return false; } - if((*m_Data)[referencePoint] >= (*m_Data)[neighborPoint]) + if(m_Data[referencePoint] >= m_Data[neighborPoint]) { - if(((*m_Data)[referencePoint] - (*m_Data)[neighborPoint]) <= m_Tolerance) + if((m_Data[referencePoint] - m_Data[neighborPoint]) <= m_Tolerance) { m_FeatureIdsArray->setValue(neighborPoint, gnum); return true; @@ -102,7 +104,7 @@ class TSpecificCompareFunctor : public SegmentFeatures::CompareFunctor } else { - if(((*m_Data)[neighborPoint] - (*m_Data)[referencePoint]) <= m_Tolerance) + if((m_Data[neighborPoint] - m_Data[referencePoint]) <= m_Tolerance) { m_FeatureIdsArray->setValue(neighborPoint, gnum); return true; @@ -118,7 +120,7 @@ class TSpecificCompareFunctor : public SegmentFeatures::CompareFunctor int64 m_Length = 0; // Length of the Data Array T m_Tolerance = static_cast(0); // The tolerance of the comparison AbstractDataStore* m_FeatureIdsArray = nullptr; // The Feature Ids - DataArrayType* m_Data = nullptr; // The data that is being compared + DataStoreType& m_Data; // The data that is being compared }; } // namespace diff --git a/src/Plugins/ComplexCore/src/ComplexCore/Filters/CalculateFeatureSizesFilter.cpp b/src/Plugins/ComplexCore/src/ComplexCore/Filters/CalculateFeatureSizesFilter.cpp index 2672e638b6..cb27e4899f 100644 --- a/src/Plugins/ComplexCore/src/ComplexCore/Filters/CalculateFeatureSizesFilter.cpp +++ b/src/Plugins/ComplexCore/src/ComplexCore/Filters/CalculateFeatureSizesFilter.cpp @@ -134,9 +134,10 @@ Result<> CalculateFeatureSizesFilter::executeImpl(DataStructure& data, const Arg { auto saveElementSizes = args.value(k_SaveElementSizes_Key); auto featureIdsPath = args.value(k_CellFeatureIdsArrayPath_Key); - const auto& featureIds = data.getDataRefAs(featureIdsPath); + const auto& featureIdsArray = data.getDataRefAs(featureIdsPath); + const auto& featureIds = featureIdsArray.getDataStoreRef(); - usize totalPoints = featureIds.getNumberOfTuples(); + usize totalPoints = featureIdsArray.getNumberOfTuples(); auto geomPath = args.value(k_GeometryPath_Key); auto* geom = data.getDataAs(geomPath); diff --git a/src/Plugins/ComplexCore/src/ComplexCore/Filters/CreateFeatureArrayFromElementArray.cpp b/src/Plugins/ComplexCore/src/ComplexCore/Filters/CreateFeatureArrayFromElementArray.cpp index 09c74c615b..0ed374e344 100644 --- a/src/Plugins/ComplexCore/src/ComplexCore/Filters/CreateFeatureArrayFromElementArray.cpp +++ b/src/Plugins/ComplexCore/src/ComplexCore/Filters/CreateFeatureArrayFromElementArray.cpp @@ -21,9 +21,11 @@ struct CopyCellDataFunctor const std::atomic_bool& shouldCancel) { const DataArray& selectedCellArray = dataStructure.getDataRefAs>(selectedCellArrayPathValue); - const DataStore selectedCellArrayStore = selectedCellArray.template getIDataStoreRefAs>(); - const Int32Array& featureIds = dataStructure.getDataRefAs(featureIdsArrayPathValue); + const auto& selectedCellArrayStore = selectedCellArray.getDataStoreRef(); + const Int32Array& featureIdsArray = dataStructure.getDataRefAs(featureIdsArrayPathValue); + const Int32AbstractDataStore& featureIds = featureIdsArray.getDataStoreRef(); auto& createdArray = dataStructure.getDataRefAs>(createdArrayNameValue); + auto& createdDataStore = createdArray.getDataStoreRef(); // Initialize the output array with a default value createdArray.fill(0); @@ -54,8 +56,8 @@ struct CopyCellDataFunctor usize firstInstanceCellTupleIdx = featureMap[featureIdx]; for(usize cellCompIdx = 0; cellCompIdx < totalCellArrayComponents; cellCompIdx++) { - T firstInstanceCellVal = selectedCellArray[firstInstanceCellTupleIdx + cellCompIdx]; - T currentCellVal = selectedCellArray[totalCellArrayComponents * cellTupleIdx + cellCompIdx]; + T firstInstanceCellVal = selectedCellArrayStore[firstInstanceCellTupleIdx + cellCompIdx]; + T currentCellVal = selectedCellArrayStore[totalCellArrayComponents * cellTupleIdx + cellCompIdx]; if(currentCellVal != firstInstanceCellVal && result.warnings().empty()) { // The values are inconsistent with the first values for this feature identifier, so throw a warning @@ -63,7 +65,7 @@ struct CopyCellDataFunctor Warning{-1000, fmt::format("Elements from Feature {} do not all have the same value. The last value copied into Feature {} will be used", featureIdx, featureIdx)}); } - createdArray[totalCellArrayComponents * featureIdx + cellCompIdx] = selectedCellArray[totalCellArrayComponents * cellTupleIdx + cellCompIdx]; + createdDataStore[totalCellArrayComponents * featureIdx + cellCompIdx] = selectedCellArrayStore[totalCellArrayComponents * cellTupleIdx + cellCompIdx]; } } @@ -177,7 +179,8 @@ Result<> CreateFeatureArrayFromElementArray::executeImpl(DataStructure& dataStru const DataPath createdArrayPath = pCellFeatureAttributeMatrixPathValue.createChildPath(pCreatedArrayNameValue); const IDataArray& selectedCellArray = dataStructure.getDataRefAs(pSelectedCellArrayPathValue); - const Int32Array& featureIds = dataStructure.getDataRefAs(pFeatureIdsArrayPathValue); + const Int32Array& featureIdsArray = dataStructure.getDataRefAs(pFeatureIdsArrayPathValue); + const Int32AbstractDataStore& featureIds = featureIdsArray.getDataStoreRef(); auto& createdArray = dataStructure.getDataRefAs(createdArrayPath); // Resize the created array to the proper size diff --git a/src/Plugins/ComplexCore/src/ComplexCore/Filters/CropImageGeometry.cpp b/src/Plugins/ComplexCore/src/ComplexCore/Filters/CropImageGeometry.cpp index 1c5abb91fe..59980066ca 100644 --- a/src/Plugins/ComplexCore/src/ComplexCore/Filters/CropImageGeometry.cpp +++ b/src/Plugins/ComplexCore/src/ComplexCore/Filters/CropImageGeometry.cpp @@ -81,6 +81,7 @@ class CropImageGeomDataArray void convert() const { size_t numComps = m_OldCellArray.getNumberOfComponents(); + const auto& oldCellData = m_OldCellArray.getDataStoreRef(); auto& dataStore = m_NewCellArray.getDataStoreRef(); std::fill(dataStore.begin(), dataStore.end(), static_cast(-1)); @@ -101,7 +102,7 @@ class CropImageGeomDataArray uint64 srcIndex = (srcDims[0] * srcDims[1] * zIndex) + (srcDims[0] * yIndex) + xIndex; for(size_t compIndex = 0; compIndex < numComps; compIndex++) { - m_NewCellArray[destTupleIndex * numComps + compIndex] = m_OldCellArray[srcIndex * numComps + compIndex]; + dataStore.setValue(destTupleIndex * numComps + compIndex, oldCellData.getValue(srcIndex * numComps + compIndex)); } destTupleIndex++; } diff --git a/src/Plugins/ComplexCore/src/ComplexCore/Filters/FindSurfaceFeatures.cpp b/src/Plugins/ComplexCore/src/ComplexCore/Filters/FindSurfaceFeatures.cpp index 2f5e324e3f..57f541e712 100644 --- a/src/Plugins/ComplexCore/src/ComplexCore/Filters/FindSurfaceFeatures.cpp +++ b/src/Plugins/ComplexCore/src/ComplexCore/Filters/FindSurfaceFeatures.cpp @@ -296,7 +296,7 @@ Result<> FindSurfaceFeatures::executeImpl(DataStructure& dataStructure, const Ar // Resize the surface features array to the proper size const Int32Array& featureIds = dataStructure.getDataRefAs(pFeatureIdsArrayPathValue); auto& surfaceFeatures = dataStructure.getDataRefAs(pSurfaceFeaturesArrayPathValue); - auto& surfaceFeaturesStore = surfaceFeatures.getIDataStoreRefAs>(); + auto& surfaceFeaturesStore = surfaceFeatures.getDataStoreRef(); const usize featureIdsMaxIdx = std::distance(featureIds.begin(), std::max_element(featureIds.cbegin(), featureIds.cend())); const usize maxFeature = featureIds[featureIdsMaxIdx]; diff --git a/src/Plugins/ComplexCore/src/ComplexCore/Filters/ImportHDF5Dataset.cpp b/src/Plugins/ComplexCore/src/ComplexCore/Filters/ImportHDF5Dataset.cpp index cdb970acd3..f735832017 100644 --- a/src/Plugins/ComplexCore/src/ComplexCore/Filters/ImportHDF5Dataset.cpp +++ b/src/Plugins/ComplexCore/src/ComplexCore/Filters/ImportHDF5Dataset.cpp @@ -43,19 +43,55 @@ std::vector createDimensionVector(const std::string& cDimsStr) } template -Result<> fillDataArray(DataStructure& dataStructure, const DataPath& dataArrayPath, const complex::HDF5::DatasetReader& datasetReader) +Result<> fillDataStore(DataArray& dataArray, const DataPath& dataArrayPath, const complex::HDF5::DatasetReader& datasetReader) { - auto& dataArray = dataStructure.getDataRefAs>(dataArrayPath); - auto& absDataStore = dataArray.getDataStoreRef(); - auto& dataStore = dynamic_cast&>(absDataStore); + using StoreType = DataStore; + StoreType& dataStore = dataArray.template getIDataStoreRefAs(); if(!datasetReader.readIntoSpan(dataStore.createSpan())) { return {MakeErrorResult(-21002, fmt::format("Error reading dataset '{}' with '{}' total elements into data store for data array '{}' with '{}' total elements ('{}' tuples and '{}' components)", dataArrayPath.getTargetName(), datasetReader.getNumElements(), dataArrayPath.toString(), dataArray.getSize(), dataArray.getNumberOfTuples(), dataArray.getNumberOfComponents()))}; } + + return {}; +} + +template +Result<> fillOocDataStore(DataArray& dataArray, const DataPath& dataArrayPath, const complex::HDF5::DatasetReader& datasetReader) +{ + if(Memory::GetTotalMemory() <= dataArray.getSize() * sizeof(T)) + { + return MakeErrorResult(-21004, fmt::format("Error reading dataset '{}' with '{}' total elements. Not enough memory to import data.", dataArray.getName(), datasetReader.getNumElements())); + } + + auto& absDataStore = dataArray.getDataStoreRef(); + std::vector data(absDataStore.getSize()); + nonstd::span span{data.data(), data.size()}; + if(!datasetReader.readIntoSpan(span)) + { + return {MakeErrorResult(-21003, fmt::format("Error reading dataset '{}' with '{}' total elements into data store for data array '{}' with '{}' total elements ('{}' tuples and '{}' components)", + dataArrayPath.getTargetName(), datasetReader.getNumElements(), dataArrayPath.toString(), dataArray.getSize(), dataArray.getNumberOfTuples(), + dataArray.getNumberOfComponents()))}; + } + std::copy(data.begin(), data.end(), absDataStore.begin()); + return {}; } + +template +Result<> fillDataArray(DataStructure& dataStructure, const DataPath& dataArrayPath, const complex::HDF5::DatasetReader& datasetReader) +{ + auto& dataArray = dataStructure.getDataRefAs>(dataArrayPath); + if(dataArray.getDataFormat().empty()) + { + return fillDataStore(dataArray, dataArrayPath, datasetReader); + } + else + { + return fillOocDataStore(dataArray, dataArrayPath, datasetReader); + } +} } // namespace namespace complex diff --git a/src/Plugins/ComplexCore/src/ComplexCore/Filters/ScalarSegmentFeaturesFilter.cpp b/src/Plugins/ComplexCore/src/ComplexCore/Filters/ScalarSegmentFeaturesFilter.cpp index 69a4832ae6..a76242f21a 100644 --- a/src/Plugins/ComplexCore/src/ComplexCore/Filters/ScalarSegmentFeaturesFilter.cpp +++ b/src/Plugins/ComplexCore/src/ComplexCore/Filters/ScalarSegmentFeaturesFilter.cpp @@ -186,7 +186,6 @@ IFilter::PreflightResult ScalarSegmentFeaturesFilter::preflightImpl(const DataSt Result<> ScalarSegmentFeaturesFilter::executeImpl(DataStructure& data, const Arguments& args, const PipelineFilter* pipelineNode, const MessageHandler& messageHandler, const std::atomic_bool& shouldCancel) const { - ScalarSegmentFeaturesInputValues inputValues; inputValues.pInputDataPath = args.value(k_InputArrayPathKey); diff --git a/src/Plugins/ComplexCore/test/AlignSectionsFeatureCentroidTest.cpp b/src/Plugins/ComplexCore/test/AlignSectionsFeatureCentroidTest.cpp index 6cebdb7497..976b1fba59 100644 --- a/src/Plugins/ComplexCore/test/AlignSectionsFeatureCentroidTest.cpp +++ b/src/Plugins/ComplexCore/test/AlignSectionsFeatureCentroidTest.cpp @@ -28,8 +28,7 @@ TEST_CASE("ComplexCore::AlignSectionsFeatureCentroidFilter", "[Reconstruction][A // would be responsible to create. const uint64_t millisFromEpoch = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); - std::shared_ptr app = std::make_shared(); - app->loadPlugins(unit_test::k_BuildDir.view(), true); + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); auto* filterList = Application::Instance()->getFilterList(); const DataPath k_ExemplarShiftsPath = k_ExemplarDataContainerPath.createChildPath("Exemplar Shifts"); diff --git a/src/Plugins/ComplexCore/test/AlignSectionsListTest.cpp b/src/Plugins/ComplexCore/test/AlignSectionsListTest.cpp index 9de92421b9..bf8cfd390d 100644 --- a/src/Plugins/ComplexCore/test/AlignSectionsListTest.cpp +++ b/src/Plugins/ComplexCore/test/AlignSectionsListTest.cpp @@ -15,9 +15,9 @@ using namespace complex; TEST_CASE("ComplexCore::AlignSectionsListFilter: Valid filter execution", "[ComplexCore][AlignSectionsListFilter]") { - std::shared_ptr app = std::make_shared(); + auto app = Application::GetOrCreateInstance(); app->loadPlugins(unit_test::k_BuildDir.view(), true); - auto* filterList = Application::Instance()->getFilterList(); + auto* filterList = app->getFilterList(); const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_align_sections_misorientation.tar.gz", "6_6_align_sections_misorientation"); diff --git a/src/Plugins/ComplexCore/test/AppendImageGeometryZSliceTest.cpp b/src/Plugins/ComplexCore/test/AppendImageGeometryZSliceTest.cpp index 86864f7399..829369339f 100644 --- a/src/Plugins/ComplexCore/test/AppendImageGeometryZSliceTest.cpp +++ b/src/Plugins/ComplexCore/test/AppendImageGeometryZSliceTest.cpp @@ -1,5 +1,6 @@ #include +#include "complex/Core/Application.hpp" #include "complex/UnitTest/UnitTestCommon.hpp" #include "complex/Utilities/StringUtilities.hpp" @@ -29,6 +30,8 @@ const DataPath k_SmallIN100Path({k_SmallIN100}); TEST_CASE("ComplexCore::AppendImageGeometryZSliceFilter: Valid Filter Execution", "[ComplexCore][AppendImageGeometryZSliceFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "Small_IN100_dream3d.tar.gz", "Small_IN100.dream3d"); // Read in starting/exemplar image geometry const auto exemplarFilePath = fs::path(fmt::format("{}/Small_IN100.dream3d", unit_test::k_TestFilesDir)); @@ -151,6 +154,7 @@ TEST_CASE("ComplexCore::AppendImageGeometryZSliceFilter: Valid Filter Execution" TEST_CASE("ComplexCore::AppendImageGeometryZSliceFilter: InValid Filter Execution", "[ComplexCore][AppendImageGeometryZSliceFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "ResampleImageGeom_Exemplar.tar.gz", "ResampleImageGeom_Exemplar.dream3d"); diff --git a/src/Plugins/ComplexCore/test/ComputeFeatureRectTest.cpp b/src/Plugins/ComplexCore/test/ComputeFeatureRectTest.cpp index f702e35fe4..79a8375380 100644 --- a/src/Plugins/ComplexCore/test/ComputeFeatureRectTest.cpp +++ b/src/Plugins/ComplexCore/test/ComputeFeatureRectTest.cpp @@ -1,6 +1,7 @@ #include "complex/DataStructure/Geometry/ImageGeom.hpp" #include "complex/UnitTest/UnitTestCommon.hpp" +#include "ComplexCore/ComplexCore_test_dirs.hpp" #include "ComplexCore/Filters/ComputeFeatureRectFilter.hpp" #include @@ -29,7 +30,7 @@ DataStructure CreateTestData() Int32Array* featureIds = Int32Array::CreateWithStore(dataStructure, k_FeatureIdsArrayName, {dims[2], dims[1], dims[0]}, {1}, cellAM->getId()); featureIds->fill(0); - auto& featureIdsStore = featureIds->getIDataStoreRefAs(); + auto& featureIdsStore = featureIds->getDataStoreRef(); featureIdsStore[6] = 1; featureIdsStore[7] = 1; featureIdsStore[8] = 1; @@ -70,7 +71,7 @@ DataStructure CreateTestData() std::vector compDims = {6}; UInt32Array* rect = UInt32Array::CreateWithStore(dataStructure, k_RectCoordsExemplaryArrayName, {4}, {6}, featureAM->getId()); - auto& rectStore = rect->getIDataStoreRefAs(); + auto& rectStore = rect->getDataStoreRef(); rectStore.setComponent(1, 0, 1); rectStore.setComponent(1, 1, 1); rectStore.setComponent(1, 2, 0); @@ -98,6 +99,8 @@ DataStructure CreateTestData() TEST_CASE("ComplexCore::ComputeFeatureRectFilter: Valid filter execution", "[ComplexCore][ComputeFeatureRectFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + // Instantiate the filter, a DataStructure object and an Arguments Object ComputeFeatureRectFilter filter; DataStructure dataStructure = CreateTestData(); @@ -117,13 +120,11 @@ TEST_CASE("ComplexCore::ComputeFeatureRectFilter: Valid filter execution", "[Com REQUIRE_NOTHROW(dataStructure.getDataRefAs({{k_ImageGeometryName, k_FeatureAttrMatrixName, k_RectCoordsArrayName}})); const UInt32Array& coords = dataStructure.getDataRefAs({{k_ImageGeometryName, k_FeatureAttrMatrixName, k_RectCoordsArrayName}}); - REQUIRE_NOTHROW(coords.getIDataStoreRefAs()); - const auto& coordsDataStore = coords.getIDataStoreRefAs(); + const auto& coordsDataStore = coords.getDataStoreRef(); REQUIRE_NOTHROW(dataStructure.getDataRefAs({{k_ImageGeometryName, k_FeatureAttrMatrixName, k_RectCoordsExemplaryArrayName}})); const UInt32Array& exemplaryCoords = dataStructure.getDataRefAs({{k_ImageGeometryName, k_FeatureAttrMatrixName, k_RectCoordsExemplaryArrayName}}); - REQUIRE_NOTHROW(exemplaryCoords.getIDataStoreRefAs()); - const auto& exemplaryCoordsDataStore = exemplaryCoords.getIDataStoreRefAs(); + const auto& exemplaryCoordsDataStore = exemplaryCoords.getDataStoreRef(); REQUIRE(coordsDataStore.getNumberOfTuples() == exemplaryCoordsDataStore.getNumberOfTuples()); REQUIRE(coordsDataStore.getNumberOfComponents() == exemplaryCoordsDataStore.getNumberOfComponents()); diff --git a/src/Plugins/ComplexCore/test/ConvertColorToGrayScaleTest.cpp b/src/Plugins/ComplexCore/test/ConvertColorToGrayScaleTest.cpp index 0d8d665c70..b63d9ef8e3 100644 --- a/src/Plugins/ComplexCore/test/ConvertColorToGrayScaleTest.cpp +++ b/src/Plugins/ComplexCore/test/ConvertColorToGrayScaleTest.cpp @@ -265,12 +265,13 @@ void CompareResults(const uint8& algoMapIndex, const DataStructure& dataStructur arrayName = arrayName.createChildPath(m_outputArrayPrefix + m_DataArrayName); auto* testArray = dataStructure.getDataAs(arrayName); REQUIRE(testArray != nullptr); + auto& testData = testArray->getDataStoreRef(); std::vector colorArray{algorithmMap[algoMapIndex]}; for(size_t index = 0; index < colorArray.size(); ++index) { - uint8 testVal = (*testArray)[index]; + uint8 testVal = testData[index]; uint8 exemplarVal = colorArray[index]; REQUIRE(testVal == exemplarVal); } @@ -332,6 +333,8 @@ void RunTest(const uint8& algoMapIndex, const ConvertColorToGrayScale::Conversio TEST_CASE("ComplexCore::ConvertColorToGrayScale: Valid Execution", "[ComplexCore][ConvertColorToGrayScaleFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + // Luminosity Algorithm testing // Test defaults std::cout << "Testing luminosity algorithm..." << std::endl; diff --git a/src/Plugins/ComplexCore/test/CoreFilterTest.cpp b/src/Plugins/ComplexCore/test/CoreFilterTest.cpp index 46f8d14a27..4a0f2b63c2 100644 --- a/src/Plugins/ComplexCore/test/CoreFilterTest.cpp +++ b/src/Plugins/ComplexCore/test/CoreFilterTest.cpp @@ -41,9 +41,9 @@ struct StringMaker TEST_CASE("CoreFilterTest:Create Core Filter") { - Application app; - app.loadPlugins(unit_test::k_BuildDir.view()); - auto filterList = app.getFilterList(); + auto app = Application::GetOrCreateInstance(); + app->loadPlugins(unit_test::k_BuildDir.view()); + auto filterList = app->getFilterList(); REQUIRE(filterList != nullptr); // Only core filters should exist since plugins were not loaded @@ -65,6 +65,8 @@ TEST_CASE("CoreFilterTest:Create Core Filter") TEST_CASE("CoreFilterTest:RunCoreFilter") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + static const fs::path k_FileName = fmt::format("{}/ascii_data.txt", complex::unit_test::k_BinaryTestOutputDir); static constexpr uint64 k_NLines = 25; @@ -130,6 +132,8 @@ TEST_CASE("CoreFilterTest:RunCoreFilter") TEST_CASE("CoreFilterTest:CreateDataGroup") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + DataStructure data; CreateDataGroup filter; Arguments args; diff --git a/src/Plugins/ComplexCore/test/CreateFeatureArrayFromElementArrayTest.cpp b/src/Plugins/ComplexCore/test/CreateFeatureArrayFromElementArrayTest.cpp index 764852ede0..7a3509a95d 100644 --- a/src/Plugins/ComplexCore/test/CreateFeatureArrayFromElementArrayTest.cpp +++ b/src/Plugins/ComplexCore/test/CreateFeatureArrayFromElementArrayTest.cpp @@ -1,6 +1,7 @@ #include "ComplexCore/Filters/CreateFeatureArrayFromElementArray.hpp" #include "ComplexCore/ComplexCore_test_dirs.hpp" +#include "complex/Core/Application.hpp" #include "complex/Parameters/ArrayCreationParameter.hpp" #include "complex/UnitTest/UnitTestCommon.hpp" @@ -17,6 +18,7 @@ const std::string k_Computed_CellData("Computed_CellData"); template void testElementArray(const DataPath& cellDataPath) { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_5_test_data_1.tar.gz", "6_5_test_data_1"); // Read the Small IN100 Data set @@ -72,6 +74,8 @@ void testElementArray(const DataPath& cellDataPath) TEST_CASE("ComplexCore::CreateFeatureArrayFromElementArray: Valid filter execution - 1 Component") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + DataPath smallIn100Group({complex::Constants::k_DataContainer}); DataPath cellDataPath = smallIn100Group.createChildPath(complex::Constants::k_CellData).createChildPath(complex::Constants::k_ConfidenceIndex); testElementArray(cellDataPath); @@ -79,6 +83,8 @@ TEST_CASE("ComplexCore::CreateFeatureArrayFromElementArray: Valid filter executi TEST_CASE("ComplexCore::CreateFeatureArrayFromElementArray: Valid filter execution - 3 Component") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + DataPath smallIn100Group({complex::Constants::k_DataContainer}); DataPath cellDataPath = smallIn100Group.createChildPath(complex::Constants::k_CellData).createChildPath(complex::Constants::k_IPFColors); testElementArray(cellDataPath); diff --git a/src/Plugins/ComplexCore/test/CropImageGeometryTest.cpp b/src/Plugins/ComplexCore/test/CropImageGeometryTest.cpp index f5c53d3a9f..fe819b3e0a 100644 --- a/src/Plugins/ComplexCore/test/CropImageGeometryTest.cpp +++ b/src/Plugins/ComplexCore/test/CropImageGeometryTest.cpp @@ -2,6 +2,7 @@ #include "ComplexCore/ComplexCore_test_dirs.hpp" #include "complex/Common/StringLiteral.hpp" +#include "complex/Core/Application.hpp" #include "complex/DataStructure/DataArray.hpp" #include "complex/DataStructure/IO/HDF5/DataStructureReader.hpp" #include "complex/DataStructure/IO/HDF5/DataStructureWriter.hpp" @@ -50,6 +51,8 @@ DataStructure CreateDataStructure() TEST_CASE("ComplexCore::CropImageGeometry(Instantiate)", "[ComplexCore][CropImageGeometry]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const std::vector k_MinVector{0, 0, 0}; const std::vector k_MaxVector{0, 0, 0}; @@ -82,6 +85,8 @@ TEST_CASE("ComplexCore::CropImageGeometry(Instantiate)", "[ComplexCore][CropImag TEST_CASE("ComplexCore::CropImageGeometry Invalid Params", "[ComplexCore][CropImageGeometry]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + std::vector k_MinVector{0, 0, 0}; std::vector k_MaxVector{500, 20, 30}; @@ -159,6 +164,8 @@ TEST_CASE("ComplexCore::CropImageGeometry Invalid Params", "[ComplexCore][CropIm TEST_CASE("ComplexCore::CropImageGeometry(Execute_Filter)", "[ComplexCore][CropImageGeometry]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const std::vector k_MinVector{10, 15, 0}; const std::vector k_MaxVector{60, 40, 50}; diff --git a/src/Plugins/ComplexCore/test/DREAM3DFileTest.cpp b/src/Plugins/ComplexCore/test/DREAM3DFileTest.cpp index f3cf704f86..0f03f6ad63 100644 --- a/src/Plugins/ComplexCore/test/DREAM3DFileTest.cpp +++ b/src/Plugins/ComplexCore/test/DREAM3DFileTest.cpp @@ -270,9 +270,9 @@ DREAM3D::FileData CreateFileData() TEST_CASE("DREAM3DFileTest:DREAM3D File IO Test") { - Application app; + auto app = Application::GetOrCreateInstance(); fs::path pluginPath = complex::unit_test::k_BuildDir.str(); - app.loadPlugins(pluginPath, false); + app->loadPlugins(pluginPath, false); std::lock_guard lock(m_DataMutex); // Write .dream3d file @@ -311,9 +311,9 @@ TEST_CASE("DREAM3DFileTest:DREAM3D File IO Test") TEST_CASE("DREAM3DFileTest:Import/Export DREAM3D Filter Test") { - Application app; + auto app = Application::GetOrCreateInstance(); fs::path pluginPath = complex::unit_test::k_BuildDir.str(); - app.loadPlugins(pluginPath, false); + app->loadPlugins(pluginPath, false); std::lock_guard lock(m_DataMutex); @@ -346,9 +346,9 @@ TEST_CASE("DREAM3DFileTest:Import/Export DREAM3D Filter Test") TEST_CASE("DREAM3DFileTest:Import/Export Multi-DREAM3D Filter Test") { - Application app; + auto app = Application::GetOrCreateInstance(); fs::path pluginPath = complex::unit_test::k_BuildDir.str(); - app.loadPlugins(pluginPath, false); + app->loadPlugins(pluginPath, false); std::lock_guard lock(m_DataMutex); diff --git a/src/Plugins/ComplexCore/test/ErodeDilateBadDataTest.cpp b/src/Plugins/ComplexCore/test/ErodeDilateBadDataTest.cpp index 6b2543992d..ed7afbb45a 100644 --- a/src/Plugins/ComplexCore/test/ErodeDilateBadDataTest.cpp +++ b/src/Plugins/ComplexCore/test/ErodeDilateBadDataTest.cpp @@ -33,8 +33,7 @@ TEST_CASE("ComplexCore::ErodeDilateBadDataFilter(Erode)", "[ComplexCore][ErodeDi { const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_erode_dilate_test.tar.gz", "6_6_erode_dilate_test"); - std::shared_ptr app = std::make_shared(); - app->loadPlugins(unit_test::k_BuildDir.view(), true); + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); // Read Exemplar DREAM3D File Filter auto exemplarFilePath = fs::path(fmt::format("{}/6_6_erode_dilate_test/6_6_erode_dilate_bad_data.dream3d", unit_test::k_TestFilesDir)); @@ -82,8 +81,7 @@ TEST_CASE("ComplexCore::ErodeDilateBadDataFilter(Dilate)", "[ComplexCore][ErodeD const std::string k_ExemplarDataContainerName("Exemplar Bad Data Dilate"); const DataPath k_DilateCellAttributeMatrixDataPath = DataPath({k_ExemplarDataContainerName, "EBSD Scan Data"}); - std::shared_ptr app = std::make_shared(); - app->loadPlugins(unit_test::k_BuildDir.view(), true); + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); // Read Exemplar DREAM3D File Filter auto exemplarFilePath = fs::path(fmt::format("{}/6_6_erode_dilate_test/6_6_erode_dilate_bad_data.dream3d", unit_test::k_TestFilesDir)); diff --git a/src/Plugins/ComplexCore/test/ErodeDilateCoordinationNumberTest.cpp b/src/Plugins/ComplexCore/test/ErodeDilateCoordinationNumberTest.cpp index 98931efb30..0884cdf5fa 100644 --- a/src/Plugins/ComplexCore/test/ErodeDilateCoordinationNumberTest.cpp +++ b/src/Plugins/ComplexCore/test/ErodeDilateCoordinationNumberTest.cpp @@ -29,8 +29,7 @@ const DataPath k_ErodeCellAttributeMatrixDataPath = DataPath({k_ExemplarDataCont TEST_CASE("ComplexCore::ErodeDilateCoordinationNumberFilter", "[ComplexCore][ErodeDilateCoordinationNumberFilter]") { - std::shared_ptr app = std::make_shared(); - app->loadPlugins(unit_test::k_BuildDir.view(), true); + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_erode_dilate_test.tar.gz", "6_6_erode_dilate_test"); diff --git a/src/Plugins/ComplexCore/test/ErodeDilateMaskTest.cpp b/src/Plugins/ComplexCore/test/ErodeDilateMaskTest.cpp index 5ed0505747..54115437ef 100644 --- a/src/Plugins/ComplexCore/test/ErodeDilateMaskTest.cpp +++ b/src/Plugins/ComplexCore/test/ErodeDilateMaskTest.cpp @@ -36,8 +36,7 @@ TEST_CASE("ComplexCore::ErodeDilateMaskFilter(Dilate)", "[ComplexCore][ErodeDila const std::string k_ExemplarDataContainerName("Exemplar Mask Dilate"); const DataPath k_DilateCellAttributeMatrixDataPath = DataPath({k_ExemplarDataContainerName, "EBSD Scan Data"}); - std::shared_ptr app = std::make_shared(); - app->loadPlugins(unit_test::k_BuildDir.view(), true); + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); // Read Exemplar DREAM3D File Filter auto exemplarFilePath = fs::path(fmt::format("{}/6_6_erode_dilate_test/6_6_erode_dilate_mask.dream3d", unit_test::k_TestFilesDir)); @@ -76,8 +75,7 @@ TEST_CASE("ComplexCore::ErodeDilateMaskFilter(Erode)", "[ComplexCore][ErodeDilat const std::string k_ExemplarDataContainerName("Exemplar Mask Erode"); const DataPath k_ErodeCellAttributeMatrixDataPath = DataPath({k_ExemplarDataContainerName, "EBSD Scan Data"}); - std::shared_ptr app = std::make_shared(); - app->loadPlugins(unit_test::k_BuildDir.view(), true); + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); // Read Exemplar DREAM3D File Filter auto exemplarFilePath = fs::path(fmt::format("{}/6_6_erode_dilate_test/6_6_erode_dilate_mask.dream3d", unit_test::k_TestFilesDir)); diff --git a/src/Plugins/ComplexCore/test/ExtractComponentAsArrayTest.cpp b/src/Plugins/ComplexCore/test/ExtractComponentAsArrayTest.cpp index ed4b01918a..1d201b7daa 100644 --- a/src/Plugins/ComplexCore/test/ExtractComponentAsArrayTest.cpp +++ b/src/Plugins/ComplexCore/test/ExtractComponentAsArrayTest.cpp @@ -22,6 +22,8 @@ const fs::path k_BaseDataFilePath = fs::path(fmt::format("{}/6_6_find_feature_ce TEST_CASE("ComplexCore::ExtractComponentAsArrayFilter: Valid filter execution", "[ComplexCore][ExtractComponentAsArrayFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + // Instantiate the filter, a DataStructure object and an Arguments Object ExtractComponentAsArrayFilter filter; @@ -93,6 +95,8 @@ TEST_CASE("ComplexCore::ExtractComponentAsArrayFilter: Valid filter execution", TEST_CASE("ComplexCore::ExtractComponentAsArrayFilter: InValid filter execution", "[ComplexCore][ExtractComponentAsArrayFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_find_feature_centroids.tar.gz", "6_6_find_feature_centroids.dream3d"); diff --git a/src/Plugins/ComplexCore/test/FindArrayStatisticsTest.cpp b/src/Plugins/ComplexCore/test/FindArrayStatisticsTest.cpp index 702ce9919e..2ba4aceab4 100644 --- a/src/Plugins/ComplexCore/test/FindArrayStatisticsTest.cpp +++ b/src/Plugins/ComplexCore/test/FindArrayStatisticsTest.cpp @@ -21,6 +21,8 @@ bool VectorContains(const std::vector& vector, T value) TEST_CASE("ComplexCore::FindArrayStatisticsFilter: Test Algorithm", "[ComplexCore][FindArrayStatisticsFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + DataStructure dataStructure; DataGroup* topLevelGroup = DataGroup::Create(dataStructure, "TestData"); DataPath statsDataPath({"TestData", "Statistics"}); @@ -175,7 +177,7 @@ TEST_CASE("ComplexCore::FindArrayStatisticsFilter: Test Algorithm", "[ComplexCor REQUIRE(std::fabs(sumVal - 129.0f) < UnitTest::EPSILON); REQUIRE(numUnique == 8); - const auto& standardizeDataStore = standardizeArray->getIDataStoreRefAs>(); + const auto& standardizeDataStore = standardizeArray->getDataStoreRef(); auto stand0 = std::ceil(standardizeDataStore[0] * 100.0f) / 100.0f; auto stand1 = std::ceil(standardizeDataStore[1] * 100.0f) / 100.0f; auto stand2 = standardizeDataStore[2]; // @@ -208,6 +210,8 @@ TEST_CASE("ComplexCore::FindArrayStatisticsFilter: Test Algorithm", "[ComplexCor TEST_CASE("ComplexCore::FindArrayStatisticsFilter: Test Algorithm By Index", "[ComplexCore][FindArrayStatisticsFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + DataStructure dataStructure; DataGroup* topLevelGroup = DataGroup::Create(dataStructure, "TestData"); DataPath statsDataPath({"TestData", "Statistics"}); @@ -429,7 +433,7 @@ TEST_CASE("ComplexCore::FindArrayStatisticsFilter: Test Algorithm By Index", "[C REQUIRE(std::fabs(sumVal3 - 64.0f) < UnitTest::EPSILON); REQUIRE(numUnique3 == 2); - const auto& standardizeDataStore = standardizeArray->getIDataStoreRefAs>(); + const auto& standardizeDataStore = standardizeArray->getDataStoreRef(); auto stand0 = standardizeDataStore[0]; auto stand1 = standardizeDataStore[1]; auto stand2 = standardizeDataStore[2]; diff --git a/src/Plugins/ComplexCore/test/FindSurfaceFeaturesTest.cpp b/src/Plugins/ComplexCore/test/FindSurfaceFeaturesTest.cpp index a7a82bf4d5..353e7fe250 100644 --- a/src/Plugins/ComplexCore/test/FindSurfaceFeaturesTest.cpp +++ b/src/Plugins/ComplexCore/test/FindSurfaceFeaturesTest.cpp @@ -25,6 +25,7 @@ const std::string k_SurfaceFeatures2DExemplaryFileName = "FindSurfaceFeaturesTes void test_impl(const std::vector& geometryDims, const std::string& featureIdsFileName, usize featureIdsSize, const std::string& exemplaryFileName) { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "FindSurfaceFeaturesTest.tar.gz", "FindSurfaceFeaturesTest"); // Instantiate the filter, a DataStructure object and an Arguments Object @@ -47,10 +48,10 @@ void test_impl(const std::vector& geometryDims, const std::string& featu rbrArgs.insertOrAssign(RawBinaryReaderFilter::k_CreatedAttributeArrayPath_Key, std::make_any(k_FeatureIDsPath)); result = rbrFilter.execute(dataStructure, rbrArgs); - COMPLEX_RESULT_REQUIRE_VALID(result.result) + COMPLEX_RESULT_REQUIRE_VALID(result.result); // Change Feature 470 to 0 - REQUIRE_NOTHROW(dataStructure.getDataRefAs(k_FeatureIDsPath)); + REQUIRE(dataStructure.getDataAs(k_FeatureIDsPath) != nullptr); Int32Array& featureIds = dataStructure.getDataRefAs(k_FeatureIDsPath); std::replace(featureIds.begin(), featureIds.end(), 470, 0); @@ -106,6 +107,7 @@ void test_impl(const std::vector& geometryDims, const std::string& featu TEST_CASE("ComplexCore::FindSurfaceFeatures: Valid filter execution in 3D", "[ComplexCore][FindSurfaceFeatures]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_5_test_data_1.tar.gz", "6_5_test_data_1"); // Read the Small IN100 Data set diff --git a/src/Plugins/ComplexCore/test/ImportHDF5DatasetTest.cpp b/src/Plugins/ComplexCore/test/ImportHDF5DatasetTest.cpp index 20674beeb0..1344c2556a 100644 --- a/src/Plugins/ComplexCore/test/ImportHDF5DatasetTest.cpp +++ b/src/Plugins/ComplexCore/test/ImportHDF5DatasetTest.cpp @@ -305,7 +305,7 @@ void DatasetTest(ImportHDF5Dataset& filter, const std::list(val)); + args.insertOrAssign(ImportHDF5Dataset::k_ImportHDF5File_Key, std::make_any(val)); // Execute Dataset Test if(dsetInfoList.size() > 1) diff --git a/src/Plugins/ComplexCore/test/PipelineTest.cpp b/src/Plugins/ComplexCore/test/PipelineTest.cpp index 4fb119b348..b78b89dbe0 100644 --- a/src/Plugins/ComplexCore/test/PipelineTest.cpp +++ b/src/Plugins/ComplexCore/test/PipelineTest.cpp @@ -108,17 +108,17 @@ class DeferredActionTestFilter : public IFilter TEST_CASE("PipelineTest:Execute Pipeline") { - Application app; - app.loadPlugins(unit_test::k_BuildDir.view()); - auto filterList = app.getFilterList(); + auto app = Application::GetOrCreateInstance(); + app->loadPlugins(unit_test::k_BuildDir.view()); + auto filterList = app->getFilterList(); - const AbstractPlugin* test1Plugin = app.getPlugin(k_Test1PluginId); + const AbstractPlugin* test1Plugin = app->getPlugin(k_Test1PluginId); REQUIRE(test1Plugin != nullptr); auto testFilter1 = filterList->createFilter(k_Test1FilterHandle); REQUIRE(testFilter1 != nullptr); FilterHandle tf1Handle(testFilter1->uuid(), test1Plugin->getId()); - const AbstractPlugin* test2Plugin = app.getPlugin(k_Test2PluginId); + const AbstractPlugin* test2Plugin = app->getPlugin(k_Test2PluginId); REQUIRE(test2Plugin != nullptr); auto testFilter2 = filterList->createFilter(k_Test2FilterHandle); REQUIRE(testFilter2 != nullptr); @@ -156,13 +156,13 @@ TEST_CASE("PipelineTest:Execute Pipeline") TEST_CASE("PipelineTest:Complex Pipeline") { - Application app; - app.loadPlugins(unit_test::k_BuildDir.view()); + auto app = Application::GetOrCreateInstance(); + app->loadPlugins(unit_test::k_BuildDir.view()); - auto filterList = app.getFilterList(); + auto filterList = app->getFilterList(); REQUIRE(filterList->size() != 0); - const AbstractPlugin* test1Plugin = app.getPlugin(k_Test1PluginId); + const AbstractPlugin* test1Plugin = app->getPlugin(k_Test1PluginId); REQUIRE(test1Plugin != nullptr); auto testFilter1 = filterList->createFilter(k_Test1FilterHandle); @@ -210,8 +210,8 @@ TEST_CASE("PipelineTest:Complex Pipeline") TEST_CASE("PipelineTest:PipelineJson") { - Application app; - app.loadPlugins(unit_test::k_BuildDir.view()); + auto app = Application::GetOrCreateInstance(); + app->loadPlugins(unit_test::k_BuildDir.view()); Pipeline pipeline("test"); @@ -274,8 +274,8 @@ TEST_CASE("PipelineTest:PipelineJson") TEST_CASE("PipelineTest:Rename Output") { - Application app; - app.loadPlugins(unit_test::k_BuildDir.view()); + auto app = Application::GetOrCreateInstance(); + app->loadPlugins(unit_test::k_BuildDir.view()); std::string group1Name = "Foo"; std::string group2Name = "Bar"; @@ -317,8 +317,8 @@ TEST_CASE("PipelineTest:Rename Output") TEST_CASE("PipelineTest:Not Renaming") { - Application app; - app.loadPlugins(unit_test::k_BuildDir.view()); + auto app = Application::GetOrCreateInstance(); + app->loadPlugins(unit_test::k_BuildDir.view()); std::string group1Name = "Foo"; std::string group2Name = "Bar"; diff --git a/src/Plugins/ComplexCore/test/RawBinaryReaderTest.cpp b/src/Plugins/ComplexCore/test/RawBinaryReaderTest.cpp index e345d214e8..707102fec9 100644 --- a/src/Plugins/ComplexCore/test/RawBinaryReaderTest.cpp +++ b/src/Plugins/ComplexCore/test/RawBinaryReaderTest.cpp @@ -114,7 +114,7 @@ void TestCase1_Execute(NumericType scalarType) COMPLEX_RESULT_REQUIRE_VALID(executeResult.result); const DataArray& createdData = dataStructure.getDataRefAs>(k_CreatedArrayPath); - const DataStore& store = createdData.template getIDataStoreRefAs>(); + const AbstractDataStore& store = createdData.getDataStoreRef(); bool isSame = true; for(usize i = 0; i < dataArraySize; ++i) { @@ -246,16 +246,14 @@ void TestCase4_Execute(NumericType scalarType) DataArray* createdArray = dataStructure.getDataAs>(k_CreatedArrayPath); REQUIRE(createdArray != nullptr); - DataStore* createdStore = createdArray->template getIDataStoreAs>(); - REQUIRE(createdStore != nullptr); - T* createdData = createdStore->data(); + AbstractDataStore& createdStore = createdArray->getDataStoreRef(); constexpr usize elementOffset = skipHeaderBytes / sizeof(T); bool isSame = true; - usize size = createdStore->getSize(); + usize size = createdStore.getSize(); for(usize i = 0; i < size; ++i) { - if(createdData[i] != exemplaryData[i + elementOffset]) + if(createdStore[i] != exemplaryData[i + elementOffset]) { isSame = false; break; diff --git a/src/Plugins/ITKImageProcessing/src/ITKImageProcessing/Common/ITKArrayHelper.hpp b/src/Plugins/ITKImageProcessing/src/ITKImageProcessing/Common/ITKArrayHelper.hpp index 2bb4960393..36d505f83f 100644 --- a/src/Plugins/ITKImageProcessing/src/ITKImageProcessing/Common/ITKArrayHelper.hpp +++ b/src/Plugins/ITKImageProcessing/src/ITKImageProcessing/Common/ITKArrayHelper.hpp @@ -718,6 +718,11 @@ Result> Execute(DataStr using ResultT = detail::ITKFilterFunctorResult_t; + if(inputArray.getDataFormat() != "") + { + return MakeErrorResult(-9999, fmt::format("Input Array '{}' utilizes out-of-core data. This is not supported within ITK filters.", inputArrayPath.toString())); + } + try { return ArraySwitchFunc(inputDataStore, imageGeom, -1, inputDataStore, imageGeom, outputDataStore, shouldCancel, progressObserver, diff --git a/src/Plugins/ITKImageProcessing/src/ITKImageProcessing/Filters/ITKImageReader.cpp b/src/Plugins/ITKImageProcessing/src/ITKImageProcessing/Filters/ITKImageReader.cpp index 5ede77c9b9..5b3bff110b 100644 --- a/src/Plugins/ITKImageProcessing/src/ITKImageProcessing/Filters/ITKImageReader.cpp +++ b/src/Plugins/ITKImageProcessing/src/ITKImageProcessing/Filters/ITKImageReader.cpp @@ -320,6 +320,12 @@ Result<> ITKImageReader::executeImpl(DataStructure& dataStructure, const Argumen auto imageGeometryPath = filterArgs.value(k_ImageGeometryPath_Key); auto imageDataArrayPath = filterArgs.value(k_ImageDataArrayPath_Key); + const IDataArray* inputArray = dataStructure.getDataAs(imageDataArrayPath); + if(inputArray->getDataFormat() != "") + { + return MakeErrorResult(-9999, fmt::format("Input Array '{}' utilizes out-of-core data. This is not supported within ITK filters.", imageDataArrayPath.toString())); + } + std::string fileNameString = fileName.string(); ImageGeom& imageGeom = dataStructure.getDataRefAs(imageGeometryPath); diff --git a/src/Plugins/ITKImageProcessing/src/ITKImageProcessing/Filters/ITKImageWriter.cpp b/src/Plugins/ITKImageProcessing/src/ITKImageProcessing/Filters/ITKImageWriter.cpp index 8c15e3e6e3..0a9292de13 100644 --- a/src/Plugins/ITKImageProcessing/src/ITKImageProcessing/Filters/ITKImageWriter.cpp +++ b/src/Plugins/ITKImageProcessing/src/ITKImageProcessing/Filters/ITKImageWriter.cpp @@ -307,6 +307,12 @@ Result<> ITKImageWriter::executeImpl(DataStructure& dataStructure, const Argumen auto imageArrayPath = filterArgs.value(k_ImageArrayPath_Key); auto imageGeomPath = filterArgs.value(k_ImageGeomPath_Key); + const IDataArray* inputArray = dataStructure.getDataAs(imageArrayPath); + if(inputArray->getDataFormat() != "") + { + return MakeErrorResult(-9999, fmt::format("Input Array '{}' utilizes out-of-core data. This is not supported within ITK filters.", imageArrayPath.toString())); + } + const auto& imageGeom = dataStructure.getDataRefAs(imageGeomPath); // Stored fastest to slowest i.e. X Y Z SizeVec3 dims = imageGeom.getDimensions(); diff --git a/src/Plugins/ITKImageProcessing/test/ITKAbsImageTest.cpp b/src/Plugins/ITKImageProcessing/test/ITKAbsImageTest.cpp index aa9c0d49a5..302f040c7b 100644 --- a/src/Plugins/ITKImageProcessing/test/ITKAbsImageTest.cpp +++ b/src/Plugins/ITKImageProcessing/test/ITKAbsImageTest.cpp @@ -16,6 +16,8 @@ using namespace complex; TEST_CASE("ITKImageProcessing::ITKAbsImageFilter(float)", "[ITKImageProcessing][ITKAbsImage][float]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + DataStructure dataStructure; ITKAbsImage filter; @@ -52,6 +54,8 @@ TEST_CASE("ITKImageProcessing::ITKAbsImageFilter(float)", "[ITKImageProcessing][ TEST_CASE("ITKImageProcessing::ITKAbsImageFilter(short)", "[ITKImageProcessing][ITKAbsImage][short]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + DataStructure dataStructure; ITKAbsImage filter; diff --git a/src/Plugins/ITKImageProcessing/test/ITKAcosImageTest.cpp b/src/Plugins/ITKImageProcessing/test/ITKAcosImageTest.cpp index 5495867c82..6e674a26d4 100644 --- a/src/Plugins/ITKImageProcessing/test/ITKAcosImageTest.cpp +++ b/src/Plugins/ITKImageProcessing/test/ITKAcosImageTest.cpp @@ -15,6 +15,8 @@ using namespace complex; TEST_CASE("ITKImageProcessing::ITKAcosImageFilter(defaults)", "[ITKImageProcessing][ITKAcosImage][defaults]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + DataStructure dataStructure; ITKAcosImage filter; diff --git a/src/Plugins/ITKImageProcessing/test/ITKAdaptiveHistogramEqualizationImageTest.cpp b/src/Plugins/ITKImageProcessing/test/ITKAdaptiveHistogramEqualizationImageTest.cpp index 37cb5845ea..e50f21c2c4 100644 --- a/src/Plugins/ITKImageProcessing/test/ITKAdaptiveHistogramEqualizationImageTest.cpp +++ b/src/Plugins/ITKImageProcessing/test/ITKAdaptiveHistogramEqualizationImageTest.cpp @@ -23,7 +23,6 @@ using namespace complex; namespace ITKImageProcessingUnitTest { -std::shared_ptr app = std::make_shared(); bool s_PluginsLoaded = false; FilterList* s_FilterList = nullptr; @@ -31,7 +30,7 @@ void InitApplicationAndPlugins() { if(!s_PluginsLoaded) { - Application::Instance()->loadPlugins(unit_test::k_BuildDir.view(), true); + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); s_FilterList = Application::Instance()->getFilterList(); s_PluginsLoaded = true; } diff --git a/src/Plugins/ITKImageProcessing/test/ITKAsinImageTest.cpp b/src/Plugins/ITKImageProcessing/test/ITKAsinImageTest.cpp index 9b5da044b7..c176ba9a45 100644 --- a/src/Plugins/ITKImageProcessing/test/ITKAsinImageTest.cpp +++ b/src/Plugins/ITKImageProcessing/test/ITKAsinImageTest.cpp @@ -15,6 +15,8 @@ using namespace complex; TEST_CASE("ITKImageProcessing::ITKAsinImageFilter(defaults)", "[ITKImageProcessing][ITKAsinImage][defaults]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + DataStructure dataStructure; ITKAsinImage filter; diff --git a/src/Plugins/ITKImageProcessing/test/ITKAtanImageTest.cpp b/src/Plugins/ITKImageProcessing/test/ITKAtanImageTest.cpp index 8b23dec2cb..4bc0ab93fe 100644 --- a/src/Plugins/ITKImageProcessing/test/ITKAtanImageTest.cpp +++ b/src/Plugins/ITKImageProcessing/test/ITKAtanImageTest.cpp @@ -15,6 +15,8 @@ using namespace complex; TEST_CASE("ITKImageProcessing::ITKAtanImageFilter(defaults)", "[ITKImageProcessing][ITKAtanImage][defaults]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + DataStructure dataStructure; ITKAtanImage filter; diff --git a/src/Plugins/ITKImageProcessing/test/ITKBinaryContourImageTest.cpp b/src/Plugins/ITKImageProcessing/test/ITKBinaryContourImageTest.cpp index 81952baca2..f6de0139e0 100644 --- a/src/Plugins/ITKImageProcessing/test/ITKBinaryContourImageTest.cpp +++ b/src/Plugins/ITKImageProcessing/test/ITKBinaryContourImageTest.cpp @@ -19,6 +19,8 @@ using namespace complex; TEST_CASE("ITKImageProcessing::ITKBinaryContourImageFilter(default)", "[ITKImageProcessing][ITKBinaryContourImage][default]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + DataStructure dataStructure; ITKBinaryContourImage filter; @@ -51,6 +53,8 @@ TEST_CASE("ITKImageProcessing::ITKBinaryContourImageFilter(default)", "[ITKImage TEST_CASE("ITKImageProcessing::ITKBinaryContourImageFilter(custom)", "[ITKImageProcessing][ITKBinaryContourImage][custom]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + DataStructure dataStructure; ITKBinaryContourImage filter; diff --git a/src/Plugins/ITKImageProcessing/test/ITKBinaryDilateImageTest.cpp b/src/Plugins/ITKImageProcessing/test/ITKBinaryDilateImageTest.cpp index a3208c4365..9ed8b7e63e 100644 --- a/src/Plugins/ITKImageProcessing/test/ITKBinaryDilateImageTest.cpp +++ b/src/Plugins/ITKImageProcessing/test/ITKBinaryDilateImageTest.cpp @@ -21,6 +21,8 @@ using namespace complex::UnitTest; TEST_CASE("ITKImageProcessing::ITKBinaryDilateImageFilter(BinaryDilate)", "[ITKImageProcessing][ITKBinaryDilateImage][BinaryDilate]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + DataStructure dataStructure; const ITKBinaryDilateImage filter; @@ -55,6 +57,8 @@ TEST_CASE("ITKImageProcessing::ITKBinaryDilateImageFilter(BinaryDilate)", "[ITKI TEST_CASE("ITKImageProcessing::ITKBinaryDilateImageFilter(BinaryDilateVectorRadius)", "[ITKImageProcessing][ITKBinaryDilateImage][BinaryDilateVectorRadius]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + DataStructure dataStructure; const ITKBinaryDilateImage filter; diff --git a/src/Plugins/ITKImageProcessing/test/ITKDiscreteGaussianImageTest.cpp b/src/Plugins/ITKImageProcessing/test/ITKDiscreteGaussianImageTest.cpp index 79de86af65..4e6e25f3d6 100644 --- a/src/Plugins/ITKImageProcessing/test/ITKDiscreteGaussianImageTest.cpp +++ b/src/Plugins/ITKImageProcessing/test/ITKDiscreteGaussianImageTest.cpp @@ -20,6 +20,8 @@ using namespace complex::UnitTest; TEST_CASE("ITKImageProcessing::ITKDiscreteGaussianImageFilter(float)", "[ITKImageProcessing][ITKDiscreteGaussianImage][float]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + DataStructure dataStructure; const ITKDiscreteGaussianImage filter; @@ -56,6 +58,8 @@ TEST_CASE("ITKImageProcessing::ITKDiscreteGaussianImageFilter(float)", "[ITKImag TEST_CASE("ITKImageProcessing::ITKDiscreteGaussianImageFilter(short)", "[ITKImageProcessing][ITKDiscreteGaussianImage][short]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + DataStructure dataStructure; const ITKDiscreteGaussianImage filter; @@ -92,6 +96,8 @@ TEST_CASE("ITKImageProcessing::ITKDiscreteGaussianImageFilter(short)", "[ITKImag TEST_CASE("ITKImageProcessing::ITKDiscreteGaussianImageFilter(bigG)", "[ITKImageProcessing][ITKDiscreteGaussianImage][bigG]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + DataStructure dataStructure; const ITKDiscreteGaussianImage filter; diff --git a/src/Plugins/ITKImageProcessing/test/ITKImageWriterTest.cpp b/src/Plugins/ITKImageProcessing/test/ITKImageWriterTest.cpp index 1386dad22b..94e11dd918 100644 --- a/src/Plugins/ITKImageProcessing/test/ITKImageWriterTest.cpp +++ b/src/Plugins/ITKImageProcessing/test/ITKImageWriterTest.cpp @@ -74,7 +74,7 @@ void validateOutputFiles(size_t numImages, uint64 offset, const std::string& tem TEST_CASE("ITKImageProcessing::ITKImageWriter: Write Stack", "[ITKImageProcessing][ITKImageWriter]") { - Application app; + auto app = Application::GetOrCreateInstance(); DataStructure dataStructure; { ITKImportImageStack filter; diff --git a/src/Plugins/ITKImageProcessing/test/ITKImportFijiMontageTest.cpp b/src/Plugins/ITKImageProcessing/test/ITKImportFijiMontageTest.cpp index 97103aed09..639f283f75 100644 --- a/src/Plugins/ITKImageProcessing/test/ITKImportFijiMontageTest.cpp +++ b/src/Plugins/ITKImageProcessing/test/ITKImportFijiMontageTest.cpp @@ -29,7 +29,7 @@ TEST_CASE("ITKImageProcessing::ITKImportFijiMontage: Basic 2x2 Grid Montage", "[ { const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "fiji_montage_test.tar.gz", "fiji_montage_test"); - std::shared_ptr app = std::make_shared(); + auto app = Application::GetOrCreateInstance(); app->loadPlugins(unit_test::k_BuildDir.view(), true); DataStructure exemplarDataStructure = UnitTest::LoadDataStructure(fs::path(fmt::format("{}/fiji_montage_test/2x2_fiji_montage_test.dream3d", unit_test::k_TestFilesDir))); diff --git a/src/Plugins/ITKImageProcessing/test/ITKMhaFileReaderTest.cpp b/src/Plugins/ITKImageProcessing/test/ITKMhaFileReaderTest.cpp index 09a10e9863..15c411e25a 100644 --- a/src/Plugins/ITKImageProcessing/test/ITKMhaFileReaderTest.cpp +++ b/src/Plugins/ITKImageProcessing/test/ITKMhaFileReaderTest.cpp @@ -17,8 +17,7 @@ TEST_CASE("ITKImageProcessing::ITKMhaFileReader: Read 2D & 3D Image Data", "[ITK const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "ITKMhaFileReaderTest_rev2.tar.gz", "ITKMhaFileReaderTest"); // Load plugins (this is needed because ITKMhaFileReader needs access to the ComplexCore plugin) - const std::shared_ptr app = std::make_shared(); - app->loadPlugins(unit_test::k_BuildDir.view(), true); + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); // Test reading 2D & 3D image data const fs::path exemplaryFilePath = fs::path(unit_test::k_TestFilesDir.view()) / "ITKMhaFileReaderTest/ExemplarySmallIN100.dream3d"; diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/FindKernelAvgMisorientations.cpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/FindKernelAvgMisorientations.cpp index f378e0af98..c0a41c7762 100644 --- a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/FindKernelAvgMisorientations.cpp +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/FindKernelAvgMisorientations.cpp @@ -208,9 +208,16 @@ Result<> FindKernelAvgMisorientations::operator()() // set up threadsafe messenger m_TotalElements = udims[2] * udims[1] * udims[0]; + typename IParallelAlgorithm::AlgorithmArrays algArrays; + algArrays.push_back(m_DataStructure.getDataAs(m_InputValues->CellPhasesArrayPath)); + algArrays.push_back(m_DataStructure.getDataAs(m_InputValues->CrystalStructuresArrayPath)); + algArrays.push_back(m_DataStructure.getDataAs(m_InputValues->FeatureIdsArrayPath)); + algArrays.push_back(m_DataStructure.getDataAs(m_InputValues->KernelAverageMisorientationsArrayName)); + algArrays.push_back(m_DataStructure.getDataAs(m_InputValues->QuatsArrayPath)); + ParallelData3DAlgorithm parallelAlgorithm; parallelAlgorithm.setRange(Range3D(0, udims[0], 0, udims[1], 0, udims[2])); - parallelAlgorithm.setParallelizationEnabled(true); + parallelAlgorithm.requireArraysInMemory(algArrays); parallelAlgorithm.execute(FindKernelAvgMisorientationsImpl(this, m_DataStructure, m_InputValues, m_ShouldCancel)); return {}; diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/GenerateFaceIPFColoring.cpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/GenerateFaceIPFColoring.cpp index add05beee6..6bbfed727f 100644 --- a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/GenerateFaceIPFColoring.cpp +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/GenerateFaceIPFColoring.cpp @@ -183,8 +183,17 @@ Result<> GenerateFaceIPFColoring::operator()() auto& faceIpfColors = m_DataStructure.getDataRefAs(faceIpfColorsArrayPath); int64 numTriangles = faceLabels.getNumberOfTuples(); + typename IParallelAlgorithm::AlgorithmArrays algArrays; + algArrays.push_back(&faceLabels); + algArrays.push_back(&faceNormals); + algArrays.push_back(&eulerAngles); + algArrays.push_back(&phases); + algArrays.push_back(&crystalStructures); + algArrays.push_back(&faceIpfColors); + ParallelDataAlgorithm parallelTask; parallelTask.setRange(0, numTriangles); + parallelTask.requireArraysInMemory(algArrays); parallelTask.execute(CalculateFaceIPFColorsImpl(faceLabels, phases, faceNormals, eulerAngles, crystalStructures, faceIpfColors)); return {}; diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/GenerateGBCDPoleFigure.cpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/GenerateGBCDPoleFigure.cpp index 224c8b8031..4101b2e067 100644 --- a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/GenerateGBCDPoleFigure.cpp +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/GenerateGBCDPoleFigure.cpp @@ -324,9 +324,14 @@ Result<> GenerateGBCDPoleFigure::operator()() m_MessageHandler({IFilter::Message::Type::Info, fmt::format("Generating Intensity Plot for phase {}", m_InputValues->PhaseOfInterest)}); + typename IParallelAlgorithm::AlgorithmArrays algArrays; + algArrays.push_back(&poleFigure); + algArrays.push_back(&gbcd); + ParallelData2DAlgorithm dataAlg; dataAlg.setRange(0, xPoints, 0, yPoints); - dataAlg.setParallelizationEnabled(true); + dataAlg.requireArraysInMemory(algArrays); + dataAlg.execute( GenerateGBCDPoleFigureImpl(poleFigure, {xPoints, yPoints}, orientOps, gbcdDeltas, gbcdLimits, gbcdSizes, gbcd, m_InputValues->PhaseOfInterest, m_InputValues->MisorientationRotation)); diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/GenerateIPFColors.cpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/GenerateIPFColors.cpp index 85c2717e68..b32a496241 100644 --- a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/GenerateIPFColors.cpp +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/GenerateIPFColors.cpp @@ -27,12 +27,12 @@ class GenerateIPFColorsImpl const complex::IDataArray* goodVoxels, complex::UInt8Array& colors) : m_Filter(filter) , m_ReferenceDir(referenceDir) - , m_CellEulerAngles(eulers) - , m_CellPhases(phases) - , m_CrystalStructures(crystalStructures) + , m_CellEulerAngles(eulers.getDataStoreRef()) + , m_CellPhases(phases.getDataStoreRef()) + , m_CrystalStructures(crystalStructures.getDataStoreRef()) , m_NumPhases(numPhases) , m_GoodVoxels(goodVoxels) - , m_CellIPFColors(colors) + , m_CellIPFColors(colors.getDataStoreRef()) { } @@ -59,12 +59,12 @@ class GenerateIPFColorsImpl { phase = m_CellPhases[i]; index = i * 3; - m_CellIPFColors[index] = 0; - m_CellIPFColors[index + 1] = 0; - m_CellIPFColors[index + 2] = 0; - dEuler[0] = m_CellEulerAngles[index]; - dEuler[1] = m_CellEulerAngles[index + 1]; - dEuler[2] = m_CellEulerAngles[index + 2]; + m_CellIPFColors.setValue(index, 0); + m_CellIPFColors.setValue(index + 1, 0); + m_CellIPFColors.setValue(index + 2, 0); + dEuler[0] = m_CellEulerAngles.getValue(index); + dEuler[1] = m_CellEulerAngles.getValue(index + 1); + dEuler[2] = m_CellEulerAngles.getValue(index + 2); // Make sure we are using a valid Euler Angles with valid crystal symmetry calcIPF = true; @@ -81,9 +81,9 @@ class GenerateIPFColorsImpl if(phase < m_NumPhases && calcIPF && m_CrystalStructures[phase] < EbsdLib::CrystalStructure::LaueGroupEnd) { argb = ops[m_CrystalStructures[phase]]->generateIPFColor(dEuler.data(), refDir.data(), false); - m_CellIPFColors[index] = static_cast(complex::RgbColor::dRed(argb)); - m_CellIPFColors[index + 1] = static_cast(complex::RgbColor::dGreen(argb)); - m_CellIPFColors[index + 2] = static_cast(complex::RgbColor::dBlue(argb)); + m_CellIPFColors.setValue(index, static_cast(complex::RgbColor::dRed(argb))); + m_CellIPFColors.setValue(index + 1, static_cast(complex::RgbColor::dGreen(argb))); + m_CellIPFColors.setValue(index + 2, static_cast(complex::RgbColor::dBlue(argb))); } } } @@ -115,12 +115,12 @@ class GenerateIPFColorsImpl private: GenerateIPFColors* m_Filter = nullptr; FloatVec3Type m_ReferenceDir; - complex::Float32Array& m_CellEulerAngles; - complex::Int32Array& m_CellPhases; - complex::UInt32Array& m_CrystalStructures; + complex::Float32AbstractDataStore& m_CellEulerAngles; + complex::Int32AbstractDataStore& m_CellPhases; + complex::UInt32AbstractDataStore& m_CrystalStructures; int32_t m_NumPhases = 0; const complex::IDataArray* m_GoodVoxels = nullptr; - complex::UInt8Array& m_CellIPFColors; + complex::UInt8AbstractDataStore& m_CellIPFColors; }; } // namespace @@ -159,14 +159,24 @@ Result<> GenerateIPFColors::operator()() MatrixMath::Normalize3x1(normRefDir[0], normRefDir[1], normRefDir[2]); + typename IParallelAlgorithm::AlgorithmArrays algArrays; + algArrays.push_back(&eulers); + algArrays.push_back(&phases); + algArrays.push_back(&crystalStructures); + algArrays.push_back(&ipfColors); + complex::IDataArray* goodVoxelsArray = nullptr; if(m_InputValues->useGoodVoxels) { goodVoxelsArray = m_DataStructure.getDataAs(m_InputValues->goodVoxelsArrayPath); + algArrays.push_back(goodVoxelsArray); } + // Allow data-based parallelization ParallelDataAlgorithm dataAlg; dataAlg.setRange(0, totalPoints); + dataAlg.requireArraysInMemory(algArrays); + dataAlg.execute(GenerateIPFColorsImpl(this, normRefDir, eulers, phases, crystalStructures, numPhases, goodVoxelsArray, ipfColors)); if(m_PhaseWarningCount > 0) diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/GenerateFZQuaternions.cpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/GenerateFZQuaternions.cpp index af958af029..f4a25ec904 100644 --- a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/GenerateFZQuaternions.cpp +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/GenerateFZQuaternions.cpp @@ -264,10 +264,21 @@ Result<> GenerateFZQuaternions::executeImpl(DataStructure& dataStructure, const std::atomic_int32_t warningCount = 0; int32_t numPhases = static_cast(xtalArray.getNumberOfTuples()); + typename IParallelAlgorithm::AlgorithmArrays algArrays; + algArrays.push_back(&phaseArray); + algArrays.push_back(&quatArray); + algArrays.push_back(&xtalArray); + algArrays.push_back(&fzQuatArray); + + if(pUseGoodVoxelsValue) + { + algArrays.push_back(maskArray); + } + // Parallel algorithm to find duplicate nodes ParallelDataAlgorithm dataAlg; dataAlg.setRange(0ULL, static_cast(quatArray.getNumberOfTuples())); - dataAlg.setParallelizationEnabled(false); + dataAlg.requireArraysInMemory(algArrays); if(pUseGoodVoxelsValue) { diff --git a/src/Plugins/OrientationAnalysis/test/AlignSectionsMisorientationTest.cpp b/src/Plugins/OrientationAnalysis/test/AlignSectionsMisorientationTest.cpp index e1921ab072..3f9d8c1261 100644 --- a/src/Plugins/OrientationAnalysis/test/AlignSectionsMisorientationTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/AlignSectionsMisorientationTest.cpp @@ -37,6 +37,7 @@ using namespace complex::UnitTest; TEST_CASE("OrientationAnalysis::AlignSectionsMisorientation Small IN100 Pipeline", "[OrientationAnalysis][AlignSectionsMisorientation]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_align_sections_misorientation.tar.gz", "6_6_align_sections_misorientation.dream3d"); @@ -51,8 +52,7 @@ TEST_CASE("OrientationAnalysis::AlignSectionsMisorientation Small IN100 Pipeline // would be responsible to create. const uint64_t millisFromEpoch = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); - std::shared_ptr app = std::make_shared(); - app->loadPlugins(unit_test::k_BuildDir.view(), true); + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); auto* filterList = Application::Instance()->getFilterList(); const DataPath k_ExemplarShiftsPath = k_DataContainerPath.createChildPath("Exemplar Shifts"); diff --git a/src/Plugins/OrientationAnalysis/test/AlignSectionsMutualInformationTest.cpp b/src/Plugins/OrientationAnalysis/test/AlignSectionsMutualInformationTest.cpp index 463e570857..2936e71715 100644 --- a/src/Plugins/OrientationAnalysis/test/AlignSectionsMutualInformationTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/AlignSectionsMutualInformationTest.cpp @@ -21,6 +21,7 @@ using namespace complex::UnitTest; TEST_CASE("OrientationAnalysis::AlignSectionsMutualInformationFilter: Valid filter execution") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_5_align_sections_mutual_information.tar.gz", "6_5_align_sections_mutual_information"); @@ -29,8 +30,7 @@ TEST_CASE("OrientationAnalysis::AlignSectionsMutualInformationFilter: Valid filt // would be responsible to create. const uint64_t millisFromEpoch = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); - std::shared_ptr app = std::make_shared(); - app->loadPlugins(unit_test::k_BuildDir.view(), true); + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); auto* filterList = Application::Instance()->getFilterList(); const DataPath k_ExemplarShiftsPath = k_ExemplarDataContainerPath.createChildPath("Exemplar Shifts"); @@ -153,6 +153,7 @@ TEST_CASE("OrientationAnalysis::AlignSectionsMutualInformationFilter: Valid filt TEST_CASE("OrientationAnalysis::AlignSectionsMutualInformationFilter: InValid filter execution") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_stats_test.tar.gz", "6_6_stats_test.dream3d"); // Read the Small IN100 Data set diff --git a/src/Plugins/OrientationAnalysis/test/BadDataNeighborOrientationCheckTest.cpp b/src/Plugins/OrientationAnalysis/test/BadDataNeighborOrientationCheckTest.cpp index da48d8394e..325ef8f6d1 100644 --- a/src/Plugins/OrientationAnalysis/test/BadDataNeighborOrientationCheckTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/BadDataNeighborOrientationCheckTest.cpp @@ -34,13 +34,13 @@ using namespace complex::UnitTest; TEST_CASE("OrientationAnalysis::BadDataNeighborOrientationCheckFilter: Small IN100 Pipeline", "[OrientationAnalysis][BadDataNeighborOrientationCheckFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "bad_data_neighbor_orientation_check.tar.gz", "bad_data_neighbor_orientation_check.dream3d"); const complex::UnitTest::TestFileSentinel testDataSentinel1(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "Small_IN100_dream3d.tar.gz", "Small_IN100.dream3d"); - std::shared_ptr app = std::make_shared(); - app->loadPlugins(unit_test::k_BuildDir.view(), true); + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); auto* filterList = Application::Instance()->getFilterList(); // Read Exemplar DREAM3D File Filter diff --git a/src/Plugins/OrientationAnalysis/test/CAxisSegmentFeaturesTest.cpp b/src/Plugins/OrientationAnalysis/test/CAxisSegmentFeaturesTest.cpp index fa682bceba..9bdbed4c96 100644 --- a/src/Plugins/OrientationAnalysis/test/CAxisSegmentFeaturesTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/CAxisSegmentFeaturesTest.cpp @@ -20,6 +20,7 @@ const std::string k_ComputedCellFeatureData = "NX_CellFeatureData"; TEST_CASE("OrientationAnalysis::CAxisSegmentFeaturesFilter: Valid Filter Execution", "[OrientationAnalysis][CAxisSegmentFeaturesFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_caxis_data.tar.gz", "6_6_caxis_data"); // Read Exemplar DREAM3D File Filter @@ -68,6 +69,7 @@ TEST_CASE("OrientationAnalysis::CAxisSegmentFeaturesFilter: Valid Filter Executi TEST_CASE("OrientationAnalysis::CAxisSegmentFeaturesFilter: Invalid Filter Execution", "[OrientationAnalysis][CAxisSegmentFeaturesFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_caxis_data.tar.gz", "6_6_caxis_data"); // Read Exemplar DREAM3D File Filter diff --git a/src/Plugins/OrientationAnalysis/test/CMakeLists.txt b/src/Plugins/OrientationAnalysis/test/CMakeLists.txt index 3d96ac3716..b9ea548532 100644 --- a/src/Plugins/OrientationAnalysis/test/CMakeLists.txt +++ b/src/Plugins/OrientationAnalysis/test/CMakeLists.txt @@ -11,8 +11,8 @@ set(${PLUGIN_NAME}UnitTest_SRCS BadDataNeighborOrientationCheckTest.cpp CAxisSegmentFeaturesTest.cpp ConvertHexGridToSquareGridTest.cpp - ConvertQuaternionTest.cpp ConvertOrientationsTest.cpp + ConvertQuaternionTest.cpp CreateEnsembleInfoTest.cpp EBSDSegmentFeaturesFilterTest.cpp EbsdToH5EbsdTest.cpp @@ -65,7 +65,6 @@ set(DISABLED_TESTS INLWriterTest.cpp # ImportEbsdMontageTest.cpp # MISSING 1 or more Parameter Implementations - ReplaceElementAttributesWithNeighborValuesTest.cpp Stereographic3DTest.cpp ) @@ -82,35 +81,34 @@ create_complex_plugin_unit_test(PLUGIN_NAME ${PLUGIN_NAME} # If there are additional source files that need to be compiled for this plugin # can use the target_sources(...) cmake call target_sources(${PLUGIN_NAME}UnitTest -# PUBLIC -# additional header files -PRIVATE -${CMAKE_CURRENT_LIST_DIR}/${PLUGIN_NAME}TestUtils.hpp + + # PUBLIC + # additional header files + PRIVATE + ${CMAKE_CURRENT_LIST_DIR}/${PLUGIN_NAME}TestUtils.hpp ) # ------------------------------------------------------------------------------ # If there are additional include directories that are needed for this plugin # you can use the target_include_directories(.....) cmake call # target_include_directories(${PLUGIN_NAME}UnitTest -# PUBLIC -# ${CMAKE_CURRENT_LIST_DIR}/../../src +# PUBLIC +# ${CMAKE_CURRENT_LIST_DIR}/../../src # ) - # ----------------------------------------------------------------------------- # Here we are going to setup to download and decompress the test files. In order # to add your own test files you will need to tar.gz the test file, compute the -# SHA 512 Hash of the file and then upload the file to +# SHA 512 Hash of the file and then upload the file to # https://github.com/BlueQuartzSoftware/complex/releases/tag/Data_Archive. # # Go to the web site above, "edit" the release, add the filename and SHA 512 to # the table and then upload your compressed file. # Save the release so that the repo is updated # ----------------------------------------------------------------------------- - option(COMPLEX_DOWNLOAD_TEST_FILES "Download the test files" ON) -if(EXISTS "${DREAM3D_DATA_DIR}" AND COMPLEX_DOWNLOAD_TEST_FILES) +if(EXISTS "${DREAM3D_DATA_DIR}" AND COMPLEX_DOWNLOAD_TEST_FILES) if(NOT EXISTS ${DREAM3D_DATA_DIR}/TestFiles/) file(MAKE_DIRECTORY "${DREAM3D_DATA_DIR}/TestFiles/") endif() @@ -151,17 +149,18 @@ set(TEST_PIPELINE_LIST_FILE ${${PLUGIN_NAME}_BINARY_DIR}/PrebuiltPipelineTests/n FILE(WRITE ${TEST_PIPELINE_LIST_FILE} "Prebuilt Pipeline Tests\n") get_target_property(PIPELINE_RUNNER_NAME nxrunner NAME) get_target_property(PIPELINE_RUNNER_DEBUG nxrunner DEBUG_POSTFIX) + # message(STATUS "PIPELINE_RUNNER_NAME: ${PIPELINE_RUNNER_NAME}") # message(STATUS "PIPELINE_RUNNER_DEBUG: ${PIPELINE_RUNNER_DEBUG}") -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ # This function creates a CTest for a given pipeiline file. -# PLUGIN_NAME: Name of the plugin: Typically you can use ${PLUGIN_NAME} -# PIPELINE_PATH: The absolute path to the pipeline file -# TEST_INDEX: The numerical test index. This can be reset for each plugin -# DELETE_FILE_LIST: The list of files that should be deleted from the system -# after the test is run -#------------------------------------------------------------------------------ +# PLUGIN_NAME: Name of the plugin: Typically you can use ${PLUGIN_NAME} +# PIPELINE_PATH: The absolute path to the pipeline file +# TEST_INDEX: The numerical test index. This can be reset for each plugin +# DELETE_FILE_LIST: The list of files that should be deleted from the system +# after the test is run +# ------------------------------------------------------------------------------ function(add_pipeline_test) set(optionsArgs) set(oneValueArgs PLUGIN_NAME PIPELINE_PATH TEST_INDEX) @@ -171,17 +170,20 @@ function(add_pipeline_test) set(TEST_SCRIPT_FILE_EXT "sh") set(EXE_EXT "") set(RM_COMMAND "rm") + if(WIN32) set(TEST_SCRIPT_FILE_EXT "bat") set(EXE_EXT ".exe") set(RM_COMMAND "del") endif() + set(PREBUILT_SUPPORT_DIR "${${PLUGIN_NAME}_SOURCE_DIR}") FILE(APPEND ${TEST_PIPELINE_LIST_FILE} "[${ARGS_TEST_INDEX}]:${ARGS_PIPELINE_PATH}\n") get_filename_component(test "${ARGS_PIPELINE_PATH}" NAME) set(COMPLEX_CTEST_TEST_DRIVER "${${PLUGIN_NAME}_BINARY_DIR}/PrebuiltPipelineTests/${test}.${TEST_SCRIPT_FILE_EXT}") + # message(STATUS "==> ${COMPLEX_CTEST_TEST_DRIVER}") set(DELETE_FILE_COMMANDS "") @@ -198,27 +200,32 @@ function(add_pipeline_test) set(DATA_DEST_DIR "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CX_CONFIG_DIR}/") endif() - foreach ( f ${ARGS_DELETE_FILE_LIST}) + foreach(f ${ARGS_DELETE_FILE_LIST}) set(abs_file_path ${DATA_DEST_DIR}${f}) + if(WIN32) file(TO_NATIVE_PATH ${abs_file_path} abs_file_path) endif() + set(DELETE_FILE_COMMANDS "${DELETE_FILE_COMMANDS}echo Deleting Input file '${abs_file_path}'\n${RM_COMMAND} \"${abs_file_path}\"\n") FILE(APPEND ${TEST_PIPELINE_LIST_FILE} " [DELETES FILE]:${abs_file_path}\n") endforeach() -#------------------------------------------------------------------------------ -# Set up the checks for the input files. -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ + # Set up the checks for the input files. + # ------------------------------------------------------------------------------ set(INPUT_FILE_COMMANDS "") - foreach ( f ${ARGS_INPUT_FILE_LIST}) + + foreach(f ${ARGS_INPUT_FILE_LIST}) set(abs_file_path ${DATA_DEST_DIR}${f}) + if(WIN32) file(TO_NATIVE_PATH ${abs_file_path} abs_file_path) endif() + if(WIN32) - set(INPUT_FILE_COMMANDS -"${INPUT_FILE_COMMANDS}echo \"Checking Input file '${abs_file_path}'\" + set(INPUT_FILE_COMMANDS + "${INPUT_FILE_COMMANDS}echo \"Checking Input file '${abs_file_path}'\" if exist \"${abs_file_path}\" ( @echo \" Input file exists\" ) else ( @@ -227,8 +234,8 @@ if exist \"${abs_file_path}\" ( ) ") else() - set(INPUT_FILE_COMMANDS -"${INPUT_FILE_COMMANDS}echo \"Checking Input file '${abs_file_path}'\" + set(INPUT_FILE_COMMANDS + "${INPUT_FILE_COMMANDS}echo \"Checking Input file '${abs_file_path}'\" if [ -e \"${abs_file_path}\" ] then echo \" Input file exists\" @@ -237,20 +244,23 @@ else exit 1 fi ") - endif() - #FILE(APPEND ${TEST_PIPELINE_LIST_FILE} " [DELETES FILE]:${abs_file_path}\n") - endforeach() + endif() + # FILE(APPEND ${TEST_PIPELINE_LIST_FILE} " [DELETES FILE]:${abs_file_path}\n") + endforeach() set(OUTPUT_FILE_COMMANDS "") - foreach ( f ${ARGS_OUTPUT_FILE_LIST}) + + foreach(f ${ARGS_OUTPUT_FILE_LIST}) set(abs_file_path ${DATA_DEST_DIR}${f}) + if(WIN32) file(TO_NATIVE_PATH ${abs_file_path} abs_file_path) endif() + if(WIN32) - set(OUTPUT_FILE_COMMANDS -"${OUTPUT_FILE_COMMANDS}echo \"Checking output file '${abs_file_path}'\" + set(OUTPUT_FILE_COMMANDS + "${OUTPUT_FILE_COMMANDS}echo \"Checking output file '${abs_file_path}'\" if exist \"${abs_file_path}\" ( @echo \" Input file exists\" ) else ( @@ -259,8 +269,8 @@ if exist \"${abs_file_path}\" ( ) ") else() - set(OUTPUT_FILE_COMMANDS -"${OUTPUT_FILE_COMMANDS}echo \"Checking output file '${abs_file_path}'\" + set(OUTPUT_FILE_COMMANDS + "${OUTPUT_FILE_COMMANDS}echo \"Checking output file '${abs_file_path}'\" if [ -e \"${abs_file_path}\" ] then echo \" Output file exists\" @@ -269,101 +279,102 @@ else exit 1 fi ") - endif() - #FILE(APPEND ${TEST_PIPELINE_LIST_FILE} " [DELETES FILE]:${abs_file_path}\n") - endforeach() + endif() + # FILE(APPEND ${TEST_PIPELINE_LIST_FILE} " [DELETES FILE]:${abs_file_path}\n") + endforeach() - configure_file(${${PLUGIN_NAME}_SOURCE_DIR}/test/ctest_pipeline_driver.${TEST_SCRIPT_FILE_EXT} - "${COMPLEX_CTEST_TEST_DRIVER}" @ONLY) + configure_file(${${PLUGIN_NAME}_SOURCE_DIR}/test/ctest_pipeline_driver.${TEST_SCRIPT_FILE_EXT} + "${COMPLEX_CTEST_TEST_DRIVER}" @ONLY) string(REPLACE "/" "_" test "${test}") - add_test(NAME ${PLUGIN_NAME}_${ARGS_TEST_INDEX} COMMAND "${COMPLEX_CTEST_TEST_DRIVER}" ) + add_test(NAME ${PLUGIN_NAME}_${ARGS_TEST_INDEX} COMMAND "${COMPLEX_CTEST_TEST_DRIVER}") endfunction() -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ # Setup our Prebuilt reconstruction pipelines for the Small IN100 Test Data -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ set(test_index 0) add_pipeline_test(PLUGIN_NAME ${PLUGIN_NAME} - PIPELINE_PATH "${${PLUGIN_NAME}_SOURCE_DIR}/pipelines/EBSD Reconstruction/(01) Small IN100 Archive.d3dpipeline" - TEST_INDEX "${test_index}") + PIPELINE_PATH "${${PLUGIN_NAME}_SOURCE_DIR}/pipelines/EBSD Reconstruction/(01) Small IN100 Archive.d3dpipeline" + TEST_INDEX "${test_index}") math(EXPR test_index "${test_index} + 1") add_pipeline_test(PLUGIN_NAME ${PLUGIN_NAME} - PIPELINE_PATH "${${PLUGIN_NAME}_SOURCE_DIR}/pipelines/EBSD Reconstruction/(08) Small IN100 Full Reconstruction.d3dpipeline" - TEST_INDEX "${test_index}" - INPUT_FILE_LIST "Data/Output/Reconstruction/Small_IN100.h5ebsd" - OUTPUT_FILE_LIST "Data/Output/Reconstruction/SmallIN100_Final.dream3d" "Data/Output/Reconstruction/SmallIN100_Final.xdmf" - ) + PIPELINE_PATH "${${PLUGIN_NAME}_SOURCE_DIR}/pipelines/EBSD Reconstruction/(08) Small IN100 Full Reconstruction.d3dpipeline" + TEST_INDEX "${test_index}" + INPUT_FILE_LIST "Data/Output/Reconstruction/Small_IN100.h5ebsd" + OUTPUT_FILE_LIST "Data/Output/Reconstruction/SmallIN100_Final.dream3d" "Data/Output/Reconstruction/SmallIN100_Final.xdmf" +) math(EXPR test_index "${test_index} + 1") add_pipeline_test(PLUGIN_NAME ${PLUGIN_NAME} - PIPELINE_PATH "${${PLUGIN_NAME}_SOURCE_DIR}/pipelines/EBSD Statistics/(01) Small IN100 Morphological Statistics.d3dpipeline" - TEST_INDEX "${test_index}" - INPUT_FILE_LIST "Data/Output/Reconstruction/SmallIN100_Final.dream3d" - OUTPUT_FILE_LIST "Data/Output/Statistics/SmallIN100_Morph.dream3d" "Data/Output/Statistics/SmallIN100_Morph.xdmf" - DELETE_FILE_LIST "Data/Output/Reconstruction/SmallIN100_Final.dream3d" "Data/Output/Reconstruction/SmallIN100_Final.xdmf") + PIPELINE_PATH "${${PLUGIN_NAME}_SOURCE_DIR}/pipelines/EBSD Statistics/(01) Small IN100 Morphological Statistics.d3dpipeline" + TEST_INDEX "${test_index}" + INPUT_FILE_LIST "Data/Output/Reconstruction/SmallIN100_Final.dream3d" + OUTPUT_FILE_LIST "Data/Output/Statistics/SmallIN100_Morph.dream3d" "Data/Output/Statistics/SmallIN100_Morph.xdmf" + DELETE_FILE_LIST "Data/Output/Reconstruction/SmallIN100_Final.dream3d" "Data/Output/Reconstruction/SmallIN100_Final.xdmf") math(EXPR test_index "${test_index} + 1") add_pipeline_test(PLUGIN_NAME ${PLUGIN_NAME} - PIPELINE_PATH "${${PLUGIN_NAME}_SOURCE_DIR}/pipelines/EBSD Statistics/(05) Small IN100 Crystallographic Statistics.d3dpipeline" - TEST_INDEX "${test_index}" - INPUT_FILE_LIST "Data/Output/Statistics/SmallIN100_Morph.dream3d" - OUTPUT_FILE_LIST "Data/Output/Statistics/SmallIN100_CrystalStats.dream3d" "Data/Output/Statistics/SmallIN100_CrystalStats.xdmf" - DELETE_FILE_LIST "Data/Output/Statistics/SmallIN100_Morph.dream3d" "Data/Output/Statistics/SmallIN100_Morph.xdmf") + PIPELINE_PATH "${${PLUGIN_NAME}_SOURCE_DIR}/pipelines/EBSD Statistics/(05) Small IN100 Crystallographic Statistics.d3dpipeline" + TEST_INDEX "${test_index}" + INPUT_FILE_LIST "Data/Output/Statistics/SmallIN100_Morph.dream3d" + OUTPUT_FILE_LIST "Data/Output/Statistics/SmallIN100_CrystalStats.dream3d" "Data/Output/Statistics/SmallIN100_CrystalStats.xdmf" + DELETE_FILE_LIST "Data/Output/Statistics/SmallIN100_Morph.dream3d" "Data/Output/Statistics/SmallIN100_Morph.xdmf") math(EXPR test_index "${test_index} + 1") add_pipeline_test(PLUGIN_NAME ${PLUGIN_NAME} - PIPELINE_PATH "${${PLUGIN_NAME}_SOURCE_DIR}/pipelines/EBSD SurfaceMeshing/(01) Small IN100 Quick Mesh.d3dpipeline" - TEST_INDEX "${test_index}" - INPUT_FILE_LIST "Data/Output/Statistics/SmallIN100_CrystalStats.dream3d" - OUTPUT_FILE_LIST "Data/Output/SurfaceMesh/SmallIN100_Mesh.dream3d" "Data/Output/SurfaceMesh/SmallIN100_Mesh.xdmf" - DELETE_FILE_LIST "Data/Output/Statistics/SmallIN100_CrystalStats.dream3d" "Data/Output/Statistics/SmallIN100_CrystalStats.xdmf") - + PIPELINE_PATH "${${PLUGIN_NAME}_SOURCE_DIR}/pipelines/EBSD SurfaceMeshing/(01) Small IN100 Quick Mesh.d3dpipeline" + TEST_INDEX "${test_index}" + INPUT_FILE_LIST "Data/Output/Statistics/SmallIN100_CrystalStats.dream3d" + OUTPUT_FILE_LIST "Data/Output/SurfaceMesh/SmallIN100_Mesh.dream3d" "Data/Output/SurfaceMesh/SmallIN100_Mesh.xdmf" + DELETE_FILE_LIST "Data/Output/Statistics/SmallIN100_CrystalStats.dream3d" "Data/Output/Statistics/SmallIN100_CrystalStats.xdmf") + math(EXPR test_index "${test_index} + 1") add_pipeline_test(PLUGIN_NAME ${PLUGIN_NAME} - PIPELINE_PATH "${${PLUGIN_NAME}_SOURCE_DIR}/pipelines/EBSD SurfaceMeshing/(02) Small IN100 Smooth Mesh.d3dpipeline" - TEST_INDEX "${test_index}" - INPUT_FILE_LIST "Data/Output/SurfaceMesh/SmallIN100_Mesh.dream3d" - OUTPUT_FILE_LIST "Data/Output/SurfaceMesh/SmallIN100_Smoothed.dream3d" "Data/Output/SurfaceMesh/SmallIN100_Smoothed.xdmf" - DELETE_FILE_LIST "Data/Output/SurfaceMesh/SmallIN100_Mesh.dream3d" "Data/Output/SurfaceMesh/SmallIN100_Mesh.xdmf") - + PIPELINE_PATH "${${PLUGIN_NAME}_SOURCE_DIR}/pipelines/EBSD SurfaceMeshing/(02) Small IN100 Smooth Mesh.d3dpipeline" + TEST_INDEX "${test_index}" + INPUT_FILE_LIST "Data/Output/SurfaceMesh/SmallIN100_Mesh.dream3d" + OUTPUT_FILE_LIST "Data/Output/SurfaceMesh/SmallIN100_Smoothed.dream3d" "Data/Output/SurfaceMesh/SmallIN100_Smoothed.xdmf" + DELETE_FILE_LIST "Data/Output/SurfaceMesh/SmallIN100_Mesh.dream3d" "Data/Output/SurfaceMesh/SmallIN100_Mesh.xdmf") + math(EXPR test_index "${test_index} + 1") add_pipeline_test(PLUGIN_NAME ${PLUGIN_NAME} - PIPELINE_PATH "${${PLUGIN_NAME}_SOURCE_DIR}/pipelines/EBSD SurfaceMeshing/(03) Small IN100 Mesh Statistics.d3dpipeline" - TEST_INDEX "${test_index}" - INPUT_FILE_LIST "Data/Output/SurfaceMesh/SmallIN100_Smoothed.dream3d" - OUTPUT_FILE_LIST "Data/Output/SurfaceMesh/SmallIN100_MeshStats.dream3d" "Data/Output/SurfaceMesh/SmallIN100_MeshStats.xdmf" - DELETE_FILE_LIST "Data/Output/SurfaceMesh/SmallIN100_Smoothed.dream3d" "Data/Output/SurfaceMesh/SmallIN100_Smoothed.xdmf") + PIPELINE_PATH "${${PLUGIN_NAME}_SOURCE_DIR}/pipelines/EBSD SurfaceMeshing/(03) Small IN100 Mesh Statistics.d3dpipeline" + TEST_INDEX "${test_index}" + INPUT_FILE_LIST "Data/Output/SurfaceMesh/SmallIN100_Smoothed.dream3d" + OUTPUT_FILE_LIST "Data/Output/SurfaceMesh/SmallIN100_MeshStats.dream3d" "Data/Output/SurfaceMesh/SmallIN100_MeshStats.xdmf" + DELETE_FILE_LIST "Data/Output/SurfaceMesh/SmallIN100_Smoothed.dream3d" "Data/Output/SurfaceMesh/SmallIN100_Smoothed.xdmf") math(EXPR test_index "${test_index} + 1") add_pipeline_test(PLUGIN_NAME ${PLUGIN_NAME} - PIPELINE_PATH "${${PLUGIN_NAME}_SOURCE_DIR}/pipelines/EBSD SurfaceMeshing/(04) Small IN100 GBCD.d3dpipeline" - TEST_INDEX "${test_index}" - INPUT_FILE_LIST "Data/Output/SurfaceMesh/SmallIN100_MeshStats.dream3d" - OUTPUT_FILE_LIST "Data/Output/SurfaceMesh/SmallIN100_GBCD.dream3d" "Data/Output/SurfaceMesh/SmallIN100_GBCD.xdmf" - DELETE_FILE_LIST "Data/Output/SmallIN100GBCD/SmallIn100Triangles.ph" - "Data/Output/SmallIN100GBCD/SmallIn100GMT_1.dat" - ) + PIPELINE_PATH "${${PLUGIN_NAME}_SOURCE_DIR}/pipelines/EBSD SurfaceMeshing/(04) Small IN100 GBCD.d3dpipeline" + TEST_INDEX "${test_index}" + INPUT_FILE_LIST "Data/Output/SurfaceMesh/SmallIN100_MeshStats.dream3d" + OUTPUT_FILE_LIST "Data/Output/SurfaceMesh/SmallIN100_GBCD.dream3d" "Data/Output/SurfaceMesh/SmallIN100_GBCD.xdmf" + DELETE_FILE_LIST "Data/Output/SmallIN100GBCD/SmallIn100Triangles.ph" + "Data/Output/SmallIN100GBCD/SmallIn100GMT_1.dat" +) math(EXPR test_index "${test_index} + 1") add_pipeline_test(PLUGIN_NAME ${PLUGIN_NAME} - PIPELINE_PATH "${${PLUGIN_NAME}_SOURCE_DIR}/pipelines/EBSD SurfaceMeshing/(05) Small IN100 GBCD Metric.d3dpipeline" - TEST_INDEX "${test_index}" - INPUT_FILE_LIST "Data/Output/SurfaceMesh/SmallIN100_MeshStats.dream3d" - OUTPUT_FILE_LIST "Data/Output/SurfaceMesh/SmallIN100_GBCD_Metric.dream3d" "Data/Output/SurfaceMesh/SmallIN100_GBCD_Metric.xdmf" - DELETE_FILE_LIST "Data/Output/SurfaceMesh/SmallIN100_MeshStats.dream3d" - "Data/Output/SurfaceMesh/SmallIN100_MeshStats.xdmf" - "Data/Output/SurfaceMesh/7_0_small_in100_distribution_1.dat" - "Data/Output/SurfaceMesh/7_0_small_in100_distribution_errors_1.dat" - "Data/Output/SurfaceMesh/SmallIN100_GBCD_Metric.dream3d" - ) - -# These should be relative to the + PIPELINE_PATH "${${PLUGIN_NAME}_SOURCE_DIR}/pipelines/EBSD SurfaceMeshing/(05) Small IN100 GBCD Metric.d3dpipeline" + TEST_INDEX "${test_index}" + INPUT_FILE_LIST "Data/Output/SurfaceMesh/SmallIN100_MeshStats.dream3d" + OUTPUT_FILE_LIST "Data/Output/SurfaceMesh/SmallIN100_GBCD_Metric.dream3d" "Data/Output/SurfaceMesh/SmallIN100_GBCD_Metric.xdmf" + DELETE_FILE_LIST "Data/Output/SurfaceMesh/SmallIN100_MeshStats.dream3d" + "Data/Output/SurfaceMesh/SmallIN100_MeshStats.xdmf" + "Data/Output/SurfaceMesh/7_0_small_in100_distribution_1.dat" + "Data/Output/SurfaceMesh/7_0_small_in100_distribution_errors_1.dat" + "Data/Output/SurfaceMesh/SmallIN100_GBCD_Metric.dream3d" +) + +# These should be relative to the set(PREBUILT_PIPELINE_NAMES + # Example or other test pipelines - "${${PLUGIN_NAME}_SOURCE_DIR}/pipelines/AlignSectionsMutualInformation.d3dpipeline" # This example depends on the SmallIN100.h5ebsd file + "${${PLUGIN_NAME}_SOURCE_DIR}/pipelines/AlignSectionsMutualInformation.d3dpipeline" # This example depends on the SmallIN100.h5ebsd file "${${PLUGIN_NAME}_SOURCE_DIR}/pipelines/CI_Histogram.d3dpipeline" "${${PLUGIN_NAME}_SOURCE_DIR}/pipelines/EnsembleInfoReader.d3dpipeline" "${${PLUGIN_NAME}_SOURCE_DIR}/pipelines/ReadAng.d3dpipeline" diff --git a/src/Plugins/OrientationAnalysis/test/ConvertOrientationsTest.cpp b/src/Plugins/OrientationAnalysis/test/ConvertOrientationsTest.cpp index 7f431f5523..2256a4339c 100644 --- a/src/Plugins/OrientationAnalysis/test/ConvertOrientationsTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/ConvertOrientationsTest.cpp @@ -84,6 +84,8 @@ void _make_code() TEST_CASE("OrientationAnalysis::ConvertOrientations: Invalid preflight", "[OrientationAnalysis][ConvertOrientations]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + //------------------------------ // This code is commented out because it generates a bunch of code. See the comment // at the top of the _make_code function. This should stay in here in case it is diff --git a/src/Plugins/OrientationAnalysis/test/ConvertQuaternionTest.cpp b/src/Plugins/OrientationAnalysis/test/ConvertQuaternionTest.cpp index 1ecb9a2fdb..a0c541a24d 100644 --- a/src/Plugins/OrientationAnalysis/test/ConvertQuaternionTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/ConvertQuaternionTest.cpp @@ -25,6 +25,8 @@ constexpr ChoicesParameter::ValueType k_ToVectorScalar = 1; TEST_CASE("OrientationAnalysis::ConvertQuaternionFilter", "[OrientationAnalysis][ConvertQuaternionFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + DataStructure dataStructure; // Build up a simple Float32Array and place default data into the array diff --git a/src/Plugins/OrientationAnalysis/test/CreateEnsembleInfoTest.cpp b/src/Plugins/OrientationAnalysis/test/CreateEnsembleInfoTest.cpp index cc7d87b2db..02d25b1d04 100644 --- a/src/Plugins/OrientationAnalysis/test/CreateEnsembleInfoTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/CreateEnsembleInfoTest.cpp @@ -11,6 +11,8 @@ using namespace complex::UnitTest; TEST_CASE("OrientationAnalysis::CreateEnsembleInfoFilter: Invalid filter execution", "[OrientationAnalysis][CreateEnsembleInfoFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + // Instantiate the filter, a DataStructure object and an Arguments Object CreateEnsembleInfoFilter filter; DataStructure dataStructure; @@ -79,6 +81,8 @@ TEST_CASE("OrientationAnalysis::CreateEnsembleInfoFilter: Invalid filter executi TEST_CASE("OrientationAnalysis::CreateEnsembleInfoFilter: Valid filter execution", "[OrientationAnalysis][CreateEnsembleInfoFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "so3_cubic_high_ipf_001.tar.gz", "so3_cubic_high_ipf_001.dream3d"); diff --git a/src/Plugins/OrientationAnalysis/test/EBSDSegmentFeaturesFilterTest.cpp b/src/Plugins/OrientationAnalysis/test/EBSDSegmentFeaturesFilterTest.cpp index e6cbe0c976..100f527d43 100644 --- a/src/Plugins/OrientationAnalysis/test/EBSDSegmentFeaturesFilterTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/EBSDSegmentFeaturesFilterTest.cpp @@ -18,13 +18,14 @@ using namespace complex::Constants; TEST_CASE("OrientationAnalysis::EBSDSegmentFeatures: Valid Execution", "[OrientationAnalysis][EBSDSegmentFeatures]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_ebsd_segment_features.tar.gz", "6_6_ebsd_segment_features.dream3d"); const complex::UnitTest::TestFileSentinel testDataSentinel1(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "Small_IN100_dream3d.tar.gz", "Small_IN100.dream3d"); - std::shared_ptr app = std::make_shared(); - app->loadPlugins(unit_test::k_BuildDir.view(), true); + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); auto* filterList = Application::Instance()->getFilterList(); // Read Exemplar DREAM3D File Filter diff --git a/src/Plugins/OrientationAnalysis/test/EbsdToH5EbsdTest.cpp b/src/Plugins/OrientationAnalysis/test/EbsdToH5EbsdTest.cpp index 2164d9e085..f6530f8c95 100644 --- a/src/Plugins/OrientationAnalysis/test/EbsdToH5EbsdTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/EbsdToH5EbsdTest.cpp @@ -198,6 +198,8 @@ GeneratedFileListParameter::ValueType k_FileListInfo = {k_StartIndex, k_EndIndex TEST_CASE("OrientationAnalysis::EbsdToH5Ebsd", "[OrientationAnalysis][EbsdToH5Ebsd]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "Small_IN100.tar.gz", "Small_IN100"); const complex::UnitTest::TestFileSentinel testDataSentinel1(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_5_h5ebsd_exemplar.tar.gz", "6_5_h5ebsd_exemplar"); diff --git a/src/Plugins/OrientationAnalysis/test/EnsembleInfoReaderTest.cpp b/src/Plugins/OrientationAnalysis/test/EnsembleInfoReaderTest.cpp index ca11d7e758..51a15c818b 100644 --- a/src/Plugins/OrientationAnalysis/test/EnsembleInfoReaderTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/EnsembleInfoReaderTest.cpp @@ -32,6 +32,8 @@ void WriteTestFile(const std::string& filePath, const std::string& groups) TEST_CASE("OrientationAnalysis::EnsembleInfoReaderFilter: Valid Filter Execution", "[OrientationAnalysis][EnsembleInfoReaderFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + // Instantiate the filter, a DataStructure object and an Arguments Object EnsembleInfoReaderFilter filter; DataStructure ds; @@ -82,6 +84,8 @@ TEST_CASE("OrientationAnalysis::EnsembleInfoReaderFilter: Valid Filter Execution TEST_CASE("OrientationAnalysis::EnsembleInfoReaderFilter: InValid Filter Execution") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + // Instantiate the filter, a DataStructure object and an Arguments Object EnsembleInfoReaderFilter filter; DataStructure ds; diff --git a/src/Plugins/OrientationAnalysis/test/ExportGBCDGMTFileTest.cpp b/src/Plugins/OrientationAnalysis/test/ExportGBCDGMTFileTest.cpp index 26798af9b3..983d4de608 100644 --- a/src/Plugins/OrientationAnalysis/test/ExportGBCDGMTFileTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/ExportGBCDGMTFileTest.cpp @@ -43,8 +43,7 @@ TEST_CASE("OrientationAnalysis::ExportGBCDGMTFileFilter", "[OrientationAnalysis] { const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_Small_IN100_GBCD.tar.gz", "6_6_Small_IN100_GBCD"); - const std::shared_ptr app = std::make_shared(); - app->loadPlugins(unit_test::k_BuildDir.view(), true); + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); auto* filterList = Application::Instance()->getFilterList(); // Read the Small IN100 Data set diff --git a/src/Plugins/OrientationAnalysis/test/ExportGBCDTriangleDataTest.cpp b/src/Plugins/OrientationAnalysis/test/ExportGBCDTriangleDataTest.cpp index a5c274507b..96599a3f53 100644 --- a/src/Plugins/OrientationAnalysis/test/ExportGBCDTriangleDataTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/ExportGBCDTriangleDataTest.cpp @@ -45,8 +45,7 @@ TEST_CASE("OrientationAnalysis::ExportGBCDTriangleDataFilter: Valid filter execu { const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_Small_IN100_GBCD.tar.gz", "6_6_Small_IN100_GBCD"); - std::shared_ptr app = std::make_shared(); - app->loadPlugins(unit_test::k_BuildDir.view(), true); + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); auto* filterList = Application::Instance()->getFilterList(); // Read the Small IN100 Data set @@ -192,6 +191,8 @@ TEST_CASE("OrientationAnalysis::ExportGBCDTriangleDataFilter: Valid filter execu TEST_CASE("OrientationAnalysis::ExportGBCDTriangleDataFilter: InValid filter execution") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_Small_IN100_GBCD.tar.gz", "6_6_Small_IN100_GBCD"); // Instantiate the filter and an Arguments Object diff --git a/src/Plugins/OrientationAnalysis/test/FindAvgCAxesTest.cpp b/src/Plugins/OrientationAnalysis/test/FindAvgCAxesTest.cpp index 8379c5e550..24ee3228d0 100644 --- a/src/Plugins/OrientationAnalysis/test/FindAvgCAxesTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/FindAvgCAxesTest.cpp @@ -16,6 +16,8 @@ const std::string k_AvgCAxesComputed = "NX_AvgCAxes"; TEST_CASE("OrientationAnalysis::FindAvgCAxesFilter: Valid Filter Execution", "[OrientationAnalysis][FindAvgCAxesFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_caxis_data.tar.gz", "6_6_caxis_data"); // Read Exemplar DREAM3D File Filter @@ -48,6 +50,8 @@ TEST_CASE("OrientationAnalysis::FindAvgCAxesFilter: Valid Filter Execution", "[O TEST_CASE("OrientationAnalysis::FindAvgCAxesFilter: Invalid Filter Execution", "[OrientationAnalysis][FindAvgCAxesFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_caxis_data.tar.gz", "6_6_caxis_data"); // Read Exemplar DREAM3D File Filter diff --git a/src/Plugins/OrientationAnalysis/test/FindAvgOrientationsTest.cpp b/src/Plugins/OrientationAnalysis/test/FindAvgOrientationsTest.cpp index d92bfedd7b..3078aadeea 100644 --- a/src/Plugins/OrientationAnalysis/test/FindAvgOrientationsTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/FindAvgOrientationsTest.cpp @@ -90,8 +90,7 @@ TEST_CASE("OrientationAnalysis::FindAvgOrientations", "[OrientationAnalysis][Fin const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "ASCIIData.tar.gz", "ASCIIData"); // Instantiate an "Application" instance to load plugins - std::shared_ptr app = std::make_shared(); - app->loadPlugins(unit_test::k_BuildDir.view(), true); + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); const uint64 k_NumTuples = 480000; const uint64 k_FeatureNumTuples = 409; diff --git a/src/Plugins/OrientationAnalysis/test/FindBoundaryStrengthsTest.cpp b/src/Plugins/OrientationAnalysis/test/FindBoundaryStrengthsTest.cpp index 0a5c890e16..58077b91d8 100644 --- a/src/Plugins/OrientationAnalysis/test/FindBoundaryStrengthsTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/FindBoundaryStrengthsTest.cpp @@ -25,6 +25,8 @@ const std::string k_mPrimes = "SurfaceMeshmPrimes"; TEST_CASE("OrientationAnalysis::FindBoundaryStrengthsFilter: Valid Filter Execution", "[OrientationAnalysis][FindBoundaryStrengthsFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "feature_boundary_neighbor_slip_transmission.tar.gz", "feature_boundary_neighbor_slip_transmission"); diff --git a/src/Plugins/OrientationAnalysis/test/FindCAxisLocationsTest.cpp b/src/Plugins/OrientationAnalysis/test/FindCAxisLocationsTest.cpp index c6a21dad67..afe3381b14 100644 --- a/src/Plugins/OrientationAnalysis/test/FindCAxisLocationsTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/FindCAxisLocationsTest.cpp @@ -16,6 +16,8 @@ const std::string k_CAxisLocationsComputed = "NX_CAxisLocations"; TEST_CASE("OrientationAnalysis::FindCAxisLocationsFilter: Valid Filter Execution", "[OrientationAnalysis][FindCAxisLocationsFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_caxis_data.tar.gz", "6_6_caxis_data"); // Read Exemplar DREAM3D File Filter @@ -46,6 +48,8 @@ TEST_CASE("OrientationAnalysis::FindCAxisLocationsFilter: Valid Filter Execution TEST_CASE("OrientationAnalysis::FindCAxisLocationsFilter: InValid Filter Execution") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_caxis_data.tar.gz", "6_6_caxis_data"); // Read Exemplar DREAM3D File Filter diff --git a/src/Plugins/OrientationAnalysis/test/FindFeatureNeighborCAxisMisalignmentsTest.cpp b/src/Plugins/OrientationAnalysis/test/FindFeatureNeighborCAxisMisalignmentsTest.cpp index 42938bd033..0095e5fa23 100644 --- a/src/Plugins/OrientationAnalysis/test/FindFeatureNeighborCAxisMisalignmentsTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/FindFeatureNeighborCAxisMisalignmentsTest.cpp @@ -19,6 +19,8 @@ const std::string k_AvgCAxisMisalignmentsNameComputed = "NX_AvgCAxisMisalignment TEST_CASE("OrientationAnalysis::FindFeatureNeighborCAxisMisalignmentsFilter: Valid Filter Execution", "[OrientationAnalysis][FindFeatureNeighborCAxisMisalignmentsFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_caxis_data.tar.gz", "6_6_caxis_data"); // Read Exemplar DREAM3D File Filter @@ -54,6 +56,8 @@ TEST_CASE("OrientationAnalysis::FindFeatureNeighborCAxisMisalignmentsFilter: Val TEST_CASE("OrientationAnalysis::FindFeatureNeighborCAxisMisalignmentsFilter: InValid Filter Execution") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_caxis_data.tar.gz", "6_6_caxis_data"); // Read Exemplar DREAM3D File Filter diff --git a/src/Plugins/OrientationAnalysis/test/FindFeatureReferenceCAxisMisorientationsTest.cpp b/src/Plugins/OrientationAnalysis/test/FindFeatureReferenceCAxisMisorientationsTest.cpp index b817e41227..c798972032 100644 --- a/src/Plugins/OrientationAnalysis/test/FindFeatureReferenceCAxisMisorientationsTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/FindFeatureReferenceCAxisMisorientationsTest.cpp @@ -21,6 +21,8 @@ const DataPath k_AvgCAxesPath = k_CellFeatureDataPath.createChildPath("AvgCAxes" TEST_CASE("OrientationAnalysis::FindFeatureReferenceCAxisMisorientationsFilter: Valid Filter Execution", "[OrientationAnalysis][FindFeatureReferenceCAxisMisorientationsFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_caxis_data.tar.gz", "6_6_caxis_data"); // Read Exemplar DREAM3D File Filter @@ -60,6 +62,8 @@ TEST_CASE("OrientationAnalysis::FindFeatureReferenceCAxisMisorientationsFilter: TEST_CASE("OrientationAnalysis::FindFeatureReferenceCAxisMisorientationsFilter: InValid Filter Execution", "[OrientationAnalysis][FindFeatureReferenceCAxisMisorientationsFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_caxis_data.tar.gz", "6_6_caxis_data"); // Read Exemplar DREAM3D File Filter diff --git a/src/Plugins/OrientationAnalysis/test/FindFeatureReferenceMisorientationsTest.cpp b/src/Plugins/OrientationAnalysis/test/FindFeatureReferenceMisorientationsTest.cpp index 021b0fdcef..821c1ecf32 100644 --- a/src/Plugins/OrientationAnalysis/test/FindFeatureReferenceMisorientationsTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/FindFeatureReferenceMisorientationsTest.cpp @@ -27,6 +27,8 @@ const std::string k_GBEuclideanDistancesArrayName2("FeatureAvgMisorientations2") TEST_CASE("OrientationAnalysis::FindFeatureReferenceMisorientationsFilter", "[OrientationAnalysis][FindFeatureReferenceMisorientationsFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_stats_test.tar.gz", "6_6_stats_test.dream3d"); // Read the Small IN100 Data set diff --git a/src/Plugins/OrientationAnalysis/test/FindGBCDMetricBasedTest.cpp b/src/Plugins/OrientationAnalysis/test/FindGBCDMetricBasedTest.cpp index 8869edc1f3..075843d73d 100644 --- a/src/Plugins/OrientationAnalysis/test/FindGBCDMetricBasedTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/FindGBCDMetricBasedTest.cpp @@ -43,11 +43,12 @@ const DataPath k_ComputedErrorPath({"NX_errors"}); TEST_CASE("OrientationAnalysis::FindGBCDMetricBasedFilter: Valid Filter Execution", "[OrientationAnalysis][FindGBCDMetricBasedFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_find_gbcd_metric_based.tar.gz", "6_6_find_gbcd_metric_based"); - const std::shared_ptr app = std::make_shared(); - app->loadPlugins(unit_test::k_BuildDir.view(), true); + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); const auto* filterListPtr = Application::Instance()->getFilterList(); // Read Exemplar DREAM3D File Input @@ -169,6 +170,8 @@ TEST_CASE("OrientationAnalysis::FindGBCDMetricBasedFilter: Valid Filter Executio TEST_CASE("OrientationAnalysis::FindGBCDMetricBasedFilter: InValid Filter Execution") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_find_gbcd_metric_based.tar.gz", "6_6_find_gbcd_metric_based"); diff --git a/src/Plugins/OrientationAnalysis/test/FindGBCDTest.cpp b/src/Plugins/OrientationAnalysis/test/FindGBCDTest.cpp index e10d424dbf..fc0b814939 100644 --- a/src/Plugins/OrientationAnalysis/test/FindGBCDTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/FindGBCDTest.cpp @@ -24,6 +24,8 @@ inline constexpr StringLiteral k_FaceEnsembleDataPath("FaceEnsembleData [NX]"); TEST_CASE("OrientationAnalysis::FindGBCD", "[OrientationAnalysis][FindGBCD]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_Small_IN100_GBCD.tar.gz", "6_6_Small_IN100_GBCD"); // Read the Small IN100 Data set diff --git a/src/Plugins/OrientationAnalysis/test/FindGBPDMetricBasedTest.cpp b/src/Plugins/OrientationAnalysis/test/FindGBPDMetricBasedTest.cpp index 9876ff2114..a5456ed8c6 100644 --- a/src/Plugins/OrientationAnalysis/test/FindGBPDMetricBasedTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/FindGBPDMetricBasedTest.cpp @@ -41,11 +41,12 @@ const DataPath k_ComputedErrorPath({"NX_errors"}); TEST_CASE("OrientationAnalysis::FindGBPDMetricBasedFilter: Valid Filter Execution", "[OrientationAnalysis][FindGBPDMetricBasedFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_find_gbcd_metric_based.tar.gz", "6_6_find_gbcd_metric_based"); - std::shared_ptr app = std::make_shared(); - app->loadPlugins(unit_test::k_BuildDir.view(), true); + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); auto* filterList = Application::Instance()->getFilterList(); // Read Exemplar DREAM3D File Input @@ -166,6 +167,8 @@ TEST_CASE("OrientationAnalysis::FindGBPDMetricBasedFilter: Valid Filter Executio TEST_CASE("OrientationAnalysis::FindGBPDMetricBasedFilter: InValid Filter Execution") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_find_gbcd_metric_based.tar.gz", "6_6_find_gbcd_metric_based"); diff --git a/src/Plugins/OrientationAnalysis/test/FindKernelAvgMisorientationsTest.cpp b/src/Plugins/OrientationAnalysis/test/FindKernelAvgMisorientationsTest.cpp index 5783473ae1..6e11fcb9ba 100644 --- a/src/Plugins/OrientationAnalysis/test/FindKernelAvgMisorientationsTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/FindKernelAvgMisorientationsTest.cpp @@ -23,6 +23,8 @@ const std::string k_KernelAverageMisorientationsArrayName("CalculatedKernelAvera TEST_CASE("OrientationAnalysis::FindKernelAvgMisorientationsFilter", "[OrientationAnalysis][FindKernelAvgMisorientationsFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_stats_test.tar.gz", "6_6_stats_test.dream3d"); // Read the Small IN100 Data set diff --git a/src/Plugins/OrientationAnalysis/test/FindMisorientationsTest.cpp b/src/Plugins/OrientationAnalysis/test/FindMisorientationsTest.cpp index 10580a21eb..090241f4da 100644 --- a/src/Plugins/OrientationAnalysis/test/FindMisorientationsTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/FindMisorientationsTest.cpp @@ -23,6 +23,8 @@ const std::string k_NeighborListArrayName("NeighborList"); TEST_CASE("OrientationAnalysis::FindMisorientationsFilter", "[OrientationAnalysis][FindMisorientationsFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_stats_test.tar.gz", "6_6_stats_test.dream3d"); // Read the Small IN100 Data set diff --git a/src/Plugins/OrientationAnalysis/test/FindSchmidsTest.cpp b/src/Plugins/OrientationAnalysis/test/FindSchmidsTest.cpp index 76ae7041df..d16f21e79e 100644 --- a/src/Plugins/OrientationAnalysis/test/FindSchmidsTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/FindSchmidsTest.cpp @@ -27,6 +27,8 @@ const std::string k_CalculatedArrayPrefix("Calculated_"); TEST_CASE("OrientationAnalysis::FindSchmidsFilter", "[OrientationAnalysis][FindSchmidsFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_stats_test.tar.gz", "6_6_stats_test.dream3d"); // Read the Small IN100 Data set diff --git a/src/Plugins/OrientationAnalysis/test/FindShapesFilterTest.cpp b/src/Plugins/OrientationAnalysis/test/FindShapesFilterTest.cpp index 5c206a4fde..6171f31825 100644 --- a/src/Plugins/OrientationAnalysis/test/FindShapesFilterTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/FindShapesFilterTest.cpp @@ -15,6 +15,8 @@ using namespace complex::UnitTest; TEST_CASE("OrientationAnalysis::FindShapesFilter", "[ComplexCore][FindShapesFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_stats_test.tar.gz", "6_6_stats_test.dream3d"); // Read the Small IN100 Data set diff --git a/src/Plugins/OrientationAnalysis/test/FindSlipTransmissionMetricsTest.cpp b/src/Plugins/OrientationAnalysis/test/FindSlipTransmissionMetricsTest.cpp index 9d3a1763a0..3af6eae324 100644 --- a/src/Plugins/OrientationAnalysis/test/FindSlipTransmissionMetricsTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/FindSlipTransmissionMetricsTest.cpp @@ -23,6 +23,8 @@ const std::string k_mPrimes = "SurfaceMeshmPrimes"; TEST_CASE("OrientationAnalysis::FindSlipTransmissionMetricsFilter: Valid Filter Execution", "[OrientationAnalysis][FindSlipTransmissionMetricsFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "feature_boundary_neighbor_slip_transmission.tar.gz", "feature_boundary_neighbor_slip_transmission"); diff --git a/src/Plugins/OrientationAnalysis/test/FindTriangleGeomShapesTest.cpp b/src/Plugins/OrientationAnalysis/test/FindTriangleGeomShapesTest.cpp index 962aa793ff..a12e4dba20 100644 --- a/src/Plugins/OrientationAnalysis/test/FindTriangleGeomShapesTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/FindTriangleGeomShapesTest.cpp @@ -36,6 +36,8 @@ using namespace FindTriangleGeomShapesFilterTest; TEST_CASE("OrientationAnalysis::FindTriangleGeomShapes", "[OrientationAnalysis][FindTriangleGeomShapes]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "12_IN625_GBCD.tar.gz", "12_IN625_GBCD"); // Read Exemplar DREAM3D File Filter diff --git a/src/Plugins/OrientationAnalysis/test/GenerateFZQuaternionsTest.cpp b/src/Plugins/OrientationAnalysis/test/GenerateFZQuaternionsTest.cpp index a55615106f..691a591b09 100644 --- a/src/Plugins/OrientationAnalysis/test/GenerateFZQuaternionsTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/GenerateFZQuaternionsTest.cpp @@ -63,6 +63,8 @@ void MessageHandlerFunction(const IFilter::Message& message) TEST_CASE("OrientationAnalysis::GenerateFZQuaternions", "[OrientationAnalysis][GenerateFZQuaternions]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + // Instantiate the filter, a DataStructure object and an Arguments Object GenerateFZQuaternions filter; DataStructure dataStructure = CreateDataStructure(); diff --git a/src/Plugins/OrientationAnalysis/test/GenerateFaceIPFColoringTest.cpp b/src/Plugins/OrientationAnalysis/test/GenerateFaceIPFColoringTest.cpp index 0819465f8a..8361ce018a 100644 --- a/src/Plugins/OrientationAnalysis/test/GenerateFaceIPFColoringTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/GenerateFaceIPFColoringTest.cpp @@ -31,6 +31,8 @@ DataPath faceAreas = faceDataGroup.createChildPath(complex::Constants::k_FaceAre TEST_CASE("OrientationAnalysis::GenerateFaceIPFColoringFilter: Valid filter execution", "[OrientationAnalysis][GenerateFaceIPFColoringFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_Small_IN100_GBCD.tar.gz", "6_6_Small_IN100_GBCD"); // Read the Small IN100 Data set @@ -65,6 +67,8 @@ TEST_CASE("OrientationAnalysis::GenerateFaceIPFColoringFilter: Valid filter exec TEST_CASE("OrientationAnalysis::GenerateFaceIPFColoringFilter: Invalid filter execution", "[OrientationAnalysis][GenerateFaceIPFColoringFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_Small_IN100_GBCD.tar.gz", "6_6_Small_IN100_GBCD"); // Read the Small IN100 Data set diff --git a/src/Plugins/OrientationAnalysis/test/GenerateFaceMisorientationColoringTest.cpp b/src/Plugins/OrientationAnalysis/test/GenerateFaceMisorientationColoringTest.cpp index 042e208ace..15a8ebb6ef 100644 --- a/src/Plugins/OrientationAnalysis/test/GenerateFaceMisorientationColoringTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/GenerateFaceMisorientationColoringTest.cpp @@ -33,6 +33,8 @@ DataPath faceAreas = faceDataGroup.createChildPath(complex::Constants::k_FaceAre TEST_CASE("OrientationAnalysis::GenerateFaceMisorientationColoringFilter: Valid filter execution", "[OrientationAnalysis][GenerateFaceMisorientationColoringFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_Small_IN100_GBCD.tar.gz", "6_6_Small_IN100_GBCD"); // Read the Small IN100 Data set @@ -86,6 +88,8 @@ TEST_CASE("OrientationAnalysis::GenerateFaceMisorientationColoringFilter: Valid TEST_CASE("OrientationAnalysis::GenerateFaceMisorientationColoringFilter: Invalid filter execution", "[OrientationAnalysis][GenerateFaceMisorientationColoringFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_Small_IN100_GBCD.tar.gz", "6_6_Small_IN100_GBCD"); // Read the Small IN100 Data set diff --git a/src/Plugins/OrientationAnalysis/test/GenerateGBCDPoleFigureTest.cpp b/src/Plugins/OrientationAnalysis/test/GenerateGBCDPoleFigureTest.cpp index 54128f3e0d..b0844421c2 100644 --- a/src/Plugins/OrientationAnalysis/test/GenerateGBCDPoleFigureTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/GenerateGBCDPoleFigureTest.cpp @@ -35,6 +35,8 @@ inline constexpr int32 k_Dimension = 300; TEST_CASE("OrientationAnalysis::GenerateGBCDPoleFigureFilter", "[OrientationAnalysis][GenerateGBCDPoleFigureFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_Small_IN100_GBCD.tar.gz", "6_6_Small_IN100_GBCD"); // Read the Small IN100 Data set diff --git a/src/Plugins/OrientationAnalysis/test/GenerateIPFColorsTest.cpp b/src/Plugins/OrientationAnalysis/test/GenerateIPFColorsTest.cpp index 7ab2571a71..44f07a11c8 100644 --- a/src/Plugins/OrientationAnalysis/test/GenerateIPFColorsTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/GenerateIPFColorsTest.cpp @@ -44,6 +44,8 @@ inline constexpr StringLiteral k_OutputIPFColors("IPF Colors_Test_Output"); TEST_CASE("OrientationAnalysis::GenerateIPFColors", "[OrientationAnalysis][GenerateIPFColors]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "so3_cubic_high_ipf_001.tar.gz", "so3_cubic_high_ipf_001.dream3d"); diff --git a/src/Plugins/OrientationAnalysis/test/GenerateQuaternionConjugateTest.cpp b/src/Plugins/OrientationAnalysis/test/GenerateQuaternionConjugateTest.cpp index fe965c7e84..83d44495fd 100644 --- a/src/Plugins/OrientationAnalysis/test/GenerateQuaternionConjugateTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/GenerateQuaternionConjugateTest.cpp @@ -19,6 +19,8 @@ const std::string k_Exemplar0 = "Exemplar0"; TEST_CASE("OrientationAnalysis::GenerateQuaternionConjugateFilter", "[OrientationAnalysis][GenerateQuaternionConjugateFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + // Instantiate the filter, a DataStructure object and an Arguments Object DataStructure dataStructure; diff --git a/src/Plugins/OrientationAnalysis/test/ImportH5EspritDataTest.cpp b/src/Plugins/OrientationAnalysis/test/ImportH5EspritDataTest.cpp index 69d46ec640..0b52df3180 100644 --- a/src/Plugins/OrientationAnalysis/test/ImportH5EspritDataTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/ImportH5EspritDataTest.cpp @@ -25,6 +25,8 @@ const std::string k_ScanName = "Section_435"; TEST_CASE("OrientationAnalysis::ImportH5EspritDataFilter: Valid Filter Execution", "[OrientationAnalysis][ImportH5EspritDataFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_ImportH5Data.tar.gz", "6_6_ImportH5Data"); // Read Exemplar DREAM3D File @@ -81,6 +83,8 @@ TEST_CASE("OrientationAnalysis::ImportH5EspritDataFilter: Valid Filter Execution TEST_CASE("OrientationAnalysis::ImportH5EspritDataFilter: InValid Filter Execution", "[OrientationAnalysis][ImportH5EspritDataFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_ImportH5Data.tar.gz", "6_6_ImportH5Data"); // Instantiate the filter, a DataStructure object and an Arguments Object diff --git a/src/Plugins/OrientationAnalysis/test/ImportH5OimDataTest.cpp b/src/Plugins/OrientationAnalysis/test/ImportH5OimDataTest.cpp index 86b4c1d29f..4ecfea29ce 100644 --- a/src/Plugins/OrientationAnalysis/test/ImportH5OimDataTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/ImportH5OimDataTest.cpp @@ -25,6 +25,8 @@ const std::string k_ScanName = "Scan 1"; TEST_CASE("OrientationAnalysis::ImportH5OimDataFilter: Valid Filter Execution", "[OrientationAnalysis][ImportH5OimDataFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_ImportH5Data.tar.gz", "6_6_ImportH5Data"); // Read Exemplar DREAM3D File @@ -80,6 +82,8 @@ TEST_CASE("OrientationAnalysis::ImportH5OimDataFilter: Valid Filter Execution", TEST_CASE("OrientationAnalysis::ImportH5OimDataFilter: InValid Filter Execution", "[OrientationAnalysis][ImportH5OimDataFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_ImportH5Data.tar.gz", "6_6_ImportH5Data"); // Instantiate the filter, a DataStructure object and an Arguments Object diff --git a/src/Plugins/OrientationAnalysis/test/MergeTwinsTest.cpp b/src/Plugins/OrientationAnalysis/test/MergeTwinsTest.cpp index bd81064a49..90e6198ee2 100644 --- a/src/Plugins/OrientationAnalysis/test/MergeTwinsTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/MergeTwinsTest.cpp @@ -19,11 +19,12 @@ using namespace complex::Constants; TEST_CASE("Reconstruction::MergeTwinsFilter: Valid Execution", "[Reconstruction][MergeTwinsFilter][.][UNIMPLEMENTED][!mayfail]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "neighbor_orientation_correlation.tar.gz", "neighbor_orientation_correlation.dream3d"); - std::shared_ptr app = std::make_shared(); - app->loadPlugins(unit_test::k_BuildDir.view(), true); + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); auto* filterList = Application::Instance()->getFilterList(); // Make sure we can load the needed filters from the plugins diff --git a/src/Plugins/OrientationAnalysis/test/NeighborOrientationCorrelationTest.cpp b/src/Plugins/OrientationAnalysis/test/NeighborOrientationCorrelationTest.cpp index fb7c9600f6..9ffd7b6e01 100644 --- a/src/Plugins/OrientationAnalysis/test/NeighborOrientationCorrelationTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/NeighborOrientationCorrelationTest.cpp @@ -42,8 +42,7 @@ TEST_CASE("OrientationAnalysis::NeighborOrientationCorrelationFilter: Small IN10 const complex::UnitTest::TestFileSentinel testDataSentinel1(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "Small_IN100_dream3d.tar.gz", "Small_IN100.dream3d"); - std::shared_ptr app = std::make_shared(); - app->loadPlugins(unit_test::k_BuildDir.view(), true); + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); auto* filterList = Application::Instance()->getFilterList(); // Read Exemplar DREAM3D File Filter diff --git a/src/Plugins/OrientationAnalysis/test/ReadAngDataTest.cpp b/src/Plugins/OrientationAnalysis/test/ReadAngDataTest.cpp index 0648642e82..842918c739 100644 --- a/src/Plugins/OrientationAnalysis/test/ReadAngDataTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/ReadAngDataTest.cpp @@ -16,6 +16,8 @@ using namespace complex::UnitTest; TEST_CASE("OrientationAnalysis::ReadAngData: Valid Execution", "[OrientationAnalysis][ReadAngData]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_read_ang_data.tar.gz", "6_6_read_ang_data"); // Read Exemplar DREAM3D File diff --git a/src/Plugins/OrientationAnalysis/test/ReadCtfDataTest.cpp b/src/Plugins/OrientationAnalysis/test/ReadCtfDataTest.cpp index e9c226a60a..3280780748 100644 --- a/src/Plugins/OrientationAnalysis/test/ReadCtfDataTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/ReadCtfDataTest.cpp @@ -16,6 +16,8 @@ using namespace complex::UnitTest; TEST_CASE("OrientationAnalysis::ReadCtfData: Valid Execution", "[OrientationAnalysis][ReadCtfData]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "6_6_read_ctf_data.tar.gz", "6_6_read_ctf_data"); // Read Exemplar DREAM3D File diff --git a/src/Plugins/OrientationAnalysis/test/ReadH5EbsdTest.cpp b/src/Plugins/OrientationAnalysis/test/ReadH5EbsdTest.cpp index d0c3653905..0a5506bd9f 100644 --- a/src/Plugins/OrientationAnalysis/test/ReadH5EbsdTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/ReadH5EbsdTest.cpp @@ -22,8 +22,7 @@ TEST_CASE("OrientationAnalysis::ReadH5Ebsd: Valid filter execution", "[Orientati const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "Small_IN100_h5ebsd.tar.gz", "Small_IN100.dream3d"); - std::shared_ptr app = std::make_shared(); - app->loadPlugins(unit_test::k_BuildDir.view(), true); + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); auto* filterList = Application::Instance()->getFilterList(); // Read Exemplar DREAM3D File diff --git a/src/Plugins/OrientationAnalysis/test/RodriguesConvertorTest.cpp b/src/Plugins/OrientationAnalysis/test/RodriguesConvertorTest.cpp index 4e858253f5..a5b2fa5891 100644 --- a/src/Plugins/OrientationAnalysis/test/RodriguesConvertorTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/RodriguesConvertorTest.cpp @@ -19,6 +19,8 @@ const std::string k_Exemplar0 = "Exemplar0"; TEST_CASE("OrientationAnalysis::RodriguesConvertorFilter", "[OrientationAnalysis][RodriguesConvertorFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + // Instantiate the filter, a DataStructure object and an Arguments Object DataStructure dataStructure; diff --git a/src/Plugins/OrientationAnalysis/test/RotateEulerRefFrameTest.cpp b/src/Plugins/OrientationAnalysis/test/RotateEulerRefFrameTest.cpp index b05141a138..6581f3c7e1 100644 --- a/src/Plugins/OrientationAnalysis/test/RotateEulerRefFrameTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/RotateEulerRefFrameTest.cpp @@ -23,8 +23,7 @@ TEST_CASE("OrientationAnalysis::RotateEulerRefFrame", "[OrientationAnalysis]") const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "ASCIIData.tar.gz", "ASCIIData"); // Instantiate an "Application" instance to load plugins - std::shared_ptr app = std::make_shared(); - app->loadPlugins(unit_test::k_BuildDir.view(), true); + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); const uint64 k_NumComponents = 3; const static DynamicTableInfo::TableDataType k_NumTuples = {{static_cast(480000)}}; diff --git a/src/Plugins/OrientationAnalysis/test/WritePoleFigureTest.cpp b/src/Plugins/OrientationAnalysis/test/WritePoleFigureTest.cpp index d4d3cdefc5..eb32c6def9 100644 --- a/src/Plugins/OrientationAnalysis/test/WritePoleFigureTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/WritePoleFigureTest.cpp @@ -25,6 +25,8 @@ const std::string k_ImagePrefix("fw-ar-IF1-aptr12-corr Discrete Pole Figure"); TEST_CASE("OrientationAnalysis::WritePoleFigureFilter-1", "[OrientationAnalysis][WritePoleFigureFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "PoleFigure_Exemplars.tar.gz", "PoleFigure_Exemplars"); // Read the Small IN100 Data set @@ -74,6 +76,8 @@ TEST_CASE("OrientationAnalysis::WritePoleFigureFilter-1", "[OrientationAnalysis] TEST_CASE("OrientationAnalysis::WritePoleFigureFilter-2", "[OrientationAnalysis][WritePoleFigureFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "PoleFigure_Exemplars.tar.gz", "PoleFigure_Exemplars"); // Read the Small IN100 Data set @@ -124,6 +128,8 @@ TEST_CASE("OrientationAnalysis::WritePoleFigureFilter-2", "[OrientationAnalysis] TEST_CASE("OrientationAnalysis::WritePoleFigureFilter-3", "[OrientationAnalysis][WritePoleFigureFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "PoleFigure_Exemplars.tar.gz", "PoleFigure_Exemplars"); // Read the Small IN100 Data set diff --git a/src/Plugins/OrientationAnalysis/test/WriteStatsGenOdfAngleFileTest.cpp b/src/Plugins/OrientationAnalysis/test/WriteStatsGenOdfAngleFileTest.cpp index 0e0140a626..811cb345fb 100644 --- a/src/Plugins/OrientationAnalysis/test/WriteStatsGenOdfAngleFileTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/WriteStatsGenOdfAngleFileTest.cpp @@ -16,6 +16,8 @@ using namespace complex; TEST_CASE("OrientationAnalysis::WriteStatsGenOdfAngleFileFilter: Valid Filter Execution", "[OrientationAnalysis][WriteStatsGenOdfAngleFileFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "write_stats_gen_odf_angle_file.tar.gz", "write_stats_gen_odf_angle_file"); @@ -66,6 +68,8 @@ TEST_CASE("OrientationAnalysis::WriteStatsGenOdfAngleFileFilter: Valid Filter Ex TEST_CASE("OrientationAnalysis::WriteStatsGenOdfAngleFileFilter: InValid Filter Execution", "[OrientationAnalysis][WriteStatsGenOdfAngleFileFilter]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); + const complex::UnitTest::TestFileSentinel testDataSentinel(complex::unit_test::k_CMakeExecutable, complex::unit_test::k_TestFilesDir, "write_stats_gen_odf_angle_file.tar.gz", "write_stats_gen_odf_angle_file"); diff --git a/src/complex/Common/Uuid.hpp b/src/complex/Common/Uuid.hpp index c304105615..f8a3a0d149 100644 --- a/src/complex/Common/Uuid.hpp +++ b/src/complex/Common/Uuid.hpp @@ -2,7 +2,11 @@ #include #include +#include #include +#include +#include +#include #include #include @@ -165,6 +169,44 @@ struct COMPLEX_EXPORT Uuid return uuid; } + static inline Uuid GenerateV4() + { + static thread_local std::random_device rd; + static thread_local std::mt19937 gen(rd()); + static thread_local std::uniform_int_distribution<> dis(0, 15); + static thread_local std::uniform_int_distribution<> dis2(8, 11); + + std::stringstream ss; + int i; + ss << std::hex; + for(i = 0; i < 8; i++) + { + ss << dis(gen); + } + ss << "-"; + for(i = 0; i < 4; i++) + { + ss << dis(gen); + } + ss << "-4"; + for(i = 0; i < 3; i++) + { + ss << dis(gen); + } + ss << "-"; + ss << dis2(gen); + for(i = 0; i < 3; i++) + { + ss << dis(gen); + } + ss << "-"; + for(i = 0; i < 12; i++) + { + ss << dis(gen); + }; + return FromString(ss.str()).value(); + } + inline constexpr uint32 time_low() const noexcept { return bit_cast_int(data.data()); diff --git a/src/complex/Core/Application.cpp b/src/complex/Core/Application.cpp index 6c81e2d759..c21bb2246e 100644 --- a/src/complex/Core/Application.cpp +++ b/src/complex/Core/Application.cpp @@ -81,29 +81,26 @@ std::string getApplicationName(Application* app) } } // namespace -Application* Application::s_Instance = nullptr; +std::shared_ptr Application::s_Instance = nullptr; Application::Application() : m_FilterList(std::make_unique()) , m_DataIOCollection(std::make_shared()) { - loadPreferences(); - assignInstance(); - initDefaultDataTypes(); + initialize(); } Application::Application(int argc, char** argv) : Application() { - loadPreferences(); - assignInstance(); - initDefaultDataTypes(); + initialize(); } -void Application::assignInstance() +void Application::initialize() { - s_Instance = this; + loadPreferences(); m_CurrentPath = findCurrentPath(); + initDefaultDataTypes(); } void Application::initDefaultDataTypes() @@ -127,27 +124,33 @@ void Application::initDefaultDataTypes() Application::~Application() { - if(Instance() == this) - { - s_Instance = nullptr; - savePreferences(); - } + savePreferences(); + s_Instance = nullptr; } -Application* Application::Instance() +std::shared_ptr Application::Instance() { return s_Instance; } -Application* Application::GetOrCreateInstance() +std::shared_ptr Application::GetOrCreateInstance() { if(s_Instance == nullptr) { - new Application(); + s_Instance = std::shared_ptr(new Application()); } return s_Instance; } +void Application::DeleteInstance() +{ + if(s_Instance != nullptr) + { + s_Instance->savePreferences(); + } + s_Instance = nullptr; +} + std::filesystem::path Application::getCurrentPath() const { return m_CurrentPath; @@ -280,7 +283,10 @@ void Application::loadPlugin(const std::filesystem::path& path, bool verbose) fmt::print("Loading Plugin: {}\n", path.string()); } auto pluginLoader = std::make_shared(path); - getFilterList()->addPlugin(pluginLoader); + if(getFilterList()->addPlugin(pluginLoader).invalid()) + { + return; + } auto plugin = pluginLoader->getPlugin(); if(plugin == nullptr) diff --git a/src/complex/Core/Application.hpp b/src/complex/Core/Application.hpp index 11f16df5eb..41396d96b9 100644 --- a/src/complex/Core/Application.hpp +++ b/src/complex/Core/Application.hpp @@ -33,21 +33,6 @@ class COMPLEX_EXPORT Application public: using name_type_map = std::map; - /** - * @brief Constructs an Application using default values and replaces the - * current Instance pointer. - */ - Application(); - - /** - * @brief Constructs an Application accepting a set of command line arguments. - * - * The current Application instance is replaced with the constructed Application. - * @param argc - * @param argv - */ - Application(int argc, char** argv); - /** * @brief Destroys the Application. If the destroyed Application matches the * current Application::Instance(), the instance pointer is set to nullptr. @@ -59,11 +44,13 @@ class COMPLEX_EXPORT Application * replaced when a new complex::Application is created, replacing the * previous value. If the current Application is destroyed, this method will * return nullptr until a new Application is created. - * @return Application* + * @return std::shared_ptr */ - static Application* Instance(); + static std::shared_ptr Instance(); + + static std::shared_ptr GetOrCreateInstance(); - static Application* GetOrCreateInstance(); + static void DeleteInstance(); /** * @brief Finds and loads plugins in the target directory. @@ -161,13 +148,25 @@ class COMPLEX_EXPORT Application std::vector getDataStoreFormats() const; -private: +protected: /** - * @brief Assigns Application as the current instance and sets the current - * executable path. + * @brief Constructs an Application using default values and replaces the + * current Instance pointer. */ - void assignInstance(); + Application(); + /** + * @brief Constructs an Application accepting a set of command line arguments. + * + * The current Application instance is replaced with the constructed Application. + * @param argc + * @param argv + */ + Application(int argc, char** argv); + + void initialize(); + +private: void initDefaultDataTypes(); /** @@ -179,7 +178,7 @@ class COMPLEX_EXPORT Application ////////////////// // Static Variable - static Application* s_Instance; + static std::shared_ptr s_Instance; //////////// // Variables diff --git a/src/complex/Core/Preferences.cpp b/src/complex/Core/Preferences.cpp index 0cd0f121db..16bb406126 100644 --- a/src/complex/Core/Preferences.cpp +++ b/src/complex/Core/Preferences.cpp @@ -1,6 +1,7 @@ #include "Preferences.hpp" #include "complex/Plugin/AbstractPlugin.hpp" +#include "complex/Utilities/MemoryUtilities.hpp" #include @@ -23,6 +24,7 @@ inline constexpr int64 k_LargeDataSize = 1073741824; // 1 GB inline constexpr StringLiteral k_LargeDataFormat = ""; inline constexpr StringLiteral k_Plugin_Key = "plugins"; inline constexpr StringLiteral k_DefaultFileName = "preferences.json"; +inline constexpr int64 k_ReducedDataStructureSize = 3221225472; // 3 GB inline constexpr int32 k_FailedToCreateDirectory_Code = -585; inline constexpr int32 k_FileDoesNotExist_Code = -586; @@ -61,6 +63,7 @@ std::filesystem::path Preferences::DefaultFilePath(const std::string& applicatio Preferences::Preferences() { setDefaultValues(); + checkUseOoc(); } Preferences::~Preferences() noexcept = default; @@ -72,6 +75,35 @@ void Preferences::setDefaultValues() m_DefaultValues[k_LargeDataSize_Key] = k_LargeDataSize; m_DefaultValues[k_PreferredLargeDataFormat_Key] = k_LargeDataFormat; + + updateMemoryDefaults(); + +#ifdef COMPLEX_FORCE_OUT_OF_CORE_DATA + m_DefaultValues[k_ForceOocData_Key] = true; +#else + m_DefaultValues[k_ForceOocData_Key] = false; +#endif +} + +std::string Preferences::defaultLargeDataFormat() const +{ + return m_DefaultValues[k_PreferredLargeDataFormat_Key].get(); +} + +void Preferences::setDefaultLargeDataFormat(std::string dataFormat) +{ + m_DefaultValues[k_PreferredLargeDataFormat_Key] = dataFormat; + checkUseOoc(); +} + +std::string Preferences::largeDataFormat() const +{ + return valueAs(k_PreferredLargeDataFormat_Key); +} +void Preferences::setLargeDataFormat(std::string dataFormat) +{ + m_Values[k_PreferredLargeDataFormat_Key] = dataFormat; + checkUseOoc(); } void Preferences::addDefaultValues(std::string pluginName, std::string valueName, const nlohmann::json& value) @@ -200,6 +232,53 @@ Result<> Preferences::loadFromFile(const std::filesystem::path& filepath) } m_Values = nlohmann::json::parse(fileStream); + checkUseOoc(); return {}; } + +void Preferences::checkUseOoc() +{ + m_UseOoc = !value(k_PreferredLargeDataFormat_Key).empty(); +} + +bool Preferences::useOocData() const +{ + return m_UseOoc; +} + +bool Preferences::forceOocData() const +{ + if(!m_UseOoc) + { + return false; + } + return valueAs(k_ForceOocData_Key); +} + +void Preferences::setForceOocData(bool forceOoc) +{ + if(!m_UseOoc) + { + return; + } + setValue(k_ForceOocData_Key, forceOoc); +} + +void Preferences::updateMemoryDefaults() +{ + const uint64 minimumRemaining = 2 * defaultValueAs(k_LargeDataSize_Key); + const uint64 totalMemory = Memory::GetTotalMemory(); + uint64 targetValue = totalMemory - minimumRemaining; + if(minimumRemaining >= totalMemory) + { + targetValue = totalMemory / 2; + } + + m_DefaultValues[k_LargeDataStructureSize_Key] = targetValue; +} + +uint64 Preferences::largeDataStructureSize() const +{ + return value(k_LargeDataStructureSize_Key).get(); +} } // namespace complex diff --git a/src/complex/Core/Preferences.hpp b/src/complex/Core/Preferences.hpp index 9d0d086156..fc4b7d1659 100644 --- a/src/complex/Core/Preferences.hpp +++ b/src/complex/Core/Preferences.hpp @@ -21,6 +21,8 @@ class COMPLEX_EXPORT Preferences public: static inline constexpr StringLiteral k_LargeDataSize_Key = "large_data_size"; static inline constexpr StringLiteral k_PreferredLargeDataFormat_Key = "large_data_format"; + static inline constexpr StringLiteral k_LargeDataStructureSize_Key = "large_datastructure_size"; + static inline constexpr StringLiteral k_ForceOocData_Key = "force_ooc_data"; static std::filesystem::path DefaultFilePath(const std::string& applicationName); @@ -72,13 +74,30 @@ class COMPLEX_EXPORT Preferences Result<> saveToFile(const std::filesystem::path& filepath) const; Result<> loadFromFile(const std::filesystem::path& filepath); + std::string defaultLargeDataFormat() const; + void setDefaultLargeDataFormat(std::string dataFormat); + + std::string largeDataFormat() const; + void setLargeDataFormat(std::string dataFormat); + + bool useOocData() const; + bool forceOocData() const; + + void setForceOocData(bool forceOoc); + + void updateMemoryDefaults(); + uint64 largeDataStructureSize() const; + protected: void setDefaultValues(); void addDefaultValues(std::string pluginName, std::string valueName, const nlohmann::json& value); + void checkUseOoc(); + private: nlohmann::json m_DefaultValues; nlohmann::json m_Values; + bool m_UseOoc = false; }; } // namespace complex diff --git a/src/complex/DataStructure/AbstractDataStore.hpp b/src/complex/DataStructure/AbstractDataStore.hpp index c7aa87cc44..f3316804ae 100644 --- a/src/complex/DataStructure/AbstractDataStore.hpp +++ b/src/complex/DataStructure/AbstractDataStore.hpp @@ -637,9 +637,9 @@ class AbstractDataStore : public IDataStore * @brief Returns the value found at the specified index of the DataStore. * This cannot be used to edit the value found at the specified index. * @param index - * @return const_reference + * @return value_type */ - virtual const_reference getValue(usize index) const = 0; + virtual value_type getValue(usize index) const = 0; /** * @brief Sets the value stored at the specified index. @@ -735,6 +735,17 @@ class AbstractDataStore : public IDataStore std::fill(begin(), end(), value); } + virtual bool copy(const AbstractDataStore& other) + { + if(getSize() != other.getSize()) + { + return false; + } + + std::copy(other.begin(), other.end(), begin()); + return true; + } + /** * @brief Returns the DataStore's DataType as an enum * @return DataType @@ -945,6 +956,11 @@ class AbstractDataStore : public IDataStore { } + virtual uint64 memoryUsage() const + { + return sizeof(T) * getSize(); + } + protected: /** * @brief Default constructor diff --git a/src/complex/DataStructure/DataArray.hpp b/src/complex/DataStructure/DataArray.hpp index 2560a6af9e..dbde09762a 100644 --- a/src/complex/DataStructure/DataArray.hpp +++ b/src/complex/DataStructure/DataArray.hpp @@ -369,7 +369,7 @@ class DataArray : public IDataArray * @param index * @return const_reference */ - const_reference at(usize index) const + value_type at(usize index) const { if(m_DataStore == nullptr) { @@ -688,6 +688,11 @@ class DataArray : public IDataArray m_DataStore->flush(); } + uint64 memoryUsage() const override + { + return m_DataStore->memoryUsage(); + } + protected: /** * @brief Constructs a DataArray with the specified name and DataStore. diff --git a/src/complex/DataStructure/DataObject.cpp b/src/complex/DataStructure/DataObject.cpp index 156774ab2b..0160326a8f 100644 --- a/src/complex/DataStructure/DataObject.cpp +++ b/src/complex/DataStructure/DataObject.cpp @@ -332,4 +332,9 @@ std::vector DataObject::getDataPaths() const void DataObject::flush() const { } + +uint64 DataObject::memoryUsage() const +{ + return 0; +} } // namespace complex diff --git a/src/complex/DataStructure/DataObject.hpp b/src/complex/DataStructure/DataObject.hpp index 77364aceb1..c681308fde 100644 --- a/src/complex/DataStructure/DataObject.hpp +++ b/src/complex/DataStructure/DataObject.hpp @@ -253,6 +253,8 @@ class COMPLEX_EXPORT DataObject */ virtual void flush() const; + virtual uint64 memoryUsage() const; + protected: /** * @brief DataObject constructor takes a reference to the DataStructure and diff --git a/src/complex/DataStructure/DataStore.hpp b/src/complex/DataStructure/DataStore.hpp index 90d09f7508..671ac5e8c5 100644 --- a/src/complex/DataStructure/DataStore.hpp +++ b/src/complex/DataStructure/DataStore.hpp @@ -253,7 +253,7 @@ class DataStore : public AbstractDataStore * @param index * @return value_type */ - const_reference getValue(usize index) const override + value_type getValue(usize index) const override { return m_Data.get()[index]; } diff --git a/src/complex/DataStructure/DataStructure.cpp b/src/complex/DataStructure/DataStructure.cpp index 35e19b7854..6665602ab0 100644 --- a/src/complex/DataStructure/DataStructure.cpp +++ b/src/complex/DataStructure/DataStructure.cpp @@ -1,5 +1,6 @@ #include "DataStructure.hpp" +#include "complex/Core/Application.hpp" #include "complex/DataStructure/BaseGroup.hpp" #include "complex/DataStructure/DataGroup.hpp" #include "complex/DataStructure/IDataArray.hpp" @@ -10,6 +11,7 @@ #include "complex/DataStructure/Messaging/DataReparentedMessage.hpp" #include "complex/DataStructure/Observers/AbstractDataStructureObserver.hpp" #include "complex/Filter/ValueParameter.hpp" +#include "complex/Utilities/DataArrayUtilities.hpp" #include "complex/Utilities/DataGroupUtilities.hpp" #include @@ -966,4 +968,46 @@ void DataStructure::flush() const sharedObj->flush(); } } + +uint64 DataStructure::memoryUsage() const +{ + uint64 memory = 0; + for(const auto& dataIter : m_DataObjects) + { + auto dataPtr = dataIter.second.lock(); + if(dataPtr == nullptr) + { + continue; + } + memory += dataPtr->memoryUsage(); + } + return memory; +} + +Result<> DataStructure::transferDataArraysOoc() +{ + auto* preferences = Application::GetOrCreateInstance()->getPreferences(); + if(!preferences->useOocData()) + { + return MakeErrorResult(-3567, "Out-of-core not available"); + } + + Result<> result; + std::string targetFormat = preferences->largeDataFormat(); + for(const auto& dataIter : m_DataObjects) + { + auto dataPtr = dataIter.second.lock(); + auto dataArrayPtr = std::dynamic_pointer_cast(dataPtr); + if(dataArrayPtr == nullptr) + { + continue; + } + if(!ConvertIDataArray(dataArrayPtr, targetFormat)) + { + result.warnings().emplace_back(Warning{-3570, fmt::format("Cannot convert DataArray: '{}' to out-of-core", dataArrayPtr->getName())}); + } + } + + return result; +} } // namespace complex diff --git a/src/complex/DataStructure/DataStructure.hpp b/src/complex/DataStructure/DataStructure.hpp index 74d9b8b59f..c1e0016a6c 100644 --- a/src/complex/DataStructure/DataStructure.hpp +++ b/src/complex/DataStructure/DataStructure.hpp @@ -709,6 +709,14 @@ class COMPLEX_EXPORT DataStructure */ void flush() const; + uint64 memoryUsage() const; + + /** + * @brief Transfers array data to OOC if available. + * @return Result with Warnings and errors + */ + Result<> transferDataArraysOoc(); + protected: /** * @brief Returns a new ID for use constructing a DataObject. diff --git a/src/complex/DataStructure/EmptyDataStore.hpp b/src/complex/DataStructure/EmptyDataStore.hpp index 0e809d76bb..746f416fd8 100644 --- a/src/complex/DataStructure/EmptyDataStore.hpp +++ b/src/complex/DataStructure/EmptyDataStore.hpp @@ -144,7 +144,7 @@ class EmptyDataStore : public AbstractDataStore * @param index * @return value_type */ - const_reference getValue(usize index) const override + value_type getValue(usize index) const override { throw std::runtime_error(""); } diff --git a/src/complex/DataStructure/IO/HDF5/DataStructureWriter.cpp b/src/complex/DataStructure/IO/HDF5/DataStructureWriter.cpp index d0049f4674..43d09d8748 100644 --- a/src/complex/DataStructure/IO/HDF5/DataStructureWriter.cpp +++ b/src/complex/DataStructure/IO/HDF5/DataStructureWriter.cpp @@ -14,7 +14,7 @@ namespace complex::HDF5 { DataStructureWriter::DataStructureWriter() { - auto* instance = Application::GetOrCreateInstance(); + auto instance = Application::GetOrCreateInstance(); m_IOManager = std::dynamic_pointer_cast(instance->getIOManager("HDF5")); } diff --git a/src/complex/Filter/FilterList.cpp b/src/complex/Filter/FilterList.cpp index cb6eea95c4..fcaee24875 100644 --- a/src/complex/Filter/FilterList.cpp +++ b/src/complex/Filter/FilterList.cpp @@ -91,26 +91,26 @@ AbstractPlugin* FilterList::getPlugin(const FilterHandle& handle) const return nullptr; } -bool FilterList::addPlugin(const std::shared_ptr& loader) +Result<> FilterList::addPlugin(const std::shared_ptr& loader) { if(!loader->isLoaded()) { - return false; + return MakeErrorResult(-444, "Plugin was not loaded"); } AbstractPlugin* plugin = loader->getPlugin(); Uuid pluginUuid = plugin->getId(); if(m_PluginMap.count(pluginUuid) > 0) { - throw std::runtime_error(fmt::format("Attempted to add plugin '{}' with uuid '{}', but plugin '{}' already exists with that uuid", plugin->getName(), pluginUuid.str(), - m_PluginMap[pluginUuid]->getPlugin()->getName())); + return MakeErrorResult(-445, fmt::format("Attempted to add plugin '{}' with uuid '{}', but plugin '{}' already exists with that uuid", plugin->getName(), pluginUuid.str(), + m_PluginMap[pluginUuid]->getPlugin()->getName())); } auto pluginHandles = plugin->getFilterHandles(); m_FilterHandles.merge(pluginHandles); m_PluginMap[pluginUuid] = loader; - return true; + return {}; } -bool FilterList::addPlugin(const std::string& path) +Result<> FilterList::addPlugin(const std::string& path) { return addPlugin(std::dynamic_pointer_cast(std::make_shared(path))); } diff --git a/src/complex/Filter/FilterList.hpp b/src/complex/Filter/FilterList.hpp index c7e8a4c20b..5e2834290f 100644 --- a/src/complex/Filter/FilterList.hpp +++ b/src/complex/Filter/FilterList.hpp @@ -127,7 +127,7 @@ class COMPLEX_EXPORT FilterList * @param loader * @return bool */ - bool addPlugin(const std::shared_ptr& loader); + Result<> addPlugin(const std::shared_ptr& loader); /** * @brief Attempts to add the plugin at the specified filepath. Returns true @@ -135,7 +135,7 @@ class COMPLEX_EXPORT FilterList * @param path * @return bool */ - bool addPlugin(const std::string& path); + Result<> addPlugin(const std::string& path); /** * @brief Removes the plugin with the given uuid. diff --git a/src/complex/Pipeline/AbstractPipelineNode.cpp b/src/complex/Pipeline/AbstractPipelineNode.cpp index f495b0fc74..31b26fc2d5 100644 --- a/src/complex/Pipeline/AbstractPipelineNode.cpp +++ b/src/complex/Pipeline/AbstractPipelineNode.cpp @@ -1,5 +1,7 @@ #include "AbstractPipelineNode.hpp" +#include "complex/Core/Application.hpp" +#include "complex/Core/Preferences.hpp" #include "complex/Pipeline/Messaging/NodeStatusMessage.hpp" #include "complex/Pipeline/Pipeline.hpp" @@ -66,6 +68,23 @@ void AbstractPipelineNode::setDataStructure(const DataStructure& dataStructure) m_DataStructure = dataStructure; } +void AbstractPipelineNode::checkDataStructureSize(DataStructure& dataStructure) +{ + const uint64 largeDataStructureSize = Application::Instance()->getPreferences()->largeDataStructureSize(); + if(dataStructure.memoryUsage() > largeDataStructureSize) + { + auto result = dataStructure.transferDataArraysOoc(); + if(result.warnings().size() > 0) + { + std::cout << "Some DataArrays not converted to out-of-core:" << std::endl; + for(const auto& warning : result.warnings()) + { + std::cout << "\tWarning: " << warning.message << std::endl; + } + } + } +} + const DataStructure& AbstractPipelineNode::getPreflightStructure() const { return m_PreflightStructure; diff --git a/src/complex/Pipeline/AbstractPipelineNode.hpp b/src/complex/Pipeline/AbstractPipelineNode.hpp index 723451b970..9c9ac649e7 100644 --- a/src/complex/Pipeline/AbstractPipelineNode.hpp +++ b/src/complex/Pipeline/AbstractPipelineNode.hpp @@ -282,6 +282,12 @@ class COMPLEX_EXPORT AbstractPipelineNode */ void setDataStructure(const DataStructure& dataStructure); + /** + * @brief Checks the DataStructure memory size and moves DataArrays to out-of-core if required. + * @param dataStructure + */ + void checkDataStructureSize(DataStructure& dataStructure); + /** * @brief Updates the stored DataStructure from preflighting the node. This * should only be called from within the preflight(DataStructure&) method. diff --git a/src/complex/Pipeline/Pipeline.cpp b/src/complex/Pipeline/Pipeline.cpp index 5744b2cbff..62be72b3e3 100644 --- a/src/complex/Pipeline/Pipeline.cpp +++ b/src/complex/Pipeline/Pipeline.cpp @@ -151,6 +151,7 @@ bool Pipeline::execute(const std::atomic_bool& shouldCancel) bool Pipeline::preflight(DataStructure& dataStructure, RenamedPaths& renamedPaths, const std::atomic_bool& shouldCancel, bool allowRenaming) { + m_MemoryRequired = 0; return preflightFrom(0, dataStructure, renamedPaths, shouldCancel, allowRenaming); } @@ -211,6 +212,7 @@ bool Pipeline::preflightFrom(index_type index, DataStructure& dataStructure, Ren PipelineFilter::RenamedPaths renamedPathsRef; bool succeeded = node->preflight(dataStructure, renamedPathsRef, shouldCancel, allowRenaming); stopObservingNode(); + m_MemoryRequired = std::max(m_MemoryRequired, dataStructure.memoryUsage()); if(allowRenaming) { @@ -314,6 +316,7 @@ bool Pipeline::executeFrom(index_type index, DataStructure& dataStructure, const } } + // checkDataStructureSize(dataStructure); setDataStructure(dataStructure); sendPipelineFaultMessage(m_FaultState); @@ -759,8 +762,7 @@ Result Pipeline::FromJson(const nlohmann::json& json, FilterList* filt Result Pipeline::FromFile(const std::filesystem::path& path) { - auto* app = Application::Instance(); - + auto app = Application::Instance(); return FromFile(path, app->getFilterList()); } @@ -790,3 +792,9 @@ void Pipeline::onNotify(AbstractPipelineNode* node, const std::shared_ptr(node, msg)); } + +uint64 Pipeline::checkMemoryRequired() +{ + preflight(); + return m_MemoryRequired; +} diff --git a/src/complex/Pipeline/Pipeline.hpp b/src/complex/Pipeline/Pipeline.hpp index f4d9d16ead..8c31eeef42 100644 --- a/src/complex/Pipeline/Pipeline.hpp +++ b/src/complex/Pipeline/Pipeline.hpp @@ -560,6 +560,12 @@ class COMPLEX_EXPORT Pipeline : public AbstractPipelineNode, protected PipelineN */ void setFilterList(complex::FilterList* filterList); + /** + * @brief Preflights the pipeline and checks the maximum amount of memory required to run the pipeline. + * @return Memory size in Bytes + */ + uint64 checkMemoryRequired(); + protected: /** * @brief Returns implementation-specific json value for the node. @@ -610,5 +616,6 @@ class COMPLEX_EXPORT Pipeline : public AbstractPipelineNode, protected PipelineN std::string m_Name; collection_type m_Collection; FilterList* m_FilterList = nullptr; + uint64 m_MemoryRequired = 0; }; } // namespace complex diff --git a/src/complex/Utilities/DataArrayUtilities.cpp b/src/complex/Utilities/DataArrayUtilities.cpp index 86f954d758..f91081eaad 100644 --- a/src/complex/Utilities/DataArrayUtilities.cpp +++ b/src/complex/Utilities/DataArrayUtilities.cpp @@ -142,6 +142,37 @@ bool CheckArraysHaveSameTupleCount(const DataStructure& dataStructure, const std return types.size() == 1; } +//----------------------------------------------------------------------------- +bool CheckMemoryRequirement(DataStructure& dataStructure, uint64 requiredMemory, std::string& format) +{ + static const uint64 k_AvailableMemory = Memory::GetTotalMemory(); + + // Only check if format is set to in-memory + if(!format.empty()) + { + return true; + } + + Preferences* preferences = Application::GetOrCreateInstance()->getPreferences(); + + const uint64 memoryUsage = dataStructure.memoryUsage() + requiredMemory; + const uint64 largeDataStructureSize = preferences->largeDataStructureSize(); + std::string largeDataFormat = preferences->largeDataFormat(); + + if(memoryUsage >= largeDataStructureSize) + { + // Check if out-of-core is available / enabled + if(largeDataFormat.empty() && memoryUsage >= k_AvailableMemory) + { + return false; + } + // Use out-of-core + format = largeDataFormat; + } + + return true; +} + //----------------------------------------------------------------------------- Result<> ConditionalReplaceValueInArray(const std::string& valueAsStr, DataObject& inputDataObject, const IDataArray& conditionalDataArray, bool invertMask) { @@ -283,4 +314,36 @@ std::unique_ptr InstantiateMaskCompare(IDataArray& maskArray) } } +//----------------------------------------------------------------------------- +bool ConvertIDataArray(const std::shared_ptr& dataArray, const std::string& dataFormat) +{ + auto dataType = dataArray->getDataType(); + switch(dataType) + { + case DataType::int8: + return ConvertDataArray(std::dynamic_pointer_cast>(dataArray), dataFormat); + case DataType::int16: + return ConvertDataArray(std::dynamic_pointer_cast>(dataArray), dataFormat); + case DataType::int32: + return ConvertDataArray(std::dynamic_pointer_cast>(dataArray), dataFormat); + case DataType::int64: + return ConvertDataArray(std::dynamic_pointer_cast>(dataArray), dataFormat); + case DataType::uint8: + return ConvertDataArray(std::dynamic_pointer_cast>(dataArray), dataFormat); + case DataType::uint16: + return ConvertDataArray(std::dynamic_pointer_cast>(dataArray), dataFormat); + case DataType::uint32: + return ConvertDataArray(std::dynamic_pointer_cast>(dataArray), dataFormat); + case DataType::uint64: + return ConvertDataArray(std::dynamic_pointer_cast>(dataArray), dataFormat); + case DataType::boolean: + return ConvertDataArray(std::dynamic_pointer_cast>(dataArray), dataFormat); + case DataType::float32: + return ConvertDataArray(std::dynamic_pointer_cast>(dataArray), dataFormat); + case DataType::float64: + return ConvertDataArray(std::dynamic_pointer_cast>(dataArray), dataFormat); + default: + return false; + } +} } // namespace complex diff --git a/src/complex/Utilities/DataArrayUtilities.hpp b/src/complex/Utilities/DataArrayUtilities.hpp index 234b0110bd..af2c67e6ac 100644 --- a/src/complex/Utilities/DataArrayUtilities.hpp +++ b/src/complex/Utilities/DataArrayUtilities.hpp @@ -12,6 +12,7 @@ #include "complex/DataStructure/NeighborList.hpp" #include "complex/DataStructure/StringArray.hpp" #include "complex/Filter/Output.hpp" +#include "complex/Utilities/MemoryUtilities.hpp" #include "complex/Utilities/ParallelAlgorithmUtilities.hpp" #include "complex/Utilities/TemplateHelpers.hpp" #include "complex/complex_export.hpp" @@ -364,6 +365,11 @@ std::shared_ptr> CreateDataStore(const typename IDataStore: } case IDataAction::Mode::Execute: { uint64 dataSize = CalculateDataSize(tupleShape, componentShape); + auto* preferences = Application::GetOrCreateInstance()->getPreferences(); + if(preferences->forceOocData()) + { + dataFormat = preferences->largeDataFormat(); + } auto ioCollection = Application::GetOrCreateInstance()->getIOCollection(); ioCollection->checkStoreDataFormat(dataSize, dataFormat); return ioCollection->createDataStoreWithType(dataFormat, tupleShape, componentShape); @@ -374,6 +380,8 @@ std::shared_ptr> CreateDataStore(const typename IDataStore: } } +COMPLEX_EXPORT bool CheckMemoryRequirement(DataStructure& dataStructure, uint64 requiredMemory, std::string& format); + /** * @brief Creates a DataArray with the given properties * @tparam T Primitive Type (int, float, ...) @@ -423,8 +431,18 @@ Result<> CreateArray(DataStructure& dataStructure, const std::vector& tup std::string name = path[last]; + const usize numTuples = std::accumulate(tupleShape.cbegin(), tupleShape.cend(), static_cast(1), std::multiplies<>()); + uint64 requiredMemory = numTuples * numComponents * sizeof(T); + if(!CheckMemoryRequirement(dataStructure, requiredMemory, dataFormat)) + { + uint64 totalMemory = requiredMemory + dataStructure.memoryUsage(); + uint64 availableMemory = Memory::GetTotalMemory(); + return MakeErrorResult( + -267, fmt::format("CreateArray: Cannot create DataArray '{}'.\n\tTotal memory required for DataStructure: '{}' Bytes.\n\tTotal memory: '{}' Bytes", name, totalMemory, availableMemory)); + } + auto store = CreateDataStore(tupleShape, compShape, mode, dataFormat); - auto dataArray = DataArray::Create(dataStructure, name, std::move(store), dataObjectId); + auto dataArray = DataArray::Create(dataStructure, name, store, dataObjectId); if(dataArray == nullptr) { if(dataStructure.getId(path).has_value()) @@ -436,7 +454,7 @@ Result<> CreateArray(DataStructure& dataStructure, const std::vector& tup { auto* attrMatrix = dynamic_cast(parentObject); std::string amShape = fmt::format("Attribute Matrix Tuple Dims: {}", fmt::join(attrMatrix->getShape(), " x ")); - std::string arrayShape = fmt::format("Data Array Tuple Shape: {}", fmt::join(tupleShape, " x ")); + std::string arrayShape = fmt::format("Data Array Tuple Shape: {}", fmt::join(store->getTupleShape(), " x ")); return MakeErrorResult(-265, fmt::format("CreateArray: Unable to create Data Array '{}' inside Attribute matrix '{}'. Mismatch of tuple dimensions. The created Data Array must have the same tuple " "dimensions or the same total number of tuples.\n{}\n{}", @@ -451,6 +469,45 @@ Result<> CreateArray(DataStructure& dataStructure, const std::vector& tup return {}; } +template +std::shared_ptr> ConvertDataStore(const AbstractDataStore& dataStore, const std::string& dataFormat) +{ + if(dataStore.getDataFormat() == dataFormat) + { + return nullptr; + } + + auto ioCollection = Application::GetOrCreateInstance()->getIOCollection(); + std::shared_ptr> newStore = ioCollection->createDataStoreWithType(dataFormat, dataStore.getTupleShape(), dataStore.getComponentShape()); + if(newStore == nullptr) + { + return nullptr; + } + + newStore->copy(dataStore); + return newStore; +} + +template +bool ConvertDataArray(const std::shared_ptr> dataArray, const std::string& dataFormat) +{ + if(dataArray == nullptr) + { + return false; + } + const AbstractDataStore& dataStore = dataArray->getDataStoreRef(); + auto convertedDataStore = ConvertDataStore(dataStore, dataFormat); + if(convertedDataStore == nullptr) + { + return false; + } + + dataArray->setDataStore(convertedDataStore); + return true; +} + +bool ConvertIDataArray(const std::shared_ptr& dataArray, const std::string& dataFormat); + /** * @brief Creates a NeighborList array with the given properties * @tparam T Primitive Type (int, float, ...) diff --git a/src/complex/Utilities/DataGroupUtilities.cpp b/src/complex/Utilities/DataGroupUtilities.cpp index 064fb20905..a1a4bef254 100644 --- a/src/complex/Utilities/DataGroupUtilities.cpp +++ b/src/complex/Utilities/DataGroupUtilities.cpp @@ -78,7 +78,7 @@ bool RemoveInactiveObjects(DataStructure& dataStructure, const DataPath& feature // Loop over all the points and correct all the feature names size_t totalPoints = cellFeatureIds.getNumberOfTuples(); - auto& featureIds = cellFeatureIds.getIDataStoreRefAs(); + auto& featureIds = cellFeatureIds.getDataStoreRef(); bool featureIdsChanged = false; for(size_t i = 0; i < totalPoints; i++) { diff --git a/src/complex/Utilities/IParallelAlgorithm.cpp b/src/complex/Utilities/IParallelAlgorithm.cpp new file mode 100644 index 0000000000..26ab7f01f8 --- /dev/null +++ b/src/complex/Utilities/IParallelAlgorithm.cpp @@ -0,0 +1,61 @@ +#include "IParallelAlgorithm.hpp" + +#include "complex/Core/Application.hpp" + +namespace complex +{ +// ----------------------------------------------------------------------------- +bool IParallelAlgorithm::CheckArraysInMemory(const AlgorithmArrays& arrays) +{ + if(arrays.empty()) + { + return true; + } + + for(const auto* arrayPtr : arrays) + { + if(arrayPtr == nullptr) + { + continue; + } + + if(!arrayPtr->getIDataStoreRef().getDataFormat().empty()) + { + return false; + } + } + + return true; +} + +// ----------------------------------------------------------------------------- +IParallelAlgorithm::IParallelAlgorithm() +{ +#ifdef COMPLEX_ENABLE_MULTICORE + // Do not run OOC data in parallel by default. + m_RunParallel = !Application::GetOrCreateInstance()->getPreferences()->useOocData(); +#endif +} + +// ----------------------------------------------------------------------------- +IParallelAlgorithm::~IParallelAlgorithm() = default; + +// ----------------------------------------------------------------------------- +bool IParallelAlgorithm::getParallelizationEnabled() const +{ + return m_RunParallel; +} + +// ----------------------------------------------------------------------------- +void IParallelAlgorithm::setParallelizationEnabled(bool doParallel) +{ +#ifdef COMPLEX_ENABLE_MULTICORE + m_RunParallel = doParallel; +#endif +} +// ----------------------------------------------------------------------------- +void IParallelAlgorithm::requireArraysInMemory(const AlgorithmArrays& arrays) +{ + setParallelizationEnabled(!CheckArraysInMemory(arrays)); +} +} // namespace complex diff --git a/src/complex/Utilities/IParallelAlgorithm.hpp b/src/complex/Utilities/IParallelAlgorithm.hpp new file mode 100644 index 0000000000..feea7739e4 --- /dev/null +++ b/src/complex/Utilities/IParallelAlgorithm.hpp @@ -0,0 +1,48 @@ +#pragma once + +#include "complex/Common/Types.hpp" +#include "complex/DataStructure/IDataArray.hpp" +#include "complex/complex_export.hpp" + +#include + +namespace complex +{ +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; + IParallelAlgorithm& operator=(IParallelAlgorithm&&) noexcept = default; + + /** + * @brief Returns true if parallelization is enabled. Returns false otherwise. + * @return + */ + bool getParallelizationEnabled() const; + + /** + * @brief Sets whether parallelization is enabled. + * @param doParallel + */ + void setParallelizationEnabled(bool doParallel); + + void requireArraysInMemory(const AlgorithmArrays& arrays); + +protected: + IParallelAlgorithm(); + ~IParallelAlgorithm(); + +private: +#ifdef COMPLEX_ENABLE_MULTICORE + bool m_RunParallel = true; +#else + bool m_RunParallel = false; +#endif +}; +} // namespace complex diff --git a/src/complex/Utilities/MemoryUtilities.cpp b/src/complex/Utilities/MemoryUtilities.cpp new file mode 100644 index 0000000000..d9d5bd1348 --- /dev/null +++ b/src/complex/Utilities/MemoryUtilities.cpp @@ -0,0 +1,62 @@ +#include "MemoryUtilities.hpp" + +#if defined(_WIN32) +#include +#include +#else +#include +#endif + +namespace complex::Memory +{ +dataStorage GetAvailableStorage() +{ + return GetAvailableStorageOnDrive(std::filesystem::temp_directory_path()); +} + +#if defined(_WIN32) +uint64 GetTotalMemory() +{ + uint64 totalKilos = 0; + GetPhysicallyInstalledSystemMemory(&totalKilos); + + return totalKilos * 1024; +} + +dataStorage GetAvailableStorageOnDrive(const std::filesystem::path& path) +{ + const std::filesystem::path rootDirectory = path.root_directory(); + const std::filesystem::path driveDirectory = path.root_name(); + + dataStorage storage; + const std::string driveName = driveDirectory.string(); + + if(GetDriveType(driveName.data()) != DRIVE_FIXED) + { + std::printf("not a fixed drive, skipping"); + } + else + { + GetDiskFreeSpaceEx(driveName.data(), NULL, (PULARGE_INTEGER)&storage.total, (PULARGE_INTEGER)&storage.free); + } + + return storage; +} +#else +uint64 GetTotalMemory() +{ + long pages = sysconf(_SC_PHYS_PAGES); + long page_size = sysconf(_SC_PAGE_SIZE); + return pages * page_size; +} + +dataStorage GetAvailableStorageOnDrive(const std::filesystem::path& directory) +{ + std::filesystem::space_info info = std::filesystem::space(directory); + dataStorage storage; + storage.free = info.available; + storage.total = info.capacity; + return storage; +} +#endif +} // namespace complex::Memory diff --git a/src/complex/Utilities/MemoryUtilities.hpp b/src/complex/Utilities/MemoryUtilities.hpp new file mode 100644 index 0000000000..2adbdd5ec6 --- /dev/null +++ b/src/complex/Utilities/MemoryUtilities.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include "complex/Common/Types.hpp" +#include "complex/complex_export.hpp" + +#include + +namespace complex +{ +namespace Memory +{ +struct COMPLEX_EXPORT dataStorage +{ + uint64_t total = 0; + uint64_t free = 0; +}; + +uint64 COMPLEX_EXPORT GetTotalMemory(); +dataStorage COMPLEX_EXPORT GetAvailableStorage(); +dataStorage COMPLEX_EXPORT GetAvailableStorageOnDrive(const std::filesystem::path& path); +} // namespace Memory +} // namespace complex diff --git a/src/complex/Utilities/ParallelData2DAlgorithm.cpp b/src/complex/Utilities/ParallelData2DAlgorithm.cpp index 60a6acd2fc..3b280de14c 100644 --- a/src/complex/Utilities/ParallelData2DAlgorithm.cpp +++ b/src/complex/Utilities/ParallelData2DAlgorithm.cpp @@ -8,18 +8,6 @@ ParallelData2DAlgorithm::ParallelData2DAlgorithm() = default; // ----------------------------------------------------------------------------- ParallelData2DAlgorithm::~ParallelData2DAlgorithm() = default; -// ----------------------------------------------------------------------------- -bool ParallelData2DAlgorithm::getParallelizationEnabled() const -{ - return m_RunParallel; -} - -// ----------------------------------------------------------------------------- -void ParallelData2DAlgorithm::setParallelizationEnabled(bool doParallel) -{ - m_RunParallel = doParallel; -} - // ----------------------------------------------------------------------------- Range2D ParallelData2DAlgorithm::getRange() const { diff --git a/src/complex/Utilities/ParallelData2DAlgorithm.hpp b/src/complex/Utilities/ParallelData2DAlgorithm.hpp index 1008108c2c..ce13164a4c 100644 --- a/src/complex/Utilities/ParallelData2DAlgorithm.hpp +++ b/src/complex/Utilities/ParallelData2DAlgorithm.hpp @@ -2,6 +2,7 @@ #include "complex/Common/Range2D.hpp" #include "complex/Common/Types.hpp" +#include "complex/Utilities/IParallelAlgorithm.hpp" #include "complex/complex_export.hpp" #ifdef COMPLEX_ENABLE_MULTICORE @@ -23,7 +24,7 @@ namespace complex * utilizes TBB for parallelization and will fallback to non-parallelization if it is not * available or the parallelization is disabled. */ -class COMPLEX_EXPORT ParallelData2DAlgorithm +class COMPLEX_EXPORT ParallelData2DAlgorithm : public IParallelAlgorithm { public: using RangeType = Range2D; @@ -36,18 +37,6 @@ class COMPLEX_EXPORT ParallelData2DAlgorithm ParallelData2DAlgorithm& operator=(const ParallelData2DAlgorithm&) = default; ParallelData2DAlgorithm& operator=(ParallelData2DAlgorithm&&) noexcept = default; - /** - * @brief Returns true if parallelization is enabled. Returns false otherwise. - * @return - */ - bool getParallelizationEnabled() const; - - /** - * @brief Sets whether parallelization is enabled. - * @param doParallel - */ - void setParallelizationEnabled(bool doParallel); - /** * @brief Returns the range to operate over. * @return @@ -129,7 +118,7 @@ class COMPLEX_EXPORT ParallelData2DAlgorithm void executeRange(const Body& body, const RangeType& range) { #ifdef COMPLEX_ENABLE_MULTICORE - if(m_RunParallel) + if(getParallelizationEnabled()) { tbb::auto_partitioner partitioner; tbb::blocked_range2d tbbRange(range.minRow(), range.maxRow(), range.minCol(), range.maxCol()); @@ -146,11 +135,6 @@ class COMPLEX_EXPORT ParallelData2DAlgorithm private: RangeType m_Range; std::optional m_ChunkSize; -#ifdef COMPLEX_ENABLE_MULTICORE - bool m_RunParallel = true; -#else - bool m_RunParallel = false; -#endif }; } // namespace complex diff --git a/src/complex/Utilities/ParallelData3DAlgorithm.cpp b/src/complex/Utilities/ParallelData3DAlgorithm.cpp index f53ddccc8b..c9097cbb46 100644 --- a/src/complex/Utilities/ParallelData3DAlgorithm.cpp +++ b/src/complex/Utilities/ParallelData3DAlgorithm.cpp @@ -8,18 +8,6 @@ ParallelData3DAlgorithm::ParallelData3DAlgorithm() = default; // ----------------------------------------------------------------------------- ParallelData3DAlgorithm::~ParallelData3DAlgorithm() = default; -// ----------------------------------------------------------------------------- -bool ParallelData3DAlgorithm::getParallelizationEnabled() const -{ - return m_RunParallel; -} - -// ----------------------------------------------------------------------------- -void ParallelData3DAlgorithm::setParallelizationEnabled(bool doParallel) -{ - m_RunParallel = doParallel; -} - // ----------------------------------------------------------------------------- ParallelData3DAlgorithm::RangeType ParallelData3DAlgorithm::getRange() const { diff --git a/src/complex/Utilities/ParallelData3DAlgorithm.hpp b/src/complex/Utilities/ParallelData3DAlgorithm.hpp index c63c70d3c9..68988bd0c5 100644 --- a/src/complex/Utilities/ParallelData3DAlgorithm.hpp +++ b/src/complex/Utilities/ParallelData3DAlgorithm.hpp @@ -2,6 +2,7 @@ #include "complex/Common/Range3D.hpp" #include "complex/Common/Types.hpp" +#include "complex/Utilities/IParallelAlgorithm.hpp" #include "complex/complex_export.hpp" #ifdef COMPLEX_ENABLE_MULTICORE @@ -22,7 +23,7 @@ namespace complex * utilizes TBB for parallelization and will fallback to non-parallelization if it is not * available or the parallelization is disabled. */ -class COMPLEX_EXPORT ParallelData3DAlgorithm +class COMPLEX_EXPORT ParallelData3DAlgorithm : public IParallelAlgorithm { public: using RangeType = Range3D; @@ -35,18 +36,6 @@ class COMPLEX_EXPORT ParallelData3DAlgorithm ParallelData3DAlgorithm& operator=(const ParallelData3DAlgorithm&) = default; ParallelData3DAlgorithm& operator=(ParallelData3DAlgorithm&&) noexcept = default; - /** - * @brief Returns true if parallelization is enabled. Returns false otherwise. - * @return - */ - bool getParallelizationEnabled() const; - - /** - * @brief Sets whether parallelization is enabled. - * @param doParallel - */ - void setParallelizationEnabled(bool doParallel); - /** * @brief Returns the range to operate over. * @return @@ -138,7 +127,7 @@ class COMPLEX_EXPORT ParallelData3DAlgorithm void executeRange(const Body& body, const RangeType& range) { #ifdef COMPLEX_ENABLE_MULTICORE - if(m_RunParallel) + if(getParallelizationEnabled()) { tbb::auto_partitioner partitioner; tbb::blocked_range3d tbbRange(range[4], range[5], range[2], range[3], range[0], range[1]); @@ -155,10 +144,5 @@ class COMPLEX_EXPORT ParallelData3DAlgorithm private: RangeType m_Range; std::optional m_ChunkSize; -#ifdef COMPLEX_ENABLE_MULTICORE - bool m_RunParallel = true; -#else - bool m_RunParallel = false; -#endif }; } // namespace complex diff --git a/src/complex/Utilities/ParallelDataAlgorithm.cpp b/src/complex/Utilities/ParallelDataAlgorithm.cpp index c90b4ab402..497feeecd2 100644 --- a/src/complex/Utilities/ParallelDataAlgorithm.cpp +++ b/src/complex/Utilities/ParallelDataAlgorithm.cpp @@ -8,18 +8,6 @@ ParallelDataAlgorithm::ParallelDataAlgorithm() = default; // ----------------------------------------------------------------------------- ParallelDataAlgorithm::~ParallelDataAlgorithm() = default; -// ----------------------------------------------------------------------------- -bool ParallelDataAlgorithm::getParallelizationEnabled() const -{ - return m_RunParallel; -} - -// ----------------------------------------------------------------------------- -void ParallelDataAlgorithm::setParallelizationEnabled(bool doParallel) -{ - m_RunParallel = doParallel; -} - // ----------------------------------------------------------------------------- Range ParallelDataAlgorithm::getRange() const { diff --git a/src/complex/Utilities/ParallelDataAlgorithm.hpp b/src/complex/Utilities/ParallelDataAlgorithm.hpp index 4259276c03..f84c68e373 100644 --- a/src/complex/Utilities/ParallelDataAlgorithm.hpp +++ b/src/complex/Utilities/ParallelDataAlgorithm.hpp @@ -1,6 +1,7 @@ #pragma once #include "complex/Common/Range.hpp" +#include "complex/Utilities/IParallelAlgorithm.hpp" #include "complex/complex_export.hpp" #ifdef COMPLEX_ENABLE_MULTICORE @@ -20,7 +21,7 @@ namespace complex * utilizes TBB for parallelization and will fallback to non-parallelization if it is not * available or the parallelization is disabled. */ -class COMPLEX_EXPORT ParallelDataAlgorithm +class COMPLEX_EXPORT ParallelDataAlgorithm : public IParallelAlgorithm { public: using RangeType = Range; @@ -33,18 +34,6 @@ class COMPLEX_EXPORT ParallelDataAlgorithm ParallelDataAlgorithm& operator=(const ParallelDataAlgorithm&) = default; ParallelDataAlgorithm& operator=(ParallelDataAlgorithm&&) noexcept = default; - /** - * @brief Returns true if parallelization is enabled. Returns false otherwise. - * @return - */ - bool getParallelizationEnabled() const; - - /** - * @brief Sets whether parallelization is enabled. - * @param doParallel - */ - void setParallelizationEnabled(bool doParallel); - /** * @brief Returns the range to operate over. * @return @@ -72,7 +61,7 @@ class COMPLEX_EXPORT ParallelDataAlgorithm void execute(const Body& body) { #ifdef COMPLEX_ENABLE_MULTICORE - if(m_RunParallel) + if(getParallelizationEnabled()) { tbb::auto_partitioner partitioner; tbb::blocked_range tbbRange(m_Range[0], m_Range[1]); @@ -88,10 +77,5 @@ class COMPLEX_EXPORT ParallelDataAlgorithm private: RangeType m_Range; -#ifdef COMPLEX_ENABLE_MULTICORE - bool m_RunParallel = true; -#else - bool m_RunParallel = false; -#endif }; } // namespace complex diff --git a/src/complex/Utilities/ParallelTaskAlgorithm.cpp b/src/complex/Utilities/ParallelTaskAlgorithm.cpp index 7a02f07012..cf7af556db 100644 --- a/src/complex/Utilities/ParallelTaskAlgorithm.cpp +++ b/src/complex/Utilities/ParallelTaskAlgorithm.cpp @@ -16,18 +16,6 @@ ParallelTaskAlgorithm::~ParallelTaskAlgorithm() #endif } -// ----------------------------------------------------------------------------- -bool ParallelTaskAlgorithm::getParallelizationEnabled() const -{ - return m_RunParallel; -} - -// ----------------------------------------------------------------------------- -void ParallelTaskAlgorithm::setParallelizationEnabled(bool doParallel) -{ - m_RunParallel = doParallel; -} - // ----------------------------------------------------------------------------- uint32_t ParallelTaskAlgorithm::getMaxThreads() const { diff --git a/src/complex/Utilities/ParallelTaskAlgorithm.hpp b/src/complex/Utilities/ParallelTaskAlgorithm.hpp index b3d0e1a920..028697098f 100644 --- a/src/complex/Utilities/ParallelTaskAlgorithm.hpp +++ b/src/complex/Utilities/ParallelTaskAlgorithm.hpp @@ -1,5 +1,6 @@ #pragma once +#include "complex/Utilities/IParallelAlgorithm.hpp" #include "complex/complex_export.hpp" #ifdef COMPLEX_ENABLE_MULTICORE @@ -19,24 +20,12 @@ namespace complex * TBB for parallelization and will fallback to non-parallelization if it is not available * or the parallelization is disabled. */ -class COMPLEX_EXPORT ParallelTaskAlgorithm +class COMPLEX_EXPORT ParallelTaskAlgorithm : public IParallelAlgorithm { public: ParallelTaskAlgorithm(); virtual ~ParallelTaskAlgorithm(); - /** - * @brief Returns true if parallelization is enabled. Returns false otherwise. - * @return - */ - bool getParallelizationEnabled() const; - - /** - * @brief Sets whether parallelization is enabled. - * @param doParallel - */ - void setParallelizationEnabled(bool doParallel); - /** * @brief Return maximum threads to use for parallelization. If Parallel Algorithms * is not enabled, the maximum hardware concurrency is returned instead. @@ -61,7 +50,7 @@ class COMPLEX_EXPORT ParallelTaskAlgorithm void execute(const Body& body) { #ifdef COMPLEX_ENABLE_MULTICORE - if(m_RunParallel) + if(getParallelizationEnabled()) { m_TaskGroup.run(body); m_CurThreads++; @@ -85,12 +74,10 @@ class COMPLEX_EXPORT ParallelTaskAlgorithm private: #ifdef COMPLEX_ENABLE_MULTICORE uint32_t m_MaxThreads = std::thread::hardware_concurrency(); - bool m_RunParallel = true; tbb::task_group m_TaskGroup; uint32_t m_CurThreads = 0; #else uint32_t m_MaxThreads = 1; - bool m_RunParallel = false; #endif }; } // namespace complex diff --git a/src/complex/Utilities/SegmentFeatures.cpp b/src/complex/Utilities/SegmentFeatures.cpp index 9521e8c803..7f8cb4f8ca 100644 --- a/src/complex/Utilities/SegmentFeatures.cpp +++ b/src/complex/Utilities/SegmentFeatures.cpp @@ -155,12 +155,12 @@ void SegmentFeatures::randomizeFeatureIds(complex::Int32Array* featureIds, uint6 auto generator = initializeStaticVoxelSeedGenerator(distribution, rangeMin, rangeMax); DataStructure tmpStructure; - auto rndNumbers = Int64Array::CreateWithStore>(tmpStructure, std::string("_INTERNAL_USE_ONLY_NewFeatureIds"), std::vector{totalFeatures}, std::vector{1}); - auto rndStore = rndNumbers->getDataStore(); + auto* rndNumbers = Int64Array::CreateWithStore>(tmpStructure, std::string("_INTERNAL_USE_ONLY_NewFeatureIds"), std::vector{totalFeatures}, std::vector{1}); + auto& rndStore = rndNumbers->getDataStoreRef(); for(int64 i = 0; i < totalFeatures; ++i) { - rndStore->setValue(i, i); + rndStore.setValue(i, i); } int64 r = 0; @@ -174,15 +174,15 @@ void SegmentFeatures::randomizeFeatureIds(complex::Int32Array* featureIds, uint6 { continue; } - temp = rndStore->getValue(i); - rndStore->setValue(i, rndStore->getValue(r)); - rndStore->setValue(r, temp); + temp = rndStore.getValue(i); + rndStore.setValue(i, rndStore.getValue(r)); + rndStore.setValue(r, temp); } // Now adjust all the Grain Id values for each Voxel - auto featureIdsStore = featureIds->getDataStore(); + auto& featureIdsStore = featureIds->getDataStoreRef(); for(int64 i = 0; i < totalPoints; ++i) { - featureIdsStore->setValue(i, rndStore->getValue(featureIdsStore->getValue(i))); + featureIdsStore[i] = rndStore[featureIdsStore[i]]; } } diff --git a/src/nxrunner/src/nxrunner.cpp b/src/nxrunner/src/nxrunner.cpp index eee59821ca..b9d13e75f8 100644 --- a/src/nxrunner/src/nxrunner.cpp +++ b/src/nxrunner/src/nxrunner.cpp @@ -46,12 +46,13 @@ inline constexpr StringLiteral k_ExecuteParamShort = "-e"; inline constexpr StringLiteral k_PreflightParamShort = "-p"; inline constexpr StringLiteral k_LogFileParamShort = "-l"; -void LoadApp(complex::Application& app) +void LoadApp() { + auto app = Application::GetOrCreateInstance(); // Try loading plugins from the directory that the executable is in. // This is the default for developer build trees and CI build trees - fs::path appPath = app.getCurrentDir(); - app.loadPlugins(appPath, true); + fs::path appPath = app->getCurrentDir(); + app->loadPlugins(appPath, true); // For non-windows platforms we need to look in the actual 'Plugins' // directory which is up one directory from the executable. @@ -62,7 +63,7 @@ void LoadApp(complex::Application& app) if(fs::exists(appPath / "Plugins")) { appPath = appPath / "Plugins"; - app.loadPlugins(appPath, true); + app->loadPlugins(appPath, true); } } #endif @@ -441,8 +442,8 @@ int main(int argc, char* argv[]) } // Load the Complex Application instance and load the plugins - complex::Application app; - LoadApp(app); + auto app = complex::Application::GetOrCreateInstance(); + LoadApp(); #if COMPLEX_EMBED_PYTHON py::scoped_interpreter guard{}; diff --git a/test/DataArrayTest.cpp b/test/DataArrayTest.cpp index 9b1fd22947..101b00e46c 100644 --- a/test/DataArrayTest.cpp +++ b/test/DataArrayTest.cpp @@ -13,6 +13,11 @@ using namespace complex; +namespace unit_test +{ +inline constexpr StringLiteral k_BuildDir = COMPLEX_BUILD_DIR; +} + TEST_CASE("Array") { FloatVec3 vec0(3.0F, 4.0F, 5.0F); @@ -52,6 +57,7 @@ TEST_CASE("DataArrayCreation") TEST_CASE("complex::DataArray Copy TupleTest", "[complex][DataArray]") { + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); const std::string k_DataArrayName("DataArray"); const DataPath k_DataPath({k_DataArrayName}); @@ -124,3 +130,23 @@ TEST_CASE("DataStore Test") REQUIRE(dataStore[8] == 99); REQUIRE(dataStore.getComponentValue(2, 2) == 99); } + +TEST_CASE("Copy DataStore", "DataArray") +{ + IDataStore::ShapeType tupleShape{5}; + IDataStore::ShapeType componentShape{3}; + DataStore dataStore(tupleShape, componentShape, 5); + usize size = dataStore.getSize(); + for(usize i = 0; i < size; i++) + { + dataStore[i] = i; + } + + DataStore dataStore2(tupleShape, componentShape, 5); + dataStore2.copy(dataStore); + + for(usize i = 0; i < size; i++) + { + REQUIRE(dataStore[i] == dataStore2[i]); + } +} diff --git a/test/DynamicFilterInstantiationTest.cpp b/test/DynamicFilterInstantiationTest.cpp index 067679a7fe..462b5b863f 100644 --- a/test/DynamicFilterInstantiationTest.cpp +++ b/test/DynamicFilterInstantiationTest.cpp @@ -10,8 +10,7 @@ */ TEST_CASE("Filter List Instantiation") { - std::shared_ptr app = std::make_shared(); - app->loadPlugins(complex::unit_test::k_BuildDir.view(), true); + Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); auto* filterList = complex::Application::Instance()->getFilterList(); REQUIRE(filterList != nullptr); diff --git a/test/H5Test.cpp b/test/H5Test.cpp index ecb3840969..5bdb6b6788 100644 --- a/test/H5Test.cpp +++ b/test/H5Test.cpp @@ -85,7 +85,7 @@ bool equalsf(const FloatVec3& lhs, const FloatVec3& rhs) #if TEST_LEGACY TEST_CASE("Read Legacy DREAM.3D Data") { - Application app; + auto app = Application::GetOrCreateInstance(); std::filesystem::path filepath = GetLegacyFilepath(); REQUIRE(exists(filepath)); Result result = DREAM3D::ImportDataStructureFromFile(filepath, true); @@ -566,7 +566,7 @@ void checkNodeGeomData(const DataStructure& dataStructure, const NodeBasedGeomDa TEST_CASE("Node Based Geometry IO") { - Application app; + auto app = Application::GetOrCreateInstance(); fs::path dataDir = GetDataDir(); @@ -618,7 +618,7 @@ TEST_CASE("Node Based Geometry IO") TEST_CASE("NeighborList IO") { - Application app; + auto app = Application::GetOrCreateInstance(); fs::path dataDir = GetDataDir(); @@ -671,7 +671,7 @@ TEST_CASE("NeighborList IO") TEST_CASE("DataArray IO") { - Application app; + auto app = Application::GetOrCreateInstance(); fs::path dataDir = GetDataDir(); diff --git a/test/IOFormat.cpp b/test/IOFormat.cpp index d265b1dcfa..73ffbcecfd 100644 --- a/test/IOFormat.cpp +++ b/test/IOFormat.cpp @@ -2,14 +2,39 @@ #include "complex/Core/Application.hpp" #include "complex/DataStructure/IO/Generic/DataIOCollection.hpp" +#include "complex/Utilities/MemoryUtilities.hpp" using namespace complex; TEST_CASE("Contains HDF5 IO Support", "IOTest") { - Application app; + auto app = Application::GetOrCreateInstance(); - auto ioCollection = app.getIOCollection(); + auto ioCollection = app->getIOCollection(); auto h5IO = ioCollection->getManager("HDF5"); REQUIRE(h5IO != nullptr); } + +TEST_CASE("Memory Check", "IOTest") +{ + REQUIRE(Memory::GetTotalMemory() > 0); + const auto storage = Memory::GetAvailableStorage(); + REQUIRE(storage.total > 0); + REQUIRE(storage.free > 0); +} + +TEST_CASE("Target DataStructure Size", "IOTest") +{ + auto* preferences = Application::GetOrCreateInstance()->getPreferences(); + REQUIRE(preferences->largeDataStructureSize() > 0); + + const uint64 memory = Memory::GetTotalMemory(); + const uint64 largeDataSize = preferences->valueAs(Preferences::k_LargeDataSize_Key); + const uint64 minimumRemaining = 2 * largeDataSize; + uint64 targetReducedSize = (memory - 2 * largeDataSize); + if(minimumRemaining >= memory) + { + targetReducedSize = memory / 2; + } + REQUIRE(preferences->defaultValueAs(Preferences::k_LargeDataStructureSize_Key) == targetReducedSize); +} diff --git a/test/PipelineSaveTest.cpp b/test/PipelineSaveTest.cpp index ceb92297ab..f6616d7530 100644 --- a/test/PipelineSaveTest.cpp +++ b/test/PipelineSaveTest.cpp @@ -9,9 +9,9 @@ using namespace complex; TEST_CASE("Save Filters To Json") { - Application app; - app.loadPlugins(unit_test::k_BuildDir.view()); - auto* filterList = app.getFilterList(); + auto app = Application::GetOrCreateInstance(); + app->loadPlugins(unit_test::k_BuildDir.view()); + auto* filterList = app->getFilterList(); REQUIRE(filterList != nullptr); const auto& handles = filterList->getFilterHandles(); @@ -36,9 +36,9 @@ TEST_CASE("Save Filters To Json") TEST_CASE("Save Pipeline To Json") { - Application app; - app.loadPlugins(unit_test::k_BuildDir.view()); - auto* filterList = app.getFilterList(); + auto app = Application::GetOrCreateInstance(); + app->loadPlugins(unit_test::k_BuildDir.view()); + auto* filterList = app->getFilterList(); REQUIRE(filterList != nullptr); const auto& handles = filterList->getFilterHandles(); diff --git a/test/PluginTest.cpp b/test/PluginTest.cpp index ea50b4839b..6d8d9895e0 100644 --- a/test/PluginTest.cpp +++ b/test/PluginTest.cpp @@ -25,8 +25,8 @@ const FilterHandle k_Test2FilterHandle(k_Test2FilterId, k_TestTwoPluginId); TEST_CASE("Test Loading Plugins") { - Application app; - app.loadPlugins(unit_test::k_BuildDir.view()); + auto app = Application::GetOrCreateInstance(); + app->loadPlugins(unit_test::k_BuildDir.view()); auto* filterListPtr = Application::Instance()->getFilterList(); const auto& filterHandles = filterListPtr->getFilterHandles(); @@ -63,12 +63,12 @@ TEST_CASE("Test Loading Plugins") TEST_CASE("Test Singleton") { - Application* appPtr = new Application(); - appPtr->loadPlugins(unit_test::k_BuildDir.view()); + auto app = Application::GetOrCreateInstance(); + app->loadPlugins(unit_test::k_BuildDir.view()); - REQUIRE(appPtr != nullptr); + REQUIRE(app != nullptr); - auto* filterListPtr = appPtr->getFilterList(); + auto* filterListPtr = app->getFilterList(); const auto& filterHandles = filterListPtr->getFilterHandles(); auto plugins = filterListPtr->getLoadedPlugins(); @@ -102,13 +102,14 @@ TEST_CASE("Test Singleton") filter2->execute(dataStructure, {}); } - delete Application::Instance(); + Application::DeleteInstance(); REQUIRE(Application::Instance() == nullptr); } TEST_CASE("Test Filter Help Text") { - Application* appPtr = new Application(); + auto appPtr = Application::GetOrCreateInstance(); + appPtr->loadPlugins(unit_test::k_BuildDir.view()); REQUIRE(appPtr != nullptr); appPtr->loadPlugins(unit_test::k_BuildDir.view()); @@ -152,7 +153,7 @@ TEST_CASE("Test Filter Help Text") } } - delete Application::Instance(); + Application::DeleteInstance(); REQUIRE(Application::Instance() == nullptr); if(!output.str().empty()) diff --git a/test/UnitTestCommon/include/complex/UnitTest/UnitTestCommon.hpp b/test/UnitTestCommon/include/complex/UnitTest/UnitTestCommon.hpp index f4a1c24f23..343abe138a 100644 --- a/test/UnitTestCommon/include/complex/UnitTest/UnitTestCommon.hpp +++ b/test/UnitTestCommon/include/complex/UnitTest/UnitTestCommon.hpp @@ -208,10 +208,6 @@ namespace UnitTest { inline constexpr float EPSILON = 0.0001; -struct make_shared_enabler : public complex::Application -{ -}; - /** * @brief This class will decompress a tar.gz file using the locally installed copy of cmake and when * then class goes out of scope the extracted contents will be deleted from disk. diff --git a/wrapping/python/CxPybind/CxPybind/CxPybind.hpp b/wrapping/python/CxPybind/CxPybind/CxPybind.hpp index 4c1b71f62c..8fc3f9861b 100644 --- a/wrapping/python/CxPybind/CxPybind/CxPybind.hpp +++ b/wrapping/python/CxPybind/CxPybind/CxPybind.hpp @@ -199,12 +199,12 @@ class Internals Application* getApp() { - return m_App; + return m_App.get(); } const Application* getApp() const { - return m_App; + return m_App.get(); } template @@ -281,7 +281,7 @@ class Internals std::unordered_map m_ParameterConversionMap; std::unordered_map> m_PluginFilterMap; std::unordered_map> m_PythonPlugins; - Application* m_App; + std::shared_ptr m_App; }; inline py::dict ConvertArgsToDict(const Internals& internals, const Parameters& parameters, const Arguments& args) diff --git a/wrapping/python/docs/generate_sphinx_docs.cpp b/wrapping/python/docs/generate_sphinx_docs.cpp index 96618a3eef..25fbfd438e 100644 --- a/wrapping/python/docs/generate_sphinx_docs.cpp +++ b/wrapping/python/docs/generate_sphinx_docs.cpp @@ -886,8 +886,8 @@ int main(int32_t argc, char** argv) { GenerateParameterList(); - Application app; - app.loadPlugins(COMPLEX_BIN_DIR, true); + auto appPtr = complex::Application::GetOrCreateInstance(); + appPtr->loadPlugins(COMPLEX_BIN_DIR, true); GeneratePythonRstFiles(); GeneratePythonSphinxIndex();