2015-12-01 20:06:28 +00:00
|
|
|
//============================================================================
|
|
|
|
// Copyright (c) Kitware, Inc.
|
|
|
|
// All rights reserved.
|
|
|
|
// See LICENSE.txt for details.
|
2019-04-15 23:24:21 +00:00
|
|
|
//
|
2015-12-01 20:06:28 +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_ArrayHandleCartesianProduct_h
|
|
|
|
#define vtk_m_cont_ArrayHandleCartesianProduct_h
|
|
|
|
|
2016-04-20 21:41:14 +00:00
|
|
|
#include <vtkm/Assert.h>
|
|
|
|
|
2015-12-01 20:06:28 +00:00
|
|
|
#include <vtkm/cont/ArrayHandle.h>
|
2017-01-09 21:15:32 +00:00
|
|
|
#include <vtkm/cont/ErrorBadAllocation.h>
|
2015-12-01 20:06:28 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
namespace vtkm
|
|
|
|
{
|
|
|
|
namespace exec
|
|
|
|
{
|
|
|
|
namespace internal
|
|
|
|
{
|
2015-12-01 20:06:28 +00:00
|
|
|
|
|
|
|
/// \brief An array portal that acts as a 3D cartesian product of 3 arrays.
|
2016-04-20 21:41:14 +00:00
|
|
|
///
|
2017-05-26 17:53:28 +00:00
|
|
|
template <typename ValueType_,
|
|
|
|
typename PortalTypeFirst_,
|
|
|
|
typename PortalTypeSecond_,
|
2017-05-18 14:29:41 +00:00
|
|
|
typename PortalTypeThird_>
|
2016-12-19 19:39:17 +00:00
|
|
|
class VTKM_ALWAYS_EXPORT ArrayPortalCartesianProduct
|
2015-12-01 20:06:28 +00:00
|
|
|
{
|
|
|
|
public:
|
2017-06-23 18:50:34 +00:00
|
|
|
using ValueType = ValueType_;
|
|
|
|
using IteratorType = ValueType_;
|
|
|
|
using PortalTypeFirst = PortalTypeFirst_;
|
|
|
|
using PortalTypeSecond = PortalTypeSecond_;
|
|
|
|
using PortalTypeThird = PortalTypeThird_;
|
2015-12-01 20:06:28 +00:00
|
|
|
|
2019-09-12 19:11:50 +00:00
|
|
|
using set_supported_p1 = vtkm::internal::PortalSupportsSets<PortalTypeFirst>;
|
|
|
|
using set_supported_p2 = vtkm::internal::PortalSupportsSets<PortalTypeSecond>;
|
|
|
|
using set_supported_p3 = vtkm::internal::PortalSupportsSets<PortalTypeThird>;
|
|
|
|
|
|
|
|
using Writable = std::integral_constant<bool,
|
|
|
|
set_supported_p1::value && set_supported_p2::value &&
|
|
|
|
set_supported_p3::value>;
|
|
|
|
|
2016-03-31 13:13:54 +00:00
|
|
|
VTKM_SUPPRESS_EXEC_WARNINGS
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_EXEC_CONT
|
2016-04-20 21:41:14 +00:00
|
|
|
ArrayPortalCartesianProduct()
|
2017-05-18 14:29:41 +00:00
|
|
|
: PortalFirst()
|
|
|
|
, PortalSecond()
|
|
|
|
, PortalThird()
|
|
|
|
{
|
|
|
|
} //needs to be host and device so that cuda can create lvalue of these
|
2015-12-01 20:06:28 +00:00
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2017-05-18 14:29:41 +00:00
|
|
|
ArrayPortalCartesianProduct(const PortalTypeFirst& portalfirst,
|
|
|
|
const PortalTypeSecond& portalsecond,
|
|
|
|
const PortalTypeThird& portalthird)
|
|
|
|
: PortalFirst(portalfirst)
|
|
|
|
, PortalSecond(portalsecond)
|
|
|
|
, PortalThird(portalthird)
|
|
|
|
{
|
|
|
|
}
|
2015-12-01 20:06:28 +00:00
|
|
|
|
2016-04-20 21:41:14 +00:00
|
|
|
/// Copy constructor for any other ArrayPortalCartesianProduct with an iterator
|
2015-12-01 20:06:28 +00:00
|
|
|
/// type that can be copied to this iterator type. This allows us to do any
|
|
|
|
/// type casting that the iterators do (like the non-const to const cast).
|
|
|
|
///
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
template <class OtherV, class OtherP1, class OtherP2, class OtherP3>
|
|
|
|
VTKM_CONT ArrayPortalCartesianProduct(
|
|
|
|
const ArrayPortalCartesianProduct<OtherV, OtherP1, OtherP2, OtherP3>& src)
|
|
|
|
: PortalFirst(src.GetPortalFirst())
|
|
|
|
, PortalSecond(src.GetPortalSecond())
|
|
|
|
, PortalThird(src.GetPortalThird())
|
|
|
|
{
|
|
|
|
}
|
2015-12-01 20:06:28 +00:00
|
|
|
|
2016-04-20 21:41:14 +00:00
|
|
|
VTKM_SUPPRESS_EXEC_WARNINGS
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_EXEC_CONT
|
2015-12-01 20:06:28 +00:00
|
|
|
vtkm::Id GetNumberOfValues() const
|
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
return this->PortalFirst.GetNumberOfValues() * this->PortalSecond.GetNumberOfValues() *
|
|
|
|
this->PortalThird.GetNumberOfValues();
|
2015-12-01 20:06:28 +00:00
|
|
|
}
|
|
|
|
|
2016-04-20 21:41:14 +00:00
|
|
|
VTKM_SUPPRESS_EXEC_WARNINGS
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_EXEC_CONT
|
2015-12-01 20:06:28 +00:00
|
|
|
ValueType Get(vtkm::Id index) const
|
|
|
|
{
|
2016-04-20 21:41:14 +00:00
|
|
|
VTKM_ASSERT(index >= 0);
|
|
|
|
VTKM_ASSERT(index < this->GetNumberOfValues());
|
|
|
|
|
|
|
|
vtkm::Id dim1 = this->PortalFirst.GetNumberOfValues();
|
|
|
|
vtkm::Id dim2 = this->PortalSecond.GetNumberOfValues();
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::Id dim12 = dim1 * dim2;
|
2016-04-20 21:41:14 +00:00
|
|
|
vtkm::Id idx12 = index % dim12;
|
|
|
|
vtkm::Id i1 = idx12 % dim1;
|
|
|
|
vtkm::Id i2 = idx12 / dim1;
|
|
|
|
vtkm::Id i3 = index / dim12;
|
|
|
|
|
2017-05-26 17:53:28 +00:00
|
|
|
return vtkm::make_Vec(
|
|
|
|
this->PortalFirst.Get(i1), this->PortalSecond.Get(i2), this->PortalThird.Get(i3));
|
2015-12-01 20:06:28 +00:00
|
|
|
}
|
|
|
|
|
2019-09-12 19:11:50 +00:00
|
|
|
|
2016-04-20 21:41:14 +00:00
|
|
|
VTKM_SUPPRESS_EXEC_WARNINGS
|
2019-09-12 19:11:50 +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
|
2015-12-01 20:06:28 +00:00
|
|
|
{
|
2016-04-20 21:41:14 +00:00
|
|
|
VTKM_ASSERT(index >= 0);
|
|
|
|
VTKM_ASSERT(index < this->GetNumberOfValues());
|
|
|
|
|
|
|
|
vtkm::Id dim1 = this->PortalFirst.GetNumberOfValues();
|
|
|
|
vtkm::Id dim2 = this->PortalSecond.GetNumberOfValues();
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::Id dim12 = dim1 * dim2;
|
2016-04-20 21:41:14 +00:00
|
|
|
vtkm::Id idx12 = index % dim12;
|
|
|
|
|
|
|
|
vtkm::Id i1 = idx12 % dim1;
|
|
|
|
vtkm::Id i2 = idx12 / dim1;
|
|
|
|
vtkm::Id i3 = index / dim12;
|
|
|
|
|
|
|
|
this->PortalFirst.Set(i1, value[0]);
|
|
|
|
this->PortalSecond.Set(i2, value[1]);
|
|
|
|
this->PortalThird.Set(i3, value[2]);
|
2015-12-01 20:06:28 +00:00
|
|
|
}
|
|
|
|
|
2016-04-20 21:41:14 +00:00
|
|
|
VTKM_SUPPRESS_EXEC_WARNINGS
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_EXEC_CONT
|
2017-05-18 14:29:41 +00:00
|
|
|
const PortalTypeFirst& GetFirstPortal() const { return this->PortalFirst; }
|
2015-12-01 20:06:28 +00:00
|
|
|
|
2016-04-20 21:41:14 +00:00
|
|
|
VTKM_SUPPRESS_EXEC_WARNINGS
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_EXEC_CONT
|
2017-05-18 14:29:41 +00:00
|
|
|
const PortalTypeSecond& GetSecondPortal() const { return this->PortalSecond; }
|
2015-12-01 20:06:28 +00:00
|
|
|
|
2016-04-20 21:41:14 +00:00
|
|
|
VTKM_SUPPRESS_EXEC_WARNINGS
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_EXEC_CONT
|
2017-05-18 14:29:41 +00:00
|
|
|
const PortalTypeThird& GetThirdPortal() const { return this->PortalThird; }
|
2015-12-01 20:06:28 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
PortalTypeFirst PortalFirst;
|
|
|
|
PortalTypeSecond PortalSecond;
|
|
|
|
PortalTypeThird PortalThird;
|
|
|
|
};
|
|
|
|
}
|
2016-08-02 15:26:29 +00:00
|
|
|
}
|
|
|
|
} // namespace vtkm::exec::internal
|
2015-12-01 20:06:28 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
namespace vtkm
|
|
|
|
{
|
|
|
|
namespace cont
|
|
|
|
{
|
2015-12-01 20:06:28 +00:00
|
|
|
|
2019-12-19 23:00:45 +00:00
|
|
|
template <typename StorageTag1, typename StorageTag2, typename StorageTag3>
|
|
|
|
struct StorageTagCartesianProduct
|
2017-05-18 14:29:41 +00:00
|
|
|
{
|
2019-12-19 23:00:45 +00:00
|
|
|
};
|
2015-12-01 20:06:28 +00:00
|
|
|
|
2019-12-19 23:00:45 +00:00
|
|
|
namespace internal
|
2017-05-18 14:29:41 +00:00
|
|
|
{
|
2015-12-01 20:06:28 +00:00
|
|
|
|
|
|
|
/// This helper struct defines the value type for a zip container containing
|
|
|
|
/// the given two array handles.
|
|
|
|
///
|
2019-12-19 23:00:45 +00:00
|
|
|
template <typename AH1, typename AH2, typename AH3>
|
2017-05-18 14:29:41 +00:00
|
|
|
struct ArrayHandleCartesianProductTraits
|
|
|
|
{
|
2019-12-19 23:00:45 +00:00
|
|
|
VTKM_IS_ARRAY_HANDLE(AH1);
|
|
|
|
VTKM_IS_ARRAY_HANDLE(AH2);
|
|
|
|
VTKM_IS_ARRAY_HANDLE(AH3);
|
|
|
|
|
|
|
|
using ComponentType = typename AH1::ValueType;
|
|
|
|
VTKM_STATIC_ASSERT_MSG(
|
|
|
|
(std::is_same<ComponentType, typename AH2::ValueType>::value),
|
|
|
|
"All arrays for ArrayHandleCartesianProduct must have the same value type. "
|
|
|
|
"Use ArrayHandleCast as necessary to make types match.");
|
|
|
|
VTKM_STATIC_ASSERT_MSG(
|
|
|
|
(std::is_same<ComponentType, typename AH3::ValueType>::value),
|
|
|
|
"All arrays for ArrayHandleCartesianProduct must have the same value type. "
|
|
|
|
"Use ArrayHandleCast as necessary to make types match.");
|
|
|
|
|
2015-12-01 20:06:28 +00:00
|
|
|
/// The ValueType (a pair containing the value types of the two arrays).
|
|
|
|
///
|
2019-12-19 23:00:45 +00:00
|
|
|
using ValueType = vtkm::Vec<ComponentType, 3>;
|
2015-12-01 20:06:28 +00:00
|
|
|
|
|
|
|
/// The appropriately templated tag.
|
|
|
|
///
|
2019-12-19 23:00:45 +00:00
|
|
|
using Tag = vtkm::cont::StorageTagCartesianProduct<typename AH1::StorageTag,
|
|
|
|
typename AH2::StorageTag,
|
|
|
|
typename AH3::StorageTag>;
|
2015-12-01 20:06:28 +00:00
|
|
|
|
|
|
|
/// The superclass for ArrayHandleCartesianProduct.
|
|
|
|
///
|
2017-08-16 15:34:21 +00:00
|
|
|
using Superclass = vtkm::cont::ArrayHandle<ValueType, Tag>;
|
2015-12-01 20:06:28 +00:00
|
|
|
};
|
|
|
|
|
2019-12-19 23:00:45 +00:00
|
|
|
template <typename T, typename ST1, typename ST2, typename ST3>
|
|
|
|
class Storage<vtkm::Vec<T, 3>, vtkm::cont::StorageTagCartesianProduct<ST1, ST2, ST3>>
|
2015-12-01 20:06:28 +00:00
|
|
|
{
|
2019-12-19 23:00:45 +00:00
|
|
|
using AH1 = vtkm::cont::ArrayHandle<T, ST1>;
|
|
|
|
using AH2 = vtkm::cont::ArrayHandle<T, ST2>;
|
|
|
|
using AH3 = vtkm::cont::ArrayHandle<T, ST3>;
|
2015-12-01 20:06:28 +00:00
|
|
|
|
|
|
|
public:
|
2019-12-19 23:00:45 +00:00
|
|
|
using ValueType = vtkm::Vec<typename AH1::ValueType, 3>;
|
2015-12-01 20:06:28 +00:00
|
|
|
|
2019-12-19 23:00:45 +00:00
|
|
|
using PortalType = vtkm::exec::internal::ArrayPortalCartesianProduct<ValueType,
|
|
|
|
typename AH1::PortalControl,
|
|
|
|
typename AH2::PortalControl,
|
|
|
|
typename AH3::PortalControl>;
|
2017-08-16 15:34:21 +00:00
|
|
|
using PortalConstType =
|
|
|
|
vtkm::exec::internal::ArrayPortalCartesianProduct<ValueType,
|
2019-12-19 23:00:45 +00:00
|
|
|
typename AH1::PortalConstControl,
|
|
|
|
typename AH2::PortalConstControl,
|
|
|
|
typename AH3::PortalConstControl>;
|
2015-12-01 20:06:28 +00:00
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2017-05-18 14:29:41 +00:00
|
|
|
Storage()
|
|
|
|
: FirstArray()
|
|
|
|
, SecondArray()
|
|
|
|
, ThirdArray()
|
|
|
|
{
|
|
|
|
}
|
2015-12-01 20:06:28 +00:00
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2019-12-19 23:00:45 +00:00
|
|
|
Storage(const AH1& array1, const AH2& array2, const AH3& array3)
|
2017-05-18 14:29:41 +00:00
|
|
|
: FirstArray(array1)
|
|
|
|
, SecondArray(array2)
|
|
|
|
, ThirdArray(array3)
|
2015-12-01 20:06:28 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2015-12-01 20:06:28 +00:00
|
|
|
PortalType GetPortal()
|
|
|
|
{
|
2017-05-26 17:53:28 +00:00
|
|
|
return PortalType(this->FirstArray.GetPortalControl(),
|
|
|
|
this->SecondArray.GetPortalControl(),
|
2017-05-18 14:29:41 +00:00
|
|
|
this->ThirdArray.GetPortalControl());
|
2015-12-01 20:06:28 +00:00
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2015-12-01 20:06:28 +00:00
|
|
|
PortalConstType GetPortalConst() const
|
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
return PortalConstType(this->FirstArray.GetPortalConstControl(),
|
|
|
|
this->SecondArray.GetPortalConstControl(),
|
|
|
|
this->ThirdArray.GetPortalConstControl());
|
2015-12-01 20:06:28 +00:00
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2015-12-01 20:06:28 +00:00
|
|
|
vtkm::Id GetNumberOfValues() const
|
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
return this->FirstArray.GetNumberOfValues() * this->SecondArray.GetNumberOfValues() *
|
|
|
|
this->ThirdArray.GetNumberOfValues();
|
2015-12-01 20:06:28 +00:00
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2015-12-01 20:06:28 +00:00
|
|
|
void Allocate(vtkm::Id /*numberOfValues*/)
|
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
throw vtkm::cont::ErrorBadAllocation("Does not make sense.");
|
2015-12-01 20:06:28 +00:00
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2015-12-01 20:06:28 +00:00
|
|
|
void Shrink(vtkm::Id /*numberOfValues*/)
|
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
throw vtkm::cont::ErrorBadAllocation("Does not make sense.");
|
2015-12-01 20:06:28 +00:00
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2015-12-01 20:06:28 +00:00
|
|
|
void ReleaseResources()
|
|
|
|
{
|
|
|
|
// This request is ignored since it is asking to release the resources
|
|
|
|
// of the arrays, which may be used elsewhere.
|
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2019-12-19 23:00:45 +00:00
|
|
|
const AH1& GetFirstArray() const { return this->FirstArray; }
|
2015-12-01 20:06:28 +00:00
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2019-12-19 23:00:45 +00:00
|
|
|
const AH2& GetSecondArray() const { return this->SecondArray; }
|
2015-12-01 20:06:28 +00:00
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2019-12-19 23:00:45 +00:00
|
|
|
const AH3& GetThirdArray() const { return this->ThirdArray; }
|
2015-12-01 20:06:28 +00:00
|
|
|
|
|
|
|
private:
|
2019-12-19 23:00:45 +00:00
|
|
|
AH1 FirstArray;
|
|
|
|
AH2 SecondArray;
|
|
|
|
AH3 ThirdArray;
|
2015-12-01 20:06:28 +00:00
|
|
|
};
|
|
|
|
|
2019-12-19 23:00:45 +00:00
|
|
|
template <typename T, typename ST1, typename ST2, typename ST3, typename Device>
|
|
|
|
class ArrayTransfer<vtkm::Vec<T, 3>, vtkm::cont::StorageTagCartesianProduct<ST1, ST2, ST3>, Device>
|
2015-12-01 20:06:28 +00:00
|
|
|
{
|
2018-06-08 15:56:40 +00:00
|
|
|
public:
|
2019-12-19 23:00:45 +00:00
|
|
|
using ValueType = vtkm::Vec<T, 3>;
|
2018-06-08 15:56:40 +00:00
|
|
|
|
|
|
|
private:
|
2019-12-19 23:00:45 +00:00
|
|
|
using AH1 = vtkm::cont::ArrayHandle<T, ST1>;
|
|
|
|
using AH2 = vtkm::cont::ArrayHandle<T, ST2>;
|
|
|
|
using AH3 = vtkm::cont::ArrayHandle<T, ST3>;
|
|
|
|
|
|
|
|
using StorageTag = vtkm::cont::StorageTagCartesianProduct<ST1, ST2, ST3>;
|
2018-06-08 15:56:40 +00:00
|
|
|
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
|
2015-12-01 20:06:28 +00:00
|
|
|
|
|
|
|
public:
|
2017-06-23 18:50:34 +00:00
|
|
|
using PortalControl = typename StorageType::PortalType;
|
|
|
|
using PortalConstControl = typename StorageType::PortalConstType;
|
2015-12-01 20:06:28 +00:00
|
|
|
|
2017-08-16 15:34:21 +00:00
|
|
|
using PortalExecution = vtkm::exec::internal::ArrayPortalCartesianProduct<
|
2017-05-26 17:53:28 +00:00
|
|
|
ValueType,
|
2019-12-19 23:00:45 +00:00
|
|
|
typename AH1::template ExecutionTypes<Device>::Portal,
|
|
|
|
typename AH2::template ExecutionTypes<Device>::Portal,
|
|
|
|
typename AH3::template ExecutionTypes<Device>::Portal>;
|
2015-12-01 20:06:28 +00:00
|
|
|
|
2017-08-16 15:34:21 +00:00
|
|
|
using PortalConstExecution = vtkm::exec::internal::ArrayPortalCartesianProduct<
|
2017-05-26 17:53:28 +00:00
|
|
|
ValueType,
|
2019-12-19 23:00:45 +00:00
|
|
|
typename AH1::template ExecutionTypes<Device>::PortalConst,
|
|
|
|
typename AH2::template ExecutionTypes<Device>::PortalConst,
|
|
|
|
typename AH3::template ExecutionTypes<Device>::PortalConst>;
|
2015-12-01 20:06:28 +00:00
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2017-05-18 14:29:41 +00:00
|
|
|
ArrayTransfer(StorageType* storage)
|
|
|
|
: FirstArray(storage->GetFirstArray())
|
|
|
|
, SecondArray(storage->GetSecondArray())
|
|
|
|
, ThirdArray(storage->GetThirdArray())
|
|
|
|
{
|
|
|
|
}
|
2015-12-01 20:06:28 +00:00
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2015-12-01 20:06:28 +00:00
|
|
|
vtkm::Id GetNumberOfValues() const
|
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
return this->FirstArray.GetNumberOfValues() * this->SecondArray.GetNumberOfValues() *
|
|
|
|
this->ThirdArray.GetNumberOfValues();
|
2015-12-01 20:06:28 +00:00
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2017-05-18 14:29:41 +00:00
|
|
|
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData))
|
|
|
|
{
|
2015-12-01 20:06:28 +00:00
|
|
|
return PortalConstExecution(this->FirstArray.PrepareForInput(Device()),
|
2015-12-24 16:19:51 +00:00
|
|
|
this->SecondArray.PrepareForInput(Device()),
|
|
|
|
this->ThirdArray.PrepareForInput(Device()));
|
2015-12-01 20:06:28 +00:00
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2015-12-01 20:06:28 +00:00
|
|
|
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData))
|
|
|
|
{
|
2017-01-09 21:15:32 +00:00
|
|
|
throw vtkm::cont::ErrorBadAllocation(
|
2017-05-18 14:29:41 +00:00
|
|
|
"Cannot write to an ArrayHandleCartesianProduct. It does not make "
|
|
|
|
"sense because there is overlap in the data.");
|
2015-12-01 20:06:28 +00:00
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2016-01-07 19:17:23 +00:00
|
|
|
PortalExecution PrepareForOutput(vtkm::Id vtkmNotUsed(numberOfValues))
|
2015-12-01 20:06:28 +00:00
|
|
|
{
|
2017-01-09 21:15:32 +00:00
|
|
|
throw vtkm::cont::ErrorBadAllocation(
|
2017-05-18 14:29:41 +00:00
|
|
|
"Cannot write to an ArrayHandleCartesianProduct. It does not make "
|
|
|
|
"sense because there is overlap in the data.");
|
2015-12-01 20:06:28 +00:00
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2017-05-18 14:29:41 +00:00
|
|
|
void RetrieveOutputData(StorageType* vtkmNotUsed(storage)) const
|
2015-12-01 20:06:28 +00:00
|
|
|
{
|
|
|
|
// Implementation of this method should be unnecessary. The internal
|
|
|
|
// first and second array handles should automatically retrieve the
|
|
|
|
// output data as necessary.
|
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2015-12-11 18:44:30 +00:00
|
|
|
void Shrink(vtkm::Id /*numberOfValues*/)
|
2015-12-01 20:06:28 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
throw vtkm::cont::ErrorBadAllocation("Does not make sense.");
|
2015-12-01 20:06:28 +00:00
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2015-12-14 16:52:07 +00:00
|
|
|
void ReleaseResources()
|
|
|
|
{
|
2015-12-01 20:06:28 +00:00
|
|
|
this->FirstArray.ReleaseResourcesExecution();
|
|
|
|
this->SecondArray.ReleaseResourcesExecution();
|
|
|
|
this->ThirdArray.ReleaseResourcesExecution();
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2019-12-19 23:00:45 +00:00
|
|
|
AH1 FirstArray;
|
|
|
|
AH2 SecondArray;
|
|
|
|
AH3 ThirdArray;
|
2015-12-01 20:06:28 +00:00
|
|
|
};
|
|
|
|
} // namespace internal
|
|
|
|
|
|
|
|
/// ArrayHandleCartesianProduct is a specialization of ArrayHandle. It takes two delegate
|
|
|
|
/// array handle and makes a new handle that access the corresponding entries
|
|
|
|
/// in these arrays as a pair.
|
|
|
|
///
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename FirstHandleType, typename SecondHandleType, typename ThirdHandleType>
|
2015-12-01 20:06:28 +00:00
|
|
|
class ArrayHandleCartesianProduct
|
2017-05-26 17:53:28 +00:00
|
|
|
: public internal::ArrayHandleCartesianProductTraits<FirstHandleType,
|
|
|
|
SecondHandleType,
|
2017-05-18 14:29:41 +00:00
|
|
|
ThirdHandleType>::Superclass
|
2015-12-01 20:06:28 +00:00
|
|
|
{
|
|
|
|
// If the following line gives a compile error, then the FirstHandleType
|
|
|
|
// template argument is not a valid ArrayHandle type.
|
|
|
|
VTKM_IS_ARRAY_HANDLE(FirstHandleType);
|
|
|
|
VTKM_IS_ARRAY_HANDLE(SecondHandleType);
|
|
|
|
VTKM_IS_ARRAY_HANDLE(ThirdHandleType);
|
|
|
|
|
|
|
|
public:
|
|
|
|
VTKM_ARRAY_HANDLE_SUBCLASS(
|
2017-05-18 14:29:41 +00:00
|
|
|
ArrayHandleCartesianProduct,
|
|
|
|
(ArrayHandleCartesianProduct<FirstHandleType, SecondHandleType, ThirdHandleType>),
|
2017-05-26 17:53:28 +00:00
|
|
|
(typename internal::ArrayHandleCartesianProductTraits<FirstHandleType,
|
|
|
|
SecondHandleType,
|
2017-05-18 14:29:41 +00:00
|
|
|
ThirdHandleType>::Superclass));
|
2015-12-01 20:06:28 +00:00
|
|
|
|
|
|
|
private:
|
2017-08-16 15:34:21 +00:00
|
|
|
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
|
2015-12-01 20:06:28 +00:00
|
|
|
|
|
|
|
public:
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2017-05-18 14:29:41 +00:00
|
|
|
ArrayHandleCartesianProduct(const FirstHandleType& firstArray,
|
|
|
|
const SecondHandleType& secondArray,
|
|
|
|
const ThirdHandleType& thirdArray)
|
|
|
|
: Superclass(StorageType(firstArray, secondArray, thirdArray))
|
|
|
|
{
|
|
|
|
}
|
2019-12-09 22:56:08 +00:00
|
|
|
|
|
|
|
/// Implemented so that it is defined exclusively in the control environment.
|
|
|
|
/// If there is a separate device for the execution environment (for example,
|
|
|
|
/// with CUDA), then the automatically generated destructor could be
|
|
|
|
/// created for all devices, and it would not be valid for all devices.
|
|
|
|
///
|
|
|
|
~ArrayHandleCartesianProduct() {}
|
2015-12-01 20:06:28 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/// A convenience function for creating an ArrayHandleCartesianProduct. It takes the two
|
|
|
|
/// arrays to be zipped together.
|
|
|
|
///
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename FirstHandleType, typename SecondHandleType, typename ThirdHandleType>
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::cont::ArrayHandleCartesianProduct<FirstHandleType, SecondHandleType, ThirdHandleType>
|
2017-05-26 17:53:28 +00:00
|
|
|
make_ArrayHandleCartesianProduct(const FirstHandleType& first,
|
|
|
|
const SecondHandleType& second,
|
2017-05-18 14:29:41 +00:00
|
|
|
const ThirdHandleType& third)
|
2015-12-01 20:06:28 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
return ArrayHandleCartesianProduct<FirstHandleType, SecondHandleType, ThirdHandleType>(
|
|
|
|
first, second, third);
|
2015-12-01 20:06:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} // namespace vtkm::cont
|
|
|
|
|
2018-06-08 15:56:40 +00:00
|
|
|
//=============================================================================
|
|
|
|
// Specializations of serialization related classes
|
2019-09-12 21:19:36 +00:00
|
|
|
/// @cond SERIALIZATION
|
2018-06-08 15:56:40 +00:00
|
|
|
namespace vtkm
|
|
|
|
{
|
|
|
|
namespace cont
|
|
|
|
{
|
|
|
|
|
|
|
|
template <typename AH1, typename AH2, typename AH3>
|
2019-02-28 18:15:27 +00:00
|
|
|
struct SerializableTypeString<vtkm::cont::ArrayHandleCartesianProduct<AH1, AH2, AH3>>
|
2018-06-08 15:56:40 +00:00
|
|
|
{
|
|
|
|
static VTKM_CONT const std::string& Get()
|
|
|
|
{
|
2019-02-28 18:15:27 +00:00
|
|
|
static std::string name = "AH_CartesianProduct<" + SerializableTypeString<AH1>::Get() + "," +
|
|
|
|
SerializableTypeString<AH2>::Get() + "," + SerializableTypeString<AH3>::Get() + ">";
|
2018-06-08 15:56:40 +00:00
|
|
|
return name;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-12-19 23:00:45 +00:00
|
|
|
template <typename T, typename ST1, typename ST2, typename ST3>
|
2019-02-28 18:15:27 +00:00
|
|
|
struct SerializableTypeString<
|
2019-12-19 23:00:45 +00:00
|
|
|
vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>, vtkm::cont::StorageTagCartesianProduct<ST1, ST2, ST3>>>
|
|
|
|
: SerializableTypeString<vtkm::cont::ArrayHandleCartesianProduct<vtkm::cont::ArrayHandle<T, ST1>,
|
|
|
|
vtkm::cont::ArrayHandle<T, ST2>,
|
|
|
|
vtkm::cont::ArrayHandle<T, ST3>>>
|
2018-06-08 15:56:40 +00:00
|
|
|
{
|
|
|
|
};
|
|
|
|
}
|
|
|
|
} // vtkm::cont
|
|
|
|
|
2019-02-05 16:02:29 +00:00
|
|
|
namespace mangled_diy_namespace
|
2018-06-08 15:56:40 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
template <typename AH1, typename AH2, typename AH3>
|
|
|
|
struct Serialization<vtkm::cont::ArrayHandleCartesianProduct<AH1, AH2, AH3>>
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
using Type = typename vtkm::cont::ArrayHandleCartesianProduct<AH1, AH2, AH3>;
|
|
|
|
using BaseType = vtkm::cont::ArrayHandle<typename Type::ValueType, typename Type::StorageTag>;
|
|
|
|
|
|
|
|
public:
|
|
|
|
static VTKM_CONT void save(BinaryBuffer& bb, const BaseType& obj)
|
|
|
|
{
|
|
|
|
auto storage = obj.GetStorage();
|
2019-02-05 16:02:29 +00:00
|
|
|
vtkmdiy::save(bb, storage.GetFirstArray());
|
|
|
|
vtkmdiy::save(bb, storage.GetSecondArray());
|
|
|
|
vtkmdiy::save(bb, storage.GetThirdArray());
|
2018-06-08 15:56:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static VTKM_CONT void load(BinaryBuffer& bb, BaseType& obj)
|
|
|
|
{
|
|
|
|
AH1 array1;
|
|
|
|
AH2 array2;
|
|
|
|
AH3 array3;
|
|
|
|
|
2019-02-05 16:02:29 +00:00
|
|
|
vtkmdiy::load(bb, array1);
|
|
|
|
vtkmdiy::load(bb, array2);
|
|
|
|
vtkmdiy::load(bb, array3);
|
2018-06-08 15:56:40 +00:00
|
|
|
|
|
|
|
obj = vtkm::cont::make_ArrayHandleCartesianProduct(array1, array2, array3);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-12-19 23:00:45 +00:00
|
|
|
template <typename T, typename ST1, typename ST2, typename ST3>
|
2018-06-08 15:56:40 +00:00
|
|
|
struct Serialization<
|
2019-12-19 23:00:45 +00:00
|
|
|
vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>, vtkm::cont::StorageTagCartesianProduct<ST1, ST2, ST3>>>
|
|
|
|
: Serialization<vtkm::cont::ArrayHandleCartesianProduct<vtkm::cont::ArrayHandle<T, ST1>,
|
|
|
|
vtkm::cont::ArrayHandle<T, ST2>,
|
|
|
|
vtkm::cont::ArrayHandle<T, ST3>>>
|
2018-06-08 15:56:40 +00:00
|
|
|
{
|
|
|
|
};
|
|
|
|
} // diy
|
2019-09-12 21:19:36 +00:00
|
|
|
/// @endcond SERIALIZATION
|
2018-06-08 15:56:40 +00:00
|
|
|
|
2015-12-01 20:06:28 +00:00
|
|
|
#endif //vtk_m_cont_ArrayHandleCartesianProduct_h
|