58fc99c2f8
The precompiled `ArrayRangeCompute` function was not following proper fast paths for special arrays. For example, when computing the range of an `ArrayHandleUniformPointCoordinates`, the ranges should be taken from the origin and spacing of the special array. However, the precompiled version was calling the generic range computation, which was doing an unnecessary reduction over the entire array. These fast paths have been fixed. These mistakes in the code were caused by quirks in how templated method overloading works. To prevent this mistake from happening again in the precompiled `ArrayRangeCompute` function and elsewhere, all templated forms of `ArrayRangeCompute` have been deprecated. Most will call `ArrayRangeCompute` with no issues. For those that need the templated version, `ArrayRangeComputeTemplate` replaces the old templated `ArrayRangeCompute`. There is exactly one templated declaration of `ArrayRangeComputeTemplate` that uses a class, `ArrayRangeComputeImpl`, with partial specialization to ensure the correct form is used.
194 lines
5.2 KiB
C++
194 lines
5.2 KiB
C++
//============================================================================
|
|
// 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_ArrayHandleConstant_h
|
|
#define vtk_m_cont_ArrayHandleConstant_h
|
|
|
|
#include <vtkm/cont/ArrayHandleImplicit.h>
|
|
|
|
#include <vtkm/Range.h>
|
|
#include <vtkm/VecFlat.h>
|
|
|
|
namespace vtkm
|
|
{
|
|
namespace cont
|
|
{
|
|
|
|
struct VTKM_ALWAYS_EXPORT StorageTagConstant
|
|
{
|
|
};
|
|
|
|
namespace internal
|
|
{
|
|
|
|
template <typename ValueType>
|
|
struct VTKM_ALWAYS_EXPORT ConstantFunctor
|
|
{
|
|
VTKM_EXEC_CONT
|
|
ConstantFunctor(const ValueType& value = ValueType())
|
|
: Value(value)
|
|
{
|
|
}
|
|
|
|
VTKM_EXEC_CONT
|
|
ValueType operator()(vtkm::Id vtkmNotUsed(index)) const { return this->Value; }
|
|
|
|
private:
|
|
ValueType Value;
|
|
};
|
|
|
|
template <typename T>
|
|
using StorageTagConstantSuperclass =
|
|
typename vtkm::cont::ArrayHandleImplicit<ConstantFunctor<T>>::StorageTag;
|
|
|
|
template <typename T>
|
|
struct Storage<T, vtkm::cont::StorageTagConstant> : Storage<T, StorageTagConstantSuperclass<T>>
|
|
{
|
|
};
|
|
|
|
} // namespace internal
|
|
|
|
/// \brief An array handle with a constant value.
|
|
///
|
|
/// ArrayHandleConstant is an implicit array handle with a constant value. A
|
|
/// constant array handle is constructed by giving a value and an array length.
|
|
/// The resulting array is of the given size with each entry the same value
|
|
/// given in the constructor. The array is defined implicitly, so there it
|
|
/// takes (almost) no memory.
|
|
///
|
|
template <typename T>
|
|
class ArrayHandleConstant : public vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagConstant>
|
|
{
|
|
public:
|
|
VTKM_ARRAY_HANDLE_SUBCLASS(ArrayHandleConstant,
|
|
(ArrayHandleConstant<T>),
|
|
(vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagConstant>));
|
|
|
|
VTKM_CONT
|
|
ArrayHandleConstant(T value, vtkm::Id numberOfValues = 0)
|
|
: Superclass(internal::FunctorToArrayHandleImplicitBuffers(internal::ConstantFunctor<T>(value),
|
|
numberOfValues))
|
|
{
|
|
}
|
|
|
|
/// \brief Returns the constant value stored in this array.
|
|
///
|
|
/// The value set in the constructor of this array is returned even if the number of values is 0.
|
|
///
|
|
VTKM_CONT T GetValue() const { return this->ReadPortal().GetFunctor()(0); }
|
|
};
|
|
|
|
/// make_ArrayHandleConstant is convenience function to generate an
|
|
/// ArrayHandleImplicit. It takes a functor and the virtual length of the
|
|
/// array.
|
|
///
|
|
template <typename T>
|
|
vtkm::cont::ArrayHandleConstant<T> make_ArrayHandleConstant(T value, vtkm::Id numberOfValues)
|
|
{
|
|
return vtkm::cont::ArrayHandleConstant<T>(value, numberOfValues);
|
|
}
|
|
|
|
namespace internal
|
|
{
|
|
|
|
template <typename S>
|
|
struct ArrayRangeComputeImpl;
|
|
|
|
template <>
|
|
struct VTKM_CONT_EXPORT ArrayRangeComputeImpl<vtkm::cont::StorageTagConstant>
|
|
{
|
|
template <typename T>
|
|
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> operator()(
|
|
const vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagConstant>& input,
|
|
vtkm::cont::DeviceAdapterId) const
|
|
{
|
|
auto value = vtkm::make_VecFlat(input.ReadPortal().Get(0));
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Range> result;
|
|
result.Allocate(value.GetNumberOfComponents());
|
|
auto resultPortal = result.WritePortal();
|
|
for (vtkm::IdComponent index = 0; index < value.GetNumberOfComponents(); ++index)
|
|
{
|
|
resultPortal.Set(index, vtkm::Range{ value[index], value[index] });
|
|
}
|
|
return result;
|
|
}
|
|
};
|
|
|
|
} // namespace internal
|
|
|
|
}
|
|
} // vtkm::cont
|
|
|
|
//=============================================================================
|
|
// Specializations of serialization related classes
|
|
/// @cond SERIALIZATION
|
|
namespace vtkm
|
|
{
|
|
namespace cont
|
|
{
|
|
|
|
template <typename T>
|
|
struct SerializableTypeString<vtkm::cont::ArrayHandleConstant<T>>
|
|
{
|
|
static VTKM_CONT const std::string& Get()
|
|
{
|
|
static std::string name = "AH_Constant<" + SerializableTypeString<T>::Get() + ">";
|
|
return name;
|
|
}
|
|
};
|
|
|
|
template <typename T>
|
|
struct SerializableTypeString<vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagConstant>>
|
|
: SerializableTypeString<vtkm::cont::ArrayHandleConstant<T>>
|
|
{
|
|
};
|
|
}
|
|
} // vtkm::cont
|
|
|
|
namespace mangled_diy_namespace
|
|
{
|
|
|
|
template <typename T>
|
|
struct Serialization<vtkm::cont::ArrayHandleConstant<T>>
|
|
{
|
|
private:
|
|
using Type = vtkm::cont::ArrayHandleConstant<T>;
|
|
using BaseType = vtkm::cont::ArrayHandle<typename Type::ValueType, typename Type::StorageTag>;
|
|
|
|
public:
|
|
static VTKM_CONT void save(BinaryBuffer& bb, const BaseType& obj)
|
|
{
|
|
vtkmdiy::save(bb, obj.GetNumberOfValues());
|
|
vtkmdiy::save(bb, obj.ReadPortal().Get(0));
|
|
}
|
|
|
|
static VTKM_CONT void load(BinaryBuffer& bb, BaseType& obj)
|
|
{
|
|
vtkm::Id count = 0;
|
|
vtkmdiy::load(bb, count);
|
|
|
|
T value;
|
|
vtkmdiy::load(bb, value);
|
|
|
|
obj = vtkm::cont::make_ArrayHandleConstant(value, count);
|
|
}
|
|
};
|
|
|
|
template <typename T>
|
|
struct Serialization<vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagConstant>>
|
|
: Serialization<vtkm::cont::ArrayHandleConstant<T>>
|
|
{
|
|
};
|
|
|
|
} // diy
|
|
/// @endcond SERIALIZATION
|
|
|
|
#endif //vtk_m_cont_ArrayHandleConstant_h
|