mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-19 18:45:43 +00:00
Change ArrayCopy to deep copy Buffer objects where possible
Now that the data in an `ArrayHandle` is stored in `Buffer` objects, we now have a more efficient way of doing deep copies of memory. Rather than call `Algorithm::Copy`, which iterates over the array and copies each item, `ArrayCopy` now uses the `Buffer` interface to do direct device-to-device (or host-to-host) mem copies. This should be more efficent and take less time to compile. Note that this direct `Buffer` copy only works if the two `ArrayHandle`s are of the same type. If they are different, `ArrayCopy` still has to fall back to using `Algorithm::Copy`. Also note that not all `ArrayHandle`s are using the new `ArrayHandle` interface (and therefore not using `Buffer` objects). Thus, a fallback is still available for old `ArrayHandle` types.
This commit is contained in:
parent
05e9d43f84
commit
694ba7e92c
@ -16,6 +16,8 @@
|
||||
#include <vtkm/cont/ErrorExecution.h>
|
||||
#include <vtkm/cont/Logging.h>
|
||||
|
||||
#include <vtkm/cont/vtkm_cont_export.h>
|
||||
|
||||
// TODO: When virtual arrays are available, compile the implementation in a .cxx/.cu file. Common
|
||||
// arrays are copied directly but anything else would be copied through virtual methods.
|
||||
|
||||
@ -27,7 +29,8 @@ namespace cont
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// normal element-wise copy:
|
||||
// Element-wise copy.
|
||||
// TODO: Remove last argument once ArryHandleNewStyle becomes ArrayHandle
|
||||
template <typename InArrayType, typename OutArrayType>
|
||||
void ArrayCopyImpl(const InArrayType& in, OutArrayType& out, std::false_type /* Copy storage */)
|
||||
{
|
||||
@ -58,6 +61,7 @@ void ArrayCopyImpl(const InArrayType& in, OutArrayType& out, std::false_type /*
|
||||
}
|
||||
|
||||
// Copy storage for implicit arrays, must be of same type:
|
||||
// TODO: This will go away once ArrayHandleNewStyle becomes ArrayHandle.
|
||||
template <typename ArrayType>
|
||||
void ArrayCopyImpl(const ArrayType& in, ArrayType& out, std::true_type /* Copy storage */)
|
||||
{
|
||||
@ -67,6 +71,33 @@ void ArrayCopyImpl(const ArrayType& in, ArrayType& out, std::true_type /* Copy s
|
||||
out = ArrayType(newStorage);
|
||||
}
|
||||
|
||||
// TODO: This will go away once ArrayHandleNewStyle becomes ArrayHandle.
|
||||
template <typename InArrayType, typename OutArrayType>
|
||||
VTKM_CONT void ArrayCopyImpl(const InArrayType& source, OutArrayType& destination)
|
||||
{
|
||||
using SameTypes = std::is_same<InArrayType, OutArrayType>;
|
||||
using IsWritable = vtkm::cont::internal::IsWritableArrayHandle<OutArrayType>;
|
||||
using JustCopyStorage = std::integral_constant<bool, SameTypes::value && !IsWritable::value>;
|
||||
ArrayCopyImpl(source, destination, JustCopyStorage{});
|
||||
}
|
||||
|
||||
// TODO: ArrayHandleNewStyle will eventually become ArrayHandle, in which case this
|
||||
// will become the only version with the same array types.
|
||||
template <typename T, typename S>
|
||||
VTKM_CONT void ArrayCopyImpl(const vtkm::cont::ArrayHandleNewStyle<T, S>& source,
|
||||
vtkm::cont::ArrayHandleNewStyle<T, S>& destination)
|
||||
{
|
||||
std::size_t numBuffers = static_cast<std::size_t>(source.GetNumberOfBuffers());
|
||||
std::vector<vtkm::cont::internal::Buffer> destinationBuffers(numBuffers);
|
||||
vtkm::cont::internal::Buffer* sourceBuffers = source.GetBuffers();
|
||||
for (std::size_t bufferIndex = 0; bufferIndex < numBuffers; ++bufferIndex)
|
||||
{
|
||||
sourceBuffers[bufferIndex].DeepCopy(destinationBuffers[bufferIndex]);
|
||||
}
|
||||
|
||||
destination = vtkm::cont::ArrayHandleNewStyle<T, S>(destinationBuffers, source.GetStorage());
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// \brief Does a deep copy from one array to another array.
|
||||
@ -93,11 +124,11 @@ VTKM_CONT void ArrayCopy(const vtkm::cont::ArrayHandle<InValueType, InStorage>&
|
||||
using IsWritable = vtkm::cont::internal::IsWritableArrayHandle<OutArrayType>;
|
||||
|
||||
// There are three cases handled here:
|
||||
// 1. Output is writable:
|
||||
// -> Do element-wise copy (normal copy behavior)
|
||||
// 2. Output is not writable and arrays are same type:
|
||||
// -> just copy storage (special case for implicit array cloning)
|
||||
// 3. Output is not writable and arrays are different types:
|
||||
// 1. The arrays are the same type:
|
||||
// -> Deep copy the buffers and the Storage object
|
||||
// 2. The arrays are different and the output is writable:
|
||||
// -> Do element-wise copy
|
||||
// 3. The arrays are different and the output is not writable:
|
||||
// -> fail (cannot copy)
|
||||
|
||||
// Give a nice error message for case 3:
|
||||
@ -105,10 +136,8 @@ VTKM_CONT void ArrayCopy(const vtkm::cont::ArrayHandle<InValueType, InStorage>&
|
||||
"Cannot copy to a read-only array with a different "
|
||||
"type than the source.");
|
||||
|
||||
using JustCopyStorage = std::integral_constant<bool, SameTypes::value && !IsWritable::value>;
|
||||
|
||||
// Static dispatch cases 1 & 2
|
||||
detail::ArrayCopyImpl(source, destination, JustCopyStorage{});
|
||||
detail::ArrayCopyImpl(source, destination);
|
||||
}
|
||||
|
||||
// Forward declaration
|
||||
|
Loading…
Reference in New Issue
Block a user