//============================================================================ // 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_ArrayRangeComputeTemplate_h #define vtk_m_cont_ArrayRangeComputeTemplate_h #include #include #include #include #include #include #include #include #include #include #include namespace vtkm { namespace cont { namespace internal { //------------------------------------------------------------------------------------------------- struct ComputeRangeOptionsDecorator { bool IgnoreInf = false; template struct Functor { SrcPortal Src; MaskPortal Mask; bool IgnoreInf; using InValueType = typename SrcPortal::ValueType; using InVecTraits = vtkm::VecTraits; using ResultType = vtkm::Vec, 2>; VTKM_EXEC_CONT ResultType operator()(vtkm::Id idx) const { if ((this->Mask.GetNumberOfValues() != 0) && (this->Mask.Get(idx) == 0)) { return { { vtkm::Range{}.Min }, { vtkm::Range{}.Max } }; } const auto& inVal = this->Src.Get(idx); ResultType outVal; for (vtkm::IdComponent i = 0; i < InVecTraits::NUM_COMPONENTS; ++i) { auto val = static_cast(InVecTraits::GetComponent(inVal, i)); if (vtkm::IsNan(val) || (this->IgnoreInf && !vtkm::IsFinite(val))) { outVal[0][i] = vtkm::Range{}.Min; outVal[1][i] = vtkm::Range{}.Max; } else { outVal[0][i] = outVal[1][i] = val; } } return outVal; } }; template Functor CreateFunctor(const SrcPortal& sp, const GhostPortal& gp) const { return { sp, gp, this->IgnoreInf }; } }; template struct ArrayValueIsNested { static constexpr bool Value = !vtkm::internal::IsFlatVec::value; }; template ::Value> struct NestedToFlat; template struct NestedToFlat { static auto Transform(const ArrayHandleType& in) { return vtkm::cont::ArrayHandleCast, ArrayHandleType>(in); } }; template struct NestedToFlat { static auto Transform(const ArrayHandleType& in) { return in; } }; template inline auto NestedToFlatTransform(const ArrayHandleType& input) { return NestedToFlat::Transform(input); } //------------------------------------------------------------------------------------------------- /// \brief A generic implementation of `ArrayRangeCompute`. This is the implementation used /// when `ArrayRangeComputeImpl` is not specialized. /// template inline vtkm::cont::ArrayHandle ArrayRangeComputeGeneric( const vtkm::cont::ArrayHandle& input, const vtkm::cont::ArrayHandle& maskArray, bool computeFiniteRange, vtkm::cont::DeviceAdapterId device) { VTKM_LOG_SCOPE(vtkm::cont::LogLevel::Perf, "ArrayRangeCompute"); using VecTraits = vtkm::VecTraits; vtkm::cont::ArrayHandle range; range.Allocate(VecTraits::NUM_COMPONENTS); //We want to minimize the amount of code that we do in try execute as //it is repeated for each if (input.GetNumberOfValues() < 1) { range.Fill(vtkm::Range{}); } else { // if input is an array of nested vectors, transform them to `VecFlat` using ArrayHandleCast auto flattened = NestedToFlatTransform(input); ComputeRangeOptionsDecorator decorator{ computeFiniteRange }; auto decorated = make_ArrayHandleDecorator(flattened.GetNumberOfValues(), decorator, flattened, maskArray); using ResultType = vtkm::Vec, 2>; using MinAndMaxFunctor = vtkm::MinAndMax; ResultType identity{ { vtkm::Range{}.Min }, { vtkm::Range{}.Max } }; auto result = vtkm::cont::Algorithm::Reduce(device, decorated, identity, MinAndMaxFunctor{}); auto portal = range.WritePortal(); for (vtkm::IdComponent i = 0; i < VecTraits::NUM_COMPONENTS; ++i) { portal.Set(i, vtkm::Range(result[0][i], result[1][i])); } } return range; } //------------------------------------------------------------------------------------------------- struct ScalarMagnitudeFunctor { template VTKM_EXEC_CONT vtkm::Float64 operator()(const T& val) const { // spcilization of `vtkm::Magnitude` for scalars should avoid `sqrt` computation by using `abs` // instead return static_cast(vtkm::Magnitude(val)); } }; struct MagnitudeSquareFunctor { template VTKM_EXEC_CONT vtkm::Float64 operator()(const T& val) const { using VecTraits = vtkm::VecTraits; vtkm::Float64 result = 0; for (vtkm::IdComponent i = 0; i < VecTraits::GetNumberOfComponents(val); ++i) { auto comp = static_cast(VecTraits::GetComponent(val, i)); result += comp * comp; } return result; } }; template vtkm::Range ArrayRangeComputeMagnitudeGenericImpl( vtkm::VecTraitsTagSingleComponent, const ArrayHandleType& input, const vtkm::cont::ArrayHandle& maskArray, bool computeFiniteRange, vtkm::cont::DeviceAdapterId device) { auto mag = vtkm::cont::make_ArrayHandleTransform(input, ScalarMagnitudeFunctor{}); auto rangeAH = ArrayRangeComputeGeneric(mag, maskArray, computeFiniteRange, device); return rangeAH.ReadPortal().Get(0); } template vtkm::Range ArrayRangeComputeMagnitudeGenericImpl( vtkm::VecTraitsTagMultipleComponents, const ArrayHandleType& input, const vtkm::cont::ArrayHandle& maskArray, bool computeFiniteRange, vtkm::cont::DeviceAdapterId device) { auto magsqr = vtkm::cont::make_ArrayHandleTransform(input, MagnitudeSquareFunctor{}); auto rangeAH = ArrayRangeComputeGeneric(magsqr, maskArray, computeFiniteRange, device); auto range = rangeAH.ReadPortal().Get(0); if (range.IsNonEmpty()) { range.Min = vtkm::Sqrt(range.Min); range.Max = vtkm::Sqrt(range.Max); } return range; } /// \brief A generic implementation of `ArrayRangeComputeMagnitude`. This is the implementation used /// when `ArrayRangeComputeMagnitudeImpl` is not specialized. /// template inline vtkm::Range ArrayRangeComputeMagnitudeGeneric( const vtkm::cont::ArrayHandle& input, const vtkm::cont::ArrayHandle& maskArray, bool computeFiniteRange, vtkm::cont::DeviceAdapterId device) { VTKM_LOG_SCOPE(vtkm::cont::LogLevel::Perf, "ArrayRangeComputeMagnitude"); using VecTraits = vtkm::VecTraits; //We want to minimize the amount of code that we do in try execute as //it is repeated for each if (input.GetNumberOfValues() < 1) { return vtkm::Range{}; } auto flattened = NestedToFlatTransform(input); return ArrayRangeComputeMagnitudeGenericImpl( typename VecTraits::HasMultipleComponents{}, flattened, maskArray, computeFiniteRange, device); } //------------------------------------------------------------------------------------------------- template struct ArrayRangeComputeImpl { template vtkm::cont::ArrayHandle operator()( const vtkm::cont::ArrayHandle& input, const vtkm::cont::ArrayHandle& maskArray, bool computeFiniteRange, vtkm::cont::DeviceAdapterId device) const { return vtkm::cont::internal::ArrayRangeComputeGeneric( input, maskArray, computeFiniteRange, device); } }; template struct ArrayRangeComputeMagnitudeImpl { template vtkm::Range operator()(const vtkm::cont::ArrayHandle& input, const vtkm::cont::ArrayHandle& maskArray, bool computeFiniteRange, vtkm::cont::DeviceAdapterId device) const { return vtkm::cont::internal::ArrayRangeComputeMagnitudeGeneric( input, maskArray, computeFiniteRange, device); } }; } // namespace internal //------------------------------------------------------------------------------------------------- /// @{ /// \brief Templated version of ArrayRangeCompute /// \sa ArrayRangeCompute /// template inline vtkm::cont::ArrayHandle ArrayRangeComputeTemplate( const vtkm::cont::ArrayHandle& input, bool computeFiniteRange = false, vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{}) { return ArrayRangeComputeTemplate( input, vtkm::cont::ArrayHandle{}, computeFiniteRange, device); } template vtkm::cont::ArrayHandle ArrayRangeComputeTemplate( const vtkm::cont::ArrayHandle& input, const vtkm::cont::ArrayHandle& maskArray, bool computeFiniteRange = false, vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{}) { VTKM_ASSERT(maskArray.GetNumberOfValues() == 0 || maskArray.GetNumberOfValues() == input.GetNumberOfValues()); return internal::ArrayRangeComputeImpl{}(input, maskArray, computeFiniteRange, device); } template inline vtkm::cont::ArrayHandle ArrayRangeComputeTemplate( const vtkm::cont::ArrayHandle& input, vtkm::cont::DeviceAdapterId device) { return ArrayRangeComputeTemplate(input, false, device); } /// @} /// @{ /// \brief Templated version of ArrayRangeComputeMagnitude /// \sa ArrayRangeComputeMagnitude /// template inline vtkm::Range ArrayRangeComputeMagnitudeTemplate( const vtkm::cont::ArrayHandle& input, bool computeFiniteRange = false, vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{}) { return ArrayRangeComputeMagnitudeTemplate( input, vtkm::cont::ArrayHandle{}, computeFiniteRange, device); } template vtkm::Range ArrayRangeComputeMagnitudeTemplate( const vtkm::cont::ArrayHandle& input, const vtkm::cont::ArrayHandle& maskArray, bool computeFiniteRange = false, vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{}) { VTKM_ASSERT(maskArray.GetNumberOfValues() == 0 || maskArray.GetNumberOfValues() == input.GetNumberOfValues()); return internal::ArrayRangeComputeMagnitudeImpl{}( input, maskArray, computeFiniteRange, device); } template inline vtkm::Range ArrayRangeComputeMagnitudeTemplate(const vtkm::cont::ArrayHandle& input, vtkm::cont::DeviceAdapterId device) { return ArrayRangeComputeMagnitudeTemplate(input, false, device); } /// @} //----------------------------------------------------------------------------- template VTKM_DEPRECATED(2.1, "Use precompiled ArrayRangeCompute or ArrayRangeComputeTemplate.") inline vtkm::cont::ArrayHandle ArrayRangeCompute( const ArrayHandleType& input, vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{}) { return ArrayRangeComputeTemplate(input, false, device); } } } // namespace vtkm::cont #define VTK_M_ARRAY_RANGE_COMPUTE_DCLR(...) \ vtkm::cont::ArrayHandle vtkm::cont::ArrayRangeComputeTemplate( \ const vtkm::cont::ArrayHandle<__VA_ARGS__>&, \ const vtkm::cont::ArrayHandle&, \ bool, \ vtkm::cont::DeviceAdapterId) #define VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(...) \ vtkm::Range vtkm::cont::ArrayRangeComputeMagnitudeTemplate( \ const vtkm::cont::ArrayHandle<__VA_ARGS__>&, \ const vtkm::cont::ArrayHandle&, \ bool, \ vtkm::cont::DeviceAdapterId) #define VTK_M_ARRAY_RANGE_COMPUTE_INT_SCALARS(modifiers, ...) \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Int8, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Int8, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::UInt8, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::UInt8, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Int16, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Int16, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::UInt16, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::UInt16, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Int32, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Int32, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::UInt32, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::UInt32, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Int64, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Int64, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::UInt64, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::UInt64, __VA_ARGS__) #define VTK_M_ARRAY_RANGE_COMPUTE_FLOAT_SCALARS(modifiers, ...) \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Float32, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Float32, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Float64, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Float64, __VA_ARGS__) #define VTK_M_ARRAY_RANGE_COMPUTE_BOOL_SCALARS(modifiers, ...) \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(bool, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(bool, __VA_ARGS__) #define VTK_M_ARRAY_RANGE_COMPUTE_OTHER_SCALARS(modifiers, ...) \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(char, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(char, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(signed VTKM_UNUSED_INT_TYPE, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(signed VTKM_UNUSED_INT_TYPE, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(unsigned VTKM_UNUSED_INT_TYPE, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(unsigned VTKM_UNUSED_INT_TYPE, __VA_ARGS__) #define VTK_M_ARRAY_RANGE_COMPUTE_ALL_SCALARS(modifiers, ...) \ VTK_M_ARRAY_RANGE_COMPUTE_INT_SCALARS(modifiers, __VA_ARGS__); \ VTK_M_ARRAY_RANGE_COMPUTE_FLOAT_SCALARS(modifiers, __VA_ARGS__); \ VTK_M_ARRAY_RANGE_COMPUTE_BOOL_SCALARS(modifiers, __VA_ARGS__); \ VTK_M_ARRAY_RANGE_COMPUTE_OTHER_SCALARS(modifiers, __VA_ARGS__) #define VTK_M_ARRAY_RANGE_COMPUTE_INT_VECN(modifiers, N, ...) \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec, __VA_ARGS__) #define VTK_M_ARRAY_RANGE_COMPUTE_FLOAT_VECN(modifiers, N, ...) \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec, __VA_ARGS__) #define VTK_M_ARRAY_RANGE_COMPUTE_BOOL_VECN(modifiers, N, ...) \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec, __VA_ARGS__) #define VTK_M_ARRAY_RANGE_COMPUTE_OTHER_VECN(modifiers, N, ...) \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec, __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec, \ __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec, \ __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec, \ __VA_ARGS__); \ modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec, \ __VA_ARGS__) #define VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(modifiers, N, ...) \ VTK_M_ARRAY_RANGE_COMPUTE_INT_VECN(modifiers, N, __VA_ARGS__); \ VTK_M_ARRAY_RANGE_COMPUTE_FLOAT_VECN(modifiers, N, __VA_ARGS__); \ VTK_M_ARRAY_RANGE_COMPUTE_BOOL_VECN(modifiers, N, __VA_ARGS__); \ VTK_M_ARRAY_RANGE_COMPUTE_OTHER_VECN(modifiers, N, __VA_ARGS__) namespace vtkm { namespace cont { struct StorageTagSOA; template struct StorageTagCartesianProduct; struct StorageTagConstant; struct StorageTagCounting; struct StorageTagXGCCoordinates; struct StorageTagStride; } } // vtkm::cont //------------------------------------------------------------------------------------------------- /// @cond NOPE VTKM_INSTANTIATION_BEGIN VTK_M_ARRAY_RANGE_COMPUTE_ALL_SCALARS(extern template VTKM_CONT_TEMPLATE_EXPORT, vtkm::cont::StorageTagBasic); VTKM_INSTANTIATION_END VTKM_INSTANTIATION_BEGIN VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT, 2, vtkm::cont::StorageTagBasic); VTKM_INSTANTIATION_END VTKM_INSTANTIATION_BEGIN VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT, 3, vtkm::cont::StorageTagBasic); VTKM_INSTANTIATION_END VTKM_INSTANTIATION_BEGIN VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT, 4, vtkm::cont::StorageTagBasic); VTKM_INSTANTIATION_END //------------------------------------------------------------------------------------------------- VTKM_INSTANTIATION_BEGIN VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT, 2, vtkm::cont::StorageTagSOA); VTKM_INSTANTIATION_END VTKM_INSTANTIATION_BEGIN VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT, 3, vtkm::cont::StorageTagSOA); VTKM_INSTANTIATION_END VTKM_INSTANTIATION_BEGIN VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT, 4, vtkm::cont::StorageTagSOA); VTKM_INSTANTIATION_END //------------------------------------------------------------------------------------------------- VTKM_INSTANTIATION_BEGIN VTK_M_ARRAY_RANGE_COMPUTE_FLOAT_VECN( extern template VTKM_CONT_TEMPLATE_EXPORT, 3, vtkm::cont::StorageTagCartesianProduct); VTKM_INSTANTIATION_END //------------------------------------------------------------------------------------------------- VTKM_INSTANTIATION_BEGIN VTK_M_ARRAY_RANGE_COMPUTE_FLOAT_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT, 3, StorageTagXGCCoordinates); VTKM_INSTANTIATION_END //------------------------------------------------------------------------------------------------- VTKM_INSTANTIATION_BEGIN VTK_M_ARRAY_RANGE_COMPUTE_ALL_SCALARS(extern template VTKM_CONT_TEMPLATE_EXPORT, vtkm::cont::StorageTagConstant); VTKM_INSTANTIATION_END VTKM_INSTANTIATION_BEGIN VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT, 2, vtkm::cont::StorageTagConstant); VTKM_INSTANTIATION_END VTKM_INSTANTIATION_BEGIN VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT, 3, vtkm::cont::StorageTagConstant); VTKM_INSTANTIATION_END VTKM_INSTANTIATION_BEGIN VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT, 4, vtkm::cont::StorageTagConstant); VTKM_INSTANTIATION_END //------------------------------------------------------------------------------------------------- VTKM_INSTANTIATION_BEGIN VTK_M_ARRAY_RANGE_COMPUTE_INT_SCALARS(extern template VTKM_CONT_TEMPLATE_EXPORT, vtkm::cont::StorageTagCounting); VTK_M_ARRAY_RANGE_COMPUTE_FLOAT_SCALARS(extern template VTKM_CONT_TEMPLATE_EXPORT, vtkm::cont::StorageTagCounting); VTK_M_ARRAY_RANGE_COMPUTE_OTHER_SCALARS(extern template VTKM_CONT_TEMPLATE_EXPORT, vtkm::cont::StorageTagCounting); VTKM_INSTANTIATION_END VTKM_INSTANTIATION_BEGIN VTK_M_ARRAY_RANGE_COMPUTE_INT_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT, 2, vtkm::cont::StorageTagCounting); VTK_M_ARRAY_RANGE_COMPUTE_FLOAT_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT, 2, vtkm::cont::StorageTagCounting); VTK_M_ARRAY_RANGE_COMPUTE_OTHER_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT, 2, vtkm::cont::StorageTagCounting); VTKM_INSTANTIATION_END VTKM_INSTANTIATION_BEGIN VTK_M_ARRAY_RANGE_COMPUTE_INT_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT, 3, vtkm::cont::StorageTagCounting); VTK_M_ARRAY_RANGE_COMPUTE_FLOAT_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT, 3, vtkm::cont::StorageTagCounting); VTK_M_ARRAY_RANGE_COMPUTE_OTHER_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT, 3, vtkm::cont::StorageTagCounting); VTKM_INSTANTIATION_END VTKM_INSTANTIATION_BEGIN VTK_M_ARRAY_RANGE_COMPUTE_INT_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT, 4, vtkm::cont::StorageTagCounting); VTK_M_ARRAY_RANGE_COMPUTE_FLOAT_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT, 4, vtkm::cont::StorageTagCounting); VTK_M_ARRAY_RANGE_COMPUTE_OTHER_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT, 4, vtkm::cont::StorageTagCounting); VTKM_INSTANTIATION_END //------------------------------------------------------------------------------------------------- VTKM_INSTANTIATION_BEGIN VTK_M_ARRAY_RANGE_COMPUTE_ALL_SCALARS(extern template VTKM_CONT_TEMPLATE_EXPORT, vtkm::cont::StorageTagStride); VTKM_INSTANTIATION_END /// @endcond #endif //vtk_m_cont_ArrayRangeComputeTemplate_h