Merge topic 'unknownarray-copy-methods'
d1160638b Add copy methods to `UnknownArrayHandle` Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !2590
This commit is contained in:
commit
d2c296aa00
24
docs/changelog/unknownarray-copy-methods.md
Normal file
24
docs/changelog/unknownarray-copy-methods.md
Normal file
@ -0,0 +1,24 @@
|
||||
# Added copy methods to `UnknownArrayHandle`
|
||||
|
||||
`vtkm::cont::UnknownArrayHandle` now provides a set of method that allows
|
||||
you to copy data from one `UnknownArrayHandle` to another. The first
|
||||
method, `DeepCopyFrom`, takes a source `UnknownArrayHandle` and deep copies
|
||||
the data to the called one. If the `UnknownArrayHandle` already points to a
|
||||
real `ArrayHandle`, the data is copied into that `ArrayHandle`. If the
|
||||
`UnknownArrayHandle` does not point to an existing `ArrayHandle`, then a
|
||||
new `ArrayHandleBasic` with the same value type as the source is created
|
||||
and copied into.
|
||||
|
||||
The second method, `CopyShallowIfPossibleFrom` behaves similarly to
|
||||
`DeepCopyFrom` except that it will perform a shallow copy if possible. That
|
||||
is, if the target `UnknownArrayHandle` points to an `ArrayHandle` of the
|
||||
same type as the source `UnknownArrayHandle`, then a shallow copy occurs
|
||||
and the underlying `ArrayHandle` will point to the source. If the types
|
||||
differ, then a deep copy is performed. If the target `UnknownArrayHandle`
|
||||
does not point to an `ArrayHandle`, then the behavior is the same as the
|
||||
`=` operator.
|
||||
|
||||
One of the intentions of these new methods is to allow you to copy arrays
|
||||
without using a device compiler (e.g. `nvcc`). Calling `ArrayCopy` requires
|
||||
you to include the `ArrayCopy.h` header file, and that in turn requires
|
||||
device adapter algorithms. These methods insulate you from these.
|
@ -12,6 +12,8 @@
|
||||
#include <vtkm/cont/DeviceAdapterList.h>
|
||||
#include <vtkm/cont/Invoker.h>
|
||||
|
||||
#include <vtkm/cont/internal/ArrayCopyUnknown.h>
|
||||
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
|
||||
namespace
|
||||
@ -163,5 +165,22 @@ void ArrayCopy(const vtkm::cont::UnknownArrayHandle& source,
|
||||
DoUnknownArrayCopy(source, destination);
|
||||
}
|
||||
|
||||
namespace internal
|
||||
{
|
||||
|
||||
void ArrayCopyUnknown(const vtkm::cont::UnknownArrayHandle& source,
|
||||
vtkm::cont::UnknownArrayHandle& destination)
|
||||
{
|
||||
vtkm::cont::ArrayCopy(source, destination);
|
||||
}
|
||||
|
||||
void ArrayCopyUnknown(const vtkm::cont::UnknownArrayHandle& source,
|
||||
const vtkm::cont::UnknownArrayHandle& destination)
|
||||
{
|
||||
vtkm::cont::ArrayCopy(source, destination);
|
||||
}
|
||||
|
||||
} // namespace vtkm::cont::internal
|
||||
|
||||
} // namespace vtkm::cont
|
||||
} // namespace vtkm
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
|
||||
#include <vtkm/cont/UncertainArrayHandle.h>
|
||||
|
||||
#include <vtkm/cont/internal/ArrayCopyUnknown.h>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace
|
||||
@ -271,6 +273,48 @@ VTKM_CONT void UnknownArrayHandle::Allocate(vtkm::Id numValues, vtkm::CopyFlag p
|
||||
this->Allocate(numValues, preserve, token);
|
||||
}
|
||||
|
||||
VTKM_CONT void UnknownArrayHandle::DeepCopyFrom(const vtkm::cont::UnknownArrayHandle& source)
|
||||
{
|
||||
vtkm::cont::internal::ArrayCopyUnknown(source, *this);
|
||||
}
|
||||
|
||||
VTKM_CONT void UnknownArrayHandle::DeepCopyFrom(const vtkm::cont::UnknownArrayHandle& source) const
|
||||
{
|
||||
vtkm::cont::internal::ArrayCopyUnknown(source, *this);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void UnknownArrayHandle::CopyShallowIfPossible(const vtkm::cont::UnknownArrayHandle& source)
|
||||
{
|
||||
if (!this->IsValid())
|
||||
{
|
||||
*this = source;
|
||||
}
|
||||
|
||||
const_cast<const UnknownArrayHandle*>(this)->CopyShallowIfPossible(source);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void UnknownArrayHandle::CopyShallowIfPossible(const vtkm::cont::UnknownArrayHandle& source) const
|
||||
{
|
||||
if (!this->IsValid())
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue(
|
||||
"Attempty to copy to a constant UnknownArrayHandle with no valid array.");
|
||||
}
|
||||
|
||||
if (source.IsValueTypeImpl(this->Container->ValueType) &&
|
||||
source.IsStorageTypeImpl(this->Container->StorageType))
|
||||
{
|
||||
this->Container->ShallowCopy(source.Container->ArrayHandlePointer,
|
||||
this->Container->ArrayHandlePointer);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->DeepCopyFrom(source);
|
||||
}
|
||||
}
|
||||
|
||||
VTKM_CONT void UnknownArrayHandle::ReleaseResourcesExecution() const
|
||||
{
|
||||
if (this->Container)
|
||||
|
@ -104,6 +104,15 @@ static void UnknownAHAllocate(void* mem,
|
||||
arrayHandle->Allocate(numValues, preserve, token);
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
static void UnknownAHShallowCopy(const void* sourceMem, void* destinationMem)
|
||||
{
|
||||
using AH = vtkm::cont::ArrayHandle<T, S>;
|
||||
const AH* source = reinterpret_cast<const AH*>(sourceMem);
|
||||
AH* destination = reinterpret_cast<AH*>(destinationMem);
|
||||
*destination = *source;
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
static std::vector<vtkm::cont::internal::Buffer>
|
||||
UnknownAHExtractComponent(void* mem, vtkm::IdComponent componentIndex, vtkm::CopyFlag allowCopy)
|
||||
@ -212,6 +221,9 @@ struct VTKM_CONT_EXPORT UnknownAHContainer
|
||||
using AllocateType = void(void*, vtkm::Id, vtkm::CopyFlag, vtkm::cont::Token&);
|
||||
AllocateType* Allocate;
|
||||
|
||||
using ShallowCopyType = void(const void*, void*);
|
||||
ShallowCopyType* ShallowCopy;
|
||||
|
||||
using ExtractComponentType = std::vector<vtkm::cont::internal::Buffer>(void*,
|
||||
vtkm::IdComponent,
|
||||
vtkm::CopyFlag);
|
||||
@ -336,6 +348,7 @@ inline UnknownAHContainer::UnknownAHContainer(const vtkm::cont::ArrayHandle<T, S
|
||||
, NumberOfComponents(detail::UnknownAHNumberOfComponents<T>)
|
||||
, NumberOfComponentsFlat(detail::UnknownAHNumberOfComponentsFlat<T>)
|
||||
, Allocate(detail::UnknownAHAllocate<T, S>)
|
||||
, ShallowCopy(detail::UnknownAHShallowCopy<T, S>)
|
||||
, ExtractComponent(detail::UnknownAHExtractComponent<T, S>)
|
||||
, ReleaseResources(detail::UnknownAHReleaseResources<T, S>)
|
||||
, ReleaseResourcesExecution(detail::UnknownAHReleaseResourcesExecution<T, S>)
|
||||
@ -662,6 +675,54 @@ public:
|
||||
result = this->AsArrayHandle<MultiplexerType>();
|
||||
}
|
||||
|
||||
/// \brief Deep copies data from another `UnknownArrayHandle`.
|
||||
///
|
||||
/// This method takes an `UnknownArrayHandle` and deep copies data from it.
|
||||
///
|
||||
/// If this object does not point to an existing `ArrayHandle`, a new `ArrayHandleBasic`
|
||||
/// with the same value type of the `source` is created.
|
||||
///
|
||||
void DeepCopyFrom(const vtkm::cont::UnknownArrayHandle& source);
|
||||
|
||||
/// \brief Deep copies data from another `UnknownArrayHandle`.
|
||||
///
|
||||
/// This method takes an `UnknownArrayHandle` and deep copies data from it.
|
||||
///
|
||||
/// If this object does not point to an existing `ArrayHandle`, this const version
|
||||
/// of `DeepCopyFrom` throws an exception.
|
||||
///
|
||||
void DeepCopyFrom(const vtkm::cont::UnknownArrayHandle& source) const;
|
||||
|
||||
/// \brief Attempts a shallow copy of an array or a deep copy if that is not possible.
|
||||
///
|
||||
/// This method takes an `UnknownArrayHandle` and attempts to perform a shallow copy.
|
||||
/// This shallow copy occurs if this object points to an `ArrayHandle` of the same type
|
||||
/// or does not point to any `ArrayHandle` at all. If this is not possible, then
|
||||
/// the array is deep copied.
|
||||
///
|
||||
/// This method is roughly equivalent to the `ArrayCopyShallowIfPossible` function
|
||||
/// (defined in `vtkm/cont/ArrayCopy.h`). However, this method can be used without
|
||||
/// having to use a device compiler (whereas `ArrayCopyShallowIfPossible` does require
|
||||
/// a device device compiler).
|
||||
///
|
||||
void CopyShallowIfPossible(const vtkm::cont::UnknownArrayHandle& source);
|
||||
|
||||
/// \brief Attempts a shallow copy of an array or a deep copy if that is not possible.
|
||||
///
|
||||
/// This method takes an `UnknownArrayHandle` and attempts to perform a shallow copy.
|
||||
/// This shallow copy occurs if this object points to an `ArrayHandle` of the same type.
|
||||
/// If the types are incompatible, then the array is deep copied.
|
||||
///
|
||||
/// If this object does not point to an existing `ArrayHandle`, this const version
|
||||
/// of `CopyShallowIfPossible` throws an exception.
|
||||
///
|
||||
/// This method is roughly equivalent to the `ArrayCopyShallowIfPossible` function
|
||||
/// (defined in `vtkm/cont/ArrayCopy.h`). However, this method can be used without
|
||||
/// having to use a device compiler (whereas `ArrayCopyShallowIfPossible` does require
|
||||
/// a device device compiler).
|
||||
///
|
||||
void CopyShallowIfPossible(const vtkm::cont::UnknownArrayHandle& source) const;
|
||||
|
||||
/// \brief Extract a component of the array.
|
||||
///
|
||||
/// This method returns an array that holds the data for a given flat component of the data.
|
||||
|
38
vtkm/cont/internal/ArrayCopyUnknown.h
Normal file
38
vtkm/cont/internal/ArrayCopyUnknown.h
Normal file
@ -0,0 +1,38 @@
|
||||
//============================================================================
|
||||
// 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_ArrayCopyUnknown_h
|
||||
#define vtk_m_cont_internal_ArrayCopyUnknown_h
|
||||
|
||||
#include <vtkm/cont/UnknownArrayHandle.h>
|
||||
|
||||
#include <vtkm/cont/vtkm_cont_export.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
|
||||
/// Same as `ArrayCopy` with `UnknownArrayHandle` except that it can be used without
|
||||
/// using a device compiler.
|
||||
///
|
||||
VTKM_CONT_EXPORT void ArrayCopyUnknown(const vtkm::cont::UnknownArrayHandle& source,
|
||||
vtkm::cont::UnknownArrayHandle& destination);
|
||||
|
||||
VTKM_CONT_EXPORT void ArrayCopyUnknown(const vtkm::cont::UnknownArrayHandle& source,
|
||||
const vtkm::cont::UnknownArrayHandle& destination);
|
||||
|
||||
|
||||
} // namespace vtkm::cont::internal
|
||||
} // namespace vtkm::cont
|
||||
} // namespace vtkm
|
||||
|
||||
#endif //vtk_m_cont_internal_ArrayCopyUnknown_h
|
@ -9,6 +9,7 @@
|
||||
##============================================================================
|
||||
|
||||
set(headers
|
||||
ArrayCopyUnknown.h
|
||||
ArrayHandleDeprecated.h
|
||||
ArrayHandleExecutionManager.h
|
||||
ArrayPortalFromIterators.h
|
||||
|
@ -118,6 +118,64 @@ void TryCopy()
|
||||
vtkm::cont::ArrayCopy(input, output);
|
||||
TestValues(input, output);
|
||||
}
|
||||
|
||||
// Test the copy methods in UnknownArrayHandle. Although this would be appropriate in
|
||||
// UnitTestUnknownArrayHandle, it is easier to test copies here.
|
||||
{
|
||||
std::cout << "unknown.DeepCopyFrom(same type)" << std::endl;
|
||||
vtkm::cont::ArrayHandle<ValueType> input = MakeInputArray<ValueType>();
|
||||
vtkm::cont::ArrayHandle<ValueType> outputArray;
|
||||
vtkm::cont::UnknownArrayHandle(outputArray).DeepCopyFrom(input);
|
||||
// Should be different arrays with same content.
|
||||
VTKM_TEST_ASSERT(input != outputArray);
|
||||
TestValues(input, outputArray);
|
||||
|
||||
vtkm::cont::UnknownArrayHandle outputUnknown;
|
||||
outputUnknown.DeepCopyFrom(input);
|
||||
// Should be different arrays with same content.
|
||||
VTKM_TEST_ASSERT(input != outputUnknown.AsArrayHandle<vtkm::cont::ArrayHandle<ValueType>>());
|
||||
TestValues(input, outputUnknown);
|
||||
}
|
||||
|
||||
{
|
||||
std::cout << "unknown.DeepCopyFrom(different type)" << std::endl;
|
||||
vtkm::cont::ArrayHandle<vtkm::UInt8> input = MakeInputArray<vtkm::UInt8>();
|
||||
vtkm::cont::ArrayHandle<ValueType> outputArray;
|
||||
vtkm::cont::UnknownArrayHandle(outputArray).DeepCopyFrom(input);
|
||||
TestValues(input, outputArray);
|
||||
|
||||
outputArray.ReleaseResources();
|
||||
vtkm::cont::UnknownArrayHandle outputUnknown(outputArray);
|
||||
outputUnknown.DeepCopyFrom(input);
|
||||
TestValues(input, outputUnknown);
|
||||
}
|
||||
|
||||
{
|
||||
std::cout << "unknown.CopyShallowIfPossible(same type)" << std::endl;
|
||||
vtkm::cont::ArrayHandle<ValueType> input = MakeInputArray<ValueType>();
|
||||
vtkm::cont::UnknownArrayHandle outputUnknown;
|
||||
outputUnknown.CopyShallowIfPossible(input);
|
||||
VTKM_TEST_ASSERT(input == outputUnknown.AsArrayHandle<vtkm::cont::ArrayHandle<ValueType>>());
|
||||
|
||||
vtkm::cont::ArrayHandle<ValueType> outputArray;
|
||||
outputUnknown = outputArray;
|
||||
outputUnknown.CopyShallowIfPossible(input);
|
||||
outputUnknown.AsArrayHandle(outputArray);
|
||||
VTKM_TEST_ASSERT(input == outputArray);
|
||||
}
|
||||
|
||||
{
|
||||
std::cout << "unknown.CopyShallowIfPossible(different type)" << std::endl;
|
||||
vtkm::cont::ArrayHandle<vtkm::UInt8> input = MakeInputArray<vtkm::UInt8>();
|
||||
vtkm::cont::ArrayHandle<ValueType> outputArray;
|
||||
vtkm::cont::UnknownArrayHandle(outputArray).CopyShallowIfPossible(input);
|
||||
TestValues(input, outputArray);
|
||||
|
||||
outputArray.ReleaseResources();
|
||||
vtkm::cont::UnknownArrayHandle outputUnknown(outputArray);
|
||||
outputUnknown.CopyShallowIfPossible(input);
|
||||
TestValues(input, outputUnknown);
|
||||
}
|
||||
}
|
||||
|
||||
void TryArrayCopyShallowIfPossible()
|
||||
|
Loading…
Reference in New Issue
Block a user