mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-10-08 03:18:58 +00:00
Add ArrayCopy specialization for Counting and Permutation array
This required adding another source file.
This commit is contained in:
parent
f3c82bfea7
commit
392d781359
51
vtkm/cont/ArrayCopy.cxx
Normal file
51
vtkm/cont/ArrayCopy.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/ArrayCopy.h>
|
||||
#include <vtkm/cont/ArrayCopyDevice.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
void ArrayCopyConcreteSrc<vtkm::cont::StorageTagCounting>::CopyCountingFloat(
|
||||
vtkm::FloatDefault start,
|
||||
vtkm::FloatDefault step,
|
||||
vtkm::Id size,
|
||||
const vtkm::cont::UnknownArrayHandle& result) const
|
||||
{
|
||||
if (result.IsBaseComponentType<vtkm::FloatDefault>())
|
||||
{
|
||||
auto outArray = result.ExtractComponent<vtkm::FloatDefault>(0);
|
||||
vtkm::cont::ArrayCopyDevice(vtkm::cont::make_ArrayHandleCounting(start, step, size), outArray);
|
||||
}
|
||||
else
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::FloatDefault> outArray;
|
||||
outArray.Allocate(size);
|
||||
CopyCountingFloat(start, step, size, outArray);
|
||||
result.DeepCopyFrom(outArray);
|
||||
}
|
||||
}
|
||||
|
||||
vtkm::cont::ArrayHandle<Id> ArrayCopyConcreteSrc<vtkm::cont::StorageTagCounting>::CopyCountingId(
|
||||
const vtkm::cont::ArrayHandleCounting<vtkm::Id>& source) const
|
||||
{
|
||||
vtkm::cont::ArrayHandle<Id> destination;
|
||||
vtkm::cont::ArrayCopyDevice(source, destination);
|
||||
return destination;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} // namespace vtkm::cont::detail
|
@ -12,11 +12,14 @@
|
||||
|
||||
#include <vtkm/cont/ArrayHandleConcatenate.h>
|
||||
#include <vtkm/cont/ArrayHandleConstant.h>
|
||||
#include <vtkm/cont/ArrayHandleCounting.h>
|
||||
#include <vtkm/cont/ArrayHandleIndex.h>
|
||||
#include <vtkm/cont/ArrayHandlePermutation.h>
|
||||
#include <vtkm/cont/ArrayHandleView.h>
|
||||
#include <vtkm/cont/UnknownArrayHandle.h>
|
||||
|
||||
#include <vtkm/cont/vtkm_cont_export.h>
|
||||
|
||||
#include <vtkm/cont/internal/MapArrayPermutation.h>
|
||||
|
||||
#include <vtkm/StaticAssert.h>
|
||||
@ -258,6 +261,48 @@ struct ArrayCopyConcreteSrc<vtkm::cont::StorageTagIndex>
|
||||
}
|
||||
};
|
||||
|
||||
// Special case for ArrayHandleCounting to be efficient.
|
||||
template <>
|
||||
struct VTKM_CONT_EXPORT ArrayCopyConcreteSrc<vtkm::cont::StorageTagCounting>
|
||||
{
|
||||
template <typename T1, typename T2, typename S2>
|
||||
void operator()(const vtkm::cont::ArrayHandle<T1, vtkm::cont::StorageTagCounting>& source,
|
||||
vtkm::cont::ArrayHandle<T2, S2>& destination) const
|
||||
{
|
||||
vtkm::cont::ArrayHandleCounting<T1> countingSource = source;
|
||||
T1 start = countingSource.GetStart();
|
||||
T1 step = countingSource.GetStep();
|
||||
vtkm::Id size = countingSource.GetNumberOfValues();
|
||||
destination.Allocate(size);
|
||||
vtkm::cont::UnknownArrayHandle unknownDest = destination;
|
||||
|
||||
using VTraits1 = vtkm::VecTraits<T1>;
|
||||
using VTraits2 = vtkm::VecTraits<T2>;
|
||||
for (vtkm::IdComponent comp = 0; comp < VTraits1::GetNumberOfComponents(start); ++comp)
|
||||
{
|
||||
this->CopyCountingFloat(
|
||||
static_cast<vtkm::FloatDefault>(VTraits1::GetComponent(start, comp)),
|
||||
static_cast<vtkm::FloatDefault>(VTraits1::GetComponent(step, comp)),
|
||||
size,
|
||||
unknownDest.ExtractComponent<typename VTraits2::BaseComponentType>(comp));
|
||||
}
|
||||
}
|
||||
|
||||
void operator()(const vtkm::cont::ArrayHandle<vtkm::Id, vtkm::cont::StorageTagCounting>& source,
|
||||
vtkm::cont::ArrayHandle<vtkm::Id>& destination) const
|
||||
{
|
||||
destination = this->CopyCountingId(source);
|
||||
}
|
||||
|
||||
private:
|
||||
void CopyCountingFloat(vtkm::FloatDefault start,
|
||||
vtkm::FloatDefault step,
|
||||
vtkm::Id size,
|
||||
const vtkm::cont::UnknownArrayHandle& result) const;
|
||||
vtkm::cont::ArrayHandle<Id> CopyCountingId(
|
||||
const vtkm::cont::ArrayHandleCounting<vtkm::Id>& source) const;
|
||||
};
|
||||
|
||||
// Special case for ArrayHandleConcatenate to be efficient
|
||||
template <typename ST1, typename ST2>
|
||||
struct ArrayCopyConcreteSrc<vtkm::cont::StorageTagConcatenate<ST1, ST2>>
|
||||
@ -280,10 +325,10 @@ struct ArrayCopyConcreteSrc<vtkm::cont::StorageTagConcatenate<ST1, ST2>>
|
||||
};
|
||||
|
||||
// Special case for ArrayHandlePermutation to be efficient
|
||||
template <typename S>
|
||||
struct ArrayCopyConcreteSrc<vtkm::cont::StorageTagPermutation<vtkm::cont::StorageTagBasic, S>>
|
||||
template <typename SIndex, typename SValue>
|
||||
struct ArrayCopyConcreteSrc<vtkm::cont::StorageTagPermutation<SIndex, SValue>>
|
||||
{
|
||||
using SourceStorageTag = vtkm::cont::StorageTagPermutation<vtkm::cont::StorageTagBasic, S>;
|
||||
using SourceStorageTag = vtkm::cont::StorageTagPermutation<SIndex, SValue>;
|
||||
template <typename T1, typename T2, typename S2>
|
||||
void operator()(const vtkm::cont::ArrayHandle<T1, SourceStorageTag>& source,
|
||||
vtkm::cont::ArrayHandle<T2, S2>& destination) const
|
||||
|
@ -138,6 +138,10 @@ public:
|
||||
internal::ArrayPortalCounting<CountingValueType>(start, step, length)))
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_CONT CountingValueType GetStart() const { return this->ReadPortal().GetStart(); }
|
||||
|
||||
VTKM_CONT CountingValueType GetStep() const { return this->ReadPortal().GetStep(); }
|
||||
};
|
||||
|
||||
/// A convenience function for creating an ArrayHandleCounting. It takes the
|
||||
|
@ -183,6 +183,7 @@ set(sources
|
||||
# This list of sources has code that uses devices and so might need to be
|
||||
# compiled with a device-specific compiler (like CUDA).
|
||||
set(device_sources
|
||||
ArrayCopy.cxx
|
||||
ArrayGetValues.cxx
|
||||
ArrayRangeCompute.cxx
|
||||
CellLocatorBoundingIntervalHierarchy.cxx
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include <vtkm/cont/internal/CastInvalidValue.h>
|
||||
#include <vtkm/cont/internal/MapArrayPermutation.h>
|
||||
|
||||
#include <vtkm/cont/ErrorBadType.h>
|
||||
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
|
||||
|
||||
@ -48,9 +50,9 @@ struct MapPermutationWorklet : vtkm::worklet::WorkletMapField
|
||||
|
||||
struct DoMapFieldPermutation
|
||||
{
|
||||
template <typename InputArrayType>
|
||||
template <typename InputArrayType, typename PermutationArrayType>
|
||||
void operator()(const InputArrayType& input,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id>& permutation,
|
||||
const PermutationArrayType& permutation,
|
||||
vtkm::cont::UnknownArrayHandle& output,
|
||||
vtkm::Float64 invalidValue) const
|
||||
{
|
||||
@ -77,13 +79,19 @@ namespace internal
|
||||
|
||||
vtkm::cont::UnknownArrayHandle MapArrayPermutation(
|
||||
const vtkm::cont::UnknownArrayHandle& inputArray,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id>& permutation,
|
||||
const vtkm::cont::UnknownArrayHandle& permutation,
|
||||
vtkm::Float64 invalidValue)
|
||||
{
|
||||
if (!permutation.IsBaseComponentType<vtkm::Id>())
|
||||
{
|
||||
throw vtkm::cont::ErrorBadType("Permutation array input to MapArrayPermutation must have "
|
||||
"values of vtkm::Id. Reported type is " +
|
||||
permutation.GetBaseComponentTypeName());
|
||||
}
|
||||
vtkm::cont::UnknownArrayHandle outputArray = inputArray.NewInstanceBasic();
|
||||
outputArray.Allocate(permutation.GetNumberOfValues());
|
||||
inputArray.CastAndCallWithExtractedArray(
|
||||
DoMapFieldPermutation{}, permutation, outputArray, invalidValue);
|
||||
DoMapFieldPermutation{}, permutation.ExtractComponent<vtkm::Id>(0), outputArray, invalidValue);
|
||||
return outputArray;
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ namespace internal
|
||||
///
|
||||
VTKM_CONT_EXPORT vtkm::cont::UnknownArrayHandle MapArrayPermutation(
|
||||
const vtkm::cont::UnknownArrayHandle& inputArray,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id>& permutation,
|
||||
const vtkm::cont::UnknownArrayHandle& permutation,
|
||||
vtkm::Float64 invalidValue = vtkm::Nan64());
|
||||
|
||||
/// Used to map a permutation array.
|
||||
|
@ -9,12 +9,14 @@
|
||||
//============================================================================
|
||||
|
||||
#include <vtkm/cont/ArrayCopy.h>
|
||||
#include <vtkm/cont/ArrayCopyDevice.h>
|
||||
#include <vtkm/cont/ArrayHandleConstant.h>
|
||||
#include <vtkm/cont/ArrayHandleIndex.h>
|
||||
#include <vtkm/cont/UncertainArrayHandle.h>
|
||||
#include <vtkm/cont/UnknownArrayHandle.h>
|
||||
|
||||
#include <vtkm/TypeTraits.h>
|
||||
#include <vtkm/VecTraits.h>
|
||||
|
||||
#include <vtkm/cont/testing/Testing.h>
|
||||
|
||||
@ -23,13 +25,43 @@ namespace
|
||||
|
||||
static constexpr vtkm::Id ARRAY_SIZE = 10;
|
||||
|
||||
template <typename RefArrayType, typename TestArrayType>
|
||||
void TestValues(const RefArrayType& refArray, const TestArrayType& testArray)
|
||||
vtkm::cont::UnknownArrayHandle MakeComparable(const vtkm::cont::UnknownArrayHandle& array,
|
||||
std::false_type)
|
||||
{
|
||||
return array;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
vtkm::cont::UnknownArrayHandle MakeComparable(const vtkm::cont::ArrayHandle<T>& array,
|
||||
std::true_type)
|
||||
{
|
||||
return array;
|
||||
}
|
||||
|
||||
template <typename ArrayType>
|
||||
vtkm::cont::UnknownArrayHandle MakeComparable(const ArrayType& array, std::true_type)
|
||||
{
|
||||
vtkm::cont::ArrayHandle<typename ArrayType::ValueType> simpleArray;
|
||||
vtkm::cont::ArrayCopyDevice(array, simpleArray);
|
||||
return simpleArray;
|
||||
}
|
||||
|
||||
void TestValuesImpl(const vtkm::cont::UnknownArrayHandle& refArray,
|
||||
const vtkm::cont::UnknownArrayHandle& testArray)
|
||||
{
|
||||
auto result = test_equal_ArrayHandles(refArray, testArray);
|
||||
VTKM_TEST_ASSERT(result, result.GetMergedMessage());
|
||||
}
|
||||
|
||||
template <typename RefArrayType, typename TestArrayType>
|
||||
void TestValues(const RefArrayType& refArray, const TestArrayType& testArray)
|
||||
{
|
||||
TestValuesImpl(
|
||||
MakeComparable(refArray, typename vtkm::cont::internal::ArrayHandleCheck<RefArrayType>::type{}),
|
||||
MakeComparable(testArray,
|
||||
typename vtkm::cont::internal::ArrayHandleCheck<TestArrayType>::type{}));
|
||||
}
|
||||
|
||||
template <typename ValueType>
|
||||
vtkm::cont::ArrayHandle<ValueType> MakeInputArray()
|
||||
{
|
||||
@ -44,18 +76,20 @@ void TryCopy()
|
||||
{
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info,
|
||||
"Trying type: " << vtkm::testing::TypeName<ValueType>::Name());
|
||||
using VTraits = vtkm::VecTraits<ValueType>;
|
||||
|
||||
{
|
||||
std::cout << "implicit -> basic" << std::endl;
|
||||
vtkm::cont::ArrayHandleIndex input(ARRAY_SIZE);
|
||||
vtkm::cont::ArrayHandle<ValueType> output;
|
||||
vtkm::cont::ArrayHandle<typename VTraits::BaseComponentType> output;
|
||||
vtkm::cont::ArrayCopy(input, output);
|
||||
TestValues(input, output);
|
||||
}
|
||||
|
||||
{
|
||||
std::cout << "basic -> basic" << std::endl;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> input = MakeInputArray<vtkm::Id>();
|
||||
using SourceType = typename VTraits::template ReplaceComponentType<vtkm::Id>;
|
||||
vtkm::cont::ArrayHandle<SourceType> input = MakeInputArray<SourceType>();
|
||||
vtkm::cont::ArrayHandle<ValueType> output;
|
||||
vtkm::cont::ArrayCopy(input, output);
|
||||
TestValues(input, output);
|
||||
@ -90,30 +124,53 @@ void TryCopy()
|
||||
TestValues(input, output);
|
||||
}
|
||||
|
||||
using TypeList = vtkm::ListAppend<vtkm::TypeListField, vtkm::List<ValueType, vtkm::UInt8>>;
|
||||
using StorageList = VTKM_DEFAULT_STORAGE_LIST;
|
||||
using UnknownArray = vtkm::cont::UnknownArrayHandle;
|
||||
using UncertainArray = vtkm::cont::UncertainArrayHandle<TypeList, StorageList>;
|
||||
|
||||
{
|
||||
std::cout << "unknown -> unknown" << std::endl;
|
||||
UnknownArray input = MakeInputArray<ValueType>();
|
||||
UnknownArray output;
|
||||
vtkm::cont::ArrayCopy(input, output);
|
||||
TestValues(input, output);
|
||||
}
|
||||
|
||||
{
|
||||
std::cout << "uncertain -> basic (same type)" << std::endl;
|
||||
UncertainArray input = MakeInputArray<ValueType>();
|
||||
std::cout << "constant -> basic" << std::endl;
|
||||
vtkm::cont::ArrayHandleConstant<ValueType> input(TestValue(2, ValueType{}), ARRAY_SIZE);
|
||||
vtkm::cont::ArrayHandle<ValueType> output;
|
||||
vtkm::cont::ArrayCopy(input, output);
|
||||
TestValues(input, output);
|
||||
}
|
||||
|
||||
{
|
||||
std::cout << "uncertain -> basic (different type)" << std::endl;
|
||||
UncertainArray input = MakeInputArray<vtkm::UInt8>();
|
||||
std::cout << "counting -> basic" << std::endl;
|
||||
vtkm::cont::ArrayHandleCounting<ValueType> input(ValueType(-4), ValueType(3), ARRAY_SIZE);
|
||||
vtkm::cont::ArrayHandle<ValueType> output;
|
||||
vtkm::cont::ArrayCopy(input, output);
|
||||
TestValues(input, output);
|
||||
}
|
||||
|
||||
{
|
||||
std::cout << "permutation -> basic" << std::endl;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> indices;
|
||||
vtkm::cont::ArrayCopy(vtkm::cont::make_ArrayHandleCounting<vtkm::Id>(0, 2, ARRAY_SIZE / 2),
|
||||
indices);
|
||||
auto input = vtkm::cont::make_ArrayHandlePermutation(indices, MakeInputArray<ValueType>());
|
||||
vtkm::cont::ArrayHandle<ValueType> output;
|
||||
vtkm::cont::ArrayCopy(input, output);
|
||||
TestValues(input, output);
|
||||
}
|
||||
|
||||
{
|
||||
std::cout << "unknown -> unknown" << std::endl;
|
||||
vtkm::cont::UnknownArrayHandle input = MakeInputArray<ValueType>();
|
||||
vtkm::cont::UnknownArrayHandle output;
|
||||
vtkm::cont::ArrayCopy(input, output);
|
||||
TestValues(input, output);
|
||||
}
|
||||
|
||||
{
|
||||
std::cout << "unknown -> basic (same type)" << std::endl;
|
||||
vtkm::cont::UnknownArrayHandle input = MakeInputArray<ValueType>();
|
||||
vtkm::cont::ArrayHandle<ValueType> output;
|
||||
vtkm::cont::ArrayCopy(input, output);
|
||||
TestValues(input, output);
|
||||
}
|
||||
|
||||
{
|
||||
std::cout << "unknown -> basic (different type)" << std::endl;
|
||||
using SourceType = typename VTraits::template ReplaceComponentType<vtkm::UInt8>;
|
||||
vtkm::cont::UnknownArrayHandle input = MakeInputArray<SourceType>();
|
||||
vtkm::cont::ArrayHandle<ValueType> output;
|
||||
vtkm::cont::ArrayCopy(input, output);
|
||||
TestValues(input, output);
|
||||
@ -139,7 +196,8 @@ void TryCopy()
|
||||
|
||||
{
|
||||
std::cout << "unknown.DeepCopyFrom(different type)" << std::endl;
|
||||
vtkm::cont::ArrayHandle<vtkm::UInt8> input = MakeInputArray<vtkm::UInt8>();
|
||||
using SourceType = typename VTraits::template ReplaceComponentType<vtkm::UInt8>;
|
||||
vtkm::cont::ArrayHandle<SourceType> input = MakeInputArray<SourceType>();
|
||||
vtkm::cont::ArrayHandle<ValueType> outputArray;
|
||||
vtkm::cont::UnknownArrayHandle(outputArray).DeepCopyFrom(input);
|
||||
TestValues(input, outputArray);
|
||||
@ -166,7 +224,8 @@ void TryCopy()
|
||||
|
||||
{
|
||||
std::cout << "unknown.CopyShallowIfPossible(different type)" << std::endl;
|
||||
vtkm::cont::ArrayHandle<vtkm::UInt8> input = MakeInputArray<vtkm::UInt8>();
|
||||
using SourceType = typename VTraits::template ReplaceComponentType<vtkm::UInt8>;
|
||||
vtkm::cont::ArrayHandle<SourceType> input = MakeInputArray<SourceType>();
|
||||
vtkm::cont::ArrayHandle<ValueType> outputArray;
|
||||
vtkm::cont::UnknownArrayHandle(outputArray).CopyShallowIfPossible(input);
|
||||
TestValues(input, outputArray);
|
||||
@ -203,6 +262,8 @@ void TestArrayCopy()
|
||||
TryCopy<vtkm::Id>();
|
||||
TryCopy<vtkm::IdComponent>();
|
||||
TryCopy<vtkm::Float32>();
|
||||
TryCopy<vtkm::Vec3f>();
|
||||
TryCopy<vtkm::Vec4i_16>();
|
||||
TryArrayCopyShallowIfPossible();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user