From 68f39b86a866d8eb05847c04af9ea6cb28b34da0 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Fri, 2 Apr 2021 11:37:49 -0600 Subject: [PATCH 01/16] Deprecate VariantArrayHandle `VaraintArrayHandle` has been replaced by `UnknownArrayHandle` and `UncertainArrayHandle`. Officially make it deprecated and point users to the new implementations. --- benchmarking/BenchmarkFilters.cxx | 2 +- benchmarking/BenchmarkTopologyAlgorithms.cxx | 10 +-- vtkm/cont/ArrayHandleCast.h | 6 +- vtkm/cont/DataSet.h | 6 +- vtkm/cont/DataSetFieldAdd.h | 4 +- vtkm/cont/ErrorBadType.h | 4 +- vtkm/cont/Field.h | 4 +- vtkm/cont/VariantArrayHandle.h | 20 ++++-- vtkm/cont/testing/Testing.h | 1 - vtkm/cont/testing/TestingSerialization.h | 1 - .../UnitTestSerializationArrayHandle.cxx | 71 +++++-------------- .../testing/UnitTestVariantArrayHandle.cxx | 12 ++-- vtkm/filter/CreateResult.h | 12 ++-- vtkm/filter/FieldMetadata.h | 4 +- vtkm/filter/PolicyBase.h | 24 ++----- ...UnitTestClipWithImplicitFunctionFilter.cxx | 8 +-- vtkm/io/VTKDataSetReaderBase.cxx | 42 +++++------ vtkm/io/VTKDataSetReaderBase.h | 4 +- vtkm/io/VTKRectilinearGridReader.cxx | 22 +++--- vtkm/worklet/Clip.h | 2 +- vtkm/worklet/DispatcherMapField.h | 2 +- vtkm/worklet/MaskIndices.h | 2 +- vtkm/worklet/MaskSelect.cxx | 5 +- vtkm/worklet/MaskSelect.h | 14 +--- vtkm/worklet/PointMerge.h | 14 ++-- vtkm/worklet/RemoveUnusedPoints.h | 6 ++ vtkm/worklet/ScatterCounting.cxx | 4 +- vtkm/worklet/ScatterCounting.h | 22 ++---- vtkm/worklet/SurfaceNormals.h | 14 ++-- vtkm/worklet/VertexClustering.h | 9 +-- .../connectivities/ImageConnectivity.h | 8 ++- .../testing/UnitTestDispatcherBase.cxx | 6 +- vtkm/worklet/testing/UnitTestContour.cxx | 5 +- .../testing/UnitTestWorkletMapField3d.cxx | 2 - .../UnitTestWorkletMapFieldExecArg.cxx | 5 +- .../UnitTestWorkletMapFieldWholeArray.cxx | 11 +-- ...nitTestWorkletMapFieldWholeArrayAtomic.cxx | 12 ++-- 37 files changed, 180 insertions(+), 220 deletions(-) diff --git a/benchmarking/BenchmarkFilters.cxx b/benchmarking/BenchmarkFilters.cxx index 23bdf2f65..509135df2 100644 --- a/benchmarking/BenchmarkFilters.cxx +++ b/benchmarking/BenchmarkFilters.cxx @@ -604,7 +604,7 @@ public: } }; -// Get the number of components in a VariantArrayHandle, ArrayHandle, or Field's +// Get the number of components in a UnknownArrayHandle, ArrayHandle, or Field's // ValueType. struct NumberOfComponents { diff --git a/benchmarking/BenchmarkTopologyAlgorithms.cxx b/benchmarking/BenchmarkTopologyAlgorithms.cxx index b55f5a783..d8f1fffbc 100644 --- a/benchmarking/BenchmarkTopologyAlgorithms.cxx +++ b/benchmarking/BenchmarkTopologyAlgorithms.cxx @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -34,7 +35,8 @@ namespace using ValueTypes = vtkm::List; -using ValueVariantHandle = vtkm::cont::VariantArrayHandleBase; +using ValueUncertainHandle = + vtkm::cont::UncertainArrayHandle; // Hold configuration state (e.g. active device) vtkm::cont::InitializeResult Config; @@ -232,7 +234,7 @@ template void BenchCellToPointAvgDynamic(::benchmark::State& state) { BenchCellToPointAvgImpl impl{ state }; - impl.Run(ValueVariantHandle{ impl.Input }); + impl.Run(ValueUncertainHandle{ impl.Input }); }; VTKM_BENCHMARK_TEMPLATES(BenchCellToPointAvgDynamic, ValueTypes); @@ -300,7 +302,7 @@ template void BenchPointToCellAvgDynamic(::benchmark::State& state) { BenchPointToCellAvgImpl impl{ state }; - impl.Run(ValueVariantHandle{ impl.Input }); + impl.Run(ValueUncertainHandle{ impl.Input }); }; VTKM_BENCHMARK_TEMPLATES(BenchPointToCellAvgDynamic, ValueTypes); @@ -371,7 +373,7 @@ template void BenchClassificationDynamic(::benchmark::State& state) { BenchClassificationImpl impl{ state }; - impl.Run(ValueVariantHandle{ impl.Input }); + impl.Run(ValueUncertainHandle{ impl.Input }); }; VTKM_BENCHMARK_TEMPLATES(BenchClassificationDynamic, ValueTypes); diff --git a/vtkm/cont/ArrayHandleCast.h b/vtkm/cont/ArrayHandleCast.h index 84c95cdb3..480a6320c 100644 --- a/vtkm/cont/ArrayHandleCast.h +++ b/vtkm/cont/ArrayHandleCast.h @@ -193,7 +193,7 @@ private: if (RangeLoss && PrecLoss) { VTKM_LOG_F(vtkm::cont::LogLevel::Warn, - "VariantArrayHandle::AsVirtual: Casting ComponentType of " + "ArrayHandleCast: Casting ComponentType of " "%s to %s reduces range and precision.", vtkm::cont::TypeToString().c_str(), vtkm::cont::TypeToString().c_str()); @@ -201,7 +201,7 @@ private: else if (RangeLoss) { VTKM_LOG_F(vtkm::cont::LogLevel::Warn, - "VariantArrayHandle::AsVirtual: Casting ComponentType of " + "ArrayHandleCast: Casting ComponentType of " "%s to %s reduces range.", vtkm::cont::TypeToString().c_str(), vtkm::cont::TypeToString().c_str()); @@ -209,7 +209,7 @@ private: else if (PrecLoss) { VTKM_LOG_F(vtkm::cont::LogLevel::Warn, - "VariantArrayHandle::AsVirtual: Casting ComponentType of " + "ArrayHandleCast: Casting ComponentType of " "%s to %s reduces precision.", vtkm::cont::TypeToString().c_str(), vtkm::cont::TypeToString().c_str()); diff --git a/vtkm/cont/DataSet.h b/vtkm/cont/DataSet.h index 73ff6cb3e..6812969d4 100644 --- a/vtkm/cont/DataSet.h +++ b/vtkm/cont/DataSet.h @@ -18,7 +18,7 @@ #include #include #include -#include +#include namespace vtkm { @@ -133,7 +133,7 @@ public: //@} VTKM_CONT - void AddPointField(const std::string& fieldName, const vtkm::cont::VariantArrayHandle& field) + void AddPointField(const std::string& fieldName, const vtkm::cont::UnknownArrayHandle& field) { this->AddField(make_FieldPoint(fieldName, field)); } @@ -161,7 +161,7 @@ public: //Cell centered field VTKM_CONT - void AddCellField(const std::string& fieldName, const vtkm::cont::VariantArrayHandle& field) + void AddCellField(const std::string& fieldName, const vtkm::cont::UnknownArrayHandle& field) { this->AddField(make_FieldCell(fieldName, field)); } diff --git a/vtkm/cont/DataSetFieldAdd.h b/vtkm/cont/DataSetFieldAdd.h index 1abd1f125..20a15de68 100644 --- a/vtkm/cont/DataSetFieldAdd.h +++ b/vtkm/cont/DataSetFieldAdd.h @@ -31,7 +31,7 @@ public: VTKM_CONT static void AddPointField(vtkm::cont::DataSet& dataSet, const std::string& fieldName, - const vtkm::cont::VariantArrayHandle& field) + const vtkm::cont::UnknownArrayHandle& field) { dataSet.AddField(make_FieldPoint(fieldName, field)); } @@ -67,7 +67,7 @@ public: VTKM_CONT static void AddCellField(vtkm::cont::DataSet& dataSet, const std::string& fieldName, - const vtkm::cont::VariantArrayHandle& field) + const vtkm::cont::UnknownArrayHandle& field) { dataSet.AddField(make_FieldCell(fieldName, field)); } diff --git a/vtkm/cont/ErrorBadType.h b/vtkm/cont/ErrorBadType.h index 2faff4c76..8f5daf7a6 100644 --- a/vtkm/cont/ErrorBadType.h +++ b/vtkm/cont/ErrorBadType.h @@ -35,8 +35,8 @@ VTKM_SILENCE_WEAK_VTABLE_WARNING_END /// Throws an ErrorBadType exception with the following message: /// Cast failed: \c baseType --> \c derivedType". -/// This is generally caused by asking for a casting of a VariantArrayHandle -/// with an insufficient type list. +/// This is generally caused by asking for a casting of a UnknownArrayHandle +/// or UncertainArrayhandle with an insufficient type list. // VTKM_CONT_EXPORT void throwFailedDynamicCast(const std::string& baseType, const std::string& derivedType); diff --git a/vtkm/cont/Field.h b/vtkm/cont/Field.h index 7d0b590e2..b9b04c996 100644 --- a/vtkm/cont/Field.h +++ b/vtkm/cont/Field.h @@ -194,7 +194,7 @@ vtkm::cont::Field make_FieldPoint(std::string name, const vtkm::cont::ArrayHandl return vtkm::cont::Field(name, vtkm::cont::Field::Association::POINTS, data); } -/// Convenience function to build point fields from vtkm::cont::VariantArrayHandle +/// Convenience function to build point fields from vtkm::cont::UnknownArrayHandle inline vtkm::cont::Field make_FieldPoint(std::string name, const vtkm::cont::UnknownArrayHandle& data) { @@ -209,7 +209,7 @@ vtkm::cont::Field make_FieldCell(std::string name, const vtkm::cont::ArrayHandle } -/// Convenience function to build cell fields from vtkm::cont::VariantArrayHandle +/// Convenience function to build cell fields from vtkm::cont::UnknownArrayHandle inline vtkm::cont::Field make_FieldCell(std::string name, const vtkm::cont::UnknownArrayHandle& data) { diff --git a/vtkm/cont/VariantArrayHandle.h b/vtkm/cont/VariantArrayHandle.h index da13e53c6..27942094c 100644 --- a/vtkm/cont/VariantArrayHandle.h +++ b/vtkm/cont/VariantArrayHandle.h @@ -106,7 +106,10 @@ VTKM_DEPRECATED_SUPPRESS_END /// /// See the documentation of `VariantArrayHandleBase` for more information. /// -class VTKM_ALWAYS_EXPORT VariantArrayHandleCommon : public vtkm::cont::UnknownArrayHandle +class VTKM_ALWAYS_EXPORT VTKM_DEPRECATED( + 1.7, + "VariantArrayHandle classes replaced with UnknownArrayHandle and UncertainArrayHandle.") + VariantArrayHandleCommon : public vtkm::cont::UnknownArrayHandle { using Superclass = vtkm::cont::UnknownArrayHandle; @@ -263,8 +266,12 @@ public: /// named `VariantArrayHandleBase`, which is templated on the list of /// component types. /// +VTKM_DEPRECATED_SUPPRESS_BEGIN template -class VTKM_ALWAYS_EXPORT VariantArrayHandleBase : public VariantArrayHandleCommon +class VTKM_ALWAYS_EXPORT VTKM_DEPRECATED( + 1.7, + "VariantArrayHandle classes replaced with UnknownArrayHandle and UncertainArrayHandle.") + VariantArrayHandleBase : public VariantArrayHandleCommon { VTKM_STATIC_ASSERT_MSG((!std::is_same::value), "Cannot use vtkm::ListUniversal with VariantArrayHandle."); @@ -319,14 +326,12 @@ public: /// be specified in the second template parameter, which will be passed to /// the CastAndCall. /// - VTKM_DEPRECATED_SUPPRESS_BEGIN template VTKM_CONT VTKM_DEPRECATED(1.6, "ArrayHandleVirtual is no longer suported.") vtkm::cont::ArrayHandleVirtual AsVirtual() const { return this->Superclass::AsVirtual(); } - VTKM_DEPRECATED_SUPPRESS_END #endif //VTKM_NO_DEPRECATED_VIRTUAL /// Changes the types to try casting to when resolving this variant array, @@ -406,7 +411,10 @@ private: } }; -using VariantArrayHandle = vtkm::cont::VariantArrayHandleBase; +using VariantArrayHandle VTKM_DEPRECATED( + 1.7, + "VariantArrayHandle classes replaced with UnknownArrayHandle and UncertainArrayHandle.") = + vtkm::cont::VariantArrayHandleBase; //============================================================================= @@ -473,5 +481,7 @@ public: } // diy /// @endcond SERIALIZATION +VTKM_DEPRECATED_SUPPRESS_END + #endif //vtk_m_virts_VariantArrayHandle_h diff --git a/vtkm/cont/testing/Testing.h b/vtkm/cont/testing/Testing.h index 97e7bb2dd..05f9c2eea 100644 --- a/vtkm/cont/testing/Testing.h +++ b/vtkm/cont/testing/Testing.h @@ -23,7 +23,6 @@ #include #include #include -#include #include diff --git a/vtkm/cont/testing/TestingSerialization.h b/vtkm/cont/testing/TestingSerialization.h index 06e4dba1c..6275f84b1 100644 --- a/vtkm/cont/testing/TestingSerialization.h +++ b/vtkm/cont/testing/TestingSerialization.h @@ -11,7 +11,6 @@ #define vtk_m_cont_testing_TestingSerialization_h #include -#include #include #include diff --git a/vtkm/cont/testing/UnitTestSerializationArrayHandle.cxx b/vtkm/cont/testing/UnitTestSerializationArrayHandle.cxx index 8777a824c..36eb174b0 100644 --- a/vtkm/cont/testing/UnitTestSerializationArrayHandle.cxx +++ b/vtkm/cont/testing/UnitTestSerializationArrayHandle.cxx @@ -30,7 +30,6 @@ #include #include -#include #include @@ -87,18 +86,6 @@ inline void RunTest(const T& obj) TestSerialization(obj, TestEqualArrayHandle{}); } -template -inline void RunTest(const T& obj, std::true_type) -{ - TestSerialization(obj, TestEqualArrayHandle{}); -} - -template -inline void RunTest(const T&, std::false_type) -{ - // Suppress running the test -} - //----------------------------------------------------------------------------- constexpr vtkm::Id ArraySize = 10; @@ -107,14 +94,14 @@ using TestTypesListVec = vtkm::List; using TestTypesList = vtkm::ListAppend; template -inline vtkm::cont::VariantArrayHandleBase>> -MakeTestVariantArrayHandle(const vtkm::cont::ArrayHandle& array) +inline vtkm::cont::UnknownArrayHandle MakeTestUnknownArrayHandle( + const vtkm::cont::ArrayHandle& array) { return array; } template -inline vtkm::cont::UnknownArrayHandle MakeTestUnknownArrayHandle( +inline vtkm::cont::UncertainArrayHandle, vtkm::List> MakeTestUncertainArrayHandle( const vtkm::cont::ArrayHandle& array) { return array; @@ -128,7 +115,7 @@ struct TestArrayHandleBasic auto array = RandomArrayHandle::Make(ArraySize); RunTest(array); RunTest(MakeTestUnknownArrayHandle(array)); - RunTest(MakeTestVariantArrayHandle(array)); + RunTest(MakeTestUncertainArrayHandle(array)); } }; @@ -141,8 +128,7 @@ struct TestArrayHandleSOA vtkm::cont::ArrayCopy(RandomArrayHandle::Make(ArraySize), array); RunTest(array); RunTest(MakeTestUnknownArrayHandle(array)); - RunTest(MakeTestVariantArrayHandle(array), - vtkm::ListHas{}); + RunTest(MakeTestUncertainArrayHandle(array)); } }; @@ -157,11 +143,7 @@ struct TestArrayHandleCartesianProduct RandomArrayHandle::Make(ArraySize)); RunTest(array); RunTest(MakeTestUnknownArrayHandle(array)); - RunTest(MakeTestVariantArrayHandle(array), - vtkm::ListHas>{}); + RunTest(MakeTestUncertainArrayHandle(array)); } }; @@ -174,9 +156,7 @@ struct TestArrayHandleCast vtkm::cont::make_ArrayHandleCast(RandomArrayHandle::Make(ArraySize)); RunTest(array); RunTest(MakeTestUnknownArrayHandle(array)); - RunTest(MakeTestVariantArrayHandle(array), - vtkm::ListHas>{}); + RunTest(MakeTestUncertainArrayHandle(array)); } template @@ -186,9 +166,7 @@ struct TestArrayHandleCast RandomArrayHandle>::Make(ArraySize)); RunTest(array); RunTest(MakeTestUnknownArrayHandle(array)); - RunTest(MakeTestVariantArrayHandle(array), - vtkm::ListHas>{}); + RunTest(MakeTestUncertainArrayHandle(array)); } }; @@ -201,8 +179,7 @@ struct TestArrayHandleConstant auto array = vtkm::cont::make_ArrayHandleConstant(cval, ArraySize); RunTest(array); RunTest(MakeTestUnknownArrayHandle(array)); - RunTest(MakeTestVariantArrayHandle(array), - vtkm::ListHas{}); + RunTest(MakeTestUncertainArrayHandle(array)); } }; @@ -216,8 +193,7 @@ struct TestArrayHandleCounting auto array = vtkm::cont::make_ArrayHandleCounting(start, step, ArraySize); RunTest(array); RunTest(MakeTestUnknownArrayHandle(array)); - RunTest(MakeTestVariantArrayHandle(array), - vtkm::ListHas{}); + RunTest(MakeTestUncertainArrayHandle(array)); } }; @@ -235,9 +211,7 @@ struct TestArrayHandleGroupVec auto array = vtkm::cont::make_ArrayHandleGroupVec<3>(flat); RunTest(array); RunTest(MakeTestUnknownArrayHandle(array)); - RunTest(MakeTestVariantArrayHandle(array), - vtkm::ListHas>{}); + RunTest(MakeTestUncertainArrayHandle(array)); break; } case 4: @@ -245,9 +219,7 @@ struct TestArrayHandleGroupVec auto array = vtkm::cont::make_ArrayHandleGroupVec<4>(flat); RunTest(array); RunTest(MakeTestUnknownArrayHandle(array)); - RunTest(MakeTestVariantArrayHandle(array), - vtkm::ListHas>{}); + RunTest(MakeTestUncertainArrayHandle(array)); break; } default: @@ -255,9 +227,7 @@ struct TestArrayHandleGroupVec auto array = vtkm::cont::make_ArrayHandleGroupVec<2>(flat); RunTest(array); RunTest(MakeTestUnknownArrayHandle(array)); - RunTest(MakeTestVariantArrayHandle(array), - vtkm::ListHas>{}); + RunTest(MakeTestUncertainArrayHandle(array)); break; } } @@ -295,8 +265,7 @@ void TestArrayHandleIndex() auto array = vtkm::cont::ArrayHandleIndex(size); RunTest(array); RunTest(MakeTestUnknownArrayHandle(array)); - RunTest(MakeTestVariantArrayHandle(array), - vtkm::ListHas{}); + RunTest(MakeTestUncertainArrayHandle(array)); } struct TestArrayHandlePermutation @@ -314,10 +283,7 @@ struct TestArrayHandlePermutation RandomArrayHandle::Make(ArraySize)); RunTest(array); RunTest(MakeTestUnknownArrayHandle(array)); - RunTest(MakeTestVariantArrayHandle(array), - vtkm::ListHas>{}); + RunTest(MakeTestUncertainArrayHandle(array)); } }; @@ -329,9 +295,7 @@ struct TestArrayHandleReverse auto array = vtkm::cont::make_ArrayHandleReverse(RandomArrayHandle::Make(ArraySize)); RunTest(array); RunTest(MakeTestUnknownArrayHandle(array)); - RunTest(MakeTestVariantArrayHandle(array), - vtkm::ListHas>{}); + RunTest(MakeTestUncertainArrayHandle(array)); } }; @@ -365,8 +329,7 @@ void TestArrayHandleUniformPointCoordinates() auto array = MakeRandomArrayHandleUniformPointCoordinates(); RunTest(array); RunTest(MakeTestUnknownArrayHandle(array)); - RunTest(MakeTestVariantArrayHandle(array), - vtkm::ListHas{}); + RunTest(MakeTestUncertainArrayHandle(array)); } diff --git a/vtkm/cont/testing/UnitTestVariantArrayHandle.cxx b/vtkm/cont/testing/UnitTestVariantArrayHandle.cxx index de5976d5e..36e9051cc 100644 --- a/vtkm/cont/testing/UnitTestVariantArrayHandle.cxx +++ b/vtkm/cont/testing/UnitTestVariantArrayHandle.cxx @@ -8,6 +8,12 @@ // PURPOSE. See the above copyright notice for more information. //============================================================================ +#include + +// This is testing a deprecated functionality. Remove this test once VariantArrayHandle +// is completely removed from VTK-m. +VTKM_DEPRECATED_SUPPRESS_BEGIN + #include #include @@ -120,7 +126,6 @@ struct CheckFunctor } #ifndef VTKM_NO_DEPRECATED_VIRTUAL - VTKM_DEPRECATED_SUPPRESS_BEGIN template void operator()(const vtkm::cont::ArrayHandleVirtual& array, bool& vtkmNotUsed(calledBasic), @@ -131,7 +136,6 @@ struct CheckFunctor CheckArray(array); } - VTKM_DEPRECATED_SUPPRESS_END #endif //VTKM_NO_DEPRECATED_VIRTUAL template @@ -273,7 +277,6 @@ void CheckCastToVirtualArrayHandle(const ArrayType& array) VariantArrayType arrayVariant = array; - VTKM_DEPRECATED_SUPPRESS_BEGIN { auto testArray = arrayVariant.template AsVirtual(); VTKM_TEST_ASSERT(testArray.GetNumberOfValues() == array.GetNumberOfValues(), @@ -329,7 +332,6 @@ void CheckCastToVirtualArrayHandle(const ArrayType& array) VTKM_TEST_ASSERT(threw, "Casting to different vector width did not throw expected " "ErrorBadType exception."); - VTKM_DEPRECATED_SUPPRESS_END } #endif //VTKM_NO_DEPRECATED_VIRTUAL @@ -544,3 +546,5 @@ int UnitTestVariantArrayHandle(int argc, char* argv[]) { return vtkm::cont::testing::Testing::Run(TestVariantArrayHandle, argc, argv); } + +VTKM_DEPRECATED_SUPPRESS_END diff --git a/vtkm/filter/CreateResult.h b/vtkm/filter/CreateResult.h index e1766e53b..0e676a049 100644 --- a/vtkm/filter/CreateResult.h +++ b/vtkm/filter/CreateResult.h @@ -59,10 +59,10 @@ inline VTKM_CONT vtkm::cont::DataSet CreateResult( return clone; } -/// Use this function if you have a VariantArrayHandle that holds the data +/// Use this function if you have a UnknownArrayHandle that holds the data /// for the field. inline VTKM_CONT vtkm::cont::DataSet CreateResult(const vtkm::cont::DataSet& inDataSet, - const vtkm::cont::VariantArrayHandle& fieldArray, + const vtkm::cont::UnknownArrayHandle& fieldArray, const std::string& fieldName, const vtkm::filter::FieldMetadata& metaData) { @@ -96,11 +96,11 @@ inline VTKM_CONT vtkm::cont::DataSet CreateResultFieldCell( return clone; } -/// Use this function if you want to explicit construct a Cell field and have a VariantArrayHandle +/// Use this function if you want to explicit construct a Cell field and have a UnknownArrayHandle /// that holds the data for the field. inline VTKM_CONT vtkm::cont::DataSet CreateResultFieldCell( const vtkm::cont::DataSet& inDataSet, - const vtkm::cont::VariantArrayHandle& fieldArray, + const vtkm::cont::UnknownArrayHandle& fieldArray, const std::string& fieldName) { VTKM_ASSERT(!fieldName.empty()); @@ -133,11 +133,11 @@ inline VTKM_CONT vtkm::cont::DataSet CreateResultFieldPoint( return clone; } -/// Use this function if you want to explicit construct a Point field and have a VariantArrayHandle +/// Use this function if you want to explicit construct a Point field and have a UnknownArrayHandle /// that holds the data for the field. inline VTKM_CONT vtkm::cont::DataSet CreateResultFieldPoint( const vtkm::cont::DataSet& inDataSet, - const vtkm::cont::VariantArrayHandle& fieldArray, + const vtkm::cont::UnknownArrayHandle& fieldArray, const std::string& fieldName) { VTKM_ASSERT(!fieldName.empty()); diff --git a/vtkm/filter/FieldMetadata.h b/vtkm/filter/FieldMetadata.h index 54141e8c4..bef47fdb8 100644 --- a/vtkm/filter/FieldMetadata.h +++ b/vtkm/filter/FieldMetadata.h @@ -67,7 +67,7 @@ public: /// but with a new name VTKM_CONT vtkm::cont::Field AsField(const std::string& name, - const vtkm::cont::VariantArrayHandle& handle) const + const vtkm::cont::UnknownArrayHandle& handle) const { return vtkm::cont::Field(name, this->Association, handle); } @@ -79,7 +79,7 @@ public: return this->AsField(this->Name, handle); } /// Construct a new field with the same association and name as stored in this FieldMetaData - VTKM_CONT vtkm::cont::Field AsField(const vtkm::cont::VariantArrayHandle& handle) const + VTKM_CONT vtkm::cont::Field AsField(const vtkm::cont::UnknownArrayHandle& handle) const { return this->AsField(this->Name, handle); } diff --git a/vtkm/filter/PolicyBase.h b/vtkm/filter/PolicyBase.h index 01de4ab16..adca28fe4 100644 --- a/vtkm/filter/PolicyBase.h +++ b/vtkm/filter/PolicyBase.h @@ -260,9 +260,13 @@ ApplyPolicyFieldOfType(const vtkm::cont::Field& field, /// the active field of this filter. /// template -VTKM_CONT vtkm::cont::VariantArrayHandleBase::InputFieldTypeList>::TypeList> +VTKM_CONT vtkm::cont::UncertainArrayHandle< + typename vtkm::filter::DeduceFilterFieldTypes< + DerivedPolicy, + typename vtkm::filter::FilterTraits::InputFieldTypeList>::TypeList, + typename vtkm::filter::DeduceFilterFieldStorage< + DerivedPolicy, + typename vtkm::filter::FilterTraits::AdditionalFieldStorage>::StorageList> ApplyPolicyFieldActive(const vtkm::cont::Field& field, vtkm::filter::PolicyBase, vtkm::filter::FilterTraits) @@ -276,20 +280,6 @@ ApplyPolicyFieldActive(const vtkm::cont::Field& field, return field.GetData().ResetTypes(TypeList{}, StorageList{}); } -////----------------------------------------------------------------------------- -///// \brief Get an array from a `Field` limited to a given set of types. -///// -//template -//VTKM_CONT vtkm::cont::VariantArrayHandleBase< -// typename vtkm::filter::DeduceFilterFieldTypes::TypeList> -//ApplyPolicyFieldOfTypes( -// const vtkm::cont::Field& field, vtkm::filter::PolicyBase, ListOfTypes) -//{ -// using TypeList = -// typename vtkm::filter::DeduceFilterFieldTypes::TypeList; -// return field.GetData().ResetTypes(TypeList()); -//} - //----------------------------------------------------------------------------- /// \brief Ge a cell set from a `DynamicCellSet` object. /// diff --git a/vtkm/filter/testing/UnitTestClipWithImplicitFunctionFilter.cxx b/vtkm/filter/testing/UnitTestClipWithImplicitFunctionFilter.cxx index 3df13612f..95ec60b12 100644 --- a/vtkm/filter/testing/UnitTestClipWithImplicitFunctionFilter.cxx +++ b/vtkm/filter/testing/UnitTestClipWithImplicitFunctionFilter.cxx @@ -62,9 +62,9 @@ void TestClipStructured() VTKM_TEST_ASSERT(outputData.GetNumberOfCells() == 8, "Wrong number of cells in the output dataset"); - vtkm::cont::VariantArrayHandle temp = outputData.GetField("scalars").GetData(); + vtkm::cont::UnknownArrayHandle temp = outputData.GetField("scalars").GetData(); vtkm::cont::ArrayHandle resultArrayHandle; - temp.CopyTo(resultArrayHandle); + temp.AsArrayHandle(resultArrayHandle); VTKM_TEST_ASSERT(resultArrayHandle.GetNumberOfValues() == 13, "Wrong number of points in the output dataset"); @@ -98,9 +98,9 @@ void TestClipStructuredInverted() VTKM_TEST_ASSERT(outputData.GetNumberOfCells() == 4, "Wrong number of cells in the output dataset"); - vtkm::cont::VariantArrayHandle temp = outputData.GetField("scalars").GetData(); + vtkm::cont::UnknownArrayHandle temp = outputData.GetField("scalars").GetData(); vtkm::cont::ArrayHandle resultArrayHandle; - temp.CopyTo(resultArrayHandle); + temp.AsArrayHandle(resultArrayHandle); VTKM_TEST_ASSERT(resultArrayHandle.GetNumberOfValues() == 13, "Wrong number of points in the output dataset"); diff --git a/vtkm/io/VTKDataSetReaderBase.cxx b/vtkm/io/VTKDataSetReaderBase.cxx index 479d1f720..e622001fa 100644 --- a/vtkm/io/VTKDataSetReaderBase.cxx +++ b/vtkm/io/VTKDataSetReaderBase.cxx @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include @@ -33,9 +33,9 @@ inline void PrintVTKDataFileSummary(const vtkm::io::internal::VTKDataSetFile& df << std::endl; } -// Since Fields and DataSets store data in the default VariantArrayHandle, convert +// Since Fields and DataSets store data in the default UnknownArrayHandle, convert // the data to the closest type supported by default. The following will -// need to be updated if VariantArrayHandle or TypeListCommon changes. +// need to be updated if UnknownArrayHandle or TypeListCommon changes. template struct ClosestCommonType { @@ -119,7 +119,7 @@ struct ClosestFloat }; template -vtkm::cont::VariantArrayHandle CreateVariantArrayHandle(const std::vector& vec) +vtkm::cont::UnknownArrayHandle CreateUnknownArrayHandle(const std::vector& vec) { switch (vtkm::VecTraits::NUM_COMPONENTS) { @@ -143,7 +143,7 @@ vtkm::cont::VariantArrayHandle CreateVariantArrayHandle(const std::vector& ve portal.Set(i, static_cast(vec[static_cast(i)])); } - return vtkm::cont::VariantArrayHandle(output); + return vtkm::cont::UnknownArrayHandle(output); } case 2: case 3: @@ -179,12 +179,12 @@ vtkm::cont::VariantArrayHandle CreateVariantArrayHandle(const std::vector& ve portal.Set(i, outval); } - return vtkm::cont::VariantArrayHandle(output); + return vtkm::cont::UnknownArrayHandle(output); } default: { VTKM_LOG_S(vtkm::cont::LogLevel::Warn, "Only 1, 2, 3, or 9 components supported. Skipping."); - return vtkm::cont::VariantArrayHandle(vtkm::cont::ArrayHandle()); + return vtkm::cont::UnknownArrayHandle(vtkm::cont::ArrayHandle()); } } } @@ -249,7 +249,7 @@ void VTKDataSetReaderBase::ReadPoints() std::size_t numPoints; this->DataFile->Stream >> numPoints >> dataType >> std::ws; - vtkm::cont::VariantArrayHandle points = + vtkm::cont::UnknownArrayHandle points = this->DoReadArrayVariant(vtkm::cont::Field::Association::POINTS, dataType, numPoints, 3); this->DataSet.AddCoordinateSystem(vtkm::cont::CoordinateSystem("coordinates", points)); @@ -446,7 +446,7 @@ void VTKDataSetReaderBase::ReadHeader() void VTKDataSetReaderBase::AddField(const std::string& name, vtkm::cont::Field::Association association, - vtkm::cont::VariantArrayHandle& data) + vtkm::cont::UnknownArrayHandle& data) { if (data.GetNumberOfValues() > 0) { @@ -491,7 +491,7 @@ void VTKDataSetReaderBase::ReadScalars(vtkm::cont::Field::Association associatio internal::parseAssert(tag == "LOOKUP_TABLE"); this->DataFile->Stream >> lookupTableName >> std::ws; - vtkm::cont::VariantArrayHandle data = + vtkm::cont::UnknownArrayHandle data = this->DoReadArrayVariant(association, dataType, numElements, numComponents); this->AddField(dataName, association, data); } @@ -505,7 +505,7 @@ void VTKDataSetReaderBase::ReadColorScalars(vtkm::cont::Field::Association assoc vtkm::IdComponent numComponents; this->DataFile->Stream >> dataName >> numComponents >> std::ws; std::string dataType = this->DataFile->IsBinary ? "unsigned_char" : "float"; - vtkm::cont::VariantArrayHandle data = + vtkm::cont::UnknownArrayHandle data = this->DoReadArrayVariant(association, dataType, numElements, numComponents); this->AddField(dataName, association, data); } @@ -528,7 +528,7 @@ void VTKDataSetReaderBase::ReadTextureCoordinates(vtkm::cont::Field::Association std::string dataType; this->DataFile->Stream >> dataName >> numComponents >> dataType >> std::ws; - vtkm::cont::VariantArrayHandle data = + vtkm::cont::UnknownArrayHandle data = this->DoReadArrayVariant(association, dataType, numElements, numComponents); this->AddField(dataName, association, data); } @@ -540,7 +540,7 @@ void VTKDataSetReaderBase::ReadVectors(vtkm::cont::Field::Association associatio std::string dataType; this->DataFile->Stream >> dataName >> dataType >> std::ws; - vtkm::cont::VariantArrayHandle data = + vtkm::cont::UnknownArrayHandle data = this->DoReadArrayVariant(association, dataType, numElements, 3); this->AddField(dataName, association, data); } @@ -552,7 +552,7 @@ void VTKDataSetReaderBase::ReadTensors(vtkm::cont::Field::Association associatio std::string dataType; this->DataFile->Stream >> dataName >> dataType >> std::ws; - vtkm::cont::VariantArrayHandle data = + vtkm::cont::UnknownArrayHandle data = this->DoReadArrayVariant(association, dataType, numElements, 9); this->AddField(dataName, association, data); } @@ -571,7 +571,7 @@ void VTKDataSetReaderBase::ReadFields(vtkm::cont::Field::Association association this->DataFile->Stream >> arrayName >> numComponents >> numTuples >> dataType >> std::ws; if (numTuples == expectedNumElements) { - vtkm::cont::VariantArrayHandle data = + vtkm::cont::UnknownArrayHandle data = this->DoReadArrayVariant(association, dataType, numTuples, numComponents); this->AddField(arrayName, association, data); } @@ -643,7 +643,7 @@ public: ReadArrayVariant(VTKDataSetReaderBase* reader, vtkm::cont::Field::Association association, std::size_t numElements, - vtkm::cont::VariantArrayHandle& data) + vtkm::cont::UnknownArrayHandle& data) : SkipArrayVariant(reader, numElements) , Association(association) , Data(&data) @@ -658,7 +658,7 @@ public: if ((this->Association != vtkm::cont::Field::Association::CELL_SET) || (this->Reader->GetCellsPermutation().GetNumberOfValues() < 1)) { - *this->Data = CreateVariantArrayHandle(buffer); + *this->Data = CreateUnknownArrayHandle(buffer); } else { @@ -672,7 +672,7 @@ public: std::size_t inIndex = static_cast(permutation.Get(outIndex)); permutedBuffer[static_cast(outIndex)] = buffer[inIndex]; } - *this->Data = CreateVariantArrayHandle(permutedBuffer); + *this->Data = CreateUnknownArrayHandle(permutedBuffer); } } @@ -686,7 +686,7 @@ public: private: vtkm::cont::Field::Association Association; - vtkm::cont::VariantArrayHandle* Data; + vtkm::cont::UnknownArrayHandle* Data; }; void VTKDataSetReaderBase::DoSkipArrayVariant(std::string dataType, @@ -712,7 +712,7 @@ void VTKDataSetReaderBase::DoSkipArrayVariant(std::string dataType, } } -vtkm::cont::VariantArrayHandle VTKDataSetReaderBase::DoReadArrayVariant( +vtkm::cont::UnknownArrayHandle VTKDataSetReaderBase::DoReadArrayVariant( vtkm::cont::Field::Association association, std::string dataType, std::size_t numElements, @@ -720,7 +720,7 @@ vtkm::cont::VariantArrayHandle VTKDataSetReaderBase::DoReadArrayVariant( { // Create empty data to start so that the return can check if data were actually read vtkm::cont::ArrayHandle empty; - vtkm::cont::VariantArrayHandle data(empty); + vtkm::cont::UnknownArrayHandle data(empty); vtkm::io::internal::DataType typeId = vtkm::io::internal::DataTypeId(dataType); vtkm::io::internal::SelectTypeAndCall( diff --git a/vtkm/io/VTKDataSetReaderBase.h b/vtkm/io/VTKDataSetReaderBase.h index c8e13c723..cc2957a9c 100644 --- a/vtkm/io/VTKDataSetReaderBase.h +++ b/vtkm/io/VTKDataSetReaderBase.h @@ -157,7 +157,7 @@ private: VTKM_CONT void ReadHeader(); VTKM_CONT void AddField(const std::string& name, vtkm::cont::Field::Association association, - vtkm::cont::VariantArrayHandle& data); + vtkm::cont::UnknownArrayHandle& data); VTKM_CONT void ReadScalars(vtkm::cont::Field::Association association, std::size_t numElements); VTKM_CONT void ReadColorScalars(vtkm::cont::Field::Association association, std::size_t numElements); @@ -182,7 +182,7 @@ protected: VTKM_CONT void DoSkipArrayVariant(std::string dataType, std::size_t numElements, vtkm::IdComponent numComponents); - VTKM_CONT vtkm::cont::VariantArrayHandle DoReadArrayVariant( + VTKM_CONT vtkm::cont::UnknownArrayHandle DoReadArrayVariant( vtkm::cont::Field::Association association, std::string dataType, std::size_t numElements, diff --git a/vtkm/io/VTKRectilinearGridReader.cxx b/vtkm/io/VTKRectilinearGridReader.cxx index 0a37ba5d1..dc10af676 100644 --- a/vtkm/io/VTKRectilinearGridReader.cxx +++ b/vtkm/io/VTKRectilinearGridReader.cxx @@ -50,7 +50,7 @@ void VTKRectilinearGridReader::Read() //Read the points. std::string fileStorageDataType; std::size_t numPoints[3]; - vtkm::cont::VariantArrayHandle X, Y, Z; + vtkm::cont::UnknownArrayHandle X, Y, Z; this->DataFile->Stream >> tag >> numPoints[0] >> fileStorageDataType >> std::ws; if (tag != "X_COORDINATES") @@ -90,13 +90,13 @@ void VTKRectilinearGridReader::Read() // We need to store all coordinate arrays as FloatDefault. vtkm::cont::ArrayHandle Xc, Yc, Zc; - // But the VariantArrayHandle has type fileStorageDataType. + // But the UnknownArrayHandle has type fileStorageDataType. // If the fileStorageDataType is the same as the storage type, no problem: if (fileStorageDataType == vtkm::io::internal::DataTypeName::Name()) { - X.CopyTo(Xc); - Y.CopyTo(Yc); - Z.CopyTo(Zc); + X.AsArrayHandle(Xc); + Y.AsArrayHandle(Yc); + Z.AsArrayHandle(Zc); } else { @@ -104,9 +104,9 @@ void VTKRectilinearGridReader::Read() if (fileStorageDataType == "float") { vtkm::cont::ArrayHandle Xcf, Ycf, Zcf; - X.CopyTo(Xcf); - Y.CopyTo(Ycf); - Z.CopyTo(Zcf); + X.AsArrayHandle(Xcf); + Y.AsArrayHandle(Ycf); + Z.AsArrayHandle(Zcf); vtkm::cont::ArrayCopy(Xcf, Xc); vtkm::cont::ArrayCopy(Ycf, Yc); vtkm::cont::ArrayCopy(Zcf, Zc); @@ -114,9 +114,9 @@ void VTKRectilinearGridReader::Read() else { vtkm::cont::ArrayHandle Xcd, Ycd, Zcd; - X.CopyTo(Xcd); - Y.CopyTo(Ycd); - Z.CopyTo(Zcd); + X.AsArrayHandle(Xcd); + Y.AsArrayHandle(Ycd); + Z.AsArrayHandle(Zcd); vtkm::cont::ArrayCopy(Xcd, Xc); vtkm::cont::ArrayCopy(Ycd, Yc); vtkm::cont::ArrayCopy(Zcd, Zc); diff --git a/vtkm/worklet/Clip.h b/vtkm/worklet/Clip.h index 7e20b22a3..c9fa8aaf0 100644 --- a/vtkm/worklet/Clip.h +++ b/vtkm/worklet/Clip.h @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include diff --git a/vtkm/worklet/DispatcherMapField.h b/vtkm/worklet/DispatcherMapField.h index 86ef64f94..f152b5c06 100644 --- a/vtkm/worklet/DispatcherMapField.h +++ b/vtkm/worklet/DispatcherMapField.h @@ -50,7 +50,7 @@ public: const InputDomainType& inputDomain = invocation.GetInputDomain(); // For a DispatcherMapField, the inputDomain must be an ArrayHandle (or - // an VariantArrayHandle that gets cast to one). The size of the domain + // an UnknownArrayHandle that gets cast to one). The size of the domain // (number of threads/worklet instances) is equal to the size of the // array. auto numInstances = SchedulingRange(inputDomain); diff --git a/vtkm/worklet/MaskIndices.h b/vtkm/worklet/MaskIndices.h index cd4b566e1..031e50d41 100644 --- a/vtkm/worklet/MaskIndices.h +++ b/vtkm/worklet/MaskIndices.h @@ -59,7 +59,7 @@ public: } //@} - // TODO? Create a version that accepts a VariantArrayHandle. Is this needed? + // TODO? Create a version that accepts an UnknownArrayHandle. Is this needed? template vtkm::Id GetThreadRange(RangeType vtkmNotUsed(outputRange)) const diff --git a/vtkm/worklet/MaskSelect.cxx b/vtkm/worklet/MaskSelect.cxx index 7261c22a2..0b2e42740 100644 --- a/vtkm/worklet/MaskSelect.cxx +++ b/vtkm/worklet/MaskSelect.cxx @@ -127,12 +127,13 @@ struct MaskBuilder } // anonymous namespace vtkm::worklet::MaskSelect::ThreadToOutputMapType vtkm::worklet::MaskSelect::Build( - const VariantArrayHandleMask& maskArray, + const vtkm::cont::UnknownArrayHandle& maskArray, vtkm::cont::DeviceAdapterId device) { VTKM_LOG_SCOPE(vtkm::cont::LogLevel::Perf, "MaskSelect::Build"); vtkm::worklet::MaskSelect::ThreadToOutputMapType threadToOutputMap; - maskArray.CastAndCall(MaskBuilder(), threadToOutputMap, device); + maskArray.CastAndCallForTypes>( + MaskBuilder(), threadToOutputMap, device); return threadToOutputMap; } diff --git a/vtkm/worklet/MaskSelect.h b/vtkm/worklet/MaskSelect.h index fa8562535..b8516d963 100644 --- a/vtkm/worklet/MaskSelect.h +++ b/vtkm/worklet/MaskSelect.h @@ -13,7 +13,7 @@ #include #include -#include +#include namespace vtkm { @@ -34,24 +34,16 @@ class VTKM_WORKLET_EXPORT MaskSelect : public internal::MaskBase { using MaskTypes = vtkm::List; - using VariantArrayHandleMask = vtkm::cont::VariantArrayHandleBase; public: using ThreadToOutputMapType = vtkm::cont::ArrayHandle; - MaskSelect(const VariantArrayHandleMask& maskArray, + MaskSelect(const vtkm::cont::UnknownArrayHandle& maskArray, vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny()) { this->ThreadToOutputMap = this->Build(maskArray, device); } - template - MaskSelect(const vtkm::cont::VariantArrayHandleBase& indexArray, - vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny()) - { - this->ThreadToOutputMap = this->Build(VariantArrayHandleMask(indexArray), device); - } - template vtkm::Id GetThreadRange(RangeType vtkmNotUsed(outputRange)) const { @@ -67,7 +59,7 @@ public: private: ThreadToOutputMapType ThreadToOutputMap; - VTKM_CONT ThreadToOutputMapType Build(const VariantArrayHandleMask& maskArray, + VTKM_CONT ThreadToOutputMapType Build(const vtkm::cont::UnknownArrayHandle& maskArray, vtkm::cont::DeviceAdapterId device); }; } diff --git a/vtkm/worklet/PointMerge.h b/vtkm/worklet/PointMerge.h index 04c653fad..6d590c740 100644 --- a/vtkm/worklet/PointMerge.h +++ b/vtkm/worklet/PointMerge.h @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include @@ -443,18 +443,16 @@ public: points = concretePoints; } - template - VTKM_CONT void Run( - vtkm::Float64 delta, // Distance to consider two points coincident - bool fastCheck, // If true, approximate distances are used - const vtkm::Bounds& bounds, // Bounds of points - vtkm::cont::VariantArrayHandleBase& points) // coordinates, modified to merge close + VTKM_CONT void Run(vtkm::Float64 delta, // Distance to consider two points coincident + bool fastCheck, // If true, approximate distances are used + const vtkm::Bounds& bounds, // Bounds of points + vtkm::cont::UnknownArrayHandle& points) // coordinates, modified to merge close { // Get a cast to a concrete set of point coordiantes so that it can be modified in place vtkm::cont::ArrayHandle concretePoints; if (points.template IsType()) { - concretePoints = points.template Cast(); + points.AsArrayHandle(concretePoints); } else { diff --git a/vtkm/worklet/RemoveUnusedPoints.h b/vtkm/worklet/RemoveUnusedPoints.h index 428459e8d..3e59602c4 100644 --- a/vtkm/worklet/RemoveUnusedPoints.h +++ b/vtkm/worklet/RemoveUnusedPoints.h @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include #include @@ -222,6 +224,7 @@ private: outHolder = vtkm::cont::UnknownArrayHandle{ outArray }; } + VTKM_DEPRECATED_SUPPRESS_BEGIN template VTKM_CONT void operator()(const vtkm::cont::ArrayHandle& inArray, vtkm::cont::VariantArrayHandleCommon& outHolder, @@ -231,6 +234,7 @@ private: (*this)(inArray, outArray, self); outHolder = vtkm::cont::VariantArrayHandleCommon{ outArray }; } + VTKM_DEPRECATED_SUPPRESS_END }; public: @@ -278,6 +282,7 @@ public: return outArray; } + VTKM_DEPRECATED_SUPPRESS_BEGIN template VTKM_CONT void MapPointFieldDeep(const vtkm::cont::VariantArrayHandleBase& inArray, OutArrayHandle& outArray) const @@ -294,6 +299,7 @@ public: return outArray; } + VTKM_DEPRECATED_SUPPRESS_END ///@} const vtkm::worklet::ScatterCounting& GetPointScatter() const diff --git a/vtkm/worklet/ScatterCounting.cxx b/vtkm/worklet/ScatterCounting.cxx index 5103b4976..fe6a995b1 100644 --- a/vtkm/worklet/ScatterCounting.cxx +++ b/vtkm/worklet/ScatterCounting.cxx @@ -199,12 +199,12 @@ struct ScatterCountingBuilder } } // namespace vtkm::worklet::detail -void vtkm::worklet::ScatterCounting::BuildArrays(const VariantArrayHandleCount& countArray, +void vtkm::worklet::ScatterCounting::BuildArrays(const vtkm::cont::UnknownArrayHandle& countArray, vtkm::cont::DeviceAdapterId device, bool saveInputToOutputMap) { VTKM_LOG_SCOPE(vtkm::cont::LogLevel::Perf, "ScatterCounting::BuildArrays"); - countArray.CastAndCall( + countArray.CastAndCallForTypes>( vtkm::worklet::detail::ScatterCountingBuilder(), device, saveInputToOutputMap, this); } diff --git a/vtkm/worklet/ScatterCounting.h b/vtkm/worklet/ScatterCounting.h index cf4e4d240..2160b2edc 100644 --- a/vtkm/worklet/ScatterCounting.h +++ b/vtkm/worklet/ScatterCounting.h @@ -13,7 +13,7 @@ #include #include -#include +#include #include @@ -51,7 +51,6 @@ struct VTKM_WORKLET_EXPORT ScatterCounting : internal::ScatterBase vtkm::UInt32, vtkm::UInt16, vtkm::UInt8>; - using VariantArrayHandleCount = vtkm::cont::VariantArrayHandleBase; /// Construct a \c ScatterCounting object using an array of counts for the /// number of outputs for each input. Part of the construction requires @@ -60,27 +59,14 @@ struct VTKM_WORKLET_EXPORT ScatterCounting : internal::ScatterBase /// other users might make use of it, so you can instruct the constructor /// to save the input to output map. /// - template - VTKM_CONT ScatterCounting(const vtkm::cont::VariantArrayHandleBase& countArray, - vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny(), - bool saveInputToOutputMap = false) - { - this->BuildArrays(VariantArrayHandleCount(countArray), device, saveInputToOutputMap); - } - VTKM_CONT ScatterCounting(const VariantArrayHandleCount& countArray, + VTKM_CONT ScatterCounting(const vtkm::cont::UnknownArrayHandle& countArray, vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny(), bool saveInputToOutputMap = false) { this->BuildArrays(countArray, device, saveInputToOutputMap); } - template - VTKM_CONT ScatterCounting(const vtkm::cont::VariantArrayHandleBase& countArray, + VTKM_CONT ScatterCounting(const vtkm::cont::UnknownArrayHandle& countArray, bool saveInputToOutputMap) - { - this->BuildArrays( - VariantArrayHandleCount(countArray), vtkm::cont::DeviceAdapterTagAny(), saveInputToOutputMap); - } - VTKM_CONT ScatterCounting(const VariantArrayHandleCount& countArray, bool saveInputToOutputMap) { this->BuildArrays(countArray, vtkm::cont::DeviceAdapterTagAny(), saveInputToOutputMap); } @@ -135,7 +121,7 @@ private: friend struct detail::ScatterCountingBuilder; - VTKM_CONT void BuildArrays(const VariantArrayHandleCount& countArray, + VTKM_CONT void BuildArrays(const vtkm::cont::UnknownArrayHandle& countArray, vtkm::cont::DeviceAdapterId device, bool saveInputToOutputMap); }; diff --git a/vtkm/worklet/SurfaceNormals.h b/vtkm/worklet/SurfaceNormals.h index 33dde10f6..45333e4de 100644 --- a/vtkm/worklet/SurfaceNormals.h +++ b/vtkm/worklet/SurfaceNormals.h @@ -17,7 +17,7 @@ #include #include #include -#include +#include namespace vtkm { @@ -194,10 +194,14 @@ public: vtkm::worklet::DispatcherMapTopology().Invoke(cellset, faceNormals, pointNormals); } - template - void Run(const CellSetType& cellset, - const vtkm::cont::VariantArrayHandleBase& faceNormals, - vtkm::cont::ArrayHandle>& pointNormals) + template + void Run( + const CellSetType& cellset, + const vtkm::cont::UncertainArrayHandle& faceNormals, + vtkm::cont::ArrayHandle>& pointNormals) { vtkm::worklet::DispatcherMapTopology().Invoke(cellset, faceNormals, pointNormals); } diff --git a/vtkm/worklet/VertexClustering.h b/vtkm/worklet/VertexClustering.h index dc458eec5..dbba6dcc2 100644 --- a/vtkm/worklet/VertexClustering.h +++ b/vtkm/worklet/VertexClustering.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -73,7 +74,7 @@ struct SelectRepresentativePoint : public vtkm::worklet::WorkletReduceByKey template VTKM_CONT void operator()(const InputPointsArrayType& points, const vtkm::worklet::Keys& keys, - vtkm::cont::VariantArrayHandle& output) const + vtkm::cont::UnknownArrayHandle& output) const { vtkm::cont::ArrayHandle out; @@ -85,11 +86,11 @@ struct SelectRepresentativePoint : public vtkm::worklet::WorkletReduceByKey }; template - VTKM_CONT static vtkm::cont::VariantArrayHandle Run( + VTKM_CONT static vtkm::cont::UnknownArrayHandle Run( const vtkm::worklet::Keys& keys, const InputDynamicPointsArrayType& inputPoints) { - vtkm::cont::VariantArrayHandle output; + vtkm::cont::UnknownArrayHandle output; RunTrampoline trampoline; vtkm::cont::CastAndCall(inputPoints, trampoline, keys, output); return output; @@ -365,7 +366,7 @@ public: #endif /// pass 2 : Choose a representative point from each cluster for the output: - vtkm::cont::VariantArrayHandle repPointArray; + vtkm::cont::UnknownArrayHandle repPointArray; { vtkm::worklet::Keys keys; keys.BuildArrays(pointCidArray, vtkm::worklet::KeysSortType::Stable); diff --git a/vtkm/worklet/connectivities/ImageConnectivity.h b/vtkm/worklet/connectivities/ImageConnectivity.h index 577f71ac5..a90ddfcfd 100644 --- a/vtkm/worklet/connectivities/ImageConnectivity.h +++ b/vtkm/worklet/connectivities/ImageConnectivity.h @@ -12,6 +12,7 @@ #define vtk_m_worklet_connectivity_ImageConnectivity_h #include +#include #include #include @@ -124,13 +125,14 @@ public: } }; - template + template void Run(const vtkm::cont::CellSetStructured& input, - const vtkm::cont::VariantArrayHandleBase& pixels, + const vtkm::cont::UnknownArrayHandle& pixels, OutputPortalType& componentsOut) const { using Types = vtkm::TypeListScalarAll; - vtkm::cont::CastAndCall(pixels.ResetTypes(Types{}), RunImpl(), input, componentsOut); + using Storages = VTKM_DEFAULT_STORAGE_LIST; + vtkm::cont::CastAndCall(pixels.ResetTypes(), RunImpl(), input, componentsOut); } template diff --git a/vtkm/worklet/internal/testing/UnitTestDispatcherBase.cxx b/vtkm/worklet/internal/testing/UnitTestDispatcherBase.cxx index 3f7fc9cfb..39182b32d 100644 --- a/vtkm/worklet/internal/testing/UnitTestDispatcherBase.cxx +++ b/vtkm/worklet/internal/testing/UnitTestDispatcherBase.cxx @@ -324,9 +324,9 @@ public: const InputDomainType& inputDomain = invocation.GetInputDomain(); // For a DispatcherMapField, the inputDomain must be an ArrayHandle (or - // an VariantArrayHandle that gets cast to one). The size of the domain - // (number of threads/worklet instances) is equal to the size of the - // array. + // an UncertainArrayHandle or an UnknownArrayHandle that gets cast to one). + // The size of the domain (number of threads/worklet instances) is equal + // to the size of the array. //verify the overloads for SchedulingRange work auto numInstances = SchedulingRange(inputDomain); diff --git a/vtkm/worklet/testing/UnitTestContour.cxx b/vtkm/worklet/testing/UnitTestContour.cxx index 8a166874b..221a50f7b 100644 --- a/vtkm/worklet/testing/UnitTestContour.cxx +++ b/vtkm/worklet/testing/UnitTestContour.cxx @@ -163,9 +163,8 @@ inline vtkm::cont::DataSet MakeRadiantDataSet::Make3DRadiantDataSet(vtkm::IdComp //Set point scalar dataSet.AddField(vtkm::cont::Field( "distanceToOrigin", vtkm::cont::Field::Association::POINTS, distanceToOrigin)); - dataSet.AddField(vtkm::cont::Field("distanceToOther", - vtkm::cont::Field::Association::POINTS, - vtkm::cont::VariantArrayHandle(distanceToOther))); + dataSet.AddField( + vtkm::cont::Field("distanceToOther", vtkm::cont::Field::Association::POINTS, distanceToOther)); CellSet cellSet; cellSet.Fill((dim + 1) * (dim + 1) * (dim + 1), HexTag::Id, HexTraits::NUM_POINTS, connectivity); diff --git a/vtkm/worklet/testing/UnitTestWorkletMapField3d.cxx b/vtkm/worklet/testing/UnitTestWorkletMapField3d.cxx index 434e93e76..044c5bb57 100644 --- a/vtkm/worklet/testing/UnitTestWorkletMapField3d.cxx +++ b/vtkm/worklet/testing/UnitTestWorkletMapField3d.cxx @@ -10,8 +10,6 @@ #include #include -#include - #include #include diff --git a/vtkm/worklet/testing/UnitTestWorkletMapFieldExecArg.cxx b/vtkm/worklet/testing/UnitTestWorkletMapFieldExecArg.cxx index 7acfd28bf..38b302d12 100644 --- a/vtkm/worklet/testing/UnitTestWorkletMapFieldExecArg.cxx +++ b/vtkm/worklet/testing/UnitTestWorkletMapFieldExecArg.cxx @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include @@ -95,7 +95,8 @@ struct DoTestWorklet outputHandle = vtkm::cont::ArrayHandle(); outputHandle.Allocate(ARRAY_SIZE); - vtkm::cont::VariantArrayHandleBase> outputFieldDynamic(outputFieldArray); + vtkm::cont::UncertainArrayHandle, vtkm::List> + outputFieldDynamic(outputFieldArray); dispatcher.Invoke(counting, inputHandle, outputHandle, outputFieldDynamic, SimpleExecObject()); std::cout << "Check dynamic array result." << std::endl; diff --git a/vtkm/worklet/testing/UnitTestWorkletMapFieldWholeArray.cxx b/vtkm/worklet/testing/UnitTestWorkletMapFieldWholeArray.cxx index 69d45bcd6..e01ebc032 100644 --- a/vtkm/worklet/testing/UnitTestWorkletMapFieldWholeArray.cxx +++ b/vtkm/worklet/testing/UnitTestWorkletMapFieldWholeArray.cxx @@ -9,7 +9,7 @@ //============================================================================ #include #include -#include +#include #include #include @@ -77,9 +77,12 @@ struct DoTestWholeArrayWorklet outHandle.Allocate(ARRAY_SIZE); vtkm::worklet::DispatcherMapField dispatcher; - dispatcher.Invoke(vtkm::cont::VariantArrayHandle(inHandle).ResetTypes(vtkm::List{}), - vtkm::cont::VariantArrayHandle(inOutHandle).ResetTypes(vtkm::List{}), - vtkm::cont::VariantArrayHandle(outHandle).ResetTypes(vtkm::List{})); + dispatcher.Invoke(vtkm::cont::UnknownArrayHandle(inHandle) + .ResetTypes, vtkm::List>(), + vtkm::cont::UnknownArrayHandle(inOutHandle) + .ResetTypes, vtkm::List>(), + vtkm::cont::UnknownArrayHandle(outHandle) + .ResetTypes, vtkm::List>()); std::cout << "Check result." << std::endl; CheckPortal(inOutHandle.ReadPortal()); diff --git a/vtkm/worklet/testing/UnitTestWorkletMapFieldWholeArrayAtomic.cxx b/vtkm/worklet/testing/UnitTestWorkletMapFieldWholeArrayAtomic.cxx index 28633b53c..92a2b7b75 100644 --- a/vtkm/worklet/testing/UnitTestWorkletMapFieldWholeArrayAtomic.cxx +++ b/vtkm/worklet/testing/UnitTestWorkletMapFieldWholeArrayAtomic.cxx @@ -9,7 +9,7 @@ //============================================================================ #include #include -#include +#include #include #include @@ -42,12 +42,14 @@ struct DoTestAtomicArrayWorklet // This just demonstrates that the WholeArray tags support dynamic arrays. VTKM_CONT - void CallWorklet(const vtkm::cont::VariantArrayHandle& inOutArray) const + void CallWorklet(const vtkm::cont::UnknownArrayHandle& inOutArray) const { std::cout << "Create and run dispatcher." << std::endl; vtkm::worklet::DispatcherMapField dispatcher; - dispatcher.Invoke(vtkm::cont::ArrayHandleIndex(ARRAY_SIZE), - inOutArray.ResetTypes()); + dispatcher.Invoke( + vtkm::cont::ArrayHandleIndex(ARRAY_SIZE), + inOutArray + .ResetTypes>()); } template @@ -56,7 +58,7 @@ struct DoTestAtomicArrayWorklet std::cout << "Set up data." << std::endl; vtkm::cont::ArrayHandle inOutHandle = vtkm::cont::make_ArrayHandle({ 0 }); - this->CallWorklet(vtkm::cont::VariantArrayHandle(inOutHandle)); + this->CallWorklet(inOutHandle); std::cout << "Check result." << std::endl; T result = inOutHandle.ReadPortal().Get(0); From b4ef9fcac3ab0f078c0be82b3e1fc097c235ec70 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Fri, 2 Apr 2021 12:24:50 -0600 Subject: [PATCH 02/16] Fix UnknownArrayHandle::CastAndCall for special arrays `UnknownArrayHandle` treats a `ArrayHandleCast` and `ArrayHandleMultiplexer` special. When you put one of these arrays in an `UnknownArrayHandle`, it takes the original array out and stores it. If you try to take an array of that type out, it will again do the proper conversion. The only problem is that if you use `IsType`, the result can be unexpected. This is what happened with `CastAndCall`, which was using `IsType` internally. Changed that to `CanConvert` to properly get the array handle out. --- vtkm/cont/UnknownArrayHandle.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vtkm/cont/UnknownArrayHandle.h b/vtkm/cont/UnknownArrayHandle.h index f996081dc..5d0fefd26 100644 --- a/vtkm/cont/UnknownArrayHandle.h +++ b/vtkm/cont/UnknownArrayHandle.h @@ -916,7 +916,7 @@ struct UnknownArrayHandleTry Args&&... args) const { using DerivedArrayType = vtkm::cont::ArrayHandle; - if (!called && unknownArray.IsType()) + if (!called && unknownArray.CanConvert()) { called = true; DerivedArrayType derivedArray; From 25e6daf93f1c60e39dfe8747985574cba2fe8e9b Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Fri, 2 Apr 2021 12:29:15 -0600 Subject: [PATCH 03/16] Add changelog for depreciating VariantArrayHandle --- docs/changelog/deprecate-variant-array-handle.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 docs/changelog/deprecate-variant-array-handle.md diff --git a/docs/changelog/deprecate-variant-array-handle.md b/docs/changelog/deprecate-variant-array-handle.md new file mode 100644 index 000000000..1d40369c0 --- /dev/null +++ b/docs/changelog/deprecate-variant-array-handle.md @@ -0,0 +1,5 @@ +# Deprecated `VariantArrayHandle` + +`VaraintArrayHandle` has been replaced by `UnknownArrayHandle` and +`UncertainArrayHandle`. Officially made `VariantArrayHandle` deprecated and +point users to the new implementations. From 5510521a06b4afcfd4f5ce886ca3ad1415c8868e Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Thu, 8 Apr 2021 09:21:39 -0600 Subject: [PATCH 04/16] Fix VariantArrayHandle::AsVirtual with cast arrays The both the underlying `UnknownArrayHandle` and `ArrayHandleVirtual` handle `ArrayHandleCast` specially. This caused problems when passing an `ArrayHandleCast` to `VariantArrayHandle::AsVirtual`. Solve the problem by stripping out the cast storage tags and letting these classes handle it internally. It's annoying to have to fix a problem in a method of a deprecated class that returns another class that is deprecated for a different reason. No one should really be running this. --- vtkm/cont/VariantArrayHandle.h | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/vtkm/cont/VariantArrayHandle.h b/vtkm/cont/VariantArrayHandle.h index 27942094c..d41c4706e 100644 --- a/vtkm/cont/VariantArrayHandle.h +++ b/vtkm/cont/VariantArrayHandle.h @@ -91,6 +91,19 @@ private: throw vtkm::cont::ErrorBadType(str.str()); } }; + +template +struct NoCastStorageTransformImpl +{ + using type = S; +}; +template +struct NoCastStorageTransformImpl> +{ + using type = S; +}; +template +using NoCastStorageTransform = typename NoCastStorageTransformImpl::type; VTKM_DEPRECATED_SUPPRESS_END } @@ -177,9 +190,12 @@ public: { VTKM_IS_LIST(StorageList); VTKM_IS_LIST(TypeList); + // Remove cast storage from storage list because we take care of casting elsewhere + using CleanStorageList = + vtkm::ListTransform; vtkm::cont::internal::variant::ForceCastToVirtual caster; vtkm::cont::ArrayHandleVirtual output; - this->CastAndCall(caster, output); + this->CastAndCall(caster, output); return output; } VTKM_DEPRECATED_SUPPRESS_END From 14839a03259599f90c8a103bfdd2f5152c1ab65d Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Thu, 8 Apr 2021 09:28:03 -0600 Subject: [PATCH 05/16] Fix deprecation warnings with MSVC --- vtkm/cont/VariantArrayHandle.h | 20 ++++--------------- .../testing/UnitTestVariantArrayHandle.cxx | 4 +++- 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/vtkm/cont/VariantArrayHandle.h b/vtkm/cont/VariantArrayHandle.h index d41c4706e..9a98eb128 100644 --- a/vtkm/cont/VariantArrayHandle.h +++ b/vtkm/cont/VariantArrayHandle.h @@ -31,6 +31,10 @@ #include #endif //VTKM_NO_DEPRECATED_VIRTUAL +// This is a deprecated class. Don't warn about deprecation while implementing +// deprecated functionality. +VTKM_DEPRECATED_SUPPRESS_BEGIN + namespace vtkm { namespace cont @@ -42,7 +46,6 @@ namespace internal namespace variant { -VTKM_DEPRECATED_SUPPRESS_BEGIN struct ForceCastToVirtual { template @@ -104,7 +107,6 @@ struct NoCastStorageTransformImpl> }; template using NoCastStorageTransform = typename NoCastStorageTransformImpl::type; -VTKM_DEPRECATED_SUPPRESS_END } } // namespace internal::variant @@ -136,14 +138,6 @@ public: { } - // MSVC will issue deprecation warnings here if this template is instantiated with - // a deprecated class even if the template is used from a section of code where - // deprecation warnings are suppressed. This is annoying behavior since this template - // has no control over what class it is used with. To get around it, we have to - // suppress all deprecation warnings here. -#ifdef VTKM_MSVC - VTKM_DEPRECATED_SUPPRESS_BEGIN -#endif /// Returns this array cast to the given \c ArrayHandle type. Throws \c /// ErrorBadType if the cast does not work. Use \c IsType /// to check if the cast can happen. @@ -153,9 +147,6 @@ public: { return this->AsArrayHandle(); } -#ifdef VTKM_MSVC - VTKM_DEPRECATED_SUPPRESS_END -#endif /// \brief Call a functor using the underlying array type. /// @@ -181,7 +172,6 @@ public: /// the CastAndCall. You can also specify a list of types to try as the optional /// third template argument. /// - VTKM_DEPRECATED_SUPPRESS_BEGIN template > @@ -198,7 +188,6 @@ public: this->CastAndCall(caster, output); return output; } - VTKM_DEPRECATED_SUPPRESS_END #endif //VTKM_NO_DEPRECATED_VIRTUAL /// Returns this array cast to a `ArrayHandleMultiplexer` of the given type. @@ -282,7 +271,6 @@ public: /// named `VariantArrayHandleBase`, which is templated on the list of /// component types. /// -VTKM_DEPRECATED_SUPPRESS_BEGIN template class VTKM_ALWAYS_EXPORT VTKM_DEPRECATED( 1.7, diff --git a/vtkm/cont/testing/UnitTestVariantArrayHandle.cxx b/vtkm/cont/testing/UnitTestVariantArrayHandle.cxx index 36e9051cc..e5cbc52dd 100644 --- a/vtkm/cont/testing/UnitTestVariantArrayHandle.cxx +++ b/vtkm/cont/testing/UnitTestVariantArrayHandle.cxx @@ -547,4 +547,6 @@ int UnitTestVariantArrayHandle(int argc, char* argv[]) return vtkm::cont::testing::Testing::Run(TestVariantArrayHandle, argc, argv); } -VTKM_DEPRECATED_SUPPRESS_END +// The MSVC compiler is sometimes complaining about use of deprecated VariantArrayHandle at the +// end of this file. This is the end of the translation unit, so just keep the suppression on. +//VTKM_DEPRECATED_SUPPRESS_END From 6f9515aa94ae5b26fcaec974ef23657ef15ee25f Mon Sep 17 00:00:00 2001 From: Nick Thompson <4nt@ornl.gov> Date: Thu, 8 Apr 2021 08:50:27 -0400 Subject: [PATCH 06/16] Quadratic roots to 3 ulps. --- vtkm/Math.h | 45 ++++++++++++++ vtkm/Math.h.in | 45 ++++++++++++++ vtkm/testing/UnitTestMath.cxx | 109 +++++++++++++++++++++++----------- 3 files changed, 165 insertions(+), 34 deletions(-) diff --git a/vtkm/Math.h b/vtkm/Math.h index 9e7caf23b..083e5978d 100644 --- a/vtkm/Math.h +++ b/vtkm/Math.h @@ -2701,12 +2701,57 @@ inline VTKM_EXEC_CONT vtkm::UInt64 FloatDistance(vtkm::Float32 x, vtkm::Float32 template inline VTKM_EXEC_CONT T DifferenceOfProducts(T a, T b, T c, T d) { + // This is a bit awkward. clang-11 does not define FP_FAST_FMA, but still compiles this to the correct assembly. + // Windows, however, generates truly horrendous assembly from this, with no fmas, to the extent I assume it could + // contort itself into a performance bug. + // You'd want to just use #ifdef FP_FAST_FMA, but then you'd lose the (correct) generated assembly on clang. + // See: https://stackoverflow.com/a/40765925/904050 T cd = c * d; T err = std::fma(-c, d, cd); T dop = std::fma(a, b, -cd); return dop + err; } +// Solves ax² + bx + c = 0. +// Only returns the real roots. +// If there are real roots, the first element of the pair is <= the second. +// If there are no real roots, both elements are NaNs. +// The error should be at most 3 ulps. +template +inline VTKM_EXEC_CONT vtkm::Pair QuadraticRoots(T a, T b, T c) +{ + if (a == 0) + { + if (b == 0) + { + if (c == 0) + { + // A degenerate case. All real numbers are roots; hopefully this arbitrary decision interacts gracefully with use. + return vtkm::Pair(0,0); + } + else + { + return vtkm::Pair(vtkm::Nan(), vtkm::Nan()); + } + } + return vtkm::Pair(-c/b, -c/b); + } + T delta = DifferenceOfProducts(b, b, 4*a, c); + if (delta < 0) + { + return vtkm::Pair(vtkm::Nan(), vtkm::Nan()); + } + + T q = -(b + vtkm::CopySign(vtkm::Sqrt(delta), b)) / 2; + T r0 = q / a; + T r1 = c / q; + if (r0 < r1) + { + return vtkm::Pair(r0, r1); + } + return vtkm::Pair(r1, r0); +} + /// Bitwise operations /// diff --git a/vtkm/Math.h.in b/vtkm/Math.h.in index d0f3f68d8..48845262e 100644 --- a/vtkm/Math.h.in +++ b/vtkm/Math.h.in @@ -1303,12 +1303,57 @@ inline VTKM_EXEC_CONT vtkm::UInt64 FloatDistance(vtkm::Float32 x, vtkm::Float32 template inline VTKM_EXEC_CONT T DifferenceOfProducts(T a, T b, T c, T d) { + // This is a bit awkward. clang-11 does not define FP_FAST_FMA, but still compiles this to the correct assembly. + // Windows, however, generates truly horrendous assembly from this, with no fmas, to the extent I assume it could + // contort itself into a performance bug. + // You'd want to just use #ifdef FP_FAST_FMA, but then you'd lose the (correct) generated assembly on clang. + // See: https://stackoverflow.com/a/40765925/904050 T cd = c * d; T err = std::fma(-c, d, cd); T dop = std::fma(a, b, -cd); return dop + err; } +// Solves ax² + bx + c = 0. +// Only returns the real roots. +// If there are real roots, the first element of the pair is <= the second. +// If there are no real roots, both elements are NaNs. +// The error should be at most 3 ulps. +template +inline VTKM_EXEC_CONT vtkm::Pair QuadraticRoots(T a, T b, T c) +{ + if (a == 0) + { + if (b == 0) + { + if (c == 0) + { + // A degenerate case. All real numbers are roots; hopefully this arbitrary decision interacts gracefully with use. + return vtkm::Pair(0,0); + } + else + { + return vtkm::Pair(vtkm::Nan(), vtkm::Nan()); + } + } + return vtkm::Pair(-c/b, -c/b); + } + T delta = DifferenceOfProducts(b, b, 4*a, c); + if (delta < 0) + { + return vtkm::Pair(vtkm::Nan(), vtkm::Nan()); + } + + T q = -(b + vtkm::CopySign(vtkm::Sqrt(delta), b)) / 2; + T r0 = q / a; + T r1 = c / q; + if (r0 < r1) + { + return vtkm::Pair(r0, r1); + } + return vtkm::Pair(r1, r0); +} + /// Bitwise operations /// diff --git a/vtkm/testing/UnitTestMath.cxx b/vtkm/testing/UnitTestMath.cxx index 5e2e1a52f..393d29e63 100644 --- a/vtkm/testing/UnitTestMath.cxx +++ b/vtkm/testing/UnitTestMath.cxx @@ -902,48 +902,89 @@ struct ScalarVectorFieldTests : public vtkm::exec::FunctorBase } VTKM_EXEC - void TestDifferenceOfProducts() const - { + void TestDifferenceOfProducts() const { +#ifdef FP_FAST_FMA { // Example taken from: // https://pharr.org/matt/blog/2019/11/03/difference-of-floats.html vtkm::Float32 a = 33962.035f; - vtkm::Float32 b = -30438.8f; - vtkm::Float32 c = 41563.4f; - vtkm::Float32 d = -24871.969f; - vtkm::Float32 computed = vtkm::DifferenceOfProducts(a, b, c, d); - // Expected result, computed in double precision and cast back to float: - vtkm::Float32 expected = 5.376600027084351f; + vtkm::Float32 b = -30438.8f; + vtkm::Float32 c = 41563.4f; + vtkm::Float32 d = -24871.969f; + vtkm::Float32 computed = vtkm::DifferenceOfProducts(a, b, c, d); + // Expected result, computed in double precision and cast back to float: + vtkm::Float32 expected = 5.376600027084351f; - vtkm::UInt64 dist = vtkm::FloatDistance(expected, computed); - VTKM_MATH_ASSERT( - dist < 2, - "Float distance for difference of products exceeds 1.5; this is in violation of a theorem " - "proved by Jeannerod in doi.org/10.1090/S0025-5718-2013-02679-8. Is your build compiled " - "with fma's enabled?"); - } - } + vtkm::UInt64 dist = vtkm::FloatDistance(expected, computed); + std::cout << "Dist = " << dist << "\n"; + VTKM_MATH_ASSERT( + dist < 2, + "Float distance for difference of products is which exceeds 1.5; this is in violation of a " + "theorem " + "proved by Jeannerod in doi.org/10.1090/S0025-5718-2013-02679-8. Is your build compiled " + "with fma's enabled?"); +} +#endif +} - VTKM_EXEC - void operator()(vtkm::Id) const +VTKM_EXEC +void TestQuadraticRoots() const +{ { - this->TestTriangleTrig(); - this->TestHyperbolicTrig(); - this->TestSqrt(); - this->TestRSqrt(); - this->TestCbrt(); - this->TestRCbrt(); - this->TestExp(); - this->TestExp2(); - this->TestExpM1(); - this->TestExp10(); - this->TestLog(); - this->TestLog10(); - this->TestLog1P(); - this->TestCopySign(); - this->TestFloatDistance(); + // (x-1)(x+1) = x^2 - 1: + auto roots = vtkm::QuadraticRoots(1.0f, 0.0f, -1.0f); + + vtkm::UInt64 dist = vtkm::FloatDistance(-1.0f, roots.first); + VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); + + dist = vtkm::FloatDistance(1.0f, roots.second); + VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); + +#ifdef FP_FAST_FMA + // Wikipedia example: + // x^2 + 200x - 0.000015 = 0 has roots + // -200.000000075, 7.5e-8 + roots = vtkm::QuadraticRoots(1.0f, 0.0f, -1.0f); + dist = vtkm::FloatDistance(-200.000000075f, roots.first); + VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); + + dist = vtkm::FloatDistance(7.5e-8f, roots.second); + VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); + + // Kahan's example: + auto roots64 = vtkm::QuadraticRoots(94906265.625, 94906267.000, 94906268.375); + dist = vtkm::FloatDistance(1.0, roots64.first); + VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); + + dist = vtkm::FloatDistance(1.000000028975958, roots64.second); + VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); +#endif } -}; +} + +VTKM_EXEC +void operator()(vtkm::Id) const +{ + this->TestTriangleTrig(); + this->TestHyperbolicTrig(); + this->TestSqrt(); + this->TestRSqrt(); + this->TestCbrt(); + this->TestRCbrt(); + this->TestExp(); + this->TestExp2(); + this->TestExpM1(); + this->TestExp10(); + this->TestLog(); + this->TestLog10(); + this->TestLog1P(); + this->TestCopySign(); + this->TestFloatDistance(); + this->TestDifferenceOfProducts(); + this->TestQuadraticRoots(); +} +} +; struct TryScalarVectorFieldTests { From 91bec19e979462b2637b68f8f5862cf6adec71a6 Mon Sep 17 00:00:00 2001 From: Nick Thompson <4nt@ornl.gov> Date: Thu, 8 Apr 2021 09:18:51 -0400 Subject: [PATCH 07/16] Additional comments and fix typo in unit test. --- vtkm/Math.h | 1 + vtkm/Math.h.in | 1 + vtkm/testing/UnitTestMath.cxx | 13 ++++++++++--- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/vtkm/Math.h b/vtkm/Math.h index 083e5978d..e9f762eaa 100644 --- a/vtkm/Math.h +++ b/vtkm/Math.h @@ -2704,6 +2704,7 @@ inline VTKM_EXEC_CONT T DifferenceOfProducts(T a, T b, T c, T d) // This is a bit awkward. clang-11 does not define FP_FAST_FMA, but still compiles this to the correct assembly. // Windows, however, generates truly horrendous assembly from this, with no fmas, to the extent I assume it could // contort itself into a performance bug. + // That said, MSVC converts even a*b - c*d into horrible assembly, so it may be a wash. // You'd want to just use #ifdef FP_FAST_FMA, but then you'd lose the (correct) generated assembly on clang. // See: https://stackoverflow.com/a/40765925/904050 T cd = c * d; diff --git a/vtkm/Math.h.in b/vtkm/Math.h.in index 48845262e..b8c5d39c6 100644 --- a/vtkm/Math.h.in +++ b/vtkm/Math.h.in @@ -1306,6 +1306,7 @@ inline VTKM_EXEC_CONT T DifferenceOfProducts(T a, T b, T c, T d) // This is a bit awkward. clang-11 does not define FP_FAST_FMA, but still compiles this to the correct assembly. // Windows, however, generates truly horrendous assembly from this, with no fmas, to the extent I assume it could // contort itself into a performance bug. + // That said, MSVC converts even a*b - c*d into horrible assembly, so it may be a wash. // You'd want to just use #ifdef FP_FAST_FMA, but then you'd lose the (correct) generated assembly on clang. // See: https://stackoverflow.com/a/40765925/904050 T cd = c * d; diff --git a/vtkm/testing/UnitTestMath.cxx b/vtkm/testing/UnitTestMath.cxx index 393d29e63..87f2813f7 100644 --- a/vtkm/testing/UnitTestMath.cxx +++ b/vtkm/testing/UnitTestMath.cxx @@ -931,7 +931,7 @@ VTKM_EXEC void TestQuadraticRoots() const { { - // (x-1)(x+1) = x^2 - 1: + // (x-1)(x+1) = x² - 1: auto roots = vtkm::QuadraticRoots(1.0f, 0.0f, -1.0f); vtkm::UInt64 dist = vtkm::FloatDistance(-1.0f, roots.first); @@ -940,11 +940,18 @@ void TestQuadraticRoots() const dist = vtkm::FloatDistance(1.0f, roots.second); VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); + // No real roots: + roots = vtkm::QuadraticRoots(1.0f, 0.0f, 1.0f); + VTKM_MATH_ASSERT(vtkm::IsNan(roots.first), + "Roots should be Nan for a quadratic with complex roots."); + VTKM_MATH_ASSERT(vtkm::IsNan(roots.second), + "Roots should be Nan for a quadratic with complex roots."); + #ifdef FP_FAST_FMA // Wikipedia example: - // x^2 + 200x - 0.000015 = 0 has roots + // x² + 200x - 0.000015 = 0 has roots // -200.000000075, 7.5e-8 - roots = vtkm::QuadraticRoots(1.0f, 0.0f, -1.0f); + roots = vtkm::QuadraticRoots(1.0f, 200.0f, -0.000015f); dist = vtkm::FloatDistance(-200.000000075f, roots.first); VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); From dd8863637aed79e86359a65388fa49e0f99b382d Mon Sep 17 00:00:00 2001 From: Nick Thompson <4nt@ornl.gov> Date: Thu, 8 Apr 2021 14:45:59 -0400 Subject: [PATCH 08/16] Return a vec rather than a vtkm::Pair. --- vtkm/Math.h | 20 +++++++------------- vtkm/Math.h.in | 20 +++++++------------- vtkm/testing/UnitTestMath.cxx | 17 ++++++++--------- 3 files changed, 22 insertions(+), 35 deletions(-) diff --git a/vtkm/Math.h b/vtkm/Math.h index e9f762eaa..18e86932e 100644 --- a/vtkm/Math.h +++ b/vtkm/Math.h @@ -2701,12 +2701,6 @@ inline VTKM_EXEC_CONT vtkm::UInt64 FloatDistance(vtkm::Float32 x, vtkm::Float32 template inline VTKM_EXEC_CONT T DifferenceOfProducts(T a, T b, T c, T d) { - // This is a bit awkward. clang-11 does not define FP_FAST_FMA, but still compiles this to the correct assembly. - // Windows, however, generates truly horrendous assembly from this, with no fmas, to the extent I assume it could - // contort itself into a performance bug. - // That said, MSVC converts even a*b - c*d into horrible assembly, so it may be a wash. - // You'd want to just use #ifdef FP_FAST_FMA, but then you'd lose the (correct) generated assembly on clang. - // See: https://stackoverflow.com/a/40765925/904050 T cd = c * d; T err = std::fma(-c, d, cd); T dop = std::fma(a, b, -cd); @@ -2719,7 +2713,7 @@ inline VTKM_EXEC_CONT T DifferenceOfProducts(T a, T b, T c, T d) // If there are no real roots, both elements are NaNs. // The error should be at most 3 ulps. template -inline VTKM_EXEC_CONT vtkm::Pair QuadraticRoots(T a, T b, T c) +inline VTKM_EXEC_CONT vtkm::Vec QuadraticRoots(T a, T b, T c) { if (a == 0) { @@ -2728,19 +2722,19 @@ inline VTKM_EXEC_CONT vtkm::Pair QuadraticRoots(T a, T b, T c) if (c == 0) { // A degenerate case. All real numbers are roots; hopefully this arbitrary decision interacts gracefully with use. - return vtkm::Pair(0,0); + return vtkm::Vec(0,0); } else { - return vtkm::Pair(vtkm::Nan(), vtkm::Nan()); + return vtkm::Vec(vtkm::Nan(), vtkm::Nan()); } } - return vtkm::Pair(-c/b, -c/b); + return vtkm::Vec(-c/b, -c/b); } T delta = DifferenceOfProducts(b, b, 4*a, c); if (delta < 0) { - return vtkm::Pair(vtkm::Nan(), vtkm::Nan()); + return vtkm::Vec(vtkm::Nan(), vtkm::Nan()); } T q = -(b + vtkm::CopySign(vtkm::Sqrt(delta), b)) / 2; @@ -2748,9 +2742,9 @@ inline VTKM_EXEC_CONT vtkm::Pair QuadraticRoots(T a, T b, T c) T r1 = c / q; if (r0 < r1) { - return vtkm::Pair(r0, r1); + return vtkm::Vec(r0, r1); } - return vtkm::Pair(r1, r0); + return vtkm::Vec(r1, r0); } /// Bitwise operations diff --git a/vtkm/Math.h.in b/vtkm/Math.h.in index b8c5d39c6..48158890f 100644 --- a/vtkm/Math.h.in +++ b/vtkm/Math.h.in @@ -1303,12 +1303,6 @@ inline VTKM_EXEC_CONT vtkm::UInt64 FloatDistance(vtkm::Float32 x, vtkm::Float32 template inline VTKM_EXEC_CONT T DifferenceOfProducts(T a, T b, T c, T d) { - // This is a bit awkward. clang-11 does not define FP_FAST_FMA, but still compiles this to the correct assembly. - // Windows, however, generates truly horrendous assembly from this, with no fmas, to the extent I assume it could - // contort itself into a performance bug. - // That said, MSVC converts even a*b - c*d into horrible assembly, so it may be a wash. - // You'd want to just use #ifdef FP_FAST_FMA, but then you'd lose the (correct) generated assembly on clang. - // See: https://stackoverflow.com/a/40765925/904050 T cd = c * d; T err = std::fma(-c, d, cd); T dop = std::fma(a, b, -cd); @@ -1321,7 +1315,7 @@ inline VTKM_EXEC_CONT T DifferenceOfProducts(T a, T b, T c, T d) // If there are no real roots, both elements are NaNs. // The error should be at most 3 ulps. template -inline VTKM_EXEC_CONT vtkm::Pair QuadraticRoots(T a, T b, T c) +inline VTKM_EXEC_CONT vtkm::Vec QuadraticRoots(T a, T b, T c) { if (a == 0) { @@ -1330,19 +1324,19 @@ inline VTKM_EXEC_CONT vtkm::Pair QuadraticRoots(T a, T b, T c) if (c == 0) { // A degenerate case. All real numbers are roots; hopefully this arbitrary decision interacts gracefully with use. - return vtkm::Pair(0,0); + return vtkm::Vec(0,0); } else { - return vtkm::Pair(vtkm::Nan(), vtkm::Nan()); + return vtkm::Vec(vtkm::Nan(), vtkm::Nan()); } } - return vtkm::Pair(-c/b, -c/b); + return vtkm::Vec(-c/b, -c/b); } T delta = DifferenceOfProducts(b, b, 4*a, c); if (delta < 0) { - return vtkm::Pair(vtkm::Nan(), vtkm::Nan()); + return vtkm::Vec(vtkm::Nan(), vtkm::Nan()); } T q = -(b + vtkm::CopySign(vtkm::Sqrt(delta), b)) / 2; @@ -1350,9 +1344,9 @@ inline VTKM_EXEC_CONT vtkm::Pair QuadraticRoots(T a, T b, T c) T r1 = c / q; if (r0 < r1) { - return vtkm::Pair(r0, r1); + return vtkm::Vec(r0, r1); } - return vtkm::Pair(r1, r0); + return vtkm::Vec(r1, r0); } /// Bitwise operations diff --git a/vtkm/testing/UnitTestMath.cxx b/vtkm/testing/UnitTestMath.cxx index 87f2813f7..35a01ddc1 100644 --- a/vtkm/testing/UnitTestMath.cxx +++ b/vtkm/testing/UnitTestMath.cxx @@ -916,7 +916,6 @@ struct ScalarVectorFieldTests : public vtkm::exec::FunctorBase vtkm::Float32 expected = 5.376600027084351f; vtkm::UInt64 dist = vtkm::FloatDistance(expected, computed); - std::cout << "Dist = " << dist << "\n"; VTKM_MATH_ASSERT( dist < 2, "Float distance for difference of products is which exceeds 1.5; this is in violation of a " @@ -934,17 +933,17 @@ void TestQuadraticRoots() const // (x-1)(x+1) = x² - 1: auto roots = vtkm::QuadraticRoots(1.0f, 0.0f, -1.0f); - vtkm::UInt64 dist = vtkm::FloatDistance(-1.0f, roots.first); + vtkm::UInt64 dist = vtkm::FloatDistance(-1.0f, roots[0]); VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); - dist = vtkm::FloatDistance(1.0f, roots.second); + dist = vtkm::FloatDistance(1.0f, roots[1]); VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); // No real roots: roots = vtkm::QuadraticRoots(1.0f, 0.0f, 1.0f); - VTKM_MATH_ASSERT(vtkm::IsNan(roots.first), + VTKM_MATH_ASSERT(vtkm::IsNan(roots[0]), "Roots should be Nan for a quadratic with complex roots."); - VTKM_MATH_ASSERT(vtkm::IsNan(roots.second), + VTKM_MATH_ASSERT(vtkm::IsNan(roots[1]), "Roots should be Nan for a quadratic with complex roots."); #ifdef FP_FAST_FMA @@ -952,18 +951,18 @@ void TestQuadraticRoots() const // x² + 200x - 0.000015 = 0 has roots // -200.000000075, 7.5e-8 roots = vtkm::QuadraticRoots(1.0f, 200.0f, -0.000015f); - dist = vtkm::FloatDistance(-200.000000075f, roots.first); + dist = vtkm::FloatDistance(-200.000000075f, roots[0]); VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); - dist = vtkm::FloatDistance(7.5e-8f, roots.second); + dist = vtkm::FloatDistance(7.5e-8f, roots[1]); VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); // Kahan's example: auto roots64 = vtkm::QuadraticRoots(94906265.625, 94906267.000, 94906268.375); - dist = vtkm::FloatDistance(1.0, roots64.first); + dist = vtkm::FloatDistance(1.0, roots64[0]); VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); - dist = vtkm::FloatDistance(1.000000028975958, roots64.second); + dist = vtkm::FloatDistance(1.000000028975958, roots64[1]); VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); #endif } From a7ecd30cdd2afcafab840a7a713b66227c8ef768 Mon Sep 17 00:00:00 2001 From: Nick Thompson <4nt@ornl.gov> Date: Thu, 8 Apr 2021 15:56:35 -0400 Subject: [PATCH 09/16] Commute #ifdef with braces to make clang-format happy. --- vtkm/testing/UnitTestMath.cxx | 141 +++++++++++++++++----------------- 1 file changed, 71 insertions(+), 70 deletions(-) diff --git a/vtkm/testing/UnitTestMath.cxx b/vtkm/testing/UnitTestMath.cxx index 35a01ddc1..f818f1e48 100644 --- a/vtkm/testing/UnitTestMath.cxx +++ b/vtkm/testing/UnitTestMath.cxx @@ -902,95 +902,96 @@ struct ScalarVectorFieldTests : public vtkm::exec::FunctorBase } VTKM_EXEC - void TestDifferenceOfProducts() const { -#ifdef FP_FAST_FMA + void TestDifferenceOfProducts() const + { + { +#ifdef FP_FAST_FMA // Example taken from: // https://pharr.org/matt/blog/2019/11/03/difference-of-floats.html vtkm::Float32 a = 33962.035f; - vtkm::Float32 b = -30438.8f; - vtkm::Float32 c = 41563.4f; - vtkm::Float32 d = -24871.969f; - vtkm::Float32 computed = vtkm::DifferenceOfProducts(a, b, c, d); - // Expected result, computed in double precision and cast back to float: - vtkm::Float32 expected = 5.376600027084351f; + vtkm::Float32 b = -30438.8f; + vtkm::Float32 c = 41563.4f; + vtkm::Float32 d = -24871.969f; + vtkm::Float32 computed = vtkm::DifferenceOfProducts(a, b, c, d); + // Expected result, computed in double precision and cast back to float: + vtkm::Float32 expected = 5.376600027084351f; - vtkm::UInt64 dist = vtkm::FloatDistance(expected, computed); - VTKM_MATH_ASSERT( - dist < 2, - "Float distance for difference of products is which exceeds 1.5; this is in violation of a " - "theorem " - "proved by Jeannerod in doi.org/10.1090/S0025-5718-2013-02679-8. Is your build compiled " - "with fma's enabled?"); -} + vtkm::UInt64 dist = vtkm::FloatDistance(expected, computed); + VTKM_MATH_ASSERT( + dist < 2, + "Float distance for difference of products is which exceeds 1.5; this is in violation of a " + "theorem " + "proved by Jeannerod in doi.org/10.1090/S0025-5718-2013-02679-8. Is your build compiled " + "with fma's enabled?"); #endif -} + } + } -VTKM_EXEC -void TestQuadraticRoots() const -{ + VTKM_EXEC + void TestQuadraticRoots() const { - // (x-1)(x+1) = x² - 1: - auto roots = vtkm::QuadraticRoots(1.0f, 0.0f, -1.0f); + { + // (x-1)(x+1) = x² - 1: + auto roots = vtkm::QuadraticRoots(1.0f, 0.0f, -1.0f); - vtkm::UInt64 dist = vtkm::FloatDistance(-1.0f, roots[0]); - VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); + vtkm::UInt64 dist = vtkm::FloatDistance(-1.0f, roots[0]); + VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); - dist = vtkm::FloatDistance(1.0f, roots[1]); - VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); + dist = vtkm::FloatDistance(1.0f, roots[1]); + VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); - // No real roots: - roots = vtkm::QuadraticRoots(1.0f, 0.0f, 1.0f); - VTKM_MATH_ASSERT(vtkm::IsNan(roots[0]), - "Roots should be Nan for a quadratic with complex roots."); - VTKM_MATH_ASSERT(vtkm::IsNan(roots[1]), - "Roots should be Nan for a quadratic with complex roots."); + // No real roots: + roots = vtkm::QuadraticRoots(1.0f, 0.0f, 1.0f); + VTKM_MATH_ASSERT(vtkm::IsNan(roots[0]), + "Roots should be Nan for a quadratic with complex roots."); + VTKM_MATH_ASSERT(vtkm::IsNan(roots[1]), + "Roots should be Nan for a quadratic with complex roots."); #ifdef FP_FAST_FMA - // Wikipedia example: - // x² + 200x - 0.000015 = 0 has roots - // -200.000000075, 7.5e-8 - roots = vtkm::QuadraticRoots(1.0f, 200.0f, -0.000015f); - dist = vtkm::FloatDistance(-200.000000075f, roots[0]); - VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); + // Wikipedia example: + // x² + 200x - 0.000015 = 0 has roots + // -200.000000075, 7.5e-8 + roots = vtkm::QuadraticRoots(1.0f, 200.0f, -0.000015f); + dist = vtkm::FloatDistance(-200.000000075f, roots[0]); + VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); - dist = vtkm::FloatDistance(7.5e-8f, roots[1]); - VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); + dist = vtkm::FloatDistance(7.5e-8f, roots[1]); + VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); - // Kahan's example: - auto roots64 = vtkm::QuadraticRoots(94906265.625, 94906267.000, 94906268.375); - dist = vtkm::FloatDistance(1.0, roots64[0]); - VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); + // Kahan's example: + auto roots64 = vtkm::QuadraticRoots(94906265.625, 94906267.000, 94906268.375); + dist = vtkm::FloatDistance(1.0, roots64[0]); + VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); - dist = vtkm::FloatDistance(1.000000028975958, roots64[1]); - VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); + dist = vtkm::FloatDistance(1.000000028975958, roots64[1]); + VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); #endif + } } -} -VTKM_EXEC -void operator()(vtkm::Id) const -{ - this->TestTriangleTrig(); - this->TestHyperbolicTrig(); - this->TestSqrt(); - this->TestRSqrt(); - this->TestCbrt(); - this->TestRCbrt(); - this->TestExp(); - this->TestExp2(); - this->TestExpM1(); - this->TestExp10(); - this->TestLog(); - this->TestLog10(); - this->TestLog1P(); - this->TestCopySign(); - this->TestFloatDistance(); - this->TestDifferenceOfProducts(); - this->TestQuadraticRoots(); -} -} -; + VTKM_EXEC + void operator()(vtkm::Id) const + { + this->TestTriangleTrig(); + this->TestHyperbolicTrig(); + this->TestSqrt(); + this->TestRSqrt(); + this->TestCbrt(); + this->TestRCbrt(); + this->TestExp(); + this->TestExp2(); + this->TestExpM1(); + this->TestExp10(); + this->TestLog(); + this->TestLog10(); + this->TestLog1P(); + this->TestCopySign(); + this->TestFloatDistance(); + this->TestDifferenceOfProducts(); + this->TestQuadraticRoots(); + } +}; struct TryScalarVectorFieldTests { From d4ead2d7673499b35c1985891339c514e0ccdd97 Mon Sep 17 00:00:00 2001 From: Nick Thompson <4nt@ornl.gov> Date: Thu, 8 Apr 2021 15:59:38 -0400 Subject: [PATCH 10/16] Remove superfluous subbraces. --- vtkm/testing/UnitTestMath.cxx | 89 +++++++++++++++++------------------ 1 file changed, 42 insertions(+), 47 deletions(-) diff --git a/vtkm/testing/UnitTestMath.cxx b/vtkm/testing/UnitTestMath.cxx index f818f1e48..bab96785f 100644 --- a/vtkm/testing/UnitTestMath.cxx +++ b/vtkm/testing/UnitTestMath.cxx @@ -904,70 +904,65 @@ struct ScalarVectorFieldTests : public vtkm::exec::FunctorBase VTKM_EXEC void TestDifferenceOfProducts() const { - - { #ifdef FP_FAST_FMA - // Example taken from: - // https://pharr.org/matt/blog/2019/11/03/difference-of-floats.html - vtkm::Float32 a = 33962.035f; - vtkm::Float32 b = -30438.8f; - vtkm::Float32 c = 41563.4f; - vtkm::Float32 d = -24871.969f; - vtkm::Float32 computed = vtkm::DifferenceOfProducts(a, b, c, d); - // Expected result, computed in double precision and cast back to float: - vtkm::Float32 expected = 5.376600027084351f; + // Example taken from: + // https://pharr.org/matt/blog/2019/11/03/difference-of-floats.html + vtkm::Float32 a = 33962.035f; + vtkm::Float32 b = -30438.8f; + vtkm::Float32 c = 41563.4f; + vtkm::Float32 d = -24871.969f; + vtkm::Float32 computed = vtkm::DifferenceOfProducts(a, b, c, d); + // Expected result, computed in double precision and cast back to float: + vtkm::Float32 expected = 5.376600027084351f; - vtkm::UInt64 dist = vtkm::FloatDistance(expected, computed); - VTKM_MATH_ASSERT( - dist < 2, - "Float distance for difference of products is which exceeds 1.5; this is in violation of a " - "theorem " - "proved by Jeannerod in doi.org/10.1090/S0025-5718-2013-02679-8. Is your build compiled " - "with fma's enabled?"); + vtkm::UInt64 dist = vtkm::FloatDistance(expected, computed); + VTKM_MATH_ASSERT( + dist < 2, + "Float distance for difference of products is which exceeds 1.5; this is in violation of a " + "theorem " + "proved by Jeannerod in doi.org/10.1090/S0025-5718-2013-02679-8. Is your build compiled " + "with fma's enabled?"); #endif - } } VTKM_EXEC void TestQuadraticRoots() const { - { - // (x-1)(x+1) = x² - 1: - auto roots = vtkm::QuadraticRoots(1.0f, 0.0f, -1.0f); + // (x-1)(x+1) = x² - 1: + auto roots = vtkm::QuadraticRoots(1.0f, 0.0f, -1.0f); - vtkm::UInt64 dist = vtkm::FloatDistance(-1.0f, roots[0]); - VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); + vtkm::UInt64 dist = vtkm::FloatDistance(-1.0f, roots[0]); + VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); - dist = vtkm::FloatDistance(1.0f, roots[1]); - VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); + dist = vtkm::FloatDistance(1.0f, roots[1]); + VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); - // No real roots: - roots = vtkm::QuadraticRoots(1.0f, 0.0f, 1.0f); - VTKM_MATH_ASSERT(vtkm::IsNan(roots[0]), - "Roots should be Nan for a quadratic with complex roots."); - VTKM_MATH_ASSERT(vtkm::IsNan(roots[1]), - "Roots should be Nan for a quadratic with complex roots."); + // No real roots: + roots = vtkm::QuadraticRoots(1.0f, 0.0f, 1.0f); + VTKM_MATH_ASSERT(vtkm::IsNan(roots[0]), + "Roots should be Nan for a quadratic with complex roots."); + VTKM_MATH_ASSERT(vtkm::IsNan(roots[1]), + "Roots should be Nan for a quadratic with complex roots."); #ifdef FP_FAST_FMA - // Wikipedia example: - // x² + 200x - 0.000015 = 0 has roots - // -200.000000075, 7.5e-8 - roots = vtkm::QuadraticRoots(1.0f, 200.0f, -0.000015f); - dist = vtkm::FloatDistance(-200.000000075f, roots[0]); - VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); + // Wikipedia example: + // x² + 200x - 0.000015 = 0 has roots + // -200.000000075, 7.5e-8 + roots = vtkm::QuadraticRoots(1.0f, 200.0f, -0.000015f); + dist = vtkm::FloatDistance(-200.000000075f, roots[0]); + VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); - dist = vtkm::FloatDistance(7.5e-8f, roots[1]); - VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); + dist = vtkm::FloatDistance(7.5e-8f, roots[1]); + VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); - // Kahan's example: - auto roots64 = vtkm::QuadraticRoots(94906265.625, 94906267.000, 94906268.375); - dist = vtkm::FloatDistance(1.0, roots64[0]); - VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); + // Kahan's example: + auto roots64 = vtkm::QuadraticRoots(94906265.625, 94906267.000, 94906268.375); + dist = vtkm::FloatDistance(1.0, roots64[0]); + VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); - dist = vtkm::FloatDistance(1.000000028975958, roots64[1]); - VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); + dist = vtkm::FloatDistance(1.000000028975958, roots64[1]); + VTKM_MATH_ASSERT(dist < 3, "Float distance for quadratic roots exceeds 3 ulps."); #endif - } } VTKM_EXEC From 53833334c49246f0c2370fc142790c251d2295d7 Mon Sep 17 00:00:00 2001 From: Caitlin Ross Date: Tue, 23 Mar 2021 09:03:25 -0400 Subject: [PATCH 11/16] change the way tbb is imported --- CMake/VTKmConfig.cmake.in | 16 +++++++++- CMake/VTKmDeviceAdapters.cmake | 37 +++-------------------- CMake/VTKmInstallCMakePackage.cmake | 47 +++++++++++++++++++++++++++++ CMakeLists.txt | 2 ++ 4 files changed, 69 insertions(+), 33 deletions(-) create mode 100644 CMake/VTKmInstallCMakePackage.cmake diff --git a/CMake/VTKmConfig.cmake.in b/CMake/VTKmConfig.cmake.in index 05b81592c..715dc5a32 100644 --- a/CMake/VTKmConfig.cmake.in +++ b/CMake/VTKmConfig.cmake.in @@ -89,6 +89,19 @@ else() set_and_check(VTKm_CMAKE_MODULE_PATH "@PACKAGE_VTKm_INSTALL_CMAKE_MODULE_DIR@") endif() +include(CMakeFindDependencyMacro) + +set(CMAKE_MODULE_PATH_save_vtkm "${CMAKE_MODULE_PATH}") +list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_CURRENT_LIST_DIR}") + +if (VTKm_ENABLE_TBB) + find_dependency(TBB) + if (NOT TBB_FOUND) + set(VTKm_FOUND 0) + list(APPEND VTKm_NOT_FOUND_REASON "TBB not found: ${TBB_NOT_FOUND_MESSAGE}") + endif() +endif() + # Load the library exports, but only if not compiling VTK-m itself set_and_check(VTKm_CONFIG_DIR "@PACKAGE_VTKm_INSTALL_CONFIG_DIR@") set(VTKM_FROM_INSTALL_DIR FALSE) @@ -113,7 +126,8 @@ endif() # VTKm requires some CMake Find modules not included with CMake, so # include the CMake modules distributed with VTKm. -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${VTKm_CMAKE_MODULE_PATH}) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH_save_vtkm} ${VTKm_CMAKE_MODULE_PATH}) +unset(CMAKE_MODULE_PATH_save_vtkm) if(VTKm_ENABLE_CUDA) if (CMAKE_VERSION VERSION_LESS 3.13) diff --git a/CMake/VTKmDeviceAdapters.cmake b/CMake/VTKmDeviceAdapters.cmake index 76ea4e001..aae081681 100644 --- a/CMake/VTKmDeviceAdapters.cmake +++ b/CMake/VTKmDeviceAdapters.cmake @@ -43,38 +43,11 @@ endfunction() if(VTKm_ENABLE_TBB AND NOT TARGET vtkm::tbb) find_package(TBB REQUIRED) - add_library(vtkm::tbb UNKNOWN IMPORTED GLOBAL) - - set_target_properties(vtkm::tbb PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${TBB_INCLUDE_DIRS}") - - if(EXISTS "${TBB_LIBRARY_RELEASE}") - vtkm_extract_real_library("${TBB_LIBRARY_RELEASE}" real_path) - set_property(TARGET vtkm::tbb APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE) - set_target_properties(vtkm::tbb PROPERTIES - IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" - IMPORTED_LOCATION_RELEASE "${real_path}" - ) - elseif(EXISTS "${TBB_LIBRARY}") - #When VTK-m is mixed with OSPray we could use the OSPray FindTBB file - #which doesn't define TBB_LIBRARY_RELEASE but instead defined only - #TBB_LIBRARY - vtkm_extract_real_library("${TBB_LIBRARY}" real_path) - set_property(TARGET vtkm::tbb APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE) - set_target_properties(vtkm::tbb PROPERTIES - IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" - IMPORTED_LOCATION_RELEASE "${real_path}" - ) - endif() - - if(EXISTS "${TBB_LIBRARY_DEBUG}") - vtkm_extract_real_library("${TBB_LIBRARY_DEBUG}" real_path) - set_property(TARGET vtkm::tbb APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG) - set_target_properties(vtkm::tbb PROPERTIES - IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" - IMPORTED_LOCATION_DEBUG "${real_path}" - ) - endif() + add_library(vtkmTBB INTERFACE) + add_library(vtkm::tbb ALIAS vtkmTBB) + target_link_libraries(vtkmTBB INTERFACE TBB::tbb) + set_target_properties(vtkmTBB PROPERTIES EXPORT_NAME tbb) + install(TARGETS vtkmTBB EXPORT ${VTKm_EXPORT_NAME}) endif() diff --git a/CMake/VTKmInstallCMakePackage.cmake b/CMake/VTKmInstallCMakePackage.cmake new file mode 100644 index 000000000..466da8b84 --- /dev/null +++ b/CMake/VTKmInstallCMakePackage.cmake @@ -0,0 +1,47 @@ +##============================================================================ +## Copyright (c) Kitware, Inc. +## All rights reserved. +## See LICENSE.txt for details. +## +## This software is distributed WITHOUT ANY WARRANTY; without even +## the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +## PURPOSE. See the above copyright notice for more information. +##============================================================================ + +if (NOT (DEFINED VTKm_BUILD_CMAKE_BASE_DIR AND + DEFINED VTKm_INSTALL_CONFIG_DIR AND + DEFINED VTKm_CMAKE_MODULE_PATH)) + message(FATAL_ERROR + "VTKmInstallCMakePackage is missing input variables") +endif() + +set(vtkm_cmake_module_files) + +if(VTKm_ENABLE_TBB) + list(APPEND vtkm_cmake_module_files FindTBB.cmake) +endif() + +set(vtkm_cmake_build_dir ${VTKm_BUILD_CMAKE_BASE_DIR}/${VTKm_INSTALL_CONFIG_DIR}) +foreach (vtkm_cmake_module_file IN LISTS vtkm_cmake_module_files) + configure_file( + "${VTKm_CMAKE_MODULE_PATH}/${vtkm_cmake_module_file}" + "${vtkm_cmake_build_dir}/${vtkm_cmake_module_file}" + COPYONLY) + list(APPEND vtkm_cmake_files_to_install + "${vtkm_cmake_module_file}") +endforeach() + +foreach (vtkm_cmake_file IN LISTS vtkm_cmake_files_to_install) + if (IS_ABSOLUTE "${vtkm_cmake_file}") + file(RELATIVE_PATH vtkm_cmake_subdir_root "${vtkm_cmake_build_dir}" "${vtkm_cmake_file}") + get_filename_component(vtkm_cmake_subdir "${vtkm_cmake_subdir_root}" DIRECTORY) + set(vtkm_cmake_original_file "${vtkm_cmake_file}") + else () + get_filename_component(vtkm_cmake_subdir "${vtkm_cmake_file}" DIRECTORY) + set(vtkm_cmake_original_file "${VTKm_CMAKE_MODULE_PATH}/${vtkm_cmake_file}") + endif () + install( + FILES "${vtkm_cmake_original_file}" + DESTINATION "${VTKm_INSTALL_CONFIG_DIR}/${vtkm_cmake_subdir}" + COMPONENT "development") +endforeach () diff --git a/CMakeLists.txt b/CMakeLists.txt index 42f9a6a27..9a4ff1ef5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -269,6 +269,8 @@ write_basic_package_version_file( VERSION ${VTKm_VERSION} COMPATIBILITY ExactVersion ) +include(VTKmInstallCMakePackage) + # Install the readme and license files. if (NOT VTKm_NO_INSTALL_README_LICENSE) install(FILES ${VTKm_SOURCE_DIR}/README.md From eac6c21c8482f910abe80c6354a81b340330254d Mon Sep 17 00:00:00 2001 From: Nick Thompson <4nt@ornl.gov> Date: Fri, 9 Apr 2021 12:42:40 -0400 Subject: [PATCH 12/16] Workletize the logistic map. --- examples/logistic_map/LogisticMap.cxx | 105 ++++++++++++++++++-------- 1 file changed, 72 insertions(+), 33 deletions(-) diff --git a/examples/logistic_map/LogisticMap.cxx b/examples/logistic_map/LogisticMap.cxx index 571b64b7b..2df358694 100644 --- a/examples/logistic_map/LogisticMap.cxx +++ b/examples/logistic_map/LogisticMap.cxx @@ -13,51 +13,90 @@ #include #include #include +#include + + +// The logistic map is xᵢ₊₁ = rxᵢ(1-xᵢ). +// If we start this iteration out at (say) x₀ = 0.5, the map has "transients", +// which we must iterate away to produce the final image. +struct LogisticBurnIn : public vtkm::worklet::WorkletMapField +{ + using ControlSignature = void(WholeArrayOut); + using ExecutionSignature = void(_1, WorkIndex); + + template + VTKM_EXEC void operator()(OutputArrayPortalType& outputArrayPortal, vtkm::Id workIndex) const + { + vtkm::Id width = outputArrayPortal.GetNumberOfValues(); + double rmin = 2.9; + double r = rmin + (4.0 - rmin) * workIndex / (width - 1); + double x = 0.5; + // 2048 should be enough iterations to get rid of the transients: + int n = 0; + while (n++ < 2048) + { + x = r * x * (1 - x); + } + outputArrayPortal.Set(workIndex, x); + } +}; + +// After burn-in, the iteration is periodic but in general not convergent, +// i.e., for large enough i, there exists an integer p > 0 such that +// xᵢ₊ₚ = xᵢ for all i. +// So color the pixels corresponding to xᵢ, xᵢ₊₁, .. xᵢ₊ₚ. +struct LogisticLimitPoints : public vtkm::worklet::WorkletMapField +{ + using ControlSignature = void(WholeArrayIn, WholeArrayOut); + using ExecutionSignature = void(_1, _2, WorkIndex); + + template + VTKM_EXEC void operator()(const InputArrayPortalType& inputArrayPortal, + OutputArrayPortalType& outputArrayPortal, + vtkm::Id workIndex) const + { + vtkm::Id width = inputArrayPortal.GetNumberOfValues(); + double x = inputArrayPortal.Get(workIndex); + double rmin = 2.9; + double r = rmin + (4.0 - rmin) * workIndex / (width - 1); + vtkm::Vec4f orange(1.0, 0.5, 0.0, 0.0); + + // We can't display need more limit points than pixels of height: + vtkm::Id limit_points = 0; + vtkm::Id height = 1800; + while (limit_points++ < height) + { + vtkm::Id j = vtkm::Round(x * (height - 1)); + outputArrayPortal.Set(j * width + workIndex, orange); + x = r * x * (1 - x); + } + } +}; int main() { - size_t height = 1800; - size_t width = height * 1.618; + vtkm::Id height = 1800; + vtkm::Id width = height * 1.618; vtkm::cont::DataSetBuilderUniform dsb; vtkm::cont::DataSet ds = dsb.Create(vtkm::Id2(width, height)); - std::vector x(width, 0.5); + vtkm::cont::ArrayHandle x; + x.Allocate(width); + vtkm::cont::Invoker invoke; + invoke(LogisticBurnIn{}, x); - double rmin = 2.9; - for (size_t i = 0; i < width; ++i) + vtkm::cont::ArrayHandle pixels; + pixels.Allocate(width * height); + auto wp = pixels.WritePortal(); + for (vtkm::Id i = 0; i < pixels.GetNumberOfValues(); ++i) { - double r = rmin + (4.0 - rmin) * i / (width - 1); - int n = 0; - // 2048 should be enough iterations to be "converged"; - // though of course the iterations actually don't all converge but cycle or are chaotic. - while (n++ < 2048) - { - x[i] = r * x[i] * (1 - x[i]); - } - } - - - vtkm::Vec4f v(1.0, 0.5, 0.0, 0.0); - std::vector pixelValues(width * height, vtkm::Vec4f(0, 0, 0, 0)); - size_t iterates = 0; - // We don't need more iterates than pixels of height, - // by the pigeonhole principle. - while (iterates++ < height) - { - for (size_t i = 0; i < width; ++i) - { - double r = rmin + (4.0 - rmin) * i / (width - 1); - double y = x[i]; - assert(y >= 0 && y <= 1); - size_t j = std::round(y * (height - 1)); - pixelValues[j * width + i] = v; - x[i] = r * x[i] * (1 - x[i]); - } + wp.Set(i, vtkm::Vec4f(0, 0, 0, 0)); } + invoke(LogisticLimitPoints{}, x, pixels); std::string colorFieldName = "pixels"; - ds.AddPointField(colorFieldName, pixelValues); + ds.AddPointField(colorFieldName, pixels); std::string filename = "logistic.png"; vtkm::io::ImageWriterPNG writer(filename); writer.WriteDataSet(ds, colorFieldName); From 7b95ef59756a99b6764f500a6bdd0a48750389c7 Mon Sep 17 00:00:00 2001 From: Nick Thompson <4nt@ornl.gov> Date: Fri, 9 Apr 2021 14:54:12 -0400 Subject: [PATCH 13/16] Refactor the structs to classes. --- examples/logistic_map/LogisticMap.cxx | 71 ++++++++++++++++++--------- 1 file changed, 47 insertions(+), 24 deletions(-) diff --git a/examples/logistic_map/LogisticMap.cxx b/examples/logistic_map/LogisticMap.cxx index 2df358694..8cddec3c2 100644 --- a/examples/logistic_map/LogisticMap.cxx +++ b/examples/logistic_map/LogisticMap.cxx @@ -19,34 +19,53 @@ // The logistic map is xᵢ₊₁ = rxᵢ(1-xᵢ). // If we start this iteration out at (say) x₀ = 0.5, the map has "transients", // which we must iterate away to produce the final image. -struct LogisticBurnIn : public vtkm::worklet::WorkletMapField +template +class LogisticBurnIn : public vtkm::worklet::WorkletMapField { - using ControlSignature = void(WholeArrayOut); - using ExecutionSignature = void(_1, WorkIndex); - - template - VTKM_EXEC void operator()(OutputArrayPortalType& outputArrayPortal, vtkm::Id workIndex) const +public: + LogisticBurnIn(T rmin, vtkm::Id width) + : rmin_(rmin) + , width_(width) { - vtkm::Id width = outputArrayPortal.GetNumberOfValues(); - double rmin = 2.9; - double r = rmin + (4.0 - rmin) * workIndex / (width - 1); - double x = 0.5; + } + + using ControlSignature = void(FieldOut); + using ExecutionSignature = _1(WorkIndex); + + VTKM_EXEC T operator()(vtkm::Id workIndex) const + { + T r = rmin_ + (4.0 - rmin_) * workIndex / (width_ - 1); + T x = 0.5; // 2048 should be enough iterations to get rid of the transients: int n = 0; while (n++ < 2048) { x = r * x * (1 - x); } - outputArrayPortal.Set(workIndex, x); + return x; } + +private: + T rmin_; + vtkm::Id width_; }; // After burn-in, the iteration is periodic but in general not convergent, // i.e., for large enough i, there exists an integer p > 0 such that // xᵢ₊ₚ = xᵢ for all i. // So color the pixels corresponding to xᵢ, xᵢ₊₁, .. xᵢ₊ₚ. -struct LogisticLimitPoints : public vtkm::worklet::WorkletMapField +template +class LogisticLimitPoints : public vtkm::worklet::WorkletMapField { +public: + LogisticLimitPoints(T rmin, vtkm::Id width, vtkm::Id height) + : rmin_(rmin) + , width_(width) + , height_(height) + { + orange_ = vtkm::Vec4f(1.0, 0.5, 0.0, 0.0); + } + using ControlSignature = void(WholeArrayIn, WholeArrayOut); using ExecutionSignature = void(_1, _2, WorkIndex); @@ -55,22 +74,23 @@ struct LogisticLimitPoints : public vtkm::worklet::WorkletMapField OutputArrayPortalType& outputArrayPortal, vtkm::Id workIndex) const { - vtkm::Id width = inputArrayPortal.GetNumberOfValues(); - double x = inputArrayPortal.Get(workIndex); - double rmin = 2.9; - double r = rmin + (4.0 - rmin) * workIndex / (width - 1); - vtkm::Vec4f orange(1.0, 0.5, 0.0, 0.0); - + T x = inputArrayPortal.Get(workIndex); + T r = rmin_ + (4.0 - rmin_) * workIndex / (width_ - 1); // We can't display need more limit points than pixels of height: vtkm::Id limit_points = 0; - vtkm::Id height = 1800; - while (limit_points++ < height) + while (limit_points++ < height_) { - vtkm::Id j = vtkm::Round(x * (height - 1)); - outputArrayPortal.Set(j * width + workIndex, orange); + vtkm::Id j = vtkm::Round(x * (height_ - 1)); + outputArrayPortal.Set(j * width_ + workIndex, orange_); x = r * x * (1 - x); } } + +private: + T rmin_; + vtkm::Id width_; + vtkm::Id height_; + vtkm::Vec4f orange_; }; @@ -84,7 +104,9 @@ int main() vtkm::cont::ArrayHandle x; x.Allocate(width); vtkm::cont::Invoker invoke; - invoke(LogisticBurnIn{}, x); + double rmin = 2.9; + auto burnIn = LogisticBurnIn(rmin, width); + invoke(burnIn, x); vtkm::cont::ArrayHandle pixels; pixels.Allocate(width * height); @@ -93,8 +115,9 @@ int main() { wp.Set(i, vtkm::Vec4f(0, 0, 0, 0)); } + auto limitPoints = LogisticLimitPoints(rmin, width, height); - invoke(LogisticLimitPoints{}, x, pixels); + invoke(limitPoints, x, pixels); std::string colorFieldName = "pixels"; ds.AddPointField(colorFieldName, pixels); std::string filename = "logistic.png"; From f1cf6c762a7d50e42e2cf013c6fc73d3acb903a2 Mon Sep 17 00:00:00 2001 From: Nick Thompson <4nt@ornl.gov> Date: Fri, 9 Apr 2021 14:56:19 -0400 Subject: [PATCH 14/16] Refactor to more idiomatic use of worklets. --- examples/logistic_map/LogisticMap.cxx | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/examples/logistic_map/LogisticMap.cxx b/examples/logistic_map/LogisticMap.cxx index 8cddec3c2..572f2fb1e 100644 --- a/examples/logistic_map/LogisticMap.cxx +++ b/examples/logistic_map/LogisticMap.cxx @@ -66,15 +66,12 @@ public: orange_ = vtkm::Vec4f(1.0, 0.5, 0.0, 0.0); } - using ControlSignature = void(WholeArrayIn, WholeArrayOut); + using ControlSignature = void(FieldIn, WholeArrayOut); using ExecutionSignature = void(_1, _2, WorkIndex); - template - VTKM_EXEC void operator()(const InputArrayPortalType& inputArrayPortal, - OutputArrayPortalType& outputArrayPortal, - vtkm::Id workIndex) const + template + VTKM_EXEC void operator()(T x, OutputArrayPortalType& outputArrayPortal, vtkm::Id workIndex) const { - T x = inputArrayPortal.Get(workIndex); T r = rmin_ + (4.0 - rmin_) * workIndex / (width_ - 1); // We can't display need more limit points than pixels of height: vtkm::Id limit_points = 0; From f60a45bc639396e76b4a08371b512c7ec7334a15 Mon Sep 17 00:00:00 2001 From: Vicente Adolfo Bolea Sanchez Date: Mon, 12 Apr 2021 13:29:46 -0400 Subject: [PATCH 15/16] Enforce C++14 in the whole project Signed-off-by: Vicente Adolfo Bolea Sanchez --- CMake/VTKmCompilerFlags.cmake | 4 ++-- vtkm/thirdparty/diy/update.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMake/VTKmCompilerFlags.cmake b/CMake/VTKmCompilerFlags.cmake index 0ed12be3e..2a4aaa545 100644 --- a/CMake/VTKmCompilerFlags.cmake +++ b/CMake/VTKmCompilerFlags.cmake @@ -40,8 +40,8 @@ add_library(vtkm_compiler_flags INTERFACE) target_link_libraries(vtkm_compiler_flags INTERFACE $) -# setup that we need C++11 support -target_compile_features(vtkm_compiler_flags INTERFACE cxx_std_11) +# setup that we need C++14 support +target_compile_features(vtkm_compiler_flags INTERFACE cxx_std_14) # setup our static libraries so that a separate ELF section # is generated for each function. This allows for the linker to diff --git a/vtkm/thirdparty/diy/update.sh b/vtkm/thirdparty/diy/update.sh index 1ee37c531..1be1c2e35 100755 --- a/vtkm/thirdparty/diy/update.sh +++ b/vtkm/thirdparty/diy/update.sh @@ -8,7 +8,7 @@ readonly name="diy" readonly ownership="Diy Upstream " readonly subtree="vtkm/thirdparty/$name/vtkm$name" readonly repo="https://gitlab.kitware.com/third-party/diy2.git" -readonly tag="for/vtk-m-20201026-master" +readonly tag="for/vtk-m-20210412-master" readonly paths=" cmake include From 89b6f2106c502e2bcd9ba0388b2890a1834a931b Mon Sep 17 00:00:00 2001 From: Diy Upstream Date: Mon, 12 Apr 2021 16:57:34 +0000 Subject: [PATCH 16/16] diy 2021-04-12 (bc7dcda5) Code extracted from: https://gitlab.kitware.com/third-party/diy2.git at commit bc7dcda5ec2c6e15fd3bd8c57389adc6613c2595 (for/vtk-m-20210412-master). --- CMakeLists.txt | 4 ++-- include/vtkmdiy/thirdparty/fmt/format.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 420b1aa6f..46861ebdc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -143,7 +143,7 @@ function(add_diy_mpi_library use_mpi) add_library(${lib_name} ${sources}) set_target_properties(${lib_name} PROPERTIES POSITION_INDEPENDENT_CODE ON) - target_compile_features(${lib_name} PRIVATE cxx_std_11) + target_compile_features(${lib_name} PRIVATE cxx_std_14) target_compile_definitions(${lib_name} PRIVATE -DVTKMDIY_HAS_MPI=${has_mpi_val} PRIVATE -Ddiy=${diy_prefix} # mangle diy namespace @@ -186,7 +186,7 @@ if (build_diy_mpi_lib) endif() # build_diy_mpi_lib add_library(${diy_prefix} INTERFACE) -target_compile_features(${diy_prefix} INTERFACE cxx_std_11) +target_compile_features(${diy_prefix} INTERFACE cxx_std_14) target_compile_definitions(${diy_prefix} INTERFACE ${diy_definitions}) target_include_directories(${diy_prefix} SYSTEM INTERFACE "$" diff --git a/include/vtkmdiy/thirdparty/fmt/format.h b/include/vtkmdiy/thirdparty/fmt/format.h index dcf4a3998..ce5d0695e 100644 --- a/include/vtkmdiy/thirdparty/fmt/format.h +++ b/include/vtkmdiy/thirdparty/fmt/format.h @@ -850,7 +850,7 @@ inline Char* format_uint(Char* buffer, UInt value, int num_digits, buffer += num_digits; Char* end = buffer; do { - const char* digits = upper ? "0123456789ABCDEF" : data::hex_digits; + const char* digits = upper ? "0123456789ABCDEF" : "0123456789abcdef"; unsigned digit = (value & ((1 << BASE_BITS) - 1)); *--buffer = static_cast(BASE_BITS < 4 ? static_cast('0' + digit) : digits[digit]);