diff --git a/docs/changelog/consolidate-count-to-offset.md b/docs/changelog/consolidate-count-to-offset.md index cc43e4d4b..76c8d20ce 100644 --- a/docs/changelog/consolidate-count-to-offset.md +++ b/docs/changelog/consolidate-count-to-offset.md @@ -16,6 +16,13 @@ device-specific code (e.g. `vtkm::cont::Algorithm`) from core classes like `CellSetExplicit` so that less code needs to use the device compiler (especially downstream code). +`ConvertNumComponentsToOffsets` has also been changed to provide a +pre-compiled version for common arrays. This helps with the dual goals of +compiling less device code and allowing data set builders to not have to +use the device compiler. For cases where you need to compile +`ConvertNumComponentsToOffsets` for a different kind of array, you can use +the internal `ConvertNumComponentsToOffsetsTemplate`. + Part of this change removed unnecessary includes of `Algorithm.h` in `ArrayHandleGroupVecVariable.h` and `CellSetExplicit.h`. This header had to be added to some classes that were not including it themselves. diff --git a/vtkm/cont/CMakeLists.txt b/vtkm/cont/CMakeLists.txt index b7c0f1255..6c0aa1768 100644 --- a/vtkm/cont/CMakeLists.txt +++ b/vtkm/cont/CMakeLists.txt @@ -177,6 +177,7 @@ set(device_sources CellSetExtrude.cxx CellSetStructured.cxx ColorTable.cxx + ConvertNumComponentsToOffsets.cxx CoordinateSystem.cxx DataSet.cxx DataSetBuilderCurvilinear.cxx diff --git a/vtkm/cont/CellSetPermutation.h b/vtkm/cont/CellSetPermutation.h index f7f4ff3c3..66f06f9e5 100644 --- a/vtkm/cont/CellSetPermutation.h +++ b/vtkm/cont/CellSetPermutation.h @@ -18,9 +18,9 @@ #include #include #include -#include #include #include +#include #include #include @@ -93,7 +93,8 @@ public: vtkm::Id& connectivityLength /* outparam */, vtkm::cont::DeviceAdapterId) { - return vtkm::cont::ConvertNumComponentsToOffsets(numIndices, connectivityLength); + return vtkm::cont::internal::ConvertNumComponentsToOffsetsTemplate(numIndices, + connectivityLength); } template diff --git a/vtkm/cont/ConvertNumComponentsToOffsets.cxx b/vtkm/cont/ConvertNumComponentsToOffsets.cxx new file mode 100644 index 000000000..8bf942190 --- /dev/null +++ b/vtkm/cont/ConvertNumComponentsToOffsets.cxx @@ -0,0 +1,103 @@ +//============================================================================ +// 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. +//============================================================================ + +#include +#include + +#include + +#include + +namespace +{ + +struct CallNumToOffsets +{ + template + VTKM_CONT void operator()(BaseType, + const vtkm::cont::UnknownArrayHandle& numComponentsArray, + vtkm::cont::ArrayHandle& offsetsArray, + vtkm::cont::DeviceAdapterId device, + bool& converted) + { + if (!numComponentsArray.IsBaseComponentType()) + { + // Not the right type. + return; + } + + vtkm::cont::internal::ConvertNumComponentsToOffsetsTemplate( + numComponentsArray.ExtractComponent(0, vtkm::CopyFlag::Off), // TODO: Allow copy + offsetsArray, + device); + converted = true; + } +}; + +} // anonymous namespace + +namespace vtkm +{ +namespace cont +{ + +void ConvertNumComponentsToOffsets(const vtkm::cont::UnknownArrayHandle& numComponentsArray, + vtkm::cont::ArrayHandle& offsetsArray, + vtkm::Id& componentsArraySize, + vtkm::cont::DeviceAdapterId device) +{ + vtkm::cont::ConvertNumComponentsToOffsets(numComponentsArray, offsetsArray, device); + + componentsArraySize = + vtkm::cont::ArrayGetValue(offsetsArray.GetNumberOfValues() - 1, offsetsArray); +} + +void ConvertNumComponentsToOffsets(const vtkm::cont::UnknownArrayHandle& numComponentsArray, + vtkm::cont::ArrayHandle& offsetsArray, + vtkm::cont::DeviceAdapterId device) +{ + if (numComponentsArray.GetNumberOfComponentsFlat() > 1) + { + throw vtkm::cont::ErrorBadType( + "ConvertNumComponentsToOffsets only works with arrays of integers, not Vecs."); + } + + using SupportedTypes = vtkm::List; + bool converted = false; + vtkm::ListForEach( + CallNumToOffsets{}, SupportedTypes{}, numComponentsArray, offsetsArray, device, converted); + if (!converted) + { + internal::ThrowCastAndCallException(numComponentsArray, typeid(SupportedTypes)); + } +} + +vtkm::cont::ArrayHandle ConvertNumComponentsToOffsets( + const vtkm::cont::UnknownArrayHandle& numComponentsArray, + vtkm::Id& componentsArraySize, + vtkm::cont::DeviceAdapterId device) +{ + vtkm::cont::ArrayHandle offsetsArray; + vtkm::cont::ConvertNumComponentsToOffsets( + numComponentsArray, offsetsArray, componentsArraySize, device); + return offsetsArray; +} + +vtkm::cont::ArrayHandle ConvertNumComponentsToOffsets( + const vtkm::cont::UnknownArrayHandle& numComponentsArray, + vtkm::cont::DeviceAdapterId device) +{ + vtkm::cont::ArrayHandle offsetsArray; + vtkm::cont::ConvertNumComponentsToOffsets(numComponentsArray, offsetsArray, device); + return offsetsArray; +} + +} // namespace vtkm::cont +} // namespace vtkm diff --git a/vtkm/cont/ConvertNumComponentsToOffsets.h b/vtkm/cont/ConvertNumComponentsToOffsets.h index 6aa20e7c4..07286927e 100644 --- a/vtkm/cont/ConvertNumComponentsToOffsets.h +++ b/vtkm/cont/ConvertNumComponentsToOffsets.h @@ -10,8 +10,11 @@ #ifndef vtk_m_cont_ConvertNumComponentsToOffsets_h #define vtk_m_cont_ConvertNumComponentsToOffsets_h -#include -#include +#include +#include +#include + +#include namespace vtkm { @@ -19,9 +22,10 @@ namespace cont { -/// \c ConvertNumComponentsToOffsets takes an array of Vec sizes (i.e. the number of components in -/// each Vec) and returns an array of offsets to a packed array of such Vecs. The resulting array -/// can be used with \c ArrayHandleGroupVecVariable. +/// @{ +/// `ConvertNumComponentsToOffsets` takes an array of Vec sizes (i.e. the number of components in +/// each `Vec`) and returns an array of offsets to a packed array of such `Vec`s. The resulting +/// array can be used with `ArrayHandleGroupVecVariable`. /// /// \param numComponentsArray the input array that specifies the number of components in each group /// Vec. @@ -29,66 +33,36 @@ namespace cont /// \param offsetsArray (optional) the output \c ArrayHandle, which must have a value type of \c /// vtkm::Id. If the output \c ArrayHandle is not given, it is returned. /// -/// \param componentsArraySize (optional) a reference to a \c vtkm::Id and is filled with the expected -/// size of the component values array. +/// \param componentsArraySize (optional) a reference to a \c vtkm::Id and is filled with the +/// expected size of the component values array. /// /// \param device (optional) specifies the device on which to run the conversion. /// -template -VTKM_CONT void ConvertNumComponentsToOffsets( - const NumComponentsArrayType& numComponentsArray, - vtkm::cont::ArrayHandle& offsetsArray, +/// Note that this function is pre-compiled for some set of `ArrayHandle` types. If you get a +/// warning about an inefficient conversion (or the operation fails outright), you might need to +/// use `vtkm::cont::internal::ConvertNumComponentsToOffsetsTemplate`. +/// +VTKM_CONT_EXPORT void ConvertNumComponentsToOffsets( + const vtkm::cont::UnknownArrayHandle& numComponentsArray, + vtkm::cont::ArrayHandle& offsetsArray, vtkm::Id& componentsArraySize, - vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny()) -{ - using namespace vtkm::cont; - VTKM_IS_ARRAY_HANDLE(NumComponentsArrayType); + vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{}); - VTKM_LOG_SCOPE_FUNCTION(vtkm::cont::LogLevel::Perf); +VTKM_CONT_EXPORT void ConvertNumComponentsToOffsets( + const vtkm::cont::UnknownArrayHandle& numComponentsArray, + vtkm::cont::ArrayHandle& offsetsArray, + vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{}); - Algorithm::ScanExtended(device, make_ArrayHandleCast(numComponentsArray), offsetsArray); - - componentsArraySize = ArrayGetValue(offsetsArray.GetNumberOfValues() - 1, offsetsArray); -} - -template -VTKM_CONT void ConvertNumComponentsToOffsets( - const NumComponentsArrayType& numComponentsArray, - vtkm::cont::ArrayHandle& offsetsArray, - vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny()) -{ - VTKM_IS_ARRAY_HANDLE(NumComponentsArrayType); - - VTKM_LOG_SCOPE_FUNCTION(vtkm::cont::LogLevel::Perf); - - vtkm::cont::Algorithm::ScanExtended( - device, vtkm::cont::make_ArrayHandleCast(numComponentsArray), offsetsArray); -} - -template -VTKM_CONT vtkm::cont::ArrayHandle ConvertNumComponentsToOffsets( - const NumComponentsArrayType& numComponentsArray, +VTKM_CONT_EXPORT vtkm::cont::ArrayHandle ConvertNumComponentsToOffsets( + const vtkm::cont::UnknownArrayHandle& numComponentsArray, vtkm::Id& componentsArraySize, - vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny()) -{ - VTKM_IS_ARRAY_HANDLE(NumComponentsArrayType); + vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{}); - vtkm::cont::ArrayHandle offsetsArray; - vtkm::cont::ConvertNumComponentsToOffsets( - numComponentsArray, offsetsArray, componentsArraySize, device); - return offsetsArray; -} +VTKM_CONT_EXPORT vtkm::cont::ArrayHandle ConvertNumComponentsToOffsets( + const vtkm::cont::UnknownArrayHandle& numComponentsArray, + vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{}); -template -VTKM_CONT vtkm::cont::ArrayHandle ConvertNumComponentsToOffsets( - const NumComponentsArrayType& numComponentsArray, - vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny()) -{ - VTKM_IS_ARRAY_HANDLE(NumComponentsArrayType); - - vtkm::Id dummy; - return vtkm::cont::ConvertNumComponentsToOffsets(numComponentsArray, dummy, device); -} +/// @} } // namespace vtkm::cont } // namespace vtkm diff --git a/vtkm/cont/internal/CMakeLists.txt b/vtkm/cont/internal/CMakeLists.txt index c342848e7..72ccae355 100644 --- a/vtkm/cont/internal/CMakeLists.txt +++ b/vtkm/cont/internal/CMakeLists.txt @@ -19,6 +19,7 @@ set(headers CastInvalidValue.h CellLocatorBase.h ConnectivityExplicitInternals.h + ConvertNumComponentsToOffsetsTemplate.h DeviceAdapterAlgorithmGeneral.h DeviceAdapterMemoryManager.h DeviceAdapterMemoryManagerShared.h diff --git a/vtkm/cont/internal/ConvertNumComponentsToOffsetsTemplate.h b/vtkm/cont/internal/ConvertNumComponentsToOffsetsTemplate.h new file mode 100644 index 000000000..8bb95efee --- /dev/null +++ b/vtkm/cont/internal/ConvertNumComponentsToOffsetsTemplate.h @@ -0,0 +1,97 @@ +//============================================================================ +// 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. +//============================================================================ +#ifndef vtk_m_cont_internal_ConvertNumComponentsToOffsetsTemplate_h +#define vtk_m_cont_internal_ConvertNumComponentsToOffsetsTemplate_h + + +#include +#include + +namespace vtkm +{ +namespace cont +{ +namespace internal +{ + +/// @{ +/// \brief Template implementation of `ConvertNumComponentsToOffsets`. +/// +/// This form of the function can be used in situations where the precompiled +/// `ConvertNumComponentsToOffsets` does not include code paths for a desired +/// array. +/// +template +VTKM_CONT void ConvertNumComponentsToOffsetsTemplate( + const NumComponentsArrayType& numComponentsArray, + vtkm::cont::ArrayHandle& offsetsArray, + vtkm::Id& componentsArraySize, + vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny()) +{ + using namespace vtkm::cont; + VTKM_IS_ARRAY_HANDLE(NumComponentsArrayType); + + VTKM_LOG_SCOPE_FUNCTION(vtkm::cont::LogLevel::Perf); + + Algorithm::ScanExtended(device, make_ArrayHandleCast(numComponentsArray), offsetsArray); + + componentsArraySize = + vtkm::cont::ArrayGetValue(offsetsArray.GetNumberOfValues() - 1, offsetsArray); +} + +template +VTKM_CONT void ConvertNumComponentsToOffsetsTemplate( + const NumComponentsArrayType& numComponentsArray, + vtkm::cont::ArrayHandle& offsetsArray, + vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny()) +{ + VTKM_IS_ARRAY_HANDLE(NumComponentsArrayType); + + VTKM_LOG_SCOPE_FUNCTION(vtkm::cont::LogLevel::Perf); + + vtkm::cont::Algorithm::ScanExtended( + device, vtkm::cont::make_ArrayHandleCast(numComponentsArray), offsetsArray); +} + +template +VTKM_CONT vtkm::cont::ArrayHandle ConvertNumComponentsToOffsetsTemplate( + const NumComponentsArrayType& numComponentsArray, + vtkm::Id& componentsArraySize, + vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny()) +{ + VTKM_IS_ARRAY_HANDLE(NumComponentsArrayType); + + vtkm::cont::ArrayHandle offsetsArray; + vtkm::cont::internal::ConvertNumComponentsToOffsetsTemplate( + numComponentsArray, offsetsArray, componentsArraySize, device); + return offsetsArray; +} + +template +VTKM_CONT vtkm::cont::ArrayHandle ConvertNumComponentsToOffsetsTemplate( + const NumComponentsArrayType& numComponentsArray, + vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny()) +{ + VTKM_IS_ARRAY_HANDLE(NumComponentsArrayType); + + vtkm::cont::ArrayHandle offsetsArray; + vtkm::cont::internal::ConvertNumComponentsToOffsetsTemplate( + numComponentsArray, offsetsArray, device); + return offsetsArray; +} + + +/// @} + +} // namespace vtkm::cont::internal +} // namespace vtkm::cont +} // namespace vtkm + +#endif // vtk_m_cont_internal_ConvertNumComponentsToOffsetsTemplate_h diff --git a/vtkm/cont/testing/TestingFancyArrayHandles.h b/vtkm/cont/testing/TestingFancyArrayHandles.h index 979ea5279..51a454b1f 100644 --- a/vtkm/cont/testing/TestingFancyArrayHandles.h +++ b/vtkm/cont/testing/TestingFancyArrayHandles.h @@ -1112,7 +1112,9 @@ private: { vtkm::Id sourceArraySize; - vtkm::cont::ArrayHandleCounting numComponentsArray(1, 1, ARRAY_SIZE); + vtkm::cont::ArrayHandle numComponentsArray; + vtkm::cont::ArrayCopy(vtkm::cont::ArrayHandleCounting(1, 1, ARRAY_SIZE), + numComponentsArray); vtkm::cont::ArrayHandle offsetsArray = vtkm::cont::ConvertNumComponentsToOffsets(numComponentsArray, sourceArraySize); @@ -1167,7 +1169,9 @@ private: { vtkm::Id sourceArraySize; - vtkm::cont::ArrayHandleCounting numComponentsArray(1, 1, ARRAY_SIZE); + vtkm::cont::ArrayHandle numComponentsArray; + vtkm::cont::ArrayCopy(vtkm::cont::ArrayHandleCounting(1, 1, ARRAY_SIZE), + numComponentsArray); vtkm::cont::ArrayHandle offsetsArray = vtkm::cont::ConvertNumComponentsToOffsets( numComponentsArray, sourceArraySize, DeviceAdapterTag());