mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-08 13:23:51 +00:00
Merge topic 'advanced-compute-range'
01bacbcde Advanced Compute Range Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: Kenneth Moreland <morelandkd@ornl.gov> Merge-request: !3082
This commit is contained in:
commit
90f09e8bcc
21
docs/changelog/advanced-compute-range.md
Normal file
21
docs/changelog/advanced-compute-range.md
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# New features for computing array ranges
|
||||||
|
|
||||||
|
ArrayRangeCompute has been update to support more features that are present
|
||||||
|
in VTK and ParaView.
|
||||||
|
|
||||||
|
New overloads for `ArrayRangeCompute` have been added:
|
||||||
|
1. Takes a boolean parameter, `computeFiniteRange`, that specifies
|
||||||
|
whether to compute only the finite range by ignoring any non-finite values (+/-inf)
|
||||||
|
in the array.
|
||||||
|
|
||||||
|
2. Takes a `maskArray` parameter of type `vtkm::cont::ArrayHandle<vtkm::UInt8>`.
|
||||||
|
The mask array must contain the same number of elements as the input array.
|
||||||
|
A value in the input array is treated as masked off if the
|
||||||
|
corresponding value in the mask array is non-zero. Masked off values are ignored
|
||||||
|
in the range computation.
|
||||||
|
|
||||||
|
A new function `ArrayRangeComputeMagnitude` has been added. If the input array
|
||||||
|
has multiple components, this function computes the range of the magnitude of
|
||||||
|
the values of the array. Nested Vecs are treated as flat. A single `Range` object
|
||||||
|
is returned containing the result. `ArrayRangeComputMagnitude` also has similar
|
||||||
|
overloads as `ArrayRangeCompute`.
|
@ -484,6 +484,13 @@ struct ArrayExtractComponentImpl<vtkm::cont::StorageTagCartesianProduct<STs...>>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T, typename S>
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeComputeGeneric(
|
||||||
|
const vtkm::cont::ArrayHandle<T, S>& input,
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||||
|
bool computeFiniteRange,
|
||||||
|
vtkm::cont::DeviceAdapterId device);
|
||||||
|
|
||||||
template <typename S>
|
template <typename S>
|
||||||
struct ArrayRangeComputeImpl;
|
struct ArrayRangeComputeImpl;
|
||||||
|
|
||||||
@ -494,63 +501,43 @@ struct VTKM_CONT_EXPORT ArrayRangeComputeImpl<vtkm::cont::StorageTagCartesianPro
|
|||||||
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> operator()(
|
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> operator()(
|
||||||
const vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>,
|
const vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>,
|
||||||
vtkm::cont::StorageTagCartesianProduct<ST1, ST2, ST3>>& input_,
|
vtkm::cont::StorageTagCartesianProduct<ST1, ST2, ST3>>& input_,
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||||
|
bool computeFiniteRange,
|
||||||
vtkm::cont::DeviceAdapterId device) const
|
vtkm::cont::DeviceAdapterId device) const
|
||||||
{
|
{
|
||||||
|
if (maskArray.GetNumberOfValues() != 0)
|
||||||
|
{
|
||||||
|
return vtkm::cont::internal::ArrayRangeComputeGeneric(
|
||||||
|
input_, maskArray, computeFiniteRange, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& input =
|
||||||
|
static_cast<const vtkm::cont::ArrayHandleCartesianProduct<vtkm::cont::ArrayHandle<T, ST1>,
|
||||||
|
vtkm::cont::ArrayHandle<T, ST2>,
|
||||||
|
vtkm::cont::ArrayHandle<T, ST3>>&>(
|
||||||
|
input_);
|
||||||
|
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Range> ranges[3];
|
||||||
|
ranges[0] = vtkm::cont::internal::ArrayRangeComputeImpl<ST1>{}(
|
||||||
|
input.GetFirstArray(), maskArray, computeFiniteRange, device);
|
||||||
|
ranges[1] = vtkm::cont::internal::ArrayRangeComputeImpl<ST2>{}(
|
||||||
|
input.GetSecondArray(), maskArray, computeFiniteRange, device);
|
||||||
|
ranges[2] = vtkm::cont::internal::ArrayRangeComputeImpl<ST3>{}(
|
||||||
|
input.GetThirdArray(), maskArray, computeFiniteRange, device);
|
||||||
|
|
||||||
|
auto numComponents =
|
||||||
|
ranges[0].GetNumberOfValues() + ranges[1].GetNumberOfValues() + ranges[2].GetNumberOfValues();
|
||||||
vtkm::cont::ArrayHandle<vtkm::Range> result;
|
vtkm::cont::ArrayHandle<vtkm::Range> result;
|
||||||
result.Allocate(3);
|
result.Allocate(numComponents);
|
||||||
auto resultPortal = result.WritePortal();
|
auto resultPortal = result.WritePortal();
|
||||||
|
for (vtkm::Id i = 0, index = 0; i < 3; ++i)
|
||||||
const vtkm::cont::ArrayHandleCartesianProduct<vtkm::cont::ArrayHandle<T, ST1>,
|
|
||||||
vtkm::cont::ArrayHandle<T, ST2>,
|
|
||||||
vtkm::cont::ArrayHandle<T, ST3>>& input = input_;
|
|
||||||
vtkm::cont::ArrayHandle<vtkm::Range> componentRangeArray;
|
|
||||||
|
|
||||||
vtkm::IdComponent index = 0;
|
|
||||||
vtkm::cont::ArrayHandle<T, ST1> firstArray = input.GetFirstArray();
|
|
||||||
componentRangeArray = vtkm::cont::internal::ArrayRangeComputeImpl<ST1>{}(firstArray, device);
|
|
||||||
vtkm::Id numSubComponents = componentRangeArray.GetNumberOfValues();
|
|
||||||
if (numSubComponents > 1)
|
|
||||||
{
|
{
|
||||||
result.Allocate(result.GetNumberOfValues() + numSubComponents - 1, vtkm::CopyFlag::On);
|
auto rangePortal = ranges[i].ReadPortal();
|
||||||
resultPortal = result.WritePortal();
|
for (vtkm::Id j = 0; j < rangePortal.GetNumberOfValues(); ++j, ++index)
|
||||||
|
{
|
||||||
|
resultPortal.Set(index, rangePortal.Get(j));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
auto componentRangePortal = componentRangeArray.ReadPortal();
|
|
||||||
for (vtkm::IdComponent subComponent = 0; subComponent < numSubComponents; ++subComponent)
|
|
||||||
{
|
|
||||||
resultPortal.Set(index, componentRangePortal.Get(subComponent));
|
|
||||||
++index;
|
|
||||||
}
|
|
||||||
|
|
||||||
vtkm::cont::ArrayHandle<T, ST2> secondArray = input.GetSecondArray();
|
|
||||||
componentRangeArray = vtkm::cont::internal::ArrayRangeComputeImpl<ST2>{}(secondArray, device);
|
|
||||||
numSubComponents = componentRangeArray.GetNumberOfValues();
|
|
||||||
if (numSubComponents > 1)
|
|
||||||
{
|
|
||||||
result.Allocate(result.GetNumberOfValues() + numSubComponents - 1, vtkm::CopyFlag::On);
|
|
||||||
resultPortal = result.WritePortal();
|
|
||||||
}
|
|
||||||
componentRangePortal = componentRangeArray.ReadPortal();
|
|
||||||
for (vtkm::IdComponent subComponent = 0; subComponent < numSubComponents; ++subComponent)
|
|
||||||
{
|
|
||||||
resultPortal.Set(index, componentRangePortal.Get(subComponent));
|
|
||||||
++index;
|
|
||||||
}
|
|
||||||
|
|
||||||
vtkm::cont::ArrayHandle<T, ST3> thirdArray = input.GetThirdArray();
|
|
||||||
componentRangeArray = vtkm::cont::internal::ArrayRangeComputeImpl<ST3>{}(thirdArray, device);
|
|
||||||
numSubComponents = componentRangeArray.GetNumberOfValues();
|
|
||||||
if (numSubComponents > 1)
|
|
||||||
{
|
|
||||||
result.Allocate(result.GetNumberOfValues() + numSubComponents - 1, vtkm::CopyFlag::On);
|
|
||||||
resultPortal = result.WritePortal();
|
|
||||||
}
|
|
||||||
componentRangePortal = componentRangeArray.ReadPortal();
|
|
||||||
for (vtkm::IdComponent subComponent = 0; subComponent < numSubComponents; ++subComponent)
|
|
||||||
{
|
|
||||||
resultPortal.Set(index, componentRangePortal.Get(subComponent));
|
|
||||||
++index;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -12,8 +12,11 @@
|
|||||||
|
|
||||||
#include <vtkm/cont/ArrayHandleImplicit.h>
|
#include <vtkm/cont/ArrayHandleImplicit.h>
|
||||||
|
|
||||||
|
#include <vtkm/cont/internal/ArrayRangeComputeUtils.h>
|
||||||
|
|
||||||
#include <vtkm/Range.h>
|
#include <vtkm/Range.h>
|
||||||
#include <vtkm/VecFlat.h>
|
#include <vtkm/VecFlat.h>
|
||||||
|
#include <vtkm/VectorAnalysis.h>
|
||||||
|
|
||||||
namespace vtkm
|
namespace vtkm
|
||||||
{
|
{
|
||||||
@ -106,8 +109,18 @@ struct VTKM_CONT_EXPORT ArrayRangeComputeImpl<vtkm::cont::StorageTagConstant>
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> operator()(
|
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> operator()(
|
||||||
const vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagConstant>& input,
|
const vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagConstant>& input,
|
||||||
vtkm::cont::DeviceAdapterId) const
|
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||||
|
bool computeFiniteRange,
|
||||||
|
vtkm::cont::DeviceAdapterId devId) const
|
||||||
{
|
{
|
||||||
|
bool allMasked = false;
|
||||||
|
if (maskArray.GetNumberOfValues() != 0)
|
||||||
|
{
|
||||||
|
// Find if there is atleast one value that is not masked
|
||||||
|
auto ids = GetFirstAndLastUnmaskedIndices(maskArray, devId);
|
||||||
|
allMasked = (ids[1] < ids[0]);
|
||||||
|
}
|
||||||
|
|
||||||
auto value = vtkm::make_VecFlat(input.ReadPortal().Get(0));
|
auto value = vtkm::make_VecFlat(input.ReadPortal().Get(0));
|
||||||
|
|
||||||
vtkm::cont::ArrayHandle<vtkm::Range> result;
|
vtkm::cont::ArrayHandle<vtkm::Range> result;
|
||||||
@ -115,12 +128,51 @@ struct VTKM_CONT_EXPORT ArrayRangeComputeImpl<vtkm::cont::StorageTagConstant>
|
|||||||
auto resultPortal = result.WritePortal();
|
auto resultPortal = result.WritePortal();
|
||||||
for (vtkm::IdComponent index = 0; index < value.GetNumberOfComponents(); ++index)
|
for (vtkm::IdComponent index = 0; index < value.GetNumberOfComponents(); ++index)
|
||||||
{
|
{
|
||||||
resultPortal.Set(index, vtkm::Range{ value[index], value[index] });
|
auto comp = static_cast<vtkm::Float64>(value[index]);
|
||||||
|
if (allMasked || (computeFiniteRange && !vtkm::IsFinite(comp)))
|
||||||
|
{
|
||||||
|
resultPortal.Set(index, vtkm::Range{});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resultPortal.Set(index, vtkm::Range{ comp, comp });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename S>
|
||||||
|
struct ArrayRangeComputeMagnitudeImpl;
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct VTKM_CONT_EXPORT ArrayRangeComputeMagnitudeImpl<vtkm::cont::StorageTagConstant>
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
VTKM_CONT vtkm::Range operator()(
|
||||||
|
const vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagConstant>& input,
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||||
|
bool computeFiniteRange,
|
||||||
|
vtkm::cont::DeviceAdapterId devId) const
|
||||||
|
{
|
||||||
|
if (maskArray.GetNumberOfValues() != 0)
|
||||||
|
{
|
||||||
|
// Find if there is atleast one value that is not masked
|
||||||
|
auto ids = GetFirstAndLastUnmaskedIndices(maskArray, devId);
|
||||||
|
if (ids[1] < ids[0])
|
||||||
|
{
|
||||||
|
return vtkm::Range{};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto value = input.ReadPortal().Get(0);
|
||||||
|
vtkm::Float64 rangeValue = vtkm::Magnitude(vtkm::make_VecFlat(value));
|
||||||
|
return (computeFiniteRange && !vtkm::IsFinite(rangeValue))
|
||||||
|
? vtkm::Range{}
|
||||||
|
: vtkm::Range{ rangeValue, rangeValue };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,8 +12,11 @@
|
|||||||
|
|
||||||
#include <vtkm/cont/ArrayHandleImplicit.h>
|
#include <vtkm/cont/ArrayHandleImplicit.h>
|
||||||
|
|
||||||
|
#include <vtkm/cont/internal/ArrayRangeComputeUtils.h>
|
||||||
|
|
||||||
#include <vtkm/Range.h>
|
#include <vtkm/Range.h>
|
||||||
#include <vtkm/TypeTraits.h>
|
#include <vtkm/TypeTraits.h>
|
||||||
|
#include <vtkm/VecFlat.h>
|
||||||
#include <vtkm/VecTraits.h>
|
#include <vtkm/VecTraits.h>
|
||||||
|
|
||||||
namespace vtkm
|
namespace vtkm
|
||||||
@ -156,33 +159,45 @@ struct VTKM_CONT_EXPORT ArrayRangeComputeImpl<vtkm::cont::StorageTagCounting>
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> operator()(
|
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> operator()(
|
||||||
const vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagCounting>& input,
|
const vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagCounting>& input,
|
||||||
vtkm::cont::DeviceAdapterId) const
|
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||||
|
bool vtkmNotUsed(computeFiniteRange), // assume array produces only finite values
|
||||||
|
vtkm::cont::DeviceAdapterId device) const
|
||||||
{
|
{
|
||||||
using Traits = vtkm::VecTraits<T>;
|
using Traits = vtkm::VecTraits<vtkm::VecFlat<T>>;
|
||||||
vtkm::cont::ArrayHandle<vtkm::Range> result;
|
vtkm::cont::ArrayHandle<vtkm::Range> result;
|
||||||
result.Allocate(Traits::NUM_COMPONENTS);
|
result.Allocate(Traits::NUM_COMPONENTS);
|
||||||
|
|
||||||
|
if (input.GetNumberOfValues() <= 0)
|
||||||
|
{
|
||||||
|
result.Fill(vtkm::Range{});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
vtkm::Id2 firstAndLast{ 0, input.GetNumberOfValues() - 1 };
|
||||||
|
if (maskArray.GetNumberOfValues() > 0)
|
||||||
|
{
|
||||||
|
firstAndLast = GetFirstAndLastUnmaskedIndices(maskArray, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (firstAndLast[1] < firstAndLast[0])
|
||||||
|
{
|
||||||
|
result.Fill(vtkm::Range{});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
auto portal = result.WritePortal();
|
auto portal = result.WritePortal();
|
||||||
if (portal.GetNumberOfValues() > 0)
|
// assume the values to be finite
|
||||||
|
auto first = make_VecFlat(input.ReadPortal().Get(firstAndLast[0]));
|
||||||
|
auto last = make_VecFlat(input.ReadPortal().Get(firstAndLast[1]));
|
||||||
|
for (vtkm::IdComponent cIndex = 0; cIndex < Traits::NUM_COMPONENTS; ++cIndex)
|
||||||
{
|
{
|
||||||
T first = input.ReadPortal().Get(0);
|
auto firstComponent = Traits::GetComponent(first, cIndex);
|
||||||
T last = input.ReadPortal().Get(input.GetNumberOfValues() - 1);
|
auto lastComponent = Traits::GetComponent(last, cIndex);
|
||||||
for (vtkm::IdComponent cIndex = 0; cIndex < Traits::NUM_COMPONENTS; ++cIndex)
|
portal.Set(cIndex,
|
||||||
{
|
vtkm::Range(vtkm::Min(firstComponent, lastComponent),
|
||||||
auto firstComponent = Traits::GetComponent(first, cIndex);
|
vtkm::Max(firstComponent, lastComponent)));
|
||||||
auto lastComponent = Traits::GetComponent(last, cIndex);
|
|
||||||
portal.Set(cIndex,
|
|
||||||
vtkm::Range(vtkm::Min(firstComponent, lastComponent),
|
|
||||||
vtkm::Max(firstComponent, lastComponent)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Array is empty
|
|
||||||
for (vtkm::IdComponent cIndex = 0; cIndex < Traits::NUM_COMPONENTS; ++cIndex)
|
|
||||||
{
|
|
||||||
portal.Set(cIndex, vtkm::Range{});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
#include <vtkmstd/integer_sequence.h>
|
#include <vtkmstd/integer_sequence.h>
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
51
vtkm/cont/ArrayHandleIndex.cxx
Normal file
51
vtkm/cont/ArrayHandleIndex.cxx
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
//============================================================================
|
||||||
|
// 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 <vtkm/cont/ArrayHandleIndex.h>
|
||||||
|
#include <vtkm/cont/internal/ArrayRangeComputeUtils.h>
|
||||||
|
|
||||||
|
namespace vtkm
|
||||||
|
{
|
||||||
|
namespace cont
|
||||||
|
{
|
||||||
|
namespace internal
|
||||||
|
{
|
||||||
|
|
||||||
|
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range>
|
||||||
|
ArrayRangeComputeImpl<vtkm::cont::StorageTagIndex>::operator()(
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::Id, vtkm::cont::StorageTagIndex>& input,
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||||
|
bool vtkmNotUsed(computeFiniteRange), // assume array produces only finite values
|
||||||
|
vtkm::cont::DeviceAdapterId device) const
|
||||||
|
{
|
||||||
|
vtkm::Range range{};
|
||||||
|
|
||||||
|
if (input.GetNumberOfValues() > 0)
|
||||||
|
{
|
||||||
|
vtkm::Id2 firstAndLast{ 0, input.GetNumberOfValues() - 1 };
|
||||||
|
if (maskArray.GetNumberOfValues() > 0)
|
||||||
|
{
|
||||||
|
firstAndLast = vtkm::cont::internal::GetFirstAndLastUnmaskedIndices(maskArray, device);
|
||||||
|
}
|
||||||
|
if (firstAndLast[0] < firstAndLast[1])
|
||||||
|
{
|
||||||
|
range = vtkm::Range(firstAndLast[0], firstAndLast[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Range> result;
|
||||||
|
result.Allocate(1);
|
||||||
|
result.WritePortal().Set(0, range);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // vtkm::cont::internal
|
@ -84,12 +84,26 @@ struct VTKM_CONT_EXPORT ArrayRangeComputeImpl<vtkm::cont::StorageTagIndex>
|
|||||||
{
|
{
|
||||||
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> operator()(
|
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> operator()(
|
||||||
const vtkm::cont::ArrayHandle<vtkm::Id, vtkm::cont::StorageTagIndex>& input,
|
const vtkm::cont::ArrayHandle<vtkm::Id, vtkm::cont::StorageTagIndex>& input,
|
||||||
vtkm::cont::DeviceAdapterId) const
|
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||||
|
bool computeFiniteRange,
|
||||||
|
vtkm::cont::DeviceAdapterId device) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename S>
|
||||||
|
struct ArrayRangeComputeMagnitudeImpl;
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct VTKM_CONT_EXPORT ArrayRangeComputeMagnitudeImpl<vtkm::cont::StorageTagIndex>
|
||||||
|
{
|
||||||
|
VTKM_CONT vtkm::Range operator()(
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::Id, vtkm::cont::StorageTagIndex>& input,
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||||
|
bool computeFiniteRange,
|
||||||
|
vtkm::cont::DeviceAdapterId device) const
|
||||||
{
|
{
|
||||||
vtkm::cont::ArrayHandle<vtkm::Range> result;
|
auto rangeAH = ArrayRangeComputeImpl<vtkm::cont::StorageTagIndex>{}(
|
||||||
result.Allocate(1);
|
input, maskArray, computeFiniteRange, device);
|
||||||
result.WritePortal().Set(0, vtkm::Range(0, input.GetNumberOfValues() - 1));
|
return rangeAH.ReadPortal().Get(0);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -13,8 +13,11 @@
|
|||||||
#include <vtkm/cont/ArrayExtractComponent.h>
|
#include <vtkm/cont/ArrayExtractComponent.h>
|
||||||
#include <vtkm/cont/ArrayHandleMultiplexer.h>
|
#include <vtkm/cont/ArrayHandleMultiplexer.h>
|
||||||
#include <vtkm/cont/ArrayHandleStride.h>
|
#include <vtkm/cont/ArrayHandleStride.h>
|
||||||
|
#include <vtkm/cont/ArrayHandleTransform.h>
|
||||||
#include <vtkm/cont/DeviceAdapterTag.h>
|
#include <vtkm/cont/DeviceAdapterTag.h>
|
||||||
|
|
||||||
|
#include <vtkm/cont/internal/ArrayRangeComputeUtils.h>
|
||||||
|
|
||||||
#include <vtkm/internal/ArrayPortalValueReference.h>
|
#include <vtkm/internal/ArrayPortalValueReference.h>
|
||||||
|
|
||||||
namespace vtkm
|
namespace vtkm
|
||||||
@ -648,6 +651,110 @@ struct ArrayExtractComponentImpl<vtkm::cont::internal::StorageTagRecombineVec>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------------------
|
||||||
|
template <typename S>
|
||||||
|
struct ArrayRangeComputeImpl;
|
||||||
|
|
||||||
|
template <typename S>
|
||||||
|
struct ArrayRangeComputeMagnitudeImpl;
|
||||||
|
|
||||||
|
template <typename T, typename S>
|
||||||
|
inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeComputeImplCaller(
|
||||||
|
const vtkm::cont::ArrayHandle<T, S>& input,
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||||
|
bool computeFiniteRange,
|
||||||
|
vtkm::cont::DeviceAdapterId device)
|
||||||
|
{
|
||||||
|
return vtkm::cont::internal::ArrayRangeComputeImpl<S>{}(
|
||||||
|
input, maskArray, computeFiniteRange, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename S>
|
||||||
|
inline vtkm::Range ArrayRangeComputeMagnitudeImplCaller(
|
||||||
|
const vtkm::cont::ArrayHandle<T, S>& input,
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||||
|
bool computeFiniteRange,
|
||||||
|
vtkm::cont::DeviceAdapterId device)
|
||||||
|
{
|
||||||
|
return vtkm::cont::internal::ArrayRangeComputeMagnitudeImpl<S>{}(
|
||||||
|
input, maskArray, computeFiniteRange, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct VTKM_CONT_EXPORT ArrayRangeComputeImpl<vtkm::cont::internal::StorageTagRecombineVec>
|
||||||
|
{
|
||||||
|
template <typename RecombineVecType>
|
||||||
|
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> operator()(
|
||||||
|
const vtkm::cont::ArrayHandle<RecombineVecType, vtkm::cont::internal::StorageTagRecombineVec>&
|
||||||
|
input_,
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||||
|
bool computeFiniteRange,
|
||||||
|
vtkm::cont::DeviceAdapterId device) const
|
||||||
|
{
|
||||||
|
auto input =
|
||||||
|
static_cast<vtkm::cont::ArrayHandleRecombineVec<typename RecombineVecType::ComponentType>>(
|
||||||
|
input_);
|
||||||
|
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Range> result;
|
||||||
|
result.Allocate(input.GetNumberOfComponents());
|
||||||
|
|
||||||
|
if (input.GetNumberOfValues() < 1)
|
||||||
|
{
|
||||||
|
result.Fill(vtkm::Range{});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto resultPortal = result.WritePortal();
|
||||||
|
for (vtkm::IdComponent i = 0; i < input.GetNumberOfComponents(); ++i)
|
||||||
|
{
|
||||||
|
auto rangeAH = ArrayRangeComputeImplCaller(
|
||||||
|
input.GetComponentArray(i), maskArray, computeFiniteRange, device);
|
||||||
|
resultPortal.Set(i, rangeAH.ReadPortal().Get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename ArrayHandleType>
|
||||||
|
struct ArrayValueIsNested;
|
||||||
|
|
||||||
|
template <typename RecombineVecType>
|
||||||
|
struct ArrayValueIsNested<
|
||||||
|
vtkm::cont::ArrayHandle<RecombineVecType, vtkm::cont::internal::StorageTagRecombineVec>>
|
||||||
|
{
|
||||||
|
static constexpr bool Value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct VTKM_CONT_EXPORT ArrayRangeComputeMagnitudeImpl<vtkm::cont::internal::StorageTagRecombineVec>
|
||||||
|
{
|
||||||
|
template <typename RecombineVecType>
|
||||||
|
VTKM_CONT vtkm::Range operator()(
|
||||||
|
const vtkm::cont::ArrayHandle<RecombineVecType, vtkm::cont::internal::StorageTagRecombineVec>&
|
||||||
|
input_,
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||||
|
bool computeFiniteRange,
|
||||||
|
vtkm::cont::DeviceAdapterId device) const
|
||||||
|
{
|
||||||
|
auto input =
|
||||||
|
static_cast<vtkm::cont::ArrayHandleRecombineVec<typename RecombineVecType::ComponentType>>(
|
||||||
|
input_);
|
||||||
|
|
||||||
|
if (input.GetNumberOfValues() < 1)
|
||||||
|
{
|
||||||
|
return vtkm::Range{};
|
||||||
|
}
|
||||||
|
if (input.GetNumberOfComponents() == 1)
|
||||||
|
{
|
||||||
|
return ArrayRangeComputeMagnitudeImplCaller(
|
||||||
|
input.GetComponentArray(0), maskArray, computeFiniteRange, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ArrayRangeComputeMagnitudeGeneric(input_, maskArray, computeFiniteRange, device);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -226,7 +226,7 @@ struct TransformFunctorManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename ValueType>
|
template <typename ValueType>
|
||||||
using TransformedValueType = decltype(std::declval<FunctorType>()(ValueType{}));
|
using TransformedValueType = decltype(std::declval<FunctorType>()(std::declval<ValueType>()));
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename ArrayHandleType,
|
template <typename ArrayHandleType,
|
||||||
|
@ -10,6 +10,10 @@
|
|||||||
|
|
||||||
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
|
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
|
||||||
|
|
||||||
|
#include <vtkm/cont/ArrayRangeComputeTemplate.h>
|
||||||
|
|
||||||
|
#include <vtkm/VectorAnalysis.h>
|
||||||
|
|
||||||
namespace vtkm
|
namespace vtkm
|
||||||
{
|
{
|
||||||
namespace cont
|
namespace cont
|
||||||
@ -89,8 +93,16 @@ ArrayExtractComponentImpl<vtkm::cont::StorageTagUniformPoints>::operator()(
|
|||||||
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range>
|
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range>
|
||||||
ArrayRangeComputeImpl<vtkm::cont::StorageTagUniformPoints>::operator()(
|
ArrayRangeComputeImpl<vtkm::cont::StorageTagUniformPoints>::operator()(
|
||||||
const vtkm::cont::ArrayHandleUniformPointCoordinates& input,
|
const vtkm::cont::ArrayHandleUniformPointCoordinates& input,
|
||||||
vtkm::cont::DeviceAdapterId vtkmNotUsed(device)) const
|
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||||
|
bool computeFiniteRange,
|
||||||
|
vtkm::cont::DeviceAdapterId device) const
|
||||||
{
|
{
|
||||||
|
if (maskArray.GetNumberOfValues() != 0)
|
||||||
|
{
|
||||||
|
return vtkm::cont::internal::ArrayRangeComputeGeneric(
|
||||||
|
input, maskArray, computeFiniteRange, device);
|
||||||
|
}
|
||||||
|
|
||||||
vtkm::internal::ArrayPortalUniformPointCoordinates portal = input.ReadPortal();
|
vtkm::internal::ArrayPortalUniformPointCoordinates portal = input.ReadPortal();
|
||||||
|
|
||||||
// In this portal we know that the min value is the first entry and the
|
// In this portal we know that the min value is the first entry and the
|
||||||
|
@ -88,6 +88,8 @@ struct VTKM_CONT_EXPORT ArrayRangeComputeImpl<vtkm::cont::StorageTagUniformPoint
|
|||||||
{
|
{
|
||||||
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> operator()(
|
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> operator()(
|
||||||
const vtkm::cont::ArrayHandleUniformPointCoordinates& input,
|
const vtkm::cont::ArrayHandleUniformPointCoordinates& input,
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||||
|
bool computeFiniteRange,
|
||||||
vtkm::cont::DeviceAdapterId device) const;
|
vtkm::cont::DeviceAdapterId device) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -8,13 +8,13 @@
|
|||||||
// PURPOSE. See the above copyright notice for more information.
|
// PURPOSE. See the above copyright notice for more information.
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
|
#include <vtkm/cont/ArrayRangeCompute.h>
|
||||||
#include <vtkm/cont/ArrayRangeComputeTemplate.h>
|
#include <vtkm/cont/ArrayRangeComputeTemplate.h>
|
||||||
|
|
||||||
#include <vtkm/TypeList.h>
|
#include <vtkm/TypeList.h>
|
||||||
|
|
||||||
#include <vtkm/cont/ArrayHandleBasic.h>
|
#include <vtkm/cont/ArrayHandleBasic.h>
|
||||||
#include <vtkm/cont/ArrayHandleCartesianProduct.h>
|
#include <vtkm/cont/ArrayHandleCartesianProduct.h>
|
||||||
#include <vtkm/cont/ArrayHandleCompositeVector.h>
|
|
||||||
#include <vtkm/cont/ArrayHandleConstant.h>
|
#include <vtkm/cont/ArrayHandleConstant.h>
|
||||||
#include <vtkm/cont/ArrayHandleCounting.h>
|
#include <vtkm/cont/ArrayHandleCounting.h>
|
||||||
#include <vtkm/cont/ArrayHandleIndex.h>
|
#include <vtkm/cont/ArrayHandleIndex.h>
|
||||||
@ -42,50 +42,39 @@ using AllVec = vtkm::ListAppend<AllVecOfSize<2>, AllVecOfSize<3>, AllVecOfSize<4
|
|||||||
|
|
||||||
using AllTypes = vtkm::ListAppend<AllScalars, AllVec>;
|
using AllTypes = vtkm::ListAppend<AllScalars, AllVec>;
|
||||||
|
|
||||||
struct ComputeRangeFunctor
|
using CartesianProductStorage = vtkm::cont::StorageTagCartesianProduct<vtkm::cont::StorageTagBasic,
|
||||||
{
|
vtkm::cont::StorageTagBasic,
|
||||||
// Used with UnknownArrayHandle::CastAndCallForTypes
|
vtkm::cont::StorageTagBasic>;
|
||||||
template <typename T, typename S>
|
|
||||||
void operator()(const vtkm::cont::ArrayHandle<T, S>& array,
|
using StorageTagsList = vtkm::List<vtkm::cont::StorageTagBasic,
|
||||||
vtkm::cont::DeviceAdapterId device,
|
vtkm::cont::StorageTagSOA,
|
||||||
vtkm::cont::ArrayHandle<vtkm::Range>& ranges) const
|
vtkm::cont::StorageTagXGCCoordinates,
|
||||||
{
|
vtkm::cont::StorageTagUniformPoints,
|
||||||
ranges = vtkm::cont::ArrayRangeComputeTemplate(array, device);
|
CartesianProductStorage,
|
||||||
|
vtkm::cont::StorageTagConstant,
|
||||||
|
vtkm::cont::StorageTagCounting,
|
||||||
|
vtkm::cont::StorageTagIndex>;
|
||||||
|
|
||||||
|
template <typename StorageTag>
|
||||||
|
struct StorageTagToValueTypesMap;
|
||||||
|
|
||||||
|
#define MAP_STORAGE_TAG_VALUE_TYPES(StorageTag, ValueTypesList) \
|
||||||
|
template <> \
|
||||||
|
struct StorageTagToValueTypesMap<StorageTag> \
|
||||||
|
{ \
|
||||||
|
using TypeList = ValueTypesList; \
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used with vtkm::ListForEach to get components
|
MAP_STORAGE_TAG_VALUE_TYPES(vtkm::cont::StorageTagBasic, AllTypes);
|
||||||
template <typename T>
|
MAP_STORAGE_TAG_VALUE_TYPES(vtkm::cont::StorageTagSOA, AllVec);
|
||||||
void operator()(T,
|
MAP_STORAGE_TAG_VALUE_TYPES(vtkm::cont::StorageTagXGCCoordinates, vtkm::TypeListFieldVec3);
|
||||||
const vtkm::cont::UnknownArrayHandle& array,
|
MAP_STORAGE_TAG_VALUE_TYPES(vtkm::cont::StorageTagUniformPoints, vtkm::List<vtkm::Vec3f>);
|
||||||
vtkm::cont::DeviceAdapterId device,
|
MAP_STORAGE_TAG_VALUE_TYPES(CartesianProductStorage, vtkm::TypeListFieldVec3);
|
||||||
vtkm::cont::ArrayHandle<vtkm::Range>& ranges,
|
MAP_STORAGE_TAG_VALUE_TYPES(vtkm::cont::StorageTagConstant, AllTypes);
|
||||||
bool& success) const
|
MAP_STORAGE_TAG_VALUE_TYPES(vtkm::cont::StorageTagCounting, AllTypes);
|
||||||
{
|
MAP_STORAGE_TAG_VALUE_TYPES(vtkm::cont::StorageTagIndex, vtkm::List<vtkm::Id>);
|
||||||
if (!success && array.IsBaseComponentType<T>())
|
|
||||||
{
|
|
||||||
vtkm::IdComponent numComponents = array.GetNumberOfComponentsFlat();
|
|
||||||
ranges.Allocate(numComponents);
|
|
||||||
auto rangePortal = ranges.WritePortal();
|
|
||||||
for (vtkm::IdComponent componentI = 0; componentI < numComponents; ++componentI)
|
|
||||||
{
|
|
||||||
vtkm::cont::ArrayHandleStride<T> componentArray = array.ExtractComponent<T>(componentI);
|
|
||||||
vtkm::cont::ArrayHandle<vtkm::Range> componentRange =
|
|
||||||
vtkm::cont::ArrayRangeComputeTemplate(componentArray, device);
|
|
||||||
rangePortal.Set(componentI, componentRange.ReadPortal().Get(0));
|
|
||||||
}
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename TList, typename Storage>
|
#undef MAP_STORAGE_TAG_VALUE_TYPES
|
||||||
vtkm::cont::ArrayHandle<vtkm::Range> ComputeForStorage(const vtkm::cont::UnknownArrayHandle& array,
|
|
||||||
vtkm::cont::DeviceAdapterId device)
|
|
||||||
{
|
|
||||||
vtkm::cont::ArrayHandle<vtkm::Range> ranges;
|
|
||||||
array.CastAndCallForTypes<TList, vtkm::List<Storage>>(ComputeRangeFunctor{}, device, ranges);
|
|
||||||
return ranges;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
@ -105,49 +94,44 @@ void ThrowArrayRangeComputeFailed()
|
|||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(const vtkm::cont::UnknownArrayHandle& array,
|
vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(const vtkm::cont::UnknownArrayHandle& array,
|
||||||
|
bool computeFiniteRange,
|
||||||
vtkm::cont::DeviceAdapterId device)
|
vtkm::cont::DeviceAdapterId device)
|
||||||
{
|
{
|
||||||
// First, try fast-paths of precompiled array types common(ish) in fields.
|
return ArrayRangeCompute(
|
||||||
|
array, vtkm::cont::ArrayHandle<vtkm::UInt8>{}, computeFiniteRange, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
|
||||||
|
const vtkm::cont::UnknownArrayHandle& array,
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||||
|
bool computeFiniteRange,
|
||||||
|
vtkm::cont::DeviceAdapterId device)
|
||||||
|
{
|
||||||
|
// First, try (potentially fast-paths) for common(ish) array types.
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (array.IsStorageType<vtkm::cont::StorageTagBasic>())
|
vtkm::cont::ArrayHandle<vtkm::Range> ranges;
|
||||||
|
|
||||||
|
auto computeForArrayHandle = [&](const auto& input) {
|
||||||
|
ranges = vtkm::cont::ArrayRangeComputeTemplate(input, maskArray, computeFiniteRange, device);
|
||||||
|
};
|
||||||
|
|
||||||
|
bool success = false;
|
||||||
|
auto computeForStorage = [&](auto storageTag) {
|
||||||
|
using STag = decltype(storageTag);
|
||||||
|
using VTypes = typename StorageTagToValueTypesMap<STag>::TypeList;
|
||||||
|
if (array.IsStorageType<STag>())
|
||||||
|
{
|
||||||
|
array.CastAndCallForTypes<VTypes, vtkm::List<STag>>(computeForArrayHandle);
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
vtkm::ListForEach(computeForStorage, StorageTagsList{});
|
||||||
|
|
||||||
|
if (success)
|
||||||
{
|
{
|
||||||
return ComputeForStorage<AllTypes, vtkm::cont::StorageTagBasic>(array, device);
|
return ranges;
|
||||||
}
|
|
||||||
if (array.IsStorageType<vtkm::cont::StorageTagSOA>())
|
|
||||||
{
|
|
||||||
return ComputeForStorage<AllVec, vtkm::cont::StorageTagSOA>(array, device);
|
|
||||||
}
|
|
||||||
if (array.IsStorageType<vtkm::cont::StorageTagXGCCoordinates>())
|
|
||||||
{
|
|
||||||
return ComputeForStorage<vtkm::TypeListFieldVec3, vtkm::cont::StorageTagXGCCoordinates>(
|
|
||||||
array, device);
|
|
||||||
}
|
|
||||||
if (array.IsStorageType<vtkm::cont::ArrayHandleUniformPointCoordinates::StorageTag>())
|
|
||||||
{
|
|
||||||
vtkm::cont::ArrayHandleUniformPointCoordinates uniformPoints;
|
|
||||||
array.AsArrayHandle(uniformPoints);
|
|
||||||
return vtkm::cont::ArrayRangeComputeTemplate(uniformPoints, device);
|
|
||||||
}
|
|
||||||
using CartesianProductStorage =
|
|
||||||
vtkm::cont::StorageTagCartesianProduct<vtkm::cont::StorageTagBasic,
|
|
||||||
vtkm::cont::StorageTagBasic,
|
|
||||||
vtkm::cont::StorageTagBasic>;
|
|
||||||
if (array.IsStorageType<CartesianProductStorage>())
|
|
||||||
{
|
|
||||||
return ComputeForStorage<vtkm::TypeListFieldVec3, CartesianProductStorage>(array, device);
|
|
||||||
}
|
|
||||||
if (array.IsStorageType<vtkm::cont::StorageTagConstant>())
|
|
||||||
{
|
|
||||||
return ComputeForStorage<AllTypes, vtkm::cont::StorageTagConstant>(array, device);
|
|
||||||
}
|
|
||||||
if (array.IsStorageType<vtkm::cont::StorageTagCounting>())
|
|
||||||
{
|
|
||||||
return ComputeForStorage<AllTypes, vtkm::cont::StorageTagCounting>(array, device);
|
|
||||||
}
|
|
||||||
if (array.IsStorageType<vtkm::cont::StorageTagIndex>())
|
|
||||||
{
|
|
||||||
return ArrayRangeComputeTemplate(array.AsArrayHandle<vtkm::cont::ArrayHandleIndex>(), device);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (vtkm::cont::ErrorBadType&)
|
catch (vtkm::cont::ErrorBadType&)
|
||||||
@ -155,11 +139,104 @@ vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(const vtkm::cont::Unknown
|
|||||||
// If a cast/call failed, try falling back to a more general implementation.
|
// If a cast/call failed, try falling back to a more general implementation.
|
||||||
}
|
}
|
||||||
|
|
||||||
vtkm::cont::ArrayHandle<vtkm::Range> ranges;
|
// fallback
|
||||||
bool success = false;
|
bool success = false;
|
||||||
vtkm::ListForEach(ComputeRangeFunctor{}, AllScalars{}, array, device, ranges, success);
|
vtkm::cont::ArrayHandle<vtkm::Range> ranges;
|
||||||
|
auto computeForExtractComponent = [&](auto valueTypeObj) {
|
||||||
|
using VT = decltype(valueTypeObj);
|
||||||
|
if (!success && array.IsBaseComponentType<VT>())
|
||||||
|
{
|
||||||
|
vtkm::IdComponent numComponents = array.GetNumberOfComponentsFlat();
|
||||||
|
ranges.Allocate(numComponents);
|
||||||
|
auto rangePortal = ranges.WritePortal();
|
||||||
|
for (vtkm::IdComponent i = 0; i < numComponents; ++i)
|
||||||
|
{
|
||||||
|
auto componentArray = array.ExtractComponent<VT>(i);
|
||||||
|
auto componentRange = vtkm::cont::ArrayRangeComputeTemplate(
|
||||||
|
componentArray, maskArray, computeFiniteRange, device);
|
||||||
|
rangePortal.Set(i, componentRange.ReadPortal().Get(0));
|
||||||
|
}
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
vtkm::ListForEach(computeForExtractComponent, AllScalars{});
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
internal::ThrowArrayRangeComputeFailed();
|
||||||
|
}
|
||||||
|
|
||||||
return ranges;
|
return ranges;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vtkm::Range ArrayRangeComputeMagnitude(const vtkm::cont::UnknownArrayHandle& array,
|
||||||
|
bool computeFiniteRange,
|
||||||
|
vtkm::cont::DeviceAdapterId device)
|
||||||
|
{
|
||||||
|
return ArrayRangeComputeMagnitude(
|
||||||
|
array, vtkm::cont::ArrayHandle<vtkm::UInt8>{}, computeFiniteRange, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
vtkm::Range ArrayRangeComputeMagnitude(const vtkm::cont::UnknownArrayHandle& array,
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||||
|
bool computeFiniteRange,
|
||||||
|
vtkm::cont::DeviceAdapterId device)
|
||||||
|
{
|
||||||
|
// First, try (potentially fast-paths) for common(ish) array types.
|
||||||
|
try
|
||||||
|
{
|
||||||
|
vtkm::Range range;
|
||||||
|
|
||||||
|
auto computeForArrayHandle = [&](const auto& input) {
|
||||||
|
range = vtkm::cont::ArrayRangeComputeMagnitudeTemplate(
|
||||||
|
input, maskArray, computeFiniteRange, device);
|
||||||
|
};
|
||||||
|
|
||||||
|
bool success = false;
|
||||||
|
auto computeForStorage = [&](auto storageTag) {
|
||||||
|
using STag = decltype(storageTag);
|
||||||
|
using VTypes = typename StorageTagToValueTypesMap<STag>::TypeList;
|
||||||
|
if (array.IsStorageType<STag>())
|
||||||
|
{
|
||||||
|
array.CastAndCallForTypes<VTypes, vtkm::List<STag>>(computeForArrayHandle);
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
vtkm::ListForEach(computeForStorage, StorageTagsList{});
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
return range;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (vtkm::cont::ErrorBadType&)
|
||||||
|
{
|
||||||
|
// If a cast/call failed, try falling back to a more general implementation.
|
||||||
|
}
|
||||||
|
|
||||||
|
// fallback
|
||||||
|
bool success = false;
|
||||||
|
vtkm::Range range;
|
||||||
|
auto computeForExtractArrayFromComponents = [&](auto valueTypeObj) {
|
||||||
|
using VT = decltype(valueTypeObj);
|
||||||
|
if (!success && array.IsBaseComponentType<VT>())
|
||||||
|
{
|
||||||
|
auto extractedArray = array.ExtractArrayFromComponents<VT>();
|
||||||
|
range = vtkm::cont::ArrayRangeComputeMagnitudeTemplate(
|
||||||
|
extractedArray, maskArray, computeFiniteRange, device);
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
vtkm::ListForEach(computeForExtractArrayFromComponents, AllScalars{});
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
internal::ThrowArrayRangeComputeFailed();
|
||||||
|
}
|
||||||
|
|
||||||
|
return range;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
} // namespace vtkm::cont
|
} // namespace vtkm::cont
|
||||||
|
@ -11,18 +11,8 @@
|
|||||||
#define vtk_m_cont_ArrayRangeCompute_h
|
#define vtk_m_cont_ArrayRangeCompute_h
|
||||||
|
|
||||||
#include <vtkm/Range.h>
|
#include <vtkm/Range.h>
|
||||||
#include <vtkm/VecTraits.h>
|
|
||||||
|
|
||||||
#include <vtkm/cont/ArrayHandle.h>
|
#include <vtkm/cont/ArrayHandle.h>
|
||||||
#include <vtkm/cont/ArrayHandleCartesianProduct.h>
|
|
||||||
#include <vtkm/cont/ArrayHandleCompositeVector.h>
|
|
||||||
#include <vtkm/cont/ArrayHandleConstant.h>
|
|
||||||
#include <vtkm/cont/ArrayHandleCounting.h>
|
|
||||||
#include <vtkm/cont/ArrayHandleIndex.h>
|
|
||||||
#include <vtkm/cont/ArrayHandleSOA.h>
|
|
||||||
#include <vtkm/cont/ArrayHandleStride.h>
|
|
||||||
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
|
|
||||||
#include <vtkm/cont/ArrayHandleXGCCoordinates.h>
|
|
||||||
#include <vtkm/cont/DeviceAdapterTag.h>
|
#include <vtkm/cont/DeviceAdapterTag.h>
|
||||||
#include <vtkm/cont/UnknownArrayHandle.h>
|
#include <vtkm/cont/UnknownArrayHandle.h>
|
||||||
|
|
||||||
@ -31,30 +21,116 @@ namespace vtkm
|
|||||||
namespace cont
|
namespace cont
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/// @{
|
||||||
/// \brief Compute the range of the data in an array handle.
|
/// \brief Compute the range of the data in an array handle.
|
||||||
///
|
///
|
||||||
/// Given an `ArrayHandle`, this function computes the range (min and max) of
|
/// Given an `ArrayHandle`, this function computes the range (min and max) of
|
||||||
/// the values in the array. For arrays containing Vec values, the range is
|
/// the values in the array. For arrays containing Vec values, the range is
|
||||||
/// computed for each component.
|
/// computed for each component, and in the case of nested Vecs, ranges are computed
|
||||||
|
/// for each of the leaf components.
|
||||||
///
|
///
|
||||||
/// This method optionally takes a `vtkm::cont::DeviceAdapterId` to control which
|
/// \param array The input array as a `vtkm::cont::UnknownArrayHandle`.
|
||||||
/// devices to try.
|
/// \param maskArray An array handle of type `vtkm::cont::ArrayHandle<vtkm::UInt8>`.
|
||||||
|
/// This array should have the same number of elements as the input array
|
||||||
|
/// with each value representing the masking status of the corresponding
|
||||||
|
/// value in the input array (masked if 0 else unmasked). Ignored if empty.
|
||||||
|
/// \param computeFiniteRange Optional boolean parameter to specify if non-finite values in the
|
||||||
|
/// array should be ignored to compute the finite range of
|
||||||
|
/// the array. For Vec types, individual component values
|
||||||
|
/// are considered independantly.
|
||||||
|
/// \param device This optional parameter can be used to specify a device to run the
|
||||||
|
/// range computation on. The default value is `vtkm::cont::DeviceAdapterTagAny{}`.
|
||||||
///
|
///
|
||||||
/// The result is returned in an `ArrayHandle` of `Range` objects. There is
|
/// \return The result is returned in an `ArrayHandle` of `Range` objects. There is
|
||||||
/// one value in the returned array for every component of the input's value
|
/// one value in the returned array for every component of the input's value
|
||||||
/// type.
|
/// type. For nested Vecs the results are stored in depth-first order.
|
||||||
///
|
///
|
||||||
/// Note that the ArrayRangeCompute.h header file contains only precompiled overloads
|
/// \note `ArrayRangeCompute` takes an UnknownArrayHandle as the input.
|
||||||
/// of ArrayRangeCompute. This is so that ArrayRangeCompute.h can be included in
|
/// The implementation uses precompiled and specicialized code for several of the
|
||||||
/// code that does not use a device compiler. If you need to compute array ranges
|
/// most commonly used value and storage types, with a fallback for other cases.
|
||||||
/// for arbitrary `ArrayHandle`s not in this precompiled list, you need to use
|
/// This is so that ArrayRangeCompute.h can be included in code that does not use a
|
||||||
/// `ArrayRangeComputeTemplate` (declared in `ArrayRangeComputeTemplate`), which
|
/// device compiler. This should be sufficient for most cases, but if you need to
|
||||||
/// will compile for any `ArrayHandle` type not already handled.
|
/// compute the range for an array type that is not explicitly handled by
|
||||||
|
/// `ArrayRangeCompute` and the fallback code is not performant, use the
|
||||||
|
/// templated version `ArrayRangeComputeTemplate`. Specializations can be
|
||||||
|
/// implemented by specializing the template class `ArrayRangeComputeImpl`.
|
||||||
|
/// Please refer to ArrayRangeComputeTemplate.h for details
|
||||||
///
|
///
|
||||||
|
/// \sa ArrayRangeComputeTemplate
|
||||||
|
///
|
||||||
|
|
||||||
VTKM_CONT_EXPORT vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
|
VTKM_CONT_EXPORT vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
|
||||||
const vtkm::cont::UnknownArrayHandle& array,
|
const vtkm::cont::UnknownArrayHandle& array,
|
||||||
|
bool computeFiniteRange = false,
|
||||||
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{});
|
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{});
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
|
||||||
|
const vtkm::cont::UnknownArrayHandle& array,
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||||
|
bool computeFiniteRange = false,
|
||||||
|
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{});
|
||||||
|
|
||||||
|
inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
|
||||||
|
const vtkm::cont::UnknownArrayHandle& array,
|
||||||
|
vtkm::cont::DeviceAdapterId device)
|
||||||
|
{
|
||||||
|
return ArrayRangeCompute(array, false, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
/// @{
|
||||||
|
/// \brief Compute the range of the magnitude of the Vec data in an array handle.
|
||||||
|
///
|
||||||
|
/// Given an `ArrayHandle`, this function computes the range (min and max) of
|
||||||
|
/// the magnitude of the values in the array.
|
||||||
|
///
|
||||||
|
/// \param array The input array as a `vtkm::cont::UnknownArrayHandle`.
|
||||||
|
/// \param maskArray An array handle of type `vtkm::cont::ArrayHandle<vtkm::UInt8>`.
|
||||||
|
/// This array should have the same number of elements as the input array
|
||||||
|
/// with each value representing the masking status of the corresponding
|
||||||
|
/// value in the input array (masked if 0 else unmasked). Ignored if empty.
|
||||||
|
/// \param computeFiniteRange Optional boolean value to specify if non-finite values in the
|
||||||
|
/// array should be ignored to compute the finite range of
|
||||||
|
/// the array. A Vec with any non-finite component will be
|
||||||
|
/// ignored.
|
||||||
|
/// \param device This optional parameter can be used to specify a device to run the
|
||||||
|
/// range computation on. The default value is `vtkm::cont::DeviceAdapterTagAny{}`.
|
||||||
|
///
|
||||||
|
/// \return The result is returned in a single `Range` objects.
|
||||||
|
///
|
||||||
|
/// \note `ArrayRangeComputeMagnitude` takes an UnknownArrayHandle as the input.
|
||||||
|
/// The implementation uses precompiled and specicialized code for several of the
|
||||||
|
/// most commonly used value and storage types, with a fallback for other cases.
|
||||||
|
/// This is so that ArrayRangeCompute.h can be included in code that does not use a
|
||||||
|
/// device compiler. This should be sufficient for most cases, but if you need to
|
||||||
|
/// compute the range for an array type that is not explicitly handled by
|
||||||
|
/// `ArrayRangeComputeMagnitude` and the fallback code is not performant, use the
|
||||||
|
/// templated version `ArrayRangeComputeMagnitudeTemplate`. Specializations can be
|
||||||
|
/// implemented by specializing the template class `ArrayRangeComputeMagnitudeImpl`.
|
||||||
|
/// Please refer to ArrayRangeComputeTemplate.h for details
|
||||||
|
///
|
||||||
|
/// \sa ArrayRangeComputeMagnitudeTemplate
|
||||||
|
///
|
||||||
|
VTKM_CONT_EXPORT vtkm::Range ArrayRangeComputeMagnitude(
|
||||||
|
const vtkm::cont::UnknownArrayHandle& array,
|
||||||
|
bool computeFiniteRange = false,
|
||||||
|
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{});
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT vtkm::Range ArrayRangeComputeMagnitude(
|
||||||
|
const vtkm::cont::UnknownArrayHandle& array,
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||||
|
bool computeFiniteRange = false,
|
||||||
|
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{});
|
||||||
|
|
||||||
|
inline vtkm::Range ArrayRangeComputeMagnitude(const vtkm::cont::UnknownArrayHandle& array,
|
||||||
|
vtkm::cont::DeviceAdapterId device)
|
||||||
|
{
|
||||||
|
return ArrayRangeComputeMagnitude(array, false, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
namespace internal
|
namespace internal
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -10,257 +10,531 @@
|
|||||||
#ifndef vtk_m_cont_ArrayRangeComputeTemplate_h
|
#ifndef vtk_m_cont_ArrayRangeComputeTemplate_h
|
||||||
#define vtk_m_cont_ArrayRangeComputeTemplate_h
|
#define vtk_m_cont_ArrayRangeComputeTemplate_h
|
||||||
|
|
||||||
#include <vtkm/cont/ArrayRangeCompute.h>
|
#include <vtkm/cont/Algorithm.h>
|
||||||
|
#include <vtkm/cont/ArrayHandleCast.h>
|
||||||
|
#include <vtkm/cont/ArrayHandleDecorator.h>
|
||||||
|
#include <vtkm/cont/ArrayHandleTransform.h>
|
||||||
|
#include <vtkm/cont/internal/ArrayRangeComputeUtils.h>
|
||||||
|
|
||||||
#include <vtkm/BinaryOperators.h>
|
#include <vtkm/BinaryOperators.h>
|
||||||
#include <vtkm/Deprecated.h>
|
#include <vtkm/Deprecated.h>
|
||||||
|
#include <vtkm/VecFlat.h>
|
||||||
#include <vtkm/VecTraits.h>
|
#include <vtkm/VecTraits.h>
|
||||||
|
#include <vtkm/VectorAnalysis.h>
|
||||||
|
|
||||||
#include <vtkm/internal/Instantiations.h>
|
#include <vtkm/internal/Instantiations.h>
|
||||||
|
|
||||||
#include <vtkm/cont/Algorithm.h>
|
|
||||||
|
|
||||||
#include <limits>
|
|
||||||
|
|
||||||
namespace vtkm
|
namespace vtkm
|
||||||
{
|
{
|
||||||
namespace cont
|
namespace cont
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
|
|
||||||
struct ArrayRangeComputeFunctor
|
|
||||||
{
|
|
||||||
template <typename Device, typename T, typename S>
|
|
||||||
VTKM_CONT bool operator()(Device,
|
|
||||||
const vtkm::cont::ArrayHandle<T, S>& handle,
|
|
||||||
const vtkm::Vec<T, 2>& initialValue,
|
|
||||||
vtkm::Vec<T, 2>& result) const
|
|
||||||
{
|
|
||||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
|
||||||
using Algorithm = vtkm::cont::DeviceAdapterAlgorithm<Device>;
|
|
||||||
result = Algorithm::Reduce(handle, initialValue, vtkm::MinAndMax<T>());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
namespace internal
|
namespace internal
|
||||||
{
|
{
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------------------
|
||||||
|
struct ComputeRangeOptionsDecorator
|
||||||
|
{
|
||||||
|
bool IgnoreInf = false;
|
||||||
|
|
||||||
|
template <typename SrcPortal, typename MaskPortal>
|
||||||
|
struct Functor
|
||||||
|
{
|
||||||
|
SrcPortal Src;
|
||||||
|
MaskPortal Mask;
|
||||||
|
bool IgnoreInf;
|
||||||
|
|
||||||
|
using InValueType = typename SrcPortal::ValueType;
|
||||||
|
using InVecTraits = vtkm::VecTraits<InValueType>;
|
||||||
|
using ResultType = vtkm::Vec<vtkm::Vec<vtkm::Float64, InVecTraits::NUM_COMPONENTS>, 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<vtkm::Float64>(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 <typename SrcPortal, typename GhostPortal>
|
||||||
|
Functor<SrcPortal, GhostPortal> CreateFunctor(const SrcPortal& sp, const GhostPortal& gp) const
|
||||||
|
{
|
||||||
|
return { sp, gp, this->IgnoreInf };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename ArrayHandleType>
|
||||||
|
struct ArrayValueIsNested
|
||||||
|
{
|
||||||
|
static constexpr bool Value =
|
||||||
|
!vtkm::internal::IsFlatVec<typename ArrayHandleType::ValueType>::value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename ArrayHandleType, bool IsNested = ArrayValueIsNested<ArrayHandleType>::Value>
|
||||||
|
struct NestedToFlat;
|
||||||
|
|
||||||
|
template <typename ArrayHandleType>
|
||||||
|
struct NestedToFlat<ArrayHandleType, true>
|
||||||
|
{
|
||||||
|
static auto Transform(const ArrayHandleType& in)
|
||||||
|
{
|
||||||
|
return vtkm::cont::ArrayHandleCast<vtkm::VecFlat<typename ArrayHandleType::ValueType>,
|
||||||
|
ArrayHandleType>(in);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename ArrayHandleType>
|
||||||
|
struct NestedToFlat<ArrayHandleType, false>
|
||||||
|
{
|
||||||
|
static auto Transform(const ArrayHandleType& in) { return in; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename ArrayHandleType>
|
||||||
|
inline auto NestedToFlatTransform(const ArrayHandleType& input)
|
||||||
|
{
|
||||||
|
return NestedToFlat<ArrayHandleType>::Transform(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------------------
|
||||||
|
/// \brief A generic implementation of `ArrayRangeCompute`. This is the implementation used
|
||||||
|
/// when `ArrayRangeComputeImpl` is not specialized.
|
||||||
|
///
|
||||||
template <typename T, typename S>
|
template <typename T, typename S>
|
||||||
inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeComputeGeneric(
|
inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeComputeGeneric(
|
||||||
const vtkm::cont::ArrayHandle<T, S>& input,
|
const vtkm::cont::ArrayHandle<T, S>& input,
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||||
|
bool computeFiniteRange,
|
||||||
vtkm::cont::DeviceAdapterId device)
|
vtkm::cont::DeviceAdapterId device)
|
||||||
{
|
{
|
||||||
VTKM_LOG_SCOPE(vtkm::cont::LogLevel::Perf, "ArrayRangeCompute");
|
VTKM_LOG_SCOPE(vtkm::cont::LogLevel::Perf, "ArrayRangeCompute");
|
||||||
|
|
||||||
using VecTraits = vtkm::VecTraits<T>;
|
using VecTraits = vtkm::VecTraits<T>;
|
||||||
using CT = typename VecTraits::ComponentType;
|
|
||||||
//We want to minimize the amount of code that we do in try execute as
|
|
||||||
//it is repeated for each
|
|
||||||
vtkm::cont::ArrayHandle<vtkm::Range> range;
|
vtkm::cont::ArrayHandle<vtkm::Range> range;
|
||||||
range.Allocate(VecTraits::NUM_COMPONENTS);
|
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)
|
if (input.GetNumberOfValues() < 1)
|
||||||
{
|
{
|
||||||
auto portal = range.WritePortal();
|
range.Fill(vtkm::Range{});
|
||||||
for (vtkm::IdComponent i = 0; i < VecTraits::NUM_COMPONENTS; ++i)
|
|
||||||
{
|
|
||||||
portal.Set(i, vtkm::Range());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//We used the limits, so that we don't need to sync the array handle
|
// if input is an array of nested vectors, transform them to `VecFlat` using ArrayHandleCast
|
||||||
//
|
auto flattened = NestedToFlatTransform(input);
|
||||||
vtkm::Vec<T, 2> result;
|
ComputeRangeOptionsDecorator decorator{ computeFiniteRange };
|
||||||
vtkm::Vec<T, 2> initial;
|
auto decorated =
|
||||||
initial[0] = T(std::numeric_limits<CT>::max());
|
make_ArrayHandleDecorator(flattened.GetNumberOfValues(), decorator, flattened, maskArray);
|
||||||
initial[1] = T(std::numeric_limits<CT>::lowest());
|
|
||||||
|
|
||||||
const bool rangeComputed = vtkm::cont::TryExecuteOnDevice(
|
using ResultType = vtkm::Vec<vtkm::Vec<vtkm::Float64, VecTraits::NUM_COMPONENTS>, 2>;
|
||||||
device, vtkm::cont::detail::ArrayRangeComputeFunctor{}, input, initial, result);
|
using MinAndMaxFunctor = vtkm::MinAndMax<typename ResultType::ComponentType>;
|
||||||
if (!rangeComputed)
|
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)
|
||||||
{
|
{
|
||||||
ThrowArrayRangeComputeFailed();
|
portal.Set(i, vtkm::Range(result[0][i], result[1][i]));
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
|
||||||
|
return range;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------------------
|
||||||
|
struct ScalarMagnitudeFunctor
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
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::Float64>(vtkm::Magnitude(val));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MagnitudeSquareFunctor
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
VTKM_EXEC_CONT vtkm::Float64 operator()(const T& val) const
|
||||||
|
{
|
||||||
|
using VecTraits = vtkm::VecTraits<T>;
|
||||||
|
vtkm::Float64 result = 0;
|
||||||
|
for (vtkm::IdComponent i = 0; i < VecTraits::GetNumberOfComponents(val); ++i)
|
||||||
{
|
{
|
||||||
auto portal = range.WritePortal();
|
auto comp = static_cast<vtkm::Float64>(VecTraits::GetComponent(val, i));
|
||||||
for (vtkm::IdComponent i = 0; i < VecTraits::NUM_COMPONENTS; ++i)
|
result += comp * comp;
|
||||||
{
|
|
||||||
portal.Set(i,
|
|
||||||
vtkm::Range(VecTraits::GetComponent(result[0], i),
|
|
||||||
VecTraits::GetComponent(result[1], i)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename ArrayHandleType>
|
||||||
|
vtkm::Range ArrayRangeComputeMagnitudeGenericImpl(
|
||||||
|
vtkm::VecTraitsTagSingleComponent,
|
||||||
|
const ArrayHandleType& input,
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::UInt8>& 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 <typename ArrayHandleType>
|
||||||
|
vtkm::Range ArrayRangeComputeMagnitudeGenericImpl(
|
||||||
|
vtkm::VecTraitsTagMultipleComponents,
|
||||||
|
const ArrayHandleType& input,
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::UInt8>& 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;
|
return range;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief A generic implementation of `ArrayRangeComputeMagnitude`. This is the implementation used
|
||||||
|
/// when `ArrayRangeComputeMagnitudeImpl` is not specialized.
|
||||||
|
///
|
||||||
|
template <typename T, typename S>
|
||||||
|
inline vtkm::Range ArrayRangeComputeMagnitudeGeneric(
|
||||||
|
const vtkm::cont::ArrayHandle<T, S>& input,
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||||
|
bool computeFiniteRange,
|
||||||
|
vtkm::cont::DeviceAdapterId device)
|
||||||
|
{
|
||||||
|
VTKM_LOG_SCOPE(vtkm::cont::LogLevel::Perf, "ArrayRangeComputeMagnitude");
|
||||||
|
|
||||||
|
using VecTraits = vtkm::VecTraits<T>;
|
||||||
|
|
||||||
|
//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 <typename S>
|
template <typename S>
|
||||||
struct ArrayRangeComputeImpl
|
struct ArrayRangeComputeImpl
|
||||||
{
|
{
|
||||||
template <typename T>
|
template <typename T>
|
||||||
vtkm::cont::ArrayHandle<vtkm::Range> operator()(const vtkm::cont::ArrayHandle<T, S>& input,
|
vtkm::cont::ArrayHandle<vtkm::Range> operator()(
|
||||||
vtkm::cont::DeviceAdapterId device) const
|
const vtkm::cont::ArrayHandle<T, S>& input,
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||||
|
bool computeFiniteRange,
|
||||||
|
vtkm::cont::DeviceAdapterId device) const
|
||||||
{
|
{
|
||||||
return vtkm::cont::internal::ArrayRangeComputeGeneric(input, device);
|
return vtkm::cont::internal::ArrayRangeComputeGeneric(
|
||||||
|
input, maskArray, computeFiniteRange, device);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename S>
|
||||||
|
struct ArrayRangeComputeMagnitudeImpl
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
vtkm::Range operator()(const vtkm::cont::ArrayHandle<T, S>& input,
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||||
|
bool computeFiniteRange,
|
||||||
|
vtkm::cont::DeviceAdapterId device) const
|
||||||
|
{
|
||||||
|
return vtkm::cont::internal::ArrayRangeComputeMagnitudeGeneric(
|
||||||
|
input, maskArray, computeFiniteRange, device);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------------------
|
||||||
template <typename ArrayHandleType>
|
/// @{
|
||||||
vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeComputeTemplate(
|
/// \brief Templated version of ArrayRangeCompute
|
||||||
const ArrayHandleType& input,
|
/// \sa ArrayRangeCompute
|
||||||
|
///
|
||||||
|
template <typename T, typename S>
|
||||||
|
inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeComputeTemplate(
|
||||||
|
const vtkm::cont::ArrayHandle<T, S>& input,
|
||||||
|
bool computeFiniteRange = false,
|
||||||
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{})
|
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{})
|
||||||
{
|
{
|
||||||
VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
|
return ArrayRangeComputeTemplate(
|
||||||
return internal::ArrayRangeComputeImpl<typename ArrayHandleType::StorageTag>{}(input, device);
|
input, vtkm::cont::ArrayHandle<vtkm::UInt8>{}, computeFiniteRange, device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, typename S>
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeComputeTemplate(
|
||||||
|
const vtkm::cont::ArrayHandle<T, S>& input,
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||||
|
bool computeFiniteRange = false,
|
||||||
|
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{})
|
||||||
|
{
|
||||||
|
VTKM_ASSERT(maskArray.GetNumberOfValues() == 0 ||
|
||||||
|
maskArray.GetNumberOfValues() == input.GetNumberOfValues());
|
||||||
|
return internal::ArrayRangeComputeImpl<S>{}(input, maskArray, computeFiniteRange, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename S>
|
||||||
|
inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeComputeTemplate(
|
||||||
|
const vtkm::cont::ArrayHandle<T, S>& input,
|
||||||
|
vtkm::cont::DeviceAdapterId device)
|
||||||
|
{
|
||||||
|
return ArrayRangeComputeTemplate(input, false, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
/// @{
|
||||||
|
/// \brief Templated version of ArrayRangeComputeMagnitude
|
||||||
|
/// \sa ArrayRangeComputeMagnitude
|
||||||
|
///
|
||||||
|
template <typename T, typename S>
|
||||||
|
inline vtkm::Range ArrayRangeComputeMagnitudeTemplate(
|
||||||
|
const vtkm::cont::ArrayHandle<T, S>& input,
|
||||||
|
bool computeFiniteRange = false,
|
||||||
|
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{})
|
||||||
|
{
|
||||||
|
return ArrayRangeComputeMagnitudeTemplate(
|
||||||
|
input, vtkm::cont::ArrayHandle<vtkm::UInt8>{}, computeFiniteRange, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename S>
|
||||||
|
vtkm::Range ArrayRangeComputeMagnitudeTemplate(
|
||||||
|
const vtkm::cont::ArrayHandle<T, S>& input,
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||||
|
bool computeFiniteRange = false,
|
||||||
|
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{})
|
||||||
|
{
|
||||||
|
VTKM_ASSERT(maskArray.GetNumberOfValues() == 0 ||
|
||||||
|
maskArray.GetNumberOfValues() == input.GetNumberOfValues());
|
||||||
|
return internal::ArrayRangeComputeMagnitudeImpl<S>{}(
|
||||||
|
input, maskArray, computeFiniteRange, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename S>
|
||||||
|
inline vtkm::Range ArrayRangeComputeMagnitudeTemplate(const vtkm::cont::ArrayHandle<T, S>& input,
|
||||||
|
vtkm::cont::DeviceAdapterId device)
|
||||||
|
{
|
||||||
|
return ArrayRangeComputeMagnitudeTemplate(input, false, device);
|
||||||
|
}
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
template <typename ArrayHandleType>
|
template <typename ArrayHandleType>
|
||||||
VTKM_DEPRECATED(2.1, "Use precompiled ArrayRangeCompute or ArrayRangeComputeTemplate.")
|
VTKM_DEPRECATED(2.1, "Use precompiled ArrayRangeCompute or ArrayRangeComputeTemplate.")
|
||||||
inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
|
inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
|
||||||
const ArrayHandleType& input,
|
const ArrayHandleType& input,
|
||||||
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{})
|
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{})
|
||||||
{
|
{
|
||||||
return ArrayRangeComputeTemplate(input, device);
|
return ArrayRangeComputeTemplate(input, false, device);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
} // namespace vtkm::cont
|
} // namespace vtkm::cont
|
||||||
|
|
||||||
#define VTK_M_ARRAY_RANGE_COMPUTE_ALL_SCALARS(modifiers, ...) \
|
#define VTK_M_ARRAY_RANGE_COMPUTE_DCLR(...) \
|
||||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
||||||
const vtkm::cont::ArrayHandle<vtkm::Int8, __VA_ARGS__>& input, \
|
const vtkm::cont::ArrayHandle<__VA_ARGS__>&, \
|
||||||
vtkm::cont::DeviceAdapterId device); \
|
const vtkm::cont::ArrayHandle<vtkm::UInt8>&, \
|
||||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
bool, \
|
||||||
const vtkm::cont::ArrayHandle<vtkm::UInt8, __VA_ARGS__>& input, \
|
vtkm::cont::DeviceAdapterId)
|
||||||
vtkm::cont::DeviceAdapterId device); \
|
|
||||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
|
||||||
const vtkm::cont::ArrayHandle<vtkm::Int16, __VA_ARGS__>& input, \
|
|
||||||
vtkm::cont::DeviceAdapterId device); \
|
|
||||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
|
||||||
const vtkm::cont::ArrayHandle<vtkm::UInt16, __VA_ARGS__>& input, \
|
|
||||||
vtkm::cont::DeviceAdapterId device); \
|
|
||||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
|
||||||
const vtkm::cont::ArrayHandle<vtkm::Int32, __VA_ARGS__>& input, \
|
|
||||||
vtkm::cont::DeviceAdapterId device); \
|
|
||||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
|
||||||
const vtkm::cont::ArrayHandle<vtkm::UInt32, __VA_ARGS__>& input, \
|
|
||||||
vtkm::cont::DeviceAdapterId device); \
|
|
||||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
|
||||||
const vtkm::cont::ArrayHandle<vtkm::Int64, __VA_ARGS__>& input, \
|
|
||||||
vtkm::cont::DeviceAdapterId device); \
|
|
||||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
|
||||||
const vtkm::cont::ArrayHandle<vtkm::UInt64, __VA_ARGS__>& input, \
|
|
||||||
vtkm::cont::DeviceAdapterId device); \
|
|
||||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
|
||||||
const vtkm::cont::ArrayHandle<vtkm::Float32, __VA_ARGS__>& input, \
|
|
||||||
vtkm::cont::DeviceAdapterId device); \
|
|
||||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
|
||||||
const vtkm::cont::ArrayHandle<vtkm::Float64, __VA_ARGS__>& input, \
|
|
||||||
vtkm::cont::DeviceAdapterId device); \
|
|
||||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
|
||||||
const vtkm::cont::ArrayHandle<bool, __VA_ARGS__>& input, vtkm::cont::DeviceAdapterId device); \
|
|
||||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
|
||||||
const vtkm::cont::ArrayHandle<char, __VA_ARGS__>& input, vtkm::cont::DeviceAdapterId device); \
|
|
||||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
|
||||||
const vtkm::cont::ArrayHandle<signed VTKM_UNUSED_INT_TYPE, __VA_ARGS__>& input, \
|
|
||||||
vtkm::cont::DeviceAdapterId device); \
|
|
||||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
|
||||||
const vtkm::cont::ArrayHandle<unsigned VTKM_UNUSED_INT_TYPE, __VA_ARGS__>& input, \
|
|
||||||
vtkm::cont::DeviceAdapterId device)
|
|
||||||
|
|
||||||
#define VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(modifiers, N, ...) \
|
#define VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(...) \
|
||||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
vtkm::Range vtkm::cont::ArrayRangeComputeMagnitudeTemplate( \
|
||||||
const vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Int8, N>, __VA_ARGS__>& input, \
|
const vtkm::cont::ArrayHandle<__VA_ARGS__>&, \
|
||||||
vtkm::cont::DeviceAdapterId device); \
|
const vtkm::cont::ArrayHandle<vtkm::UInt8>&, \
|
||||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
bool, \
|
||||||
const vtkm::cont::ArrayHandle<vtkm::Vec<UInt8, N>, __VA_ARGS__>& input, \
|
vtkm::cont::DeviceAdapterId)
|
||||||
vtkm::cont::DeviceAdapterId device); \
|
|
||||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
|
||||||
const vtkm::cont::ArrayHandle<vtkm::Vec<Int16, N>, __VA_ARGS__>& input, \
|
|
||||||
vtkm::cont::DeviceAdapterId device); \
|
|
||||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
|
||||||
const vtkm::cont::ArrayHandle<vtkm::Vec<UInt16, N>, __VA_ARGS__>& input, \
|
|
||||||
vtkm::cont::DeviceAdapterId device); \
|
|
||||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
|
||||||
const vtkm::cont::ArrayHandle<vtkm::Vec<Int32, N>, __VA_ARGS__>& input, \
|
|
||||||
vtkm::cont::DeviceAdapterId device); \
|
|
||||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
|
||||||
const vtkm::cont::ArrayHandle<vtkm::Vec<UInt32, N>, __VA_ARGS__>& input, \
|
|
||||||
vtkm::cont::DeviceAdapterId device); \
|
|
||||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
|
||||||
const vtkm::cont::ArrayHandle<vtkm::Vec<Int64, N>, __VA_ARGS__>& input, \
|
|
||||||
vtkm::cont::DeviceAdapterId device); \
|
|
||||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
|
||||||
const vtkm::cont::ArrayHandle<vtkm::Vec<UInt64, N>, __VA_ARGS__>& input, \
|
|
||||||
vtkm::cont::DeviceAdapterId device); \
|
|
||||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
|
||||||
const vtkm::cont::ArrayHandle<vtkm::Vec<Float32, N>, __VA_ARGS__>& input, \
|
|
||||||
vtkm::cont::DeviceAdapterId device); \
|
|
||||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
|
||||||
const vtkm::cont::ArrayHandle<vtkm::Vec<Float64, N>, __VA_ARGS__>& input, \
|
|
||||||
vtkm::cont::DeviceAdapterId device); \
|
|
||||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
|
||||||
const vtkm::cont::ArrayHandle<vtkm::Vec<bool, N>, __VA_ARGS__>& input, \
|
|
||||||
vtkm::cont::DeviceAdapterId device); \
|
|
||||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
|
||||||
const vtkm::cont::ArrayHandle<vtkm::Vec<char, N>, __VA_ARGS__>& input, \
|
|
||||||
vtkm::cont::DeviceAdapterId device); \
|
|
||||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
|
||||||
const vtkm::cont::ArrayHandle<vtkm::Vec<signed VTKM_UNUSED_INT_TYPE, N>, __VA_ARGS__>& input, \
|
|
||||||
vtkm::cont::DeviceAdapterId device); \
|
|
||||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
|
||||||
const vtkm::cont::ArrayHandle<vtkm::Vec<unsigned VTKM_UNUSED_INT_TYPE, N>, __VA_ARGS__>& \
|
|
||||||
input, \
|
|
||||||
vtkm::cont::DeviceAdapterId device)
|
|
||||||
|
|
||||||
|
#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<vtkm::Int8, N>, __VA_ARGS__); \
|
||||||
|
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec<vtkm::Int8, N>, __VA_ARGS__); \
|
||||||
|
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec<vtkm::UInt8, N>, __VA_ARGS__); \
|
||||||
|
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec<vtkm::UInt8, N>, __VA_ARGS__); \
|
||||||
|
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec<vtkm::Int16, N>, __VA_ARGS__); \
|
||||||
|
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec<vtkm::Int16, N>, __VA_ARGS__); \
|
||||||
|
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec<vtkm::UInt16, N>, __VA_ARGS__); \
|
||||||
|
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec<vtkm::UInt16, N>, __VA_ARGS__); \
|
||||||
|
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec<vtkm::Int32, N>, __VA_ARGS__); \
|
||||||
|
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec<vtkm::Int32, N>, __VA_ARGS__); \
|
||||||
|
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec<vtkm::UInt32, N>, __VA_ARGS__); \
|
||||||
|
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec<vtkm::UInt32, N>, __VA_ARGS__); \
|
||||||
|
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec<vtkm::Int64, N>, __VA_ARGS__); \
|
||||||
|
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec<vtkm::Int64, N>, __VA_ARGS__); \
|
||||||
|
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec<vtkm::UInt64, N>, __VA_ARGS__); \
|
||||||
|
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec<vtkm::UInt64, N>, __VA_ARGS__)
|
||||||
|
|
||||||
|
#define VTK_M_ARRAY_RANGE_COMPUTE_FLOAT_VECN(modifiers, N, ...) \
|
||||||
|
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec<vtkm::Float32, N>, __VA_ARGS__); \
|
||||||
|
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec<vtkm::Float32, N>, __VA_ARGS__); \
|
||||||
|
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec<vtkm::Float64, N>, __VA_ARGS__); \
|
||||||
|
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec<vtkm::Float64, N>, __VA_ARGS__)
|
||||||
|
|
||||||
|
#define VTK_M_ARRAY_RANGE_COMPUTE_BOOL_VECN(modifiers, N, ...) \
|
||||||
|
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec<bool, N>, __VA_ARGS__); \
|
||||||
|
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec<bool, N>, __VA_ARGS__)
|
||||||
|
|
||||||
|
#define VTK_M_ARRAY_RANGE_COMPUTE_OTHER_VECN(modifiers, N, ...) \
|
||||||
|
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec<char, N>, __VA_ARGS__); \
|
||||||
|
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec<char, N>, __VA_ARGS__); \
|
||||||
|
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec<signed VTKM_UNUSED_INT_TYPE, N>, \
|
||||||
|
__VA_ARGS__); \
|
||||||
|
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec<signed VTKM_UNUSED_INT_TYPE, N>, \
|
||||||
|
__VA_ARGS__); \
|
||||||
|
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec<unsigned VTKM_UNUSED_INT_TYPE, N>, \
|
||||||
|
__VA_ARGS__); \
|
||||||
|
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec<unsigned VTKM_UNUSED_INT_TYPE, N>, \
|
||||||
|
__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 <typename ST1, typename ST2, typename ST3>
|
||||||
|
struct StorageTagCartesianProduct;
|
||||||
|
|
||||||
|
struct StorageTagConstant;
|
||||||
|
|
||||||
|
struct StorageTagCounting;
|
||||||
|
|
||||||
|
struct StorageTagXGCCoordinates;
|
||||||
|
|
||||||
|
struct StorageTagStride;
|
||||||
|
|
||||||
|
}
|
||||||
|
} // vtkm::cont
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------------------
|
||||||
VTKM_INSTANTIATION_BEGIN
|
VTKM_INSTANTIATION_BEGIN
|
||||||
VTK_M_ARRAY_RANGE_COMPUTE_ALL_SCALARS(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
VTK_M_ARRAY_RANGE_COMPUTE_ALL_SCALARS(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||||
vtkm::cont::StorageTagBasic);
|
vtkm::cont::StorageTagBasic);
|
||||||
VTKM_INSTANTIATION_END
|
VTKM_INSTANTIATION_END
|
||||||
|
|
||||||
VTKM_INSTANTIATION_BEGIN
|
VTKM_INSTANTIATION_BEGIN
|
||||||
VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||||
2,
|
2,
|
||||||
vtkm::cont::StorageTagBasic);
|
vtkm::cont::StorageTagBasic);
|
||||||
VTKM_INSTANTIATION_END
|
VTKM_INSTANTIATION_END
|
||||||
|
|
||||||
VTKM_INSTANTIATION_BEGIN
|
VTKM_INSTANTIATION_BEGIN
|
||||||
VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||||
3,
|
3,
|
||||||
vtkm::cont::StorageTagBasic);
|
vtkm::cont::StorageTagBasic);
|
||||||
VTKM_INSTANTIATION_END
|
VTKM_INSTANTIATION_END
|
||||||
|
|
||||||
VTKM_INSTANTIATION_BEGIN
|
VTKM_INSTANTIATION_BEGIN
|
||||||
VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||||
4,
|
4,
|
||||||
vtkm::cont::StorageTagBasic);
|
vtkm::cont::StorageTagBasic);
|
||||||
VTKM_INSTANTIATION_END
|
VTKM_INSTANTIATION_END
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------------------
|
||||||
VTKM_INSTANTIATION_BEGIN
|
VTKM_INSTANTIATION_BEGIN
|
||||||
VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||||
2,
|
2,
|
||||||
vtkm::cont::StorageTagSOA);
|
vtkm::cont::StorageTagSOA);
|
||||||
VTKM_INSTANTIATION_END
|
VTKM_INSTANTIATION_END
|
||||||
|
|
||||||
VTKM_INSTANTIATION_BEGIN
|
VTKM_INSTANTIATION_BEGIN
|
||||||
VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||||
3,
|
3,
|
||||||
vtkm::cont::StorageTagSOA);
|
vtkm::cont::StorageTagSOA);
|
||||||
VTKM_INSTANTIATION_END
|
VTKM_INSTANTIATION_END
|
||||||
|
|
||||||
VTKM_INSTANTIATION_BEGIN
|
VTKM_INSTANTIATION_BEGIN
|
||||||
VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||||
4,
|
4,
|
||||||
vtkm::cont::StorageTagSOA);
|
vtkm::cont::StorageTagSOA);
|
||||||
VTKM_INSTANTIATION_END
|
VTKM_INSTANTIATION_END
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------------------
|
||||||
VTKM_INSTANTIATION_BEGIN
|
VTKM_INSTANTIATION_BEGIN
|
||||||
VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(
|
VTK_M_ARRAY_RANGE_COMPUTE_FLOAT_VECN(
|
||||||
extern template VTKM_CONT_TEMPLATE_EXPORT,
|
extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||||
3,
|
3,
|
||||||
vtkm::cont::StorageTagCartesianProduct<vtkm::cont::StorageTagBasic,
|
vtkm::cont::StorageTagCartesianProduct<vtkm::cont::StorageTagBasic,
|
||||||
@ -268,24 +542,87 @@ VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(
|
|||||||
vtkm::cont::StorageTagBasic>);
|
vtkm::cont::StorageTagBasic>);
|
||||||
VTKM_INSTANTIATION_END
|
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
|
VTKM_INSTANTIATION_BEGIN
|
||||||
VTK_M_ARRAY_RANGE_COMPUTE_ALL_SCALARS(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
VTK_M_ARRAY_RANGE_COMPUTE_ALL_SCALARS(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||||
vtkm::cont::StorageTagConstant);
|
vtkm::cont::StorageTagConstant);
|
||||||
VTKM_INSTANTIATION_END
|
VTKM_INSTANTIATION_END
|
||||||
|
|
||||||
VTKM_INSTANTIATION_BEGIN
|
VTKM_INSTANTIATION_BEGIN
|
||||||
VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||||
2,
|
2,
|
||||||
vtkm::cont::StorageTagConstant);
|
vtkm::cont::StorageTagConstant);
|
||||||
VTKM_INSTANTIATION_END
|
VTKM_INSTANTIATION_END
|
||||||
|
|
||||||
VTKM_INSTANTIATION_BEGIN
|
VTKM_INSTANTIATION_BEGIN
|
||||||
VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||||
3,
|
3,
|
||||||
vtkm::cont::StorageTagConstant);
|
vtkm::cont::StorageTagConstant);
|
||||||
VTKM_INSTANTIATION_END
|
VTKM_INSTANTIATION_END
|
||||||
|
|
||||||
VTKM_INSTANTIATION_BEGIN
|
VTKM_INSTANTIATION_BEGIN
|
||||||
VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||||
4,
|
4,
|
||||||
vtkm::cont::StorageTagConstant);
|
vtkm::cont::StorageTagConstant);
|
||||||
VTKM_INSTANTIATION_END
|
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
|
||||||
|
|
||||||
#endif //vtk_m_cont_ArrayRangeComputeTemplate_h
|
#endif //vtk_m_cont_ArrayRangeComputeTemplate_h
|
||||||
|
22
vtkm/cont/ArrayRangeComputeTemplateInstantiationsIncludes.h
Normal file
22
vtkm/cont/ArrayRangeComputeTemplateInstantiationsIncludes.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
//============================================================================
|
||||||
|
// 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_ArrayRangeComputeTemplateInstantiationsIncludes_h
|
||||||
|
#define vtk_m_cont_ArrayRangeComputeTemplateInstantiationsIncludes_h
|
||||||
|
|
||||||
|
#include <vtkm/cont/ArrayRangeComputeTemplate.h>
|
||||||
|
|
||||||
|
#include <vtkm/cont/ArrayHandleCartesianProduct.h>
|
||||||
|
#include <vtkm/cont/ArrayHandleConstant.h>
|
||||||
|
#include <vtkm/cont/ArrayHandleCounting.h>
|
||||||
|
#include <vtkm/cont/ArrayHandleRecombineVec.h>
|
||||||
|
#include <vtkm/cont/ArrayHandleSOA.h>
|
||||||
|
#include <vtkm/cont/ArrayHandleXGCCoordinates.h>
|
||||||
|
|
||||||
|
#endif // vtk_m_cont_ArrayRangeComputeTemplateInstantiationsIncludes_h
|
@ -51,6 +51,7 @@ set(headers
|
|||||||
ArrayPortalToIterators.h
|
ArrayPortalToIterators.h
|
||||||
ArrayRangeCompute.h
|
ArrayRangeCompute.h
|
||||||
ArrayRangeComputeTemplate.h
|
ArrayRangeComputeTemplate.h
|
||||||
|
ArrayRangeComputeTemplateInstantiationsIncludes.h
|
||||||
AssignerPartitionedDataSet.h
|
AssignerPartitionedDataSet.h
|
||||||
AtomicArray.h
|
AtomicArray.h
|
||||||
BitField.h
|
BitField.h
|
||||||
@ -135,7 +136,6 @@ set(sources
|
|||||||
ArrayHandleBasic.cxx
|
ArrayHandleBasic.cxx
|
||||||
ArrayHandleSOA.cxx
|
ArrayHandleSOA.cxx
|
||||||
ArrayHandleStride.cxx
|
ArrayHandleStride.cxx
|
||||||
ArrayHandleUniformPointCoordinates.cxx
|
|
||||||
AssignerPartitionedDataSet.cxx
|
AssignerPartitionedDataSet.cxx
|
||||||
BitField.cxx
|
BitField.cxx
|
||||||
BoundsCompute.cxx
|
BoundsCompute.cxx
|
||||||
@ -183,6 +183,8 @@ set(sources
|
|||||||
set(device_sources
|
set(device_sources
|
||||||
ArrayCopy.cxx
|
ArrayCopy.cxx
|
||||||
ArrayGetValues.cxx
|
ArrayGetValues.cxx
|
||||||
|
ArrayHandleIndex.cxx
|
||||||
|
ArrayHandleUniformPointCoordinates.cxx
|
||||||
ArrayRangeCompute.cxx
|
ArrayRangeCompute.cxx
|
||||||
CellLocatorBoundingIntervalHierarchy.cxx
|
CellLocatorBoundingIntervalHierarchy.cxx
|
||||||
CellLocatorUniformBins.cxx
|
CellLocatorUniformBins.cxx
|
||||||
@ -193,6 +195,7 @@ set(device_sources
|
|||||||
ConvertNumComponentsToOffsets.cxx
|
ConvertNumComponentsToOffsets.cxx
|
||||||
Field.cxx
|
Field.cxx
|
||||||
internal/ArrayCopyUnknown.cxx
|
internal/ArrayCopyUnknown.cxx
|
||||||
|
internal/ArrayRangeComputeUtils.cxx
|
||||||
internal/Buffer.cxx
|
internal/Buffer.cxx
|
||||||
internal/MapArrayPermutation.cxx
|
internal/MapArrayPermutation.cxx
|
||||||
MergePartitionedDataSet.cxx
|
MergePartitionedDataSet.cxx
|
||||||
@ -268,6 +271,7 @@ vtkm_install_headers(vtkm/cont
|
|||||||
# compiles by breaking them up into smaller units.
|
# compiles by breaking them up into smaller units.
|
||||||
vtkm_add_instantiations(array_range_instantiations
|
vtkm_add_instantiations(array_range_instantiations
|
||||||
INSTANTIATIONS_FILE ArrayRangeComputeTemplate.h
|
INSTANTIATIONS_FILE ArrayRangeComputeTemplate.h
|
||||||
|
TEMPLATE_SOURCE ArrayRangeComputeTemplateInstantiationsIncludes.h
|
||||||
)
|
)
|
||||||
list(APPEND device_sources ${array_range_instantiations})
|
list(APPEND device_sources ${array_range_instantiations})
|
||||||
|
|
||||||
|
52
vtkm/cont/internal/ArrayRangeComputeUtils.cxx
Normal file
52
vtkm/cont/internal/ArrayRangeComputeUtils.cxx
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// 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 <vtkm/cont/internal/ArrayRangeComputeUtils.h>
|
||||||
|
|
||||||
|
#include <vtkm/cont/Algorithm.h>
|
||||||
|
#include <vtkm/cont/ArrayHandleIndex.h>
|
||||||
|
#include <vtkm/cont/ArrayHandleTransform.h>
|
||||||
|
#include <vtkm/cont/ArrayHandleZip.h>
|
||||||
|
|
||||||
|
#include <vtkm/BinaryOperators.h>
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
struct UnmaskedIndicesTransform
|
||||||
|
{
|
||||||
|
VTKM_EXEC vtkm::Id2 operator()(vtkm::Pair<vtkm::UInt8, vtkm::Id> in) const
|
||||||
|
{
|
||||||
|
if (in.first == 0)
|
||||||
|
{
|
||||||
|
return { std::numeric_limits<vtkm::Id>::max(), std::numeric_limits<vtkm::Id>::min() };
|
||||||
|
}
|
||||||
|
return { in.second };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
vtkm::Id2 vtkm::cont::internal::GetFirstAndLastUnmaskedIndices(
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||||
|
vtkm::cont::DeviceAdapterId device)
|
||||||
|
{
|
||||||
|
vtkm::Id2 initialValue = { std::numeric_limits<vtkm::Id>::max(),
|
||||||
|
std::numeric_limits<vtkm::Id>::min() };
|
||||||
|
auto maskValsAndInds = vtkm::cont::make_ArrayHandleZip(
|
||||||
|
maskArray, vtkm::cont::ArrayHandleIndex(maskArray.GetNumberOfValues()));
|
||||||
|
auto unmaskedIndices =
|
||||||
|
vtkm::cont::make_ArrayHandleTransform(maskValsAndInds, UnmaskedIndicesTransform{});
|
||||||
|
return vtkm::cont::Algorithm::Reduce(
|
||||||
|
device, unmaskedIndices, initialValue, vtkm::MinAndMax<vtkm::Id>());
|
||||||
|
}
|
33
vtkm/cont/internal/ArrayRangeComputeUtils.h
Normal file
33
vtkm/cont/internal/ArrayRangeComputeUtils.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
//============================================================================
|
||||||
|
// 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_ArrayRangeComputeUtils_h
|
||||||
|
#define vtk_m_cont_internal_ArrayRangeComputeUtils_h
|
||||||
|
|
||||||
|
#include <vtkm/VecTraits.h>
|
||||||
|
|
||||||
|
#include <vtkm/cont/ArrayHandle.h>
|
||||||
|
#include <vtkm/cont/vtkm_cont_export.h>
|
||||||
|
|
||||||
|
namespace vtkm
|
||||||
|
{
|
||||||
|
namespace cont
|
||||||
|
{
|
||||||
|
namespace internal
|
||||||
|
{
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT vtkm::Id2 GetFirstAndLastUnmaskedIndices(
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||||
|
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // vtkm::cont::internal
|
||||||
|
|
||||||
|
#endif // vtk_m_cont_internal_ArrayRangeComputeUtils_h
|
@ -12,6 +12,7 @@ set(headers
|
|||||||
ArrayCopyUnknown.h
|
ArrayCopyUnknown.h
|
||||||
ArrayHandleExecutionManager.h
|
ArrayHandleExecutionManager.h
|
||||||
ArrayPortalFromIterators.h
|
ArrayPortalFromIterators.h
|
||||||
|
ArrayRangeComputeUtils.h
|
||||||
ArrayTransfer.h
|
ArrayTransfer.h
|
||||||
Buffer.h
|
Buffer.h
|
||||||
CastInvalidValue.h
|
CastInvalidValue.h
|
||||||
|
@ -36,8 +36,10 @@ namespace
|
|||||||
constexpr vtkm::Id ARRAY_SIZE = 20;
|
constexpr vtkm::Id ARRAY_SIZE = 20;
|
||||||
|
|
||||||
template <typename T, typename S>
|
template <typename T, typename S>
|
||||||
void VerifyRange(const vtkm::cont::ArrayHandle<T, S>& array,
|
void VerifyRangeScalar(const vtkm::cont::ArrayHandle<T, S>& array,
|
||||||
const vtkm::cont::ArrayHandle<vtkm::Range>& computedRangeArray)
|
const vtkm::cont::ArrayHandle<vtkm::Range>& computedRangeArray,
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||||
|
bool finitesOnly)
|
||||||
{
|
{
|
||||||
using Traits = vtkm::VecTraits<T>;
|
using Traits = vtkm::VecTraits<T>;
|
||||||
vtkm::IdComponent numComponents = Traits::NUM_COMPONENTS;
|
vtkm::IdComponent numComponents = Traits::NUM_COMPONENTS;
|
||||||
@ -46,40 +48,237 @@ void VerifyRange(const vtkm::cont::ArrayHandle<T, S>& array,
|
|||||||
auto computedRangePortal = computedRangeArray.ReadPortal();
|
auto computedRangePortal = computedRangeArray.ReadPortal();
|
||||||
|
|
||||||
auto portal = array.ReadPortal();
|
auto portal = array.ReadPortal();
|
||||||
|
auto maskPortal = maskArray.ReadPortal();
|
||||||
for (vtkm::IdComponent component = 0; component < numComponents; ++component)
|
for (vtkm::IdComponent component = 0; component < numComponents; ++component)
|
||||||
{
|
{
|
||||||
vtkm::Range computedRange = computedRangePortal.Get(component);
|
vtkm::Range computedRange = computedRangePortal.Get(component);
|
||||||
vtkm::Range expectedRange;
|
vtkm::Range expectedRange{};
|
||||||
for (vtkm::Id index = 0; index < portal.GetNumberOfValues(); ++index)
|
for (vtkm::Id index = 0; index < portal.GetNumberOfValues(); ++index)
|
||||||
{
|
{
|
||||||
T value = portal.Get(index);
|
if (maskPortal.GetNumberOfValues() != 0 && (maskPortal.Get(index) == 0))
|
||||||
expectedRange.Include(Traits::GetComponent(value, component));
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto value = static_cast<vtkm::Float64>(Traits::GetComponent(portal.Get(index), component));
|
||||||
|
if (finitesOnly && !vtkm::IsFinite(value))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
expectedRange.Include(value);
|
||||||
}
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
VTKM_TEST_ASSERT(!vtkm::IsNan(computedRange.Min));
|
||||||
|
VTKM_TEST_ASSERT(!vtkm::IsNan(computedRange.Max));
|
||||||
|
VTKM_TEST_ASSERT((!expectedRange.IsNonEmpty() && !computedRange.IsNonEmpty()) ||
|
||||||
|
(test_equal(expectedRange, computedRange)));
|
||||||
|
}
|
||||||
|
catch (const vtkm::testing::Testing::TestFailure&)
|
||||||
|
{
|
||||||
|
std::cout << "Test array: \n";
|
||||||
|
vtkm::cont::printSummary_ArrayHandle(array, std::cout, true);
|
||||||
|
std::cout << "Mask array: \n";
|
||||||
|
vtkm::cont::printSummary_ArrayHandle(maskArray, std::cout, true);
|
||||||
|
std::cout << "Range type: " << (finitesOnly ? "Scalar, Finite" : "Scalar, NonFinite") << "\n";
|
||||||
|
std::cout << "Computed range: \n";
|
||||||
|
vtkm::cont::printSummary_ArrayHandle(computedRangeArray, std::cout, true);
|
||||||
|
std::cout << "Expected range: " << expectedRange << ", component: " << component << "\n";
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename S>
|
||||||
|
void VerifyRangeVector(const vtkm::cont::ArrayHandle<T, S>& array,
|
||||||
|
const vtkm::Range& computedRange,
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||||
|
bool finitesOnly)
|
||||||
|
{
|
||||||
|
auto portal = array.ReadPortal();
|
||||||
|
auto maskPortal = maskArray.ReadPortal();
|
||||||
|
vtkm::Range expectedRange{};
|
||||||
|
for (vtkm::Id index = 0; index < portal.GetNumberOfValues(); ++index)
|
||||||
|
{
|
||||||
|
if (maskPortal.GetNumberOfValues() != 0 && (maskPortal.Get(index) == 0))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto value = static_cast<vtkm::Float64>(vtkm::MagnitudeSquared(portal.Get(index)));
|
||||||
|
if (finitesOnly && !vtkm::IsFinite(value))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
expectedRange.Include(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expectedRange.IsNonEmpty())
|
||||||
|
{
|
||||||
|
expectedRange.Min = vtkm::Sqrt(expectedRange.Min);
|
||||||
|
expectedRange.Max = vtkm::Sqrt(expectedRange.Max);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
VTKM_TEST_ASSERT(!vtkm::IsNan(computedRange.Min));
|
VTKM_TEST_ASSERT(!vtkm::IsNan(computedRange.Min));
|
||||||
VTKM_TEST_ASSERT(!vtkm::IsNan(computedRange.Max));
|
VTKM_TEST_ASSERT(!vtkm::IsNan(computedRange.Max));
|
||||||
VTKM_TEST_ASSERT(test_equal(expectedRange, computedRange));
|
VTKM_TEST_ASSERT((!expectedRange.IsNonEmpty() && !computedRange.IsNonEmpty()) ||
|
||||||
|
(test_equal(expectedRange, computedRange)));
|
||||||
}
|
}
|
||||||
|
catch (const vtkm::testing::Testing::TestFailure&)
|
||||||
|
{
|
||||||
|
std::cout << "Test array: \n";
|
||||||
|
vtkm::cont::printSummary_ArrayHandle(array, std::cout, true);
|
||||||
|
std::cout << "Mask array: \n";
|
||||||
|
vtkm::cont::printSummary_ArrayHandle(maskArray, std::cout, true);
|
||||||
|
std::cout << "Range type: " << (finitesOnly ? "Vector, Finite" : "Vector, NonFinite") << "\n";
|
||||||
|
std::cout << "Computed range: " << computedRange << "\n";
|
||||||
|
std::cout << "Expected range: " << expectedRange << "\n";
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto FillMaskArray(vtkm::Id length)
|
||||||
|
{
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::UInt8> maskArray;
|
||||||
|
maskArray.Allocate(length);
|
||||||
|
|
||||||
|
vtkm::cont::ArrayHandleRandomUniformBits randomBits(length + 1);
|
||||||
|
auto randomPortal = randomBits.ReadPortal();
|
||||||
|
switch (randomPortal.Get(length) % 3)
|
||||||
|
{
|
||||||
|
case 0: // all masked
|
||||||
|
maskArray.Fill(0);
|
||||||
|
break;
|
||||||
|
case 1: // none masked
|
||||||
|
maskArray.Fill(1);
|
||||||
|
break;
|
||||||
|
case 2: // random masked
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
auto maskPortal = maskArray.WritePortal();
|
||||||
|
for (vtkm::Id i = 0; i < length; ++i)
|
||||||
|
{
|
||||||
|
vtkm::UInt8 maskVal = ((randomPortal.Get(i) % 8) == 0) ? 0 : 1;
|
||||||
|
maskPortal.Set(i, maskVal);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return maskArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename S>
|
template <typename T, typename S>
|
||||||
void CheckRange(const vtkm::cont::ArrayHandle<T, S>& array)
|
void CheckRange(const vtkm::cont::ArrayHandle<T, S>& array)
|
||||||
{
|
{
|
||||||
VerifyRange(array, vtkm::cont::ArrayRangeCompute(array));
|
auto length = array.GetNumberOfValues();
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::UInt8> emptyMaskArray;
|
||||||
|
|
||||||
|
auto maskArray = FillMaskArray(length);
|
||||||
|
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Range> scalarRange;
|
||||||
|
std::cout << "\tchecking scalar range without mask\n";
|
||||||
|
scalarRange = vtkm::cont::ArrayRangeCompute(array);
|
||||||
|
VerifyRangeScalar(array, scalarRange, emptyMaskArray, false);
|
||||||
|
std::cout << "\tchecking scalar range with mask\n";
|
||||||
|
scalarRange = vtkm::cont::ArrayRangeCompute(array, maskArray);
|
||||||
|
VerifyRangeScalar(array, scalarRange, maskArray, false);
|
||||||
|
|
||||||
|
vtkm::Range vectorRange;
|
||||||
|
std::cout << "\tchecking vector range without mask\n";
|
||||||
|
vectorRange = vtkm::cont::ArrayRangeComputeMagnitude(array);
|
||||||
|
VerifyRangeVector(array, vectorRange, emptyMaskArray, false);
|
||||||
|
std::cout << "\tchecking vector range with mask\n";
|
||||||
|
vectorRange = vtkm::cont::ArrayRangeComputeMagnitude(array, maskArray);
|
||||||
|
VerifyRangeVector(array, vectorRange, maskArray, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ArrayHandleType>
|
||||||
|
void CheckRangeFiniteImpl(const ArrayHandleType& array, std::true_type)
|
||||||
|
{
|
||||||
|
auto length = array.GetNumberOfValues();
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::UInt8> emptyMaskArray;
|
||||||
|
|
||||||
|
auto maskArray = FillMaskArray(length);
|
||||||
|
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Range> scalarRange;
|
||||||
|
std::cout << "\tchecking finite scalar range without mask\n";
|
||||||
|
scalarRange = vtkm::cont::ArrayRangeCompute(array, true);
|
||||||
|
VerifyRangeScalar(array, scalarRange, emptyMaskArray, true);
|
||||||
|
std::cout << "\tchecking finite scalar range with mask\n";
|
||||||
|
scalarRange = vtkm::cont::ArrayRangeCompute(array, maskArray, true);
|
||||||
|
VerifyRangeScalar(array, scalarRange, maskArray, true);
|
||||||
|
|
||||||
|
vtkm::Range vectorRange;
|
||||||
|
std::cout << "\tchecking finite vector range without mask\n";
|
||||||
|
vectorRange = vtkm::cont::ArrayRangeComputeMagnitude(array, true);
|
||||||
|
VerifyRangeVector(array, vectorRange, emptyMaskArray, true);
|
||||||
|
std::cout << "\tchecking finite vector range with mask\n";
|
||||||
|
vectorRange = vtkm::cont::ArrayRangeComputeMagnitude(array, maskArray, true);
|
||||||
|
VerifyRangeVector(array, vectorRange, maskArray, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ArrayHandleType>
|
||||||
|
void CheckRangeFiniteImpl(const ArrayHandleType&, std::false_type)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename S>
|
template <typename T, typename S>
|
||||||
void FillArray(vtkm::cont::ArrayHandle<T, S>& array)
|
void CheckRangeFinite(const vtkm::cont::ArrayHandle<T, S>& array)
|
||||||
|
{
|
||||||
|
using ComponentType = typename vtkm::VecTraits<T>::ComponentType;
|
||||||
|
auto tag = std::integral_constant < bool,
|
||||||
|
std::is_same<ComponentType, vtkm::Float32>::value ||
|
||||||
|
std::is_same<ComponentType, vtkm::Float64>::value > {};
|
||||||
|
CheckRangeFiniteImpl(array, tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transform random values in range [0, 1) to the range [From, To).
|
||||||
|
// If the `AddNonFinites` flag is set, some values are transformed to non-finite values.
|
||||||
|
struct TransformRange
|
||||||
|
{
|
||||||
|
vtkm::Float64 From, To;
|
||||||
|
bool AddNonFinites = false;
|
||||||
|
|
||||||
|
VTKM_EXEC vtkm::Float64 operator()(vtkm::Float64 in) const
|
||||||
|
{
|
||||||
|
if (AddNonFinites)
|
||||||
|
{
|
||||||
|
if (in >= 0.3 && in <= 0.33)
|
||||||
|
{
|
||||||
|
return vtkm::NegativeInfinity64();
|
||||||
|
}
|
||||||
|
if (in >= 0.9 && in <= 0.93)
|
||||||
|
{
|
||||||
|
return vtkm::Infinity64();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (in * (this->To - this->From)) + this->From;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename S>
|
||||||
|
void FillArray(vtkm::cont::ArrayHandle<T, S>& array, bool addNonFinites)
|
||||||
{
|
{
|
||||||
using Traits = vtkm::VecTraits<T>;
|
using Traits = vtkm::VecTraits<T>;
|
||||||
vtkm::IdComponent numComponents = Traits::NUM_COMPONENTS;
|
vtkm::IdComponent numComponents = Traits::NUM_COMPONENTS;
|
||||||
|
|
||||||
|
// non-finites only applies to floating point types
|
||||||
|
addNonFinites = addNonFinites &&
|
||||||
|
(std::is_same<typename Traits::ComponentType, vtkm::Float32>::value ||
|
||||||
|
std::is_same<typename Traits::ComponentType, vtkm::Float64>::value);
|
||||||
|
|
||||||
array.AllocateAndFill(ARRAY_SIZE, vtkm::TypeTraits<T>::ZeroInitialization());
|
array.AllocateAndFill(ARRAY_SIZE, vtkm::TypeTraits<T>::ZeroInitialization());
|
||||||
|
|
||||||
for (vtkm::IdComponent component = 0; component < numComponents; ++component)
|
for (vtkm::IdComponent component = 0; component < numComponents; ++component)
|
||||||
{
|
{
|
||||||
vtkm::cont::ArrayHandleRandomUniformReal<vtkm::Float64> randomArray(ARRAY_SIZE);
|
vtkm::cont::ArrayHandleRandomUniformReal<vtkm::Float64> randomArray(ARRAY_SIZE);
|
||||||
auto dest = vtkm::cont::make_ArrayHandleExtractComponent(array, component);
|
auto dest = vtkm::cont::make_ArrayHandleExtractComponent(array, component);
|
||||||
vtkm::cont::ArrayCopyDevice(randomArray, dest);
|
auto transformFunctor = std::numeric_limits<typename Traits::BaseComponentType>::is_signed
|
||||||
|
? TransformRange{ -100.0, 100.0, addNonFinites }
|
||||||
|
: TransformRange{ 0.0, 200.0, addNonFinites };
|
||||||
|
vtkm::cont::ArrayCopyDevice(
|
||||||
|
vtkm::cont::make_ArrayHandleTransform(randomArray, transformFunctor), dest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,8 +287,10 @@ void TestBasicArray()
|
|||||||
{
|
{
|
||||||
std::cout << "Checking basic array" << std::endl;
|
std::cout << "Checking basic array" << std::endl;
|
||||||
vtkm::cont::ArrayHandleBasic<T> array;
|
vtkm::cont::ArrayHandleBasic<T> array;
|
||||||
FillArray(array);
|
FillArray(array, false);
|
||||||
CheckRange(array);
|
CheckRange(array);
|
||||||
|
FillArray(array, true);
|
||||||
|
CheckRangeFinite(array);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -97,8 +298,10 @@ void TestSOAArray(vtkm::TypeTraitsVectorTag)
|
|||||||
{
|
{
|
||||||
std::cout << "Checking SOA array" << std::endl;
|
std::cout << "Checking SOA array" << std::endl;
|
||||||
vtkm::cont::ArrayHandleSOA<T> array;
|
vtkm::cont::ArrayHandleSOA<T> array;
|
||||||
FillArray(array);
|
FillArray(array, false);
|
||||||
CheckRange(array);
|
CheckRange(array);
|
||||||
|
FillArray(array, true);
|
||||||
|
CheckRangeFinite(array);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -112,8 +315,10 @@ void TestStrideArray()
|
|||||||
{
|
{
|
||||||
std::cout << "Checking stride array" << std::endl;
|
std::cout << "Checking stride array" << std::endl;
|
||||||
vtkm::cont::ArrayHandleBasic<T> array;
|
vtkm::cont::ArrayHandleBasic<T> array;
|
||||||
FillArray(array);
|
FillArray(array, false);
|
||||||
CheckRange(vtkm::cont::ArrayHandleStride<T>(array, ARRAY_SIZE / 2, 2, 1));
|
CheckRange(vtkm::cont::ArrayHandleStride<T>(array, ARRAY_SIZE / 2, 2, 1));
|
||||||
|
FillArray(array, true);
|
||||||
|
CheckRangeFinite(vtkm::cont::ArrayHandleStride<T>(array, ARRAY_SIZE / 2, 2, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -122,23 +327,30 @@ void TestCastArray()
|
|||||||
std::cout << "Checking cast array" << std::endl;
|
std::cout << "Checking cast array" << std::endl;
|
||||||
using CastType = typename vtkm::VecTraits<T>::template ReplaceBaseComponentType<vtkm::Float64>;
|
using CastType = typename vtkm::VecTraits<T>::template ReplaceBaseComponentType<vtkm::Float64>;
|
||||||
vtkm::cont::ArrayHandle<T> array;
|
vtkm::cont::ArrayHandle<T> array;
|
||||||
FillArray(array);
|
FillArray(array, false);
|
||||||
CheckRange(vtkm::cont::make_ArrayHandleCast<CastType>(array));
|
CheckRange(vtkm::cont::make_ArrayHandleCast<CastType>(array));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
auto FillCartesianProductArray(bool addNonFinites)
|
||||||
|
{
|
||||||
|
vtkm::cont::ArrayHandleBasic<T> array0;
|
||||||
|
FillArray(array0, addNonFinites);
|
||||||
|
vtkm::cont::ArrayHandleBasic<T> array1;
|
||||||
|
FillArray(array1, addNonFinites);
|
||||||
|
vtkm::cont::ArrayHandleBasic<T> array2;
|
||||||
|
FillArray(array2, addNonFinites);
|
||||||
|
return vtkm::cont::make_ArrayHandleCartesianProduct(array0, array1, array2);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void TestCartesianProduct(vtkm::TypeTraitsScalarTag)
|
void TestCartesianProduct(vtkm::TypeTraitsScalarTag)
|
||||||
{
|
{
|
||||||
std::cout << "Checking Cartesian product" << std::endl;
|
std::cout << "Checking Cartesian product" << std::endl;
|
||||||
|
auto array = FillCartesianProductArray<T>(false);
|
||||||
vtkm::cont::ArrayHandleBasic<T> array0;
|
CheckRange(array);
|
||||||
FillArray(array0);
|
array = FillCartesianProductArray<T>(true);
|
||||||
vtkm::cont::ArrayHandleBasic<T> array1;
|
CheckRangeFinite(array);
|
||||||
FillArray(array1);
|
|
||||||
vtkm::cont::ArrayHandleBasic<T> array2;
|
|
||||||
FillArray(array2);
|
|
||||||
|
|
||||||
CheckRange(vtkm::cont::make_ArrayHandleCartesianProduct(array0, array1, array2));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -147,19 +359,27 @@ void TestCartesianProduct(vtkm::TypeTraitsVectorTag)
|
|||||||
// Skip test.
|
// Skip test.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
auto FillCompositeVectorArray(bool addNonFinites)
|
||||||
|
{
|
||||||
|
vtkm::cont::ArrayHandleBasic<T> array0;
|
||||||
|
FillArray(array0, addNonFinites);
|
||||||
|
vtkm::cont::ArrayHandleBasic<T> array1;
|
||||||
|
FillArray(array1, addNonFinites);
|
||||||
|
vtkm::cont::ArrayHandleBasic<T> array2;
|
||||||
|
FillArray(array2, addNonFinites);
|
||||||
|
return vtkm::cont::make_ArrayHandleCompositeVector(array0, array1, array2);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void TestComposite(vtkm::TypeTraitsScalarTag)
|
void TestComposite(vtkm::TypeTraitsScalarTag)
|
||||||
{
|
{
|
||||||
std::cout << "Checking composite vector array" << std::endl;
|
std::cout << "Checking composite vector array" << std::endl;
|
||||||
|
|
||||||
vtkm::cont::ArrayHandleBasic<T> array0;
|
auto array = FillCompositeVectorArray<T>(false);
|
||||||
FillArray(array0);
|
CheckRange(array);
|
||||||
vtkm::cont::ArrayHandleBasic<T> array1;
|
array = FillCompositeVectorArray<T>(true);
|
||||||
FillArray(array1);
|
CheckRangeFinite(array);
|
||||||
vtkm::cont::ArrayHandleBasic<T> array2;
|
|
||||||
FillArray(array2);
|
|
||||||
|
|
||||||
CheckRange(vtkm::cont::make_ArrayHandleCompositeVector(array0, array1, array2));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -174,8 +394,10 @@ void TestGroup(vtkm::TypeTraitsScalarTag)
|
|||||||
std::cout << "Checking group vec array" << std::endl;
|
std::cout << "Checking group vec array" << std::endl;
|
||||||
|
|
||||||
vtkm::cont::ArrayHandleBasic<T> array;
|
vtkm::cont::ArrayHandleBasic<T> array;
|
||||||
FillArray(array);
|
FillArray(array, false);
|
||||||
CheckRange(vtkm::cont::make_ArrayHandleGroupVec<2>(array));
|
CheckRange(vtkm::cont::make_ArrayHandleGroupVec<2>(array));
|
||||||
|
FillArray(array, true);
|
||||||
|
CheckRangeFinite(vtkm::cont::make_ArrayHandleGroupVec<2>(array));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -190,8 +412,10 @@ void TestView()
|
|||||||
std::cout << "Checking view array" << std::endl;
|
std::cout << "Checking view array" << std::endl;
|
||||||
|
|
||||||
vtkm::cont::ArrayHandleBasic<T> array;
|
vtkm::cont::ArrayHandleBasic<T> array;
|
||||||
FillArray(array);
|
FillArray(array, false);
|
||||||
CheckRange(vtkm::cont::make_ArrayHandleView(array, 2, ARRAY_SIZE - 5));
|
CheckRange(vtkm::cont::make_ArrayHandleView(array, 2, ARRAY_SIZE - 5));
|
||||||
|
FillArray(array, true);
|
||||||
|
CheckRangeFinite(vtkm::cont::make_ArrayHandleView(array, 2, ARRAY_SIZE - 5));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -234,8 +458,10 @@ void TestXGCCoordinates()
|
|||||||
{
|
{
|
||||||
std::cout << "Checking XGC coordinates array" << std::endl;
|
std::cout << "Checking XGC coordinates array" << std::endl;
|
||||||
vtkm::cont::ArrayHandle<vtkm::FloatDefault> array;
|
vtkm::cont::ArrayHandle<vtkm::FloatDefault> array;
|
||||||
FillArray(array);
|
FillArray(array, false);
|
||||||
CheckRange(vtkm::cont::make_ArrayHandleXGCCoordinates(array, 4, true));
|
CheckRange(vtkm::cont::make_ArrayHandleXGCCoordinates(array, 4, true));
|
||||||
|
FillArray(array, true);
|
||||||
|
CheckRangeFinite(vtkm::cont::make_ArrayHandleXGCCoordinates(array, 4, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DoTestFunctor
|
struct DoTestFunctor
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <vtkm/cont/ArrayRangeCompute.h>
|
|
||||||
#include <vtkm/cont/CellSetSingleType.h>
|
#include <vtkm/cont/CellSetSingleType.h>
|
||||||
#include <vtkm/cont/DataSet.h>
|
#include <vtkm/cont/DataSet.h>
|
||||||
#include <vtkm/cont/DataSetBuilderExplicit.h>
|
#include <vtkm/cont/DataSetBuilderExplicit.h>
|
||||||
|
@ -73,8 +73,6 @@
|
|||||||
#include <vtkm/cont/ArrayHandleIndex.h>
|
#include <vtkm/cont/ArrayHandleIndex.h>
|
||||||
#include <vtkm/cont/ArrayHandlePermutation.h>
|
#include <vtkm/cont/ArrayHandlePermutation.h>
|
||||||
#include <vtkm/cont/ArrayPortalToIterators.h>
|
#include <vtkm/cont/ArrayPortalToIterators.h>
|
||||||
#include <vtkm/cont/ArrayRangeCompute.h>
|
|
||||||
#include <vtkm/cont/ArrayRangeComputeTemplate.h>
|
|
||||||
#include <vtkm/cont/ConvertNumComponentsToOffsets.h>
|
#include <vtkm/cont/ConvertNumComponentsToOffsets.h>
|
||||||
#include <vtkm/cont/EnvironmentTracker.h>
|
#include <vtkm/cont/EnvironmentTracker.h>
|
||||||
#include <vtkm/cont/Timer.h>
|
#include <vtkm/cont/Timer.h>
|
||||||
@ -576,9 +574,7 @@ template <typename FieldType>
|
|||||||
inline void ContourTreeMesh<FieldType>::ComputeMaxNeighbors()
|
inline void ContourTreeMesh<FieldType>::ComputeMaxNeighbors()
|
||||||
{
|
{
|
||||||
auto neighborCounts = make_ArrayHandleOffsetsToNumComponents(this->NeighborOffsets);
|
auto neighborCounts = make_ArrayHandleOffsetsToNumComponents(this->NeighborOffsets);
|
||||||
vtkm::cont::ArrayHandle<vtkm::Range> rangeArray =
|
this->MaxNeighbors = vtkm::cont::Algorithm::Reduce(neighborCounts, 0, vtkm::Maximum{});
|
||||||
vtkm::cont::ArrayRangeComputeTemplate(neighborCounts);
|
|
||||||
this->MaxNeighbors = static_cast<vtkm::Id>(rangeArray.ReadPortal().Get(0).Max);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define the behavior for the execution object generate by the PrepareForExecution function
|
// Define the behavior for the execution object generate by the PrepareForExecution function
|
||||||
|
Loading…
Reference in New Issue
Block a user