mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-16 17:22:55 +00:00
Merge topic 'shallow-array-copy'
1fb114172 Update code to use ArrayCopyShallowIfPossible 5c36eafe5 Add ArrayCopyShallowIfPossible Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: Li-Ta Lo <ollie@lanl.gov> Merge-request: !2529
This commit is contained in:
commit
bf6d6ca517
12
docs/changelog/shallow-copy-if-possible.md
Normal file
12
docs/changelog/shallow-copy-if-possible.md
Normal file
@ -0,0 +1,12 @@
|
||||
# Added `ArrayCopyShallowIfPossible`
|
||||
|
||||
Often times you have an array of an unknown type (likely from a data set),
|
||||
and you need it to be of a particular type (or can make a reasonable but
|
||||
uncertain assumption about it being a particular type). You really just
|
||||
want a shallow copy (a reference in a concrete `ArrayHandle`) if that is
|
||||
possible.
|
||||
|
||||
`ArrayCopyShallowIfPossible` pulls an array of a specific type from an
|
||||
`UnknownArrayHandle`. If the type is compatible, it will perform a shallow
|
||||
copy. If it is not possible, a deep copy is performed to get it to the
|
||||
correct type.
|
@ -130,6 +130,8 @@ VTKM_CONT void ArrayCopyImpl(const vtkm::cont::ArrayHandle<T, S>& source,
|
||||
/// This should work on some non-writable array handles as well, as long as
|
||||
/// both \a source and \a destination are the same type.
|
||||
///
|
||||
/// @{
|
||||
///
|
||||
template <typename InValueType, typename InStorage, typename OutValueType, typename OutStorage>
|
||||
VTKM_CONT void ArrayCopy(const vtkm::cont::ArrayHandle<InValueType, InStorage>& source,
|
||||
vtkm::cont::ArrayHandle<OutValueType, OutStorage>& destination)
|
||||
@ -169,7 +171,7 @@ VTKM_CONT void ArrayCopy(const vtkm::cont::UnknownArrayHandle& source,
|
||||
vtkm::cont::ArrayHandle<T, S>& destination)
|
||||
{
|
||||
using DestType = vtkm::cont::ArrayHandle<T, S>;
|
||||
if (source.IsType<DestType>())
|
||||
if (source.CanConvert<DestType>())
|
||||
{
|
||||
ArrayCopy(source.AsArrayHandle<DestType>(), destination);
|
||||
}
|
||||
@ -182,6 +184,37 @@ VTKM_CONT void ArrayCopy(const vtkm::cont::UnknownArrayHandle& source,
|
||||
}
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
/// \brief Copies from an unknown to a known array type.
|
||||
///
|
||||
/// Often times you have an array of an unknown type (likely from a data set),
|
||||
/// and you need it to be of a particular type (or can make a reasonable but uncertain
|
||||
/// assumption about it being a particular type). You really just want a shallow
|
||||
/// copy (a reference in a concrete `ArrayHandle`) if that is possible.
|
||||
///
|
||||
/// `ArrayCopyShallowIfPossible` pulls an array of a specific type from an
|
||||
/// `UnknownArrayHandle`. If the type is compatible, it will perform a shallow copy.
|
||||
/// If it is not possible, a deep copy is performed to get it to the correct type.
|
||||
///
|
||||
template <typename T, typename S>
|
||||
VTKM_CONT void ArrayCopyShallowIfPossible(const vtkm::cont::UnknownArrayHandle source,
|
||||
vtkm::cont::ArrayHandle<T, S>& destination)
|
||||
{
|
||||
using DestType = vtkm::cont::ArrayHandle<T, S>;
|
||||
if (source.CanConvert<DestType>())
|
||||
{
|
||||
source.AsArrayHandle(destination);
|
||||
}
|
||||
else
|
||||
{
|
||||
vtkm::cont::UnknownArrayHandle destWrapper(destination);
|
||||
ArrayCopy(source, destWrapper);
|
||||
// Destination array should not change, but just in case.
|
||||
destWrapper.AsArrayHandle(destination);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
|
||||
|
@ -120,11 +120,32 @@ void TryCopy()
|
||||
}
|
||||
}
|
||||
|
||||
void TryArrayCopyShallowIfPossible()
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> input = MakeInputArray<vtkm::Float32>();
|
||||
vtkm::cont::UnknownArrayHandle unknownInput = input;
|
||||
|
||||
{
|
||||
std::cout << "shallow copy" << std::endl;
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> output;
|
||||
vtkm::cont::ArrayCopyShallowIfPossible(unknownInput, output);
|
||||
VTKM_TEST_ASSERT(input == output, "Copy was not shallow");
|
||||
}
|
||||
|
||||
{
|
||||
std::cout << "cannot shallow copy" << std::endl;
|
||||
vtkm::cont::ArrayHandle<vtkm::Float64> output;
|
||||
vtkm::cont::ArrayCopyShallowIfPossible(unknownInput, output);
|
||||
TestValues(input, output);
|
||||
}
|
||||
}
|
||||
|
||||
void TestArrayCopy()
|
||||
{
|
||||
TryCopy<vtkm::Id>();
|
||||
TryCopy<vtkm::IdComponent>();
|
||||
TryCopy<vtkm::Float32>();
|
||||
TryArrayCopyShallowIfPossible();
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <vtkm/filter/ImageDifference.h>
|
||||
|
||||
#include <vtkm/cont/Algorithm.h>
|
||||
#include <vtkm/cont/ArrayCopy.h>
|
||||
#include <vtkm/cont/ArrayPortalToIterators.h>
|
||||
#include <vtkm/cont/Logging.h>
|
||||
|
||||
@ -89,7 +90,7 @@ inline VTKM_CONT vtkm::cont::DataSet ImageDifference::DoExecute(
|
||||
{
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info, "Not performing average");
|
||||
primaryOutput = primary;
|
||||
secondaryField.GetData().AsArrayHandle(secondaryOutput);
|
||||
vtkm::cont::ArrayCopyShallowIfPossible(secondaryField.GetData(), secondaryOutput);
|
||||
}
|
||||
|
||||
if (this->PixelShiftRadius > 0)
|
||||
|
@ -74,11 +74,7 @@ protected:
|
||||
|
||||
FieldHandleType fieldArray;
|
||||
auto fieldData = ds.GetField(fieldNm).GetData();
|
||||
if (fieldData.IsType<FieldHandleType>())
|
||||
fieldArray = fieldData.AsArrayHandle<FieldHandleType>();
|
||||
else
|
||||
vtkm::cont::ArrayCopy(
|
||||
fieldData.ResetTypes<vtkm::TypeListFieldVec3, VTKM_DEFAULT_STORAGE_LIST>(), fieldArray);
|
||||
vtkm::cont::ArrayCopyShallowIfPossible(fieldData, fieldArray);
|
||||
|
||||
return fieldArray;
|
||||
}
|
||||
|
@ -306,16 +306,7 @@ void VTKDataSetReaderBase::ReadCells(vtkm::cont::ArrayHandle<vtkm::Id>& connecti
|
||||
internal::parseAssert(tag == "CONNECTIVITY");
|
||||
auto conn =
|
||||
this->DoReadArrayVariant(vtkm::cont::Field::Association::ANY, dataType, connSize, 1);
|
||||
if (conn.IsValueType<vtkm::Id>())
|
||||
{
|
||||
conn.AsArrayHandle(connectivity);
|
||||
}
|
||||
else
|
||||
{
|
||||
conn.CastAndCallForTypes<vtkm::List<vtkm::Int64, vtkm::Int32>,
|
||||
vtkm::List<vtkm::cont::StorageTagBasic>>(
|
||||
[&](const auto& connAH) { vtkm::cont::ArrayCopy(connAH, connectivity); });
|
||||
}
|
||||
vtkm::cont::ArrayCopyShallowIfPossible(conn, connectivity);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,39 +91,9 @@ void VTKRectilinearGridReader::Read()
|
||||
// We need to store all coordinate arrays as FloatDefault.
|
||||
vtkm::cont::ArrayHandle<vtkm::FloatDefault> Xc, Yc, Zc;
|
||||
// But the UnknownArrayHandle has type fileStorageDataType.
|
||||
// If the fileStorageDataType is the same as the storage type, no problem:
|
||||
if (fileStorageDataType == vtkm::io::internal::DataTypeName<vtkm::FloatDefault>::Name())
|
||||
{
|
||||
X.AsArrayHandle(Xc);
|
||||
Y.AsArrayHandle(Yc);
|
||||
Z.AsArrayHandle(Zc);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Two cases if the data in the file differs from FloatDefault:
|
||||
if (fileStorageDataType == "float")
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> Xcf, Ycf, Zcf;
|
||||
X.AsArrayHandle(Xcf);
|
||||
Y.AsArrayHandle(Ycf);
|
||||
Z.AsArrayHandle(Zcf);
|
||||
vtkm::cont::ArrayCopy(Xcf, Xc);
|
||||
vtkm::cont::ArrayCopy(Ycf, Yc);
|
||||
vtkm::cont::ArrayCopy(Zcf, Zc);
|
||||
}
|
||||
else
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::Float64> Xcd, Ycd, Zcd;
|
||||
X.AsArrayHandle(Xcd);
|
||||
Y.AsArrayHandle(Ycd);
|
||||
Z.AsArrayHandle(Zcd);
|
||||
vtkm::cont::ArrayCopy(Xcd, Xc);
|
||||
vtkm::cont::ArrayCopy(Ycd, Yc);
|
||||
vtkm::cont::ArrayCopy(Zcd, Zc);
|
||||
}
|
||||
}
|
||||
// As a postscript to this somewhat branchy code, I thought that X.CopyTo(Xc) should be able to cast to the value_type of Xc.
|
||||
// But that would break the ability to make the cast lazy, and hence if you change it you induce performance bugs.
|
||||
vtkm::cont::ArrayCopyShallowIfPossible(X, Xc);
|
||||
vtkm::cont::ArrayCopyShallowIfPossible(Y, Yc);
|
||||
vtkm::cont::ArrayCopyShallowIfPossible(Z, Zc);
|
||||
|
||||
coords = vtkm::cont::make_ArrayHandleCartesianProduct(Xc, Yc, Zc);
|
||||
vtkm::cont::CoordinateSystem coordSys("coordinates", coords);
|
||||
|
@ -710,7 +710,7 @@ public:
|
||||
vtkm::cont::ArrayHandleCartesianProduct<DefaultHandle, DefaultHandle, DefaultHandle>;
|
||||
|
||||
auto coordData = coord.GetData();
|
||||
if (coordData.IsType<CartesianArrayHandle>())
|
||||
if (coordData.CanConvert<CartesianArrayHandle>())
|
||||
{
|
||||
const auto vertices = coordData.AsArrayHandle<CartesianArrayHandle>();
|
||||
const auto vertsSize = vertices.GetNumberOfValues();
|
||||
|
@ -428,14 +428,7 @@ public:
|
||||
{
|
||||
// Get a cast to a concrete set of point coordiantes so that it can be modified in place
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec3f> concretePoints;
|
||||
if (points.template IsType<decltype(concretePoints)>())
|
||||
{
|
||||
points.AsArrayHandle(concretePoints);
|
||||
}
|
||||
else
|
||||
{
|
||||
vtkm::cont::ArrayCopy(points, concretePoints);
|
||||
}
|
||||
vtkm::cont::ArrayCopyShallowIfPossible(points, concretePoints);
|
||||
|
||||
Run(delta, fastCheck, bounds, concretePoints);
|
||||
|
||||
@ -450,14 +443,7 @@ public:
|
||||
{
|
||||
// Get a cast to a concrete set of point coordiantes so that it can be modified in place
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec3f> concretePoints;
|
||||
if (points.template IsType<decltype(concretePoints)>())
|
||||
{
|
||||
points.AsArrayHandle(concretePoints);
|
||||
}
|
||||
else
|
||||
{
|
||||
vtkm::cont::ArrayCopy(points, concretePoints);
|
||||
}
|
||||
vtkm::cont::ArrayCopyShallowIfPossible(points, concretePoints);
|
||||
|
||||
Run(delta, fastCheck, bounds, concretePoints);
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <vtkm/CellClassification.h>
|
||||
#include <vtkm/Types.h>
|
||||
#include <vtkm/VectorAnalysis.h>
|
||||
#include <vtkm/cont/ArrayCopy.h>
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/CellLocatorGeneral.h>
|
||||
#include <vtkm/cont/CellLocatorRectilinearGrid.h>
|
||||
@ -177,10 +178,7 @@ public:
|
||||
if (dataSet.HasCellField("vtkmGhostCells"))
|
||||
{
|
||||
auto arr = dataSet.GetCellField("vtkmGhostCells").GetData();
|
||||
if (arr.IsType<GhostCellArrayType>())
|
||||
this->GhostCellArray = arr.AsArrayHandle<GhostCellArrayType>();
|
||||
else
|
||||
throw vtkm::cont::ErrorInternal("vtkmGhostCells not of type vtkm::UInt8");
|
||||
vtkm::cont::ArrayCopyShallowIfPossible(arr, this->GhostCellArray);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user