2018-08-29 20:54:31 +00:00
|
|
|
//============================================================================
|
|
|
|
// Copyright (c) Kitware, Inc.
|
|
|
|
// All rights reserved.
|
|
|
|
// See LICENSE.txt for details.
|
2019-04-15 23:24:21 +00:00
|
|
|
//
|
2018-08-29 20:54:31 +00:00
|
|
|
// 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_ArrayHandleView_h
|
|
|
|
#define vtk_m_cont_ArrayHandleView_h
|
|
|
|
|
|
|
|
#include <vtkm/Assert.h>
|
2020-01-06 18:06:31 +00:00
|
|
|
#include <vtkm/Deprecated.h>
|
2018-08-29 20:54:31 +00:00
|
|
|
|
2020-09-10 23:54:12 +00:00
|
|
|
#include <vtkm/cont/ArrayExtractComponent.h>
|
2018-08-29 20:54:31 +00:00
|
|
|
#include <vtkm/cont/ArrayHandle.h>
|
|
|
|
#include <vtkm/cont/ArrayPortal.h>
|
|
|
|
|
|
|
|
namespace vtkm
|
|
|
|
{
|
|
|
|
|
|
|
|
namespace internal
|
|
|
|
{
|
|
|
|
|
2020-11-09 23:55:50 +00:00
|
|
|
struct ViewIndices
|
|
|
|
{
|
|
|
|
vtkm::Id StartIndex = 0;
|
|
|
|
vtkm::Id NumberOfValues = 0;
|
|
|
|
|
|
|
|
ViewIndices() = default;
|
|
|
|
|
|
|
|
ViewIndices(vtkm::Id start, vtkm::Id numValues)
|
|
|
|
: StartIndex(start)
|
|
|
|
, NumberOfValues(numValues)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-08-29 20:54:31 +00:00
|
|
|
template <typename TargetPortalType>
|
|
|
|
class ArrayPortalView
|
|
|
|
{
|
2019-09-13 15:42:33 +00:00
|
|
|
using Writable = vtkm::internal::PortalSupportsSets<TargetPortalType>;
|
|
|
|
|
2018-08-29 20:54:31 +00:00
|
|
|
public:
|
|
|
|
using ValueType = typename TargetPortalType::ValueType;
|
|
|
|
|
|
|
|
VTKM_EXEC_CONT
|
|
|
|
ArrayPortalView() {}
|
|
|
|
|
|
|
|
VTKM_EXEC_CONT
|
2020-11-09 23:55:50 +00:00
|
|
|
ArrayPortalView(const TargetPortalType& targetPortal, ViewIndices indices)
|
2018-08-29 20:54:31 +00:00
|
|
|
: TargetPortal(targetPortal)
|
2020-11-09 23:55:50 +00:00
|
|
|
, Indices(indices)
|
2018-08-29 20:54:31 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename OtherPortalType>
|
|
|
|
VTKM_EXEC_CONT ArrayPortalView(const ArrayPortalView<OtherPortalType>& otherPortal)
|
|
|
|
: TargetPortal(otherPortal.GetTargetPortal())
|
2020-11-09 23:55:50 +00:00
|
|
|
, Indices(otherPortal.GetStartIndex(), otherPortal.GetNumberOfValues())
|
2018-08-29 20:54:31 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_EXEC_CONT
|
2020-11-09 23:55:50 +00:00
|
|
|
vtkm::Id GetNumberOfValues() const { return this->Indices.NumberOfValues; }
|
2018-08-29 20:54:31 +00:00
|
|
|
|
|
|
|
VTKM_EXEC_CONT
|
2020-11-09 23:55:50 +00:00
|
|
|
ValueType Get(vtkm::Id index) const
|
|
|
|
{
|
|
|
|
return this->TargetPortal.Get(index + this->GetStartIndex());
|
|
|
|
}
|
2018-08-29 20:54:31 +00:00
|
|
|
|
2019-09-13 15:42:33 +00:00
|
|
|
template <typename Writable_ = Writable,
|
|
|
|
typename = typename std::enable_if<Writable_::value>::type>
|
|
|
|
VTKM_EXEC_CONT void Set(vtkm::Id index, const ValueType& value) const
|
2018-08-29 20:54:31 +00:00
|
|
|
{
|
2020-11-09 23:55:50 +00:00
|
|
|
this->TargetPortal.Set(index + this->GetStartIndex(), value);
|
2018-08-29 20:54:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_EXEC_CONT
|
|
|
|
const TargetPortalType& GetTargetPortal() const { return this->TargetPortal; }
|
|
|
|
VTKM_EXEC_CONT
|
2020-11-09 23:55:50 +00:00
|
|
|
vtkm::Id GetStartIndex() const { return this->Indices.StartIndex; }
|
2018-08-29 20:54:31 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
TargetPortalType TargetPortal;
|
2020-11-09 23:55:50 +00:00
|
|
|
ViewIndices Indices;
|
2018-08-29 20:54:31 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace internal
|
|
|
|
|
2020-11-09 23:55:50 +00:00
|
|
|
namespace cont
|
|
|
|
{
|
|
|
|
|
2020-01-06 18:06:31 +00:00
|
|
|
template <typename StorageTag>
|
2020-01-04 06:46:43 +00:00
|
|
|
struct VTKM_ALWAYS_EXPORT StorageTagView
|
2018-08-29 20:54:31 +00:00
|
|
|
{
|
|
|
|
};
|
|
|
|
|
|
|
|
namespace internal
|
|
|
|
{
|
|
|
|
|
2020-01-06 18:06:31 +00:00
|
|
|
namespace detail
|
|
|
|
{
|
|
|
|
|
|
|
|
template <typename T, typename ArrayOrStorage, bool IsArrayType>
|
|
|
|
struct ViewTypeArgImpl;
|
|
|
|
|
|
|
|
template <typename T, typename Storage>
|
|
|
|
struct ViewTypeArgImpl<T, Storage, false>
|
2018-08-29 20:54:31 +00:00
|
|
|
{
|
2020-01-06 18:06:31 +00:00
|
|
|
using StorageTag = Storage;
|
|
|
|
using ArrayHandle = vtkm::cont::ArrayHandle<T, StorageTag>;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename T, typename Array>
|
|
|
|
struct ViewTypeArgImpl<T, Array, true>
|
|
|
|
{
|
|
|
|
VTKM_STATIC_ASSERT_MSG((std::is_same<T, typename Array::ValueType>::value),
|
|
|
|
"Used array with wrong type in ArrayHandleView.");
|
|
|
|
using StorageTag VTKM_DEPRECATED(1.6,
|
|
|
|
"Use storage tag instead of array handle in StorageTagView.") =
|
|
|
|
typename Array::StorageTag;
|
|
|
|
using ArrayHandle VTKM_DEPRECATED(1.6,
|
|
|
|
"Use storage tag instead of array handle in StorageTagView.") =
|
|
|
|
vtkm::cont::ArrayHandle<T, typename Array::StorageTag>;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename T, typename ArrayOrStorage>
|
|
|
|
struct ViewTypeArg
|
|
|
|
: ViewTypeArgImpl<T,
|
|
|
|
ArrayOrStorage,
|
|
|
|
vtkm::cont::internal::ArrayHandleCheck<ArrayOrStorage>::type::value>
|
|
|
|
{
|
|
|
|
};
|
|
|
|
|
2020-11-09 23:55:50 +00:00
|
|
|
} // namespace detail
|
2020-01-06 18:06:31 +00:00
|
|
|
|
|
|
|
template <typename T, typename ST>
|
|
|
|
class Storage<T, StorageTagView<ST>>
|
|
|
|
{
|
|
|
|
using ArrayHandleType = typename detail::ViewTypeArg<T, ST>::ArrayHandle;
|
2020-11-09 23:55:50 +00:00
|
|
|
using SourceStorage = Storage<T, ST>;
|
2020-01-06 18:06:31 +00:00
|
|
|
|
2018-08-29 20:54:31 +00:00
|
|
|
public:
|
2020-11-09 23:55:50 +00:00
|
|
|
VTKM_STORAGE_NO_RESIZE;
|
2018-08-29 20:54:31 +00:00
|
|
|
|
2020-11-09 23:55:50 +00:00
|
|
|
using ReadPortalType = vtkm::internal::ArrayPortalView<typename ArrayHandleType::ReadPortalType>;
|
|
|
|
using WritePortalType =
|
|
|
|
vtkm::internal::ArrayPortalView<typename ArrayHandleType::WritePortalType>;
|
2018-08-29 20:54:31 +00:00
|
|
|
|
2020-11-09 23:55:50 +00:00
|
|
|
VTKM_CONT static constexpr vtkm::IdComponent GetNumberOfBuffers()
|
2018-08-29 20:54:31 +00:00
|
|
|
{
|
2020-11-09 23:55:50 +00:00
|
|
|
return SourceStorage::GetNumberOfBuffers() + 1;
|
2018-08-29 20:54:31 +00:00
|
|
|
}
|
|
|
|
|
2020-11-09 23:55:50 +00:00
|
|
|
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
|
2018-08-29 20:54:31 +00:00
|
|
|
{
|
2020-11-09 23:55:50 +00:00
|
|
|
return buffers[0].GetMetaData<vtkm::internal::ViewIndices>().NumberOfValues;
|
2018-08-29 20:54:31 +00:00
|
|
|
}
|
|
|
|
|
2020-11-09 23:55:50 +00:00
|
|
|
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
|
|
|
|
vtkm::cont::DeviceAdapterId device,
|
|
|
|
vtkm::cont::Token& token)
|
2018-08-29 20:54:31 +00:00
|
|
|
{
|
2020-11-09 23:55:50 +00:00
|
|
|
vtkm::internal::ViewIndices indices = buffers[0].GetMetaData<vtkm::internal::ViewIndices>();
|
|
|
|
return ReadPortalType(SourceStorage::CreateReadPortal(buffers + 1, device, token), indices);
|
2018-08-29 20:54:31 +00:00
|
|
|
}
|
|
|
|
|
2022-01-11 14:15:41 +00:00
|
|
|
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
|
|
|
|
const T& fillValue,
|
|
|
|
vtkm::Id startIndex,
|
|
|
|
vtkm::Id endIndex,
|
|
|
|
vtkm::cont::Token& token)
|
2022-01-04 16:29:12 +00:00
|
|
|
{
|
2022-01-11 14:15:41 +00:00
|
|
|
vtkm::internal::ViewIndices indices = buffers[0].GetMetaData<vtkm::internal::ViewIndices>();
|
|
|
|
vtkm::Id adjustedStartIndex = startIndex + indices.StartIndex;
|
|
|
|
vtkm::Id adjustedEndIndex = (endIndex < indices.NumberOfValues)
|
|
|
|
? endIndex + indices.StartIndex
|
|
|
|
: indices.NumberOfValues + indices.StartIndex;
|
2022-01-20 16:29:16 +00:00
|
|
|
SourceStorage::Fill(buffers + 1, fillValue, adjustedStartIndex, adjustedEndIndex, token);
|
2022-01-04 16:29:12 +00:00
|
|
|
}
|
|
|
|
|
2020-11-09 23:55:50 +00:00
|
|
|
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
|
|
|
|
vtkm::cont::DeviceAdapterId device,
|
|
|
|
vtkm::cont::Token& token)
|
2018-08-29 20:54:31 +00:00
|
|
|
{
|
2020-11-09 23:55:50 +00:00
|
|
|
vtkm::internal::ViewIndices indices = buffers[0].GetMetaData<vtkm::internal::ViewIndices>();
|
|
|
|
return WritePortalType(SourceStorage::CreateWritePortal(buffers + 1, device, token), indices);
|
2018-08-29 20:54:31 +00:00
|
|
|
}
|
|
|
|
|
2020-11-09 23:55:50 +00:00
|
|
|
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer>
|
|
|
|
CreateBuffers(vtkm::Id startIndex, vtkm::Id numValues, const ArrayHandleType& array)
|
2018-08-29 20:54:31 +00:00
|
|
|
{
|
2020-11-09 23:55:50 +00:00
|
|
|
return vtkm::cont::internal::CreateBuffers(vtkm::internal::ViewIndices(startIndex, numValues),
|
|
|
|
array);
|
2018-08-29 20:54:31 +00:00
|
|
|
}
|
2020-12-22 14:47:18 +00:00
|
|
|
|
|
|
|
VTKM_CONT static ArrayHandleType GetSourceArray(const vtkm::cont::internal::Buffer* buffers)
|
|
|
|
{
|
|
|
|
return ArrayHandleType(buffers + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_CONT static vtkm::Id GetStartIndex(const vtkm::cont::internal::Buffer* buffers)
|
|
|
|
{
|
|
|
|
return buffers[0].GetMetaData<vtkm::internal::ViewIndices>().StartIndex;
|
|
|
|
}
|
2018-08-29 20:54:31 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace internal
|
|
|
|
|
|
|
|
template <typename ArrayHandleType>
|
2020-01-06 18:06:31 +00:00
|
|
|
class ArrayHandleView
|
|
|
|
: public vtkm::cont::ArrayHandle<typename ArrayHandleType::ValueType,
|
|
|
|
StorageTagView<typename ArrayHandleType::StorageTag>>
|
2018-08-29 20:54:31 +00:00
|
|
|
{
|
|
|
|
VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
|
|
|
|
|
|
|
|
public:
|
2020-01-06 18:06:31 +00:00
|
|
|
VTKM_ARRAY_HANDLE_SUBCLASS(
|
|
|
|
ArrayHandleView,
|
|
|
|
(ArrayHandleView<ArrayHandleType>),
|
|
|
|
(vtkm::cont::ArrayHandle<typename ArrayHandleType::ValueType,
|
|
|
|
StorageTagView<typename ArrayHandleType::StorageTag>>));
|
2018-08-29 20:54:31 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
|
|
|
|
|
|
|
|
public:
|
|
|
|
VTKM_CONT
|
|
|
|
ArrayHandleView(const ArrayHandleType& array, vtkm::Id startIndex, vtkm::Id numValues)
|
2020-11-09 23:55:50 +00:00
|
|
|
: Superclass(StorageType::CreateBuffers(startIndex, numValues, array))
|
2018-08-29 20:54:31 +00:00
|
|
|
{
|
|
|
|
}
|
2020-09-10 23:54:12 +00:00
|
|
|
|
2020-12-22 14:47:18 +00:00
|
|
|
VTKM_CONT ArrayHandleType GetSourceArray() const
|
|
|
|
{
|
|
|
|
return this->GetStorage().GetSourceArray(this->GetBuffers());
|
|
|
|
}
|
2020-09-10 23:54:12 +00:00
|
|
|
|
2020-12-22 14:47:18 +00:00
|
|
|
VTKM_CONT vtkm::Id GetStartIndex() const
|
|
|
|
{
|
|
|
|
return this->GetStorage().GetStartIndex(this->GetBuffers());
|
|
|
|
}
|
2018-08-29 20:54:31 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
template <typename ArrayHandleType>
|
|
|
|
ArrayHandleView<ArrayHandleType> make_ArrayHandleView(const ArrayHandleType& array,
|
|
|
|
vtkm::Id startIndex,
|
|
|
|
vtkm::Id numValues)
|
|
|
|
{
|
|
|
|
VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
|
|
|
|
|
|
|
|
return ArrayHandleView<ArrayHandleType>(array, startIndex, numValues);
|
|
|
|
}
|
2020-09-10 23:54:12 +00:00
|
|
|
|
|
|
|
namespace internal
|
|
|
|
{
|
|
|
|
|
2022-01-19 21:59:27 +00:00
|
|
|
// Superclass will inherit the ArrayExtractComponentImplInefficient property if
|
|
|
|
// the sub-storage is inefficient (thus making everything inefficient).
|
2020-09-10 23:54:12 +00:00
|
|
|
template <typename StorageTag>
|
|
|
|
struct ArrayExtractComponentImpl<StorageTagView<StorageTag>>
|
2022-01-19 21:59:27 +00:00
|
|
|
: vtkm::cont::internal::ArrayExtractComponentImpl<StorageTag>
|
2020-09-10 23:54:12 +00:00
|
|
|
{
|
|
|
|
template <typename T>
|
|
|
|
using StrideArrayType =
|
|
|
|
vtkm::cont::ArrayHandleStride<typename vtkm::VecTraits<T>::BaseComponentType>;
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
StrideArrayType<T> operator()(
|
|
|
|
const vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagView<StorageTag>>& src,
|
|
|
|
vtkm::IdComponent componentIndex,
|
|
|
|
vtkm::CopyFlag allowCopy) const
|
|
|
|
{
|
|
|
|
vtkm::cont::ArrayHandleView<vtkm::cont::ArrayHandle<T, StorageTag>> srcArray(src);
|
|
|
|
StrideArrayType<T> subArray =
|
|
|
|
ArrayExtractComponentImpl<StorageTag>{}(srcArray.GetSourceArray(), componentIndex, allowCopy);
|
|
|
|
// Narrow the array by adjusting the size and offset.
|
|
|
|
return StrideArrayType<T>(subArray.GetBasicArray(),
|
|
|
|
srcArray.GetNumberOfValues(),
|
|
|
|
subArray.GetStride(),
|
|
|
|
subArray.GetOffset() +
|
|
|
|
(subArray.GetStride() * srcArray.GetStartIndex()),
|
|
|
|
subArray.GetModulo(),
|
|
|
|
subArray.GetDivisor());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace internal
|
|
|
|
|
2018-08-29 20:54:31 +00:00
|
|
|
}
|
|
|
|
} // namespace vtkm::cont
|
|
|
|
|
|
|
|
#endif //vtk_m_cont_ArrayHandleView_h
|