mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-08 13:23:51 +00:00
Implement ArrayHandleGroupVecVariable
This is a fancy array handle that can group entries in another array by arbitrary amounts. This allows us to implement input and output arrays with a different sized Vec for each instance. This is necessary for generating new topologies with cells of different types.
This commit is contained in:
parent
b3d0e1f99b
commit
63c748f049
@ -25,6 +25,8 @@
|
||||
#include <vtkm/TypeTraits.h>
|
||||
#include <vtkm/VecTraits.h>
|
||||
|
||||
#include <vtkm/internal/ArrayPortalValueReference.h>
|
||||
|
||||
namespace vtkm {
|
||||
|
||||
/// \brief A short variable-length array from a window in an ArrayPortal.
|
||||
@ -68,9 +70,11 @@ public:
|
||||
|
||||
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||
VTKM_EXEC_CONT
|
||||
ComponentType operator[](vtkm::IdComponent index) const
|
||||
vtkm::internal::ArrayPortalValueReference<PortalType>
|
||||
operator[](vtkm::IdComponent index) const
|
||||
{
|
||||
return this->Portal.Get(index + this->Offset);
|
||||
return vtkm::internal::ArrayPortalValueReference<PortalType>(
|
||||
this->Portal, index + this->Offset);
|
||||
}
|
||||
|
||||
private:
|
||||
|
538
vtkm/cont/ArrayHandleGroupVecVariable.h
Normal file
538
vtkm/cont/ArrayHandleGroupVecVariable.h
Normal file
@ -0,0 +1,538 @@
|
||||
//============================================================================
|
||||
// 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.
|
||||
//
|
||||
// Copyright 2016 Sandia Corporation.
|
||||
// Copyright 2016 UT-Battelle, LLC.
|
||||
// Copyright 2016 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||
// the U.S. Government retains certain rights in this software.
|
||||
//
|
||||
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
||||
// Laboratory (LANL), the U.S. Government retains certain rights in
|
||||
// this software.
|
||||
//============================================================================
|
||||
#ifndef vtk_m_cont_ArrayHandleGroupVecVariable_h
|
||||
#define vtk_m_cont_ArrayHandleGroupVecVariable_h
|
||||
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/ArrayHandleCast.h>
|
||||
#include <vtkm/cont/ArrayPortal.h>
|
||||
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
|
||||
#include <vtkm/cont/ErrorControlBadValue.h>
|
||||
#include <vtkm/cont/TryExecute.h>
|
||||
|
||||
#include <vtkm/Assert.h>
|
||||
#include <vtkm/VecFromPortal.h>
|
||||
|
||||
#include <vtkm/exec/arg/FetchTagArrayDirectOut.h>
|
||||
|
||||
namespace vtkm {
|
||||
namespace exec {
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<typename SourcePortalType, typename OffsetsPortalType>
|
||||
class ArrayPortalGroupVecVariable
|
||||
{
|
||||
public:
|
||||
using ComponentType =
|
||||
typename std::remove_const<typename SourcePortalType::ValueType>::type;
|
||||
using ValueType = vtkm::VecFromPortal<SourcePortalType>;
|
||||
|
||||
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||
VTKM_EXEC_CONT
|
||||
ArrayPortalGroupVecVariable() : SourcePortal(), OffsetsPortal() { }
|
||||
|
||||
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||
VTKM_EXEC_CONT
|
||||
ArrayPortalGroupVecVariable(const SourcePortalType &sourcePortal,
|
||||
const OffsetsPortalType &offsetsPortal)
|
||||
: SourcePortal(sourcePortal), OffsetsPortal(offsetsPortal) { }
|
||||
|
||||
/// Copy constructor for any other ArrayPortalConcatenate with a portal type
|
||||
/// that can be copied to this portal type. This allows us to do any type
|
||||
/// casting that the portals do (like the non-const to const cast).
|
||||
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||
template<typename OtherSourcePortalType, typename OtherOffsetsPortalType>
|
||||
VTKM_EXEC_CONT
|
||||
ArrayPortalGroupVecVariable(
|
||||
const ArrayPortalGroupVecVariable<OtherSourcePortalType, OtherOffsetsPortalType> &src)
|
||||
: SourcePortal(src.GetSourcePortal()),
|
||||
OffsetsPortal(src.GetOffsetsPortal())
|
||||
{ }
|
||||
|
||||
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||
VTKM_EXEC_CONT
|
||||
vtkm::Id GetNumberOfValues() const
|
||||
{
|
||||
return this->OffsetsPortal.GetNumberOfValues();
|
||||
}
|
||||
|
||||
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||
VTKM_EXEC_CONT
|
||||
ValueType Get(vtkm::Id index) const
|
||||
{
|
||||
vtkm::Id offsetIndex = this->OffsetsPortal.Get(index);
|
||||
vtkm::Id nextOffsetIndex;
|
||||
if (index+1 < this->GetNumberOfValues())
|
||||
{
|
||||
nextOffsetIndex = this->OffsetsPortal.Get(index+1);
|
||||
}
|
||||
else
|
||||
{
|
||||
nextOffsetIndex = this->SourcePortal.GetNumberOfValues();
|
||||
}
|
||||
|
||||
return
|
||||
ValueType(this->SourcePortal,
|
||||
static_cast<vtkm::IdComponent>(nextOffsetIndex-offsetIndex),
|
||||
offsetIndex);
|
||||
}
|
||||
|
||||
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||
VTKM_EXEC_CONT
|
||||
void Set(vtkm::Id vtkmNotUsed(index),
|
||||
const ValueType &vtkmNotUsed(value)) const
|
||||
{
|
||||
// The ValueType (VecFromPortal) operates on demand. Thus, if you set
|
||||
// something in the value, it has already been passed to the array. Perhaps
|
||||
// we should check to make sure that the value used matches the location
|
||||
// you are trying to set in the array, but we don't do that.
|
||||
}
|
||||
|
||||
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||
VTKM_EXEC_CONT
|
||||
const SourcePortalType &GetSourcePortal() const
|
||||
{
|
||||
return this->SourcePortal;
|
||||
}
|
||||
|
||||
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||
VTKM_EXEC_CONT
|
||||
const OffsetsPortalType &GetOffsetsPortal() const
|
||||
{
|
||||
return this->OffsetsPortal;
|
||||
}
|
||||
|
||||
private:
|
||||
SourcePortalType SourcePortal;
|
||||
OffsetsPortalType OffsetsPortal;
|
||||
};
|
||||
|
||||
} // namespace internal (in vtkm::exec)
|
||||
|
||||
namespace arg {
|
||||
|
||||
// We need to override the fetch for output fields using
|
||||
// ArrayPortalGroupVecVariable because this portal does not behave like most
|
||||
// ArrayPortals. Usually you ignore the Load and implement the Store. But if
|
||||
// you ignore the Load, the VecFromPortal gets no portal to set values into.
|
||||
// Instead, you need to implement the Load to point to the array portal. You
|
||||
// can also ignore the Store because the data is already set in the array at
|
||||
// that point.
|
||||
template<typename ThreadIndicesType,
|
||||
typename SourcePortalType,
|
||||
typename OffsetsPortalType>
|
||||
struct Fetch<
|
||||
vtkm::exec::arg::FetchTagArrayDirectOut,
|
||||
vtkm::exec::arg::AspectTagDefault,
|
||||
ThreadIndicesType,
|
||||
vtkm::exec::internal::ArrayPortalGroupVecVariable<SourcePortalType,OffsetsPortalType> >
|
||||
{
|
||||
using ExecObjectType =
|
||||
vtkm::exec::internal::ArrayPortalGroupVecVariable<
|
||||
SourcePortalType,OffsetsPortalType>;
|
||||
using ValueType = typename ExecObjectType::ValueType;
|
||||
|
||||
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||
VTKM_EXEC
|
||||
ValueType Load(const ThreadIndicesType &indices,
|
||||
const ExecObjectType &arrayPortal) const
|
||||
{
|
||||
return arrayPortal.Get(indices.GetOutputIndex());
|
||||
}
|
||||
|
||||
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||
VTKM_EXEC
|
||||
void Store(const ThreadIndicesType &,
|
||||
const ExecObjectType &,
|
||||
const ValueType &) const
|
||||
{
|
||||
// We can actually ignore this because the VecFromPortal will already have
|
||||
// set new values in the array.
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace arg (in vtkm::exec)
|
||||
|
||||
}
|
||||
} // namespace vtkm::exec
|
||||
|
||||
namespace vtkm {
|
||||
namespace cont {
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<typename SourceArrayHandleType, typename OffsetsArrayHandleType>
|
||||
struct StorageTagGroupVecVariable { };
|
||||
|
||||
template<typename SourceArrayHandleType, typename OffsetsArrayHandleType>
|
||||
class Storage<
|
||||
vtkm::VecFromPortal<typename SourceArrayHandleType::PortalControl>,
|
||||
vtkm::cont::internal::StorageTagGroupVecVariable<
|
||||
SourceArrayHandleType, OffsetsArrayHandleType> >
|
||||
{
|
||||
using ComponentType = typename SourceArrayHandleType::ValueType;
|
||||
|
||||
public:
|
||||
using ValueType =
|
||||
vtkm::VecFromPortal<typename SourceArrayHandleType::PortalControl>;
|
||||
|
||||
using PortalType =
|
||||
vtkm::exec::internal::ArrayPortalGroupVecVariable<
|
||||
typename SourceArrayHandleType::PortalControl,
|
||||
typename OffsetsArrayHandleType::PortalControl>;
|
||||
using PortalConstType =
|
||||
vtkm::exec::internal::ArrayPortalGroupVecVariable<
|
||||
typename SourceArrayHandleType::PortalConstControl,
|
||||
typename OffsetsArrayHandleType::PortalConstControl>;
|
||||
|
||||
VTKM_CONT
|
||||
Storage() : Valid(false) { }
|
||||
|
||||
VTKM_CONT
|
||||
Storage(const SourceArrayHandleType &sourceArray,
|
||||
const OffsetsArrayHandleType &offsetsArray)
|
||||
: SourceArray(sourceArray), OffsetsArray(offsetsArray), Valid(true) { }
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::Id GetNumberOfValues() const
|
||||
{
|
||||
VTKM_ASSERT(this->Valid);
|
||||
return this->OffsetsArray.GetNumberOfValues();
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void Allocate(vtkm::Id vtkmNotUsed(numberOfValues))
|
||||
{
|
||||
VTKM_ASSERT(
|
||||
"Allocate not supported for ArrayhandleGroupVecVariable" && false);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void Shrink(vtkm::Id numberOfValues)
|
||||
{
|
||||
VTKM_ASSERT(this->Valid);
|
||||
this->OffsetsArray.Shrink(numberOfValues);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void ReleaseResources()
|
||||
{
|
||||
if (this->Valid)
|
||||
{
|
||||
this->SourceArray.ReleaseResources();
|
||||
this->OffsetsArray.ReleaseResources();
|
||||
}
|
||||
}
|
||||
|
||||
// Required for later use in ArrayTransfer class
|
||||
VTKM_CONT
|
||||
const SourceArrayHandleType &GetSourceArray() const
|
||||
{
|
||||
VTKM_ASSERT(this->Valid);
|
||||
return this->SourceArray;
|
||||
}
|
||||
|
||||
// Required for later use in ArrayTransfer class
|
||||
VTKM_CONT
|
||||
const OffsetsArrayHandleType &GetOffsetsArray() const
|
||||
{
|
||||
VTKM_ASSERT(this->Valid);
|
||||
return this->OffsetsArray;
|
||||
}
|
||||
|
||||
private:
|
||||
SourceArrayHandleType SourceArray;
|
||||
OffsetsArrayHandleType OffsetsArray;
|
||||
bool Valid;
|
||||
};
|
||||
|
||||
template<typename SourceArrayHandleType,
|
||||
typename OffsetsArrayHandleType,
|
||||
typename Device>
|
||||
class ArrayTransfer<
|
||||
vtkm::VecFromPortal<typename SourceArrayHandleType::PortalControl>,
|
||||
vtkm::cont::internal::StorageTagGroupVecVariable<
|
||||
SourceArrayHandleType, OffsetsArrayHandleType>,
|
||||
Device>
|
||||
{
|
||||
public:
|
||||
using ComponentType = typename SourceArrayHandleType::ValueType;
|
||||
using ValueType =
|
||||
vtkm::VecFromPortal<typename SourceArrayHandleType::PortalControl>;
|
||||
|
||||
private:
|
||||
using StorageTag =
|
||||
vtkm::cont::internal::StorageTagGroupVecVariable<
|
||||
SourceArrayHandleType, OffsetsArrayHandleType>;
|
||||
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
|
||||
|
||||
public:
|
||||
using PortalControl = typename StorageType::PortalType;
|
||||
using PortalConstControl = typename StorageType::PortalConstType;
|
||||
|
||||
using PortalExecution =
|
||||
vtkm::exec::internal::ArrayPortalGroupVecVariable<
|
||||
typename SourceArrayHandleType::template ExecutionTypes<Device>::Portal,
|
||||
typename OffsetsArrayHandleType::template ExecutionTypes<Device>::Portal>;
|
||||
using PortalConstExecution =
|
||||
vtkm::exec::internal::ArrayPortalGroupVecVariable<
|
||||
typename SourceArrayHandleType::template ExecutionTypes<Device>::PortalConst,
|
||||
typename OffsetsArrayHandleType::template ExecutionTypes<Device>::PortalConst>;
|
||||
|
||||
VTKM_CONT
|
||||
ArrayTransfer(StorageType *storage)
|
||||
: SourceArray(storage->GetSourceArray()),
|
||||
OffsetsArray(storage->GetOffsetsArray())
|
||||
{ }
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::Id GetNumberOfValues() const
|
||||
{
|
||||
return this->OffsetsArray.GetNumberOfValues();
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData))
|
||||
{
|
||||
return PortalConstExecution(this->SourceArray.PrepareForInput(Device()),
|
||||
this->OffsetsArray.PrepareForInput(Device()));
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData))
|
||||
{
|
||||
return PortalExecution(this->SourceArray.PrepareForInPlace(Device()),
|
||||
this->OffsetsArray.PrepareForInPlace(Device()));
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
PortalExecution PrepareForOutput(vtkm::Id numberOfValues)
|
||||
{
|
||||
// Cannot reallocate an ArrayHandleGroupVecVariable
|
||||
VTKM_ASSERT(numberOfValues == this->OffsetsArray.GetNumberOfValues());
|
||||
return PortalExecution(this->SourceArray.PrepareForOutput(
|
||||
this->SourceArray.GetNumberOfValues(), Device()),
|
||||
this->OffsetsArray.PrepareForOutput(
|
||||
numberOfValues, Device()));
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void RetrieveOutputData(StorageType *vtkmNotUsed(storage)) const
|
||||
{
|
||||
// Implementation of this method should be unnecessary. The internal
|
||||
// array handles should automatically retrieve the output data as
|
||||
// necessary.
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void Shrink(vtkm::Id numberOfValues)
|
||||
{
|
||||
this->OffsetsArray.Shrink(numberOfValues);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void ReleaseResources()
|
||||
{
|
||||
this->SourceArray.ReleaseResourcesExecution();
|
||||
this->OffsetsArray.ReleaseResourcesExecution();
|
||||
}
|
||||
|
||||
private:
|
||||
SourceArrayHandleType SourceArray;
|
||||
OffsetsArrayHandleType OffsetsArray;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
/// \brief Fancy array handle that groups values into vectors of different sizes.
|
||||
///
|
||||
/// It is sometimes the case that you need to run a worklet with an input or
|
||||
/// output that has a different number of values per instance. For example, the
|
||||
/// cells of a CellCetExplicit can have different numbers of points in each
|
||||
/// cell. If inputting or outputting cells of this type, each instance of the
|
||||
/// worklet might need a \c Vec of a different length. This fance array handle
|
||||
/// takes an array of values and an array of offsets and groups the consecutive
|
||||
/// values in Vec-like objects. The values are treated as tightly packed, so
|
||||
/// that each Vec contains the values from one offset to the next. The last
|
||||
/// value contains values from the last offset to the end of the array.
|
||||
///
|
||||
/// For example, if you have an array handle with the 9 values
|
||||
/// 0,1,2,3,4,5,6,7,8 an offsets array handle with the 3 values 0,4,6 and give
|
||||
/// them to an \c ArrayHandleGroupVecVariable, you get an array that looks like
|
||||
/// it contains three values of Vec-like objects with the data [0,1,2,3],
|
||||
/// [4,5], and [6,7,8].
|
||||
///
|
||||
/// Note that this version of \c ArrayHandle breaks some of the assumptions
|
||||
/// about \c ArrayHandle a little bit. Typically, there is exactly one type for
|
||||
/// every value in the array, and this value is also the same between the
|
||||
/// control and execution environment. However, this class uses \c
|
||||
/// VecFromPortal it implement a Vec-like class that has a variable number of
|
||||
/// values, and this type can change between control and execution
|
||||
/// environments.
|
||||
///
|
||||
/// The offsets array is often derived from a list of sizes for each of the
|
||||
/// entries. You can use the convenience function \c
|
||||
/// ConvertNumComponentsToOffsets to take an array of sizes (i.e. the number of
|
||||
/// components for each entry) and get an array of offsets needed for \c
|
||||
/// ArrayHandleGroupVecVariable.
|
||||
///
|
||||
template<typename SourceArrayHandleType, typename OffsetsArrayHandleType>
|
||||
class ArrayHandleGroupVecVariable
|
||||
: public vtkm::cont::ArrayHandle<
|
||||
vtkm::VecFromPortal<typename SourceArrayHandleType::PortalControl>,
|
||||
vtkm::cont::internal::StorageTagGroupVecVariable<
|
||||
SourceArrayHandleType, OffsetsArrayHandleType> >
|
||||
{
|
||||
VTKM_IS_ARRAY_HANDLE(SourceArrayHandleType);
|
||||
VTKM_IS_ARRAY_HANDLE(OffsetsArrayHandleType);
|
||||
|
||||
public:
|
||||
VTKM_ARRAY_HANDLE_SUBCLASS(
|
||||
ArrayHandleGroupVecVariable,
|
||||
(ArrayHandleGroupVecVariable<SourceArrayHandleType, OffsetsArrayHandleType>),
|
||||
(vtkm::cont::ArrayHandle<
|
||||
vtkm::VecFromPortal<typename SourceArrayHandleType::PortalControl>,
|
||||
vtkm::cont::internal::StorageTagGroupVecVariable<
|
||||
SourceArrayHandleType, OffsetsArrayHandleType> >));
|
||||
|
||||
using ComponentType = typename SourceArrayHandleType::ValueType;
|
||||
|
||||
private:
|
||||
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
ArrayHandleGroupVecVariable(const SourceArrayHandleType &sourceArray,
|
||||
const OffsetsArrayHandleType &offsetsArray)
|
||||
: Superclass(StorageType(sourceArray, offsetsArray)) { }
|
||||
};
|
||||
|
||||
/// \c make_ArrayHandleGroupVecVariable is convenience function to generate an
|
||||
/// ArrayHandleGroupVecVariable. It takes in an ArrayHandle of values and an
|
||||
/// array handle of offsets and returns an array handle with consecutive
|
||||
/// entries grouped in a Vec.
|
||||
///
|
||||
template<typename SourceArrayHandleType, typename OffsetsArrayHandleType>
|
||||
VTKM_CONT
|
||||
vtkm::cont::ArrayHandleGroupVecVariable<
|
||||
SourceArrayHandleType, OffsetsArrayHandleType>
|
||||
make_ArrayHandleGroupVecVariable(const SourceArrayHandleType &sourceArray,
|
||||
const OffsetsArrayHandleType &offsetsArray)
|
||||
{
|
||||
return vtkm::cont::ArrayHandleGroupVecVariable<
|
||||
SourceArrayHandleType, OffsetsArrayHandleType>(sourceArray, offsetsArray);
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename NumComponentsArrayType>
|
||||
struct ConvertNumComponentsToOffsetsFunctor
|
||||
{
|
||||
const NumComponentsArrayType NumComponentsArray;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> OffsetsArray;
|
||||
vtkm::Id SourceArraySize;
|
||||
|
||||
VTKM_CONT
|
||||
ConvertNumComponentsToOffsetsFunctor(
|
||||
const NumComponentsArrayType &numCompArray)
|
||||
: NumComponentsArray(numCompArray), SourceArraySize(0)
|
||||
{ }
|
||||
|
||||
template<typename Device>
|
||||
VTKM_CONT
|
||||
bool operator()(Device)
|
||||
{
|
||||
this->SourceArraySize =
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::
|
||||
ScanExclusive(this->NumComponentsArray, this->OffsetsArray);
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename NumComponentsArrayType>
|
||||
VTKM_CONT
|
||||
vtkm::cont::ArrayHandle<vtkm::Id>
|
||||
DoConvertNumComponentsToOffsets(const NumComponentsArrayType &numComponentsArray,
|
||||
vtkm::Id &sourceArraySize)
|
||||
{
|
||||
VTKM_IS_ARRAY_HANDLE(NumComponentsArrayType);
|
||||
|
||||
detail::ConvertNumComponentsToOffsetsFunctor<NumComponentsArrayType>
|
||||
functor(numComponentsArray);
|
||||
bool success = vtkm::cont::TryExecute(functor);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
// Internal error? Maybe need to make a failed to execute error.
|
||||
throw vtkm::cont::ErrorControlInternal(
|
||||
"Failed to run ExclusiveScan on any device.");
|
||||
}
|
||||
|
||||
sourceArraySize = functor.SourceArraySize;
|
||||
return functor.OffsetsArray;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// \c ConvertNumComponentsToOffsets takes an array of Vec sizes (i.e. the
|
||||
/// number of components in each Vec) and returns an array of offsets to a
|
||||
/// packed array of such Vecs. The resulting array can be used with
|
||||
/// \c ArrayHandleGroupVecVariable.
|
||||
///
|
||||
/// If an optional second parameter is given, the expected size of the source
|
||||
/// values array is returned in it.
|
||||
///
|
||||
template<typename NumComponentsArrayType>
|
||||
VTKM_CONT
|
||||
vtkm::cont::ArrayHandle<vtkm::Id>
|
||||
ConvertNumComponentsToOffsets(const NumComponentsArrayType &numComponentsArray,
|
||||
vtkm::Id &sourceArraySize)
|
||||
{
|
||||
VTKM_IS_ARRAY_HANDLE(NumComponentsArrayType);
|
||||
|
||||
return detail::DoConvertNumComponentsToOffsets(
|
||||
vtkm::cont::make_ArrayHandleCast<vtkm::Id>(numComponentsArray),
|
||||
sourceArraySize);
|
||||
}
|
||||
template<typename StorageTag>
|
||||
VTKM_CONT
|
||||
vtkm::cont::ArrayHandle<vtkm::Id>
|
||||
ConvertNumComponentsToOffsets(
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id,StorageTag> &numComponentsArray,
|
||||
vtkm::Id &sourceArraySize)
|
||||
{
|
||||
return detail::DoConvertNumComponentsToOffsets(numComponentsArray,
|
||||
sourceArraySize);
|
||||
}
|
||||
template<typename NumComponentsArrayType>
|
||||
VTKM_CONT
|
||||
vtkm::cont::ArrayHandle<vtkm::Id>
|
||||
ConvertNumComponentsToOffsets(const NumComponentsArrayType &numComponentsArray)
|
||||
{
|
||||
vtkm::Id dummy;
|
||||
return ConvertNumComponentsToOffsets(numComponentsArray, dummy);
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
|
||||
#endif //vtk_m_cont_ArrayHandleGroupVecVariable_h
|
@ -26,6 +26,7 @@ set(headers
|
||||
ArrayHandleConstant.h
|
||||
ArrayHandleCounting.h
|
||||
ArrayHandleGroupVec.h
|
||||
ArrayHandleGroupVecVariable.h
|
||||
ArrayHandleImplicit.h
|
||||
ArrayHandleIndex.h
|
||||
ArrayHandlePermutation.h
|
||||
|
@ -55,34 +55,34 @@ struct WrappedBinaryOperator
|
||||
|
||||
template<typename Argument1, typename Argument2>
|
||||
VTKM_CONT ResultType operator()(
|
||||
const detail::IteratorFromArrayPortalValue<Argument1> &x,
|
||||
const detail::IteratorFromArrayPortalValue<Argument2> &y) const
|
||||
const vtkm::internal::ArrayPortalValueReference<Argument1> &x,
|
||||
const vtkm::internal::ArrayPortalValueReference<Argument2> &y) const
|
||||
{
|
||||
typedef typename detail::IteratorFromArrayPortalValue<Argument1>::ValueType
|
||||
ValueTypeX;
|
||||
typedef typename detail::IteratorFromArrayPortalValue<Argument2>::ValueType
|
||||
ValueTypeY;
|
||||
return m_f( (ValueTypeX)x, (ValueTypeY)y );
|
||||
using ValueTypeX =
|
||||
typename vtkm::internal::ArrayPortalValueReference<Argument1>::ValueType;
|
||||
using ValueTypeY =
|
||||
typename vtkm::internal::ArrayPortalValueReference<Argument2>::ValueType;
|
||||
return m_f( (ValueTypeX)x, (ValueTypeY)y );
|
||||
}
|
||||
|
||||
template<typename Argument1, typename Argument2>
|
||||
VTKM_CONT ResultType operator()(
|
||||
const Argument1 &x,
|
||||
const detail::IteratorFromArrayPortalValue<Argument2> &y) const
|
||||
const vtkm::internal::ArrayPortalValueReference<Argument2> &y) const
|
||||
{
|
||||
typedef typename detail::IteratorFromArrayPortalValue<Argument2>::ValueType
|
||||
ValueTypeY;
|
||||
return m_f( x, (ValueTypeY)y );
|
||||
using ValueTypeY =
|
||||
typename vtkm::internal::ArrayPortalValueReference<Argument2>::ValueType;
|
||||
return m_f( x, (ValueTypeY)y );
|
||||
}
|
||||
|
||||
template<typename Argument1, typename Argument2>
|
||||
VTKM_CONT ResultType operator()(
|
||||
const detail::IteratorFromArrayPortalValue<Argument1> &x,
|
||||
const vtkm::internal::ArrayPortalValueReference<Argument1> &x,
|
||||
const Argument2 &y) const
|
||||
{
|
||||
typedef typename detail::IteratorFromArrayPortalValue<Argument1>::ValueType
|
||||
ValueTypeX;
|
||||
return m_f( (ValueTypeX)x, y );
|
||||
using ValueTypeX =
|
||||
typename vtkm::internal::ArrayPortalValueReference<Argument1>::ValueType;
|
||||
return m_f( (ValueTypeX)x, y );
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -21,60 +21,12 @@
|
||||
#define vtk_m_cont_internal_IteratorFromArrayPortal_h
|
||||
|
||||
#include <vtkm/Assert.h>
|
||||
|
||||
#include <vtkm/internal/ArrayPortalValueReference.h>
|
||||
#include <vtkm/cont/ArrayPortal.h>
|
||||
|
||||
namespace vtkm {
|
||||
namespace cont {
|
||||
namespace internal {
|
||||
namespace detail {
|
||||
|
||||
template<class ArrayPortalType>
|
||||
struct IteratorFromArrayPortalValue
|
||||
{
|
||||
typedef typename ArrayPortalType::ValueType ValueType;
|
||||
|
||||
VTKM_CONT
|
||||
IteratorFromArrayPortalValue(const ArrayPortalType &portal, vtkm::Id index)
|
||||
: Portal(portal), Index(index) { }
|
||||
|
||||
VTKM_CONT
|
||||
void Swap( IteratorFromArrayPortalValue<ArrayPortalType> &rhs ) throw()
|
||||
{
|
||||
//we need use the explicit type not a proxy temp object
|
||||
//A proxy temp object would point to the same underlying data structure
|
||||
//and would not hold the old value of *this once *this was set to rhs.
|
||||
const ValueType aValue = *this;
|
||||
*this = rhs;
|
||||
rhs = aValue;
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
IteratorFromArrayPortalValue<ArrayPortalType> &operator=(
|
||||
const IteratorFromArrayPortalValue<ArrayPortalType> &rhs)
|
||||
{
|
||||
this->Portal.Set(this->Index, rhs.Portal.Get(rhs.Index));
|
||||
return *this;
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
ValueType operator=(const ValueType& value)
|
||||
{
|
||||
this->Portal.Set(this->Index, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
operator ValueType(void) const
|
||||
{
|
||||
return this->Portal.Get(this->Index);
|
||||
}
|
||||
|
||||
const ArrayPortalType& Portal;
|
||||
vtkm::Id Index;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class ArrayPortalType>
|
||||
class IteratorFromArrayPortal
|
||||
@ -82,7 +34,7 @@ class IteratorFromArrayPortal
|
||||
public:
|
||||
using value_type =
|
||||
typename std::remove_const<typename ArrayPortalType::ValueType>::type;
|
||||
using reference = detail::IteratorFromArrayPortalValue<ArrayPortalType>;
|
||||
using reference = vtkm::internal::ArrayPortalValueReference<ArrayPortalType>;
|
||||
using pointer = typename std::add_pointer<value_type>::type;
|
||||
|
||||
using difference_type = std::ptrdiff_t;
|
||||
@ -180,16 +132,6 @@ IteratorFromArrayPortal<ArrayPortalType> make_IteratorEnd(
|
||||
}
|
||||
|
||||
|
||||
//implement a custom swap function, since the std::swap won't work
|
||||
//since we return RValues instead of Lvalues
|
||||
template<typename T>
|
||||
void swap( vtkm::cont::internal::detail::IteratorFromArrayPortalValue<T> a,
|
||||
vtkm::cont::internal::detail::IteratorFromArrayPortalValue<T> b)
|
||||
{
|
||||
a.Swap(b);
|
||||
}
|
||||
|
||||
|
||||
template <typename PortalType>
|
||||
bool
|
||||
operator==(vtkm::cont::internal::IteratorFromArrayPortal<PortalType> const& lhs,
|
||||
|
@ -25,15 +25,16 @@
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/ArrayHandleCast.h>
|
||||
#include <vtkm/cont/ArrayHandleCompositeVector.h>
|
||||
#include <vtkm/cont/ArrayHandleConcatenate.h>
|
||||
#include <vtkm/cont/ArrayHandleConstant.h>
|
||||
#include <vtkm/cont/ArrayHandleCounting.h>
|
||||
#include <vtkm/cont/ArrayHandleGroupVec.h>
|
||||
#include <vtkm/cont/ArrayHandleGroupVecVariable.h>
|
||||
#include <vtkm/cont/ArrayHandleImplicit.h>
|
||||
#include <vtkm/cont/ArrayHandleIndex.h>
|
||||
#include <vtkm/cont/ArrayHandlePermutation.h>
|
||||
#include <vtkm/cont/ArrayHandleTransform.h>
|
||||
#include <vtkm/cont/ArrayHandleZip.h>
|
||||
#include <vtkm/cont/ArrayHandleConcatenate.h>
|
||||
#include <vtkm/VecTraits.h>
|
||||
|
||||
#include <vtkm/worklet/DispatcherMapField.h>
|
||||
@ -113,16 +114,16 @@ private:
|
||||
|
||||
public:
|
||||
struct PassThrough : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
typedef void ControlSignature(FieldIn<>, FieldOut<>);
|
||||
typedef _2 ExecutionSignature(_1);
|
||||
{
|
||||
typedef void ControlSignature(FieldIn<>, FieldOut<>);
|
||||
typedef _2 ExecutionSignature(_1);
|
||||
|
||||
template<class ValueType>
|
||||
VTKM_EXEC
|
||||
ValueType operator()(const ValueType &inValue) const
|
||||
{ return inValue; }
|
||||
template<class ValueType>
|
||||
VTKM_EXEC
|
||||
ValueType operator()(const ValueType &inValue) const
|
||||
{ return inValue; }
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
private:
|
||||
@ -615,6 +616,124 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
// GroupVecVariable is a bit strange because it supports values of different
|
||||
// lengths, so a simple pass through worklet will not work. Use custom
|
||||
// worklets.
|
||||
struct GroupVariableInputWorklet : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
typedef void ControlSignature(FieldIn<>);
|
||||
typedef void ExecutionSignature(_1, WorkIndex);
|
||||
|
||||
template<typename InputType>
|
||||
VTKM_EXEC
|
||||
void operator()(const InputType &input, vtkm::Id workIndex) const
|
||||
{
|
||||
using ComponentType = typename InputType::ComponentType;
|
||||
vtkm::IdComponent expectedSize =
|
||||
static_cast<vtkm::IdComponent>(workIndex + 1);
|
||||
if (expectedSize != input.GetNumberOfComponents())
|
||||
{
|
||||
this->RaiseError("Got unexpected number of components.");
|
||||
}
|
||||
|
||||
vtkm::Id valueIndex = workIndex*(workIndex+1)/2;
|
||||
for (vtkm::IdComponent componentIndex = 0;
|
||||
componentIndex < expectedSize;
|
||||
componentIndex++)
|
||||
{
|
||||
ComponentType expectedValue = TestValue(valueIndex, ComponentType());
|
||||
if (expectedValue != input[componentIndex])
|
||||
{
|
||||
this->RaiseError("Got bad value in GroupVariableInputWorklet.");
|
||||
}
|
||||
valueIndex++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct TestGroupVecVariableAsInput
|
||||
{
|
||||
template<typename ComponentType>
|
||||
VTKM_CONT
|
||||
void operator()(ComponentType) const
|
||||
{
|
||||
vtkm::Id sourceArraySize;
|
||||
|
||||
vtkm::cont::ArrayHandleCounting<vtkm::IdComponent>
|
||||
numComponentsArray(1, 1, ARRAY_SIZE);
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> offsetsArray =
|
||||
vtkm::cont::ConvertNumComponentsToOffsets(numComponentsArray,
|
||||
sourceArraySize);
|
||||
|
||||
vtkm::cont::ArrayHandle<ComponentType> sourceArray;
|
||||
sourceArray.Allocate(sourceArraySize);
|
||||
SetPortal(sourceArray.GetPortalControl());
|
||||
|
||||
vtkm::worklet::DispatcherMapField<GroupVariableInputWorklet,DeviceAdapterTag> dispatcher;
|
||||
dispatcher.Invoke(
|
||||
vtkm::cont::make_ArrayHandleGroupVecVariable(
|
||||
sourceArray, offsetsArray));
|
||||
}
|
||||
};
|
||||
|
||||
// GroupVecVariable is a bit strange because it supports values of different
|
||||
// lengths, so a simple pass through worklet will not work. Use custom
|
||||
// worklets.
|
||||
struct GroupVariableOutputWorklet : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
typedef void ControlSignature(FieldIn<>, FieldOut<>);
|
||||
typedef void ExecutionSignature(_2, WorkIndex);
|
||||
|
||||
template<typename OutputType>
|
||||
VTKM_EXEC
|
||||
void operator()(OutputType &output, vtkm::Id workIndex) const
|
||||
{
|
||||
using ComponentType = typename OutputType::ComponentType;
|
||||
vtkm::IdComponent expectedSize =
|
||||
static_cast<vtkm::IdComponent>(workIndex + 1);
|
||||
if (expectedSize != output.GetNumberOfComponents())
|
||||
{
|
||||
this->RaiseError("Got unexpected number of components.");
|
||||
}
|
||||
|
||||
vtkm::Id valueIndex = workIndex*(workIndex+1)/2;
|
||||
for (vtkm::IdComponent componentIndex = 0;
|
||||
componentIndex < expectedSize;
|
||||
componentIndex++)
|
||||
{
|
||||
output[componentIndex] = TestValue(valueIndex, ComponentType());
|
||||
valueIndex++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct TestGroupVecVariableAsOutput
|
||||
{
|
||||
template<typename ComponentType>
|
||||
VTKM_CONT
|
||||
void operator()(ComponentType) const
|
||||
{
|
||||
vtkm::Id sourceArraySize;
|
||||
|
||||
vtkm::cont::ArrayHandleCounting<vtkm::IdComponent>
|
||||
numComponentsArray(1, 1, ARRAY_SIZE);
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> offsetsArray =
|
||||
vtkm::cont::ConvertNumComponentsToOffsets(numComponentsArray,
|
||||
sourceArraySize);
|
||||
|
||||
vtkm::cont::ArrayHandle<ComponentType> sourceArray;
|
||||
sourceArray.Allocate(sourceArraySize);
|
||||
|
||||
vtkm::worklet::DispatcherMapField<GroupVariableOutputWorklet,DeviceAdapterTag> dispatcher;
|
||||
dispatcher.Invoke(
|
||||
vtkm::cont::ArrayHandleIndex(ARRAY_SIZE),
|
||||
vtkm::cont::make_ArrayHandleGroupVecVariable(
|
||||
sourceArray, offsetsArray));
|
||||
|
||||
CheckPortal(sourceArray.GetPortalConstControl());
|
||||
}
|
||||
};
|
||||
|
||||
struct TestZipAsInput
|
||||
{
|
||||
template< typename KeyType, typename ValueType >
|
||||
@ -858,6 +977,18 @@ private:
|
||||
TestingFancyArrayHandles<DeviceAdapterTag>::TestGroupVecAsOutput<3>(),
|
||||
ScalarTypesToTest());
|
||||
|
||||
std::cout << "-------------------------------------------" << std::endl;
|
||||
std::cout << "Testing ArrayHandleGroupVecVariable as Input" << std::endl;
|
||||
vtkm::testing::Testing::TryTypes(
|
||||
TestingFancyArrayHandles<DeviceAdapterTag>::TestGroupVecVariableAsInput(),
|
||||
ScalarTypesToTest());
|
||||
|
||||
std::cout << "-------------------------------------------" << std::endl;
|
||||
std::cout << "Testing ArrayHandleGroupVecVariable as Output" << std::endl;
|
||||
vtkm::testing::Testing::TryTypes(
|
||||
TestingFancyArrayHandles<DeviceAdapterTag>::TestGroupVecVariableAsOutput(),
|
||||
ScalarTypesToTest());
|
||||
|
||||
std::cout << "-------------------------------------------" << std::endl;
|
||||
std::cout << "Testing ArrayHandleZip as Input" << std::endl;
|
||||
vtkm::testing::Testing::TryTypes(
|
||||
|
124
vtkm/internal/ArrayPortalValueReference.h
Normal file
124
vtkm/internal/ArrayPortalValueReference.h
Normal file
@ -0,0 +1,124 @@
|
||||
//============================================================================
|
||||
// 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.
|
||||
//
|
||||
// Copyright 2016 Sandia Corporation.
|
||||
// Copyright 2016 UT-Battelle, LLC.
|
||||
// Copyright 2016 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||
// the U.S. Government retains certain rights in this software.
|
||||
//
|
||||
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
||||
// Laboratory (LANL), the U.S. Government retains certain rights in
|
||||
// this software.
|
||||
//============================================================================
|
||||
#ifndef vtk_m_internal_ArrayPortalValueReference_h
|
||||
#define vtk_m_internal_ArrayPortalValueReference_h
|
||||
|
||||
#include <vtkm/Types.h>
|
||||
#include <vtkm/TypeTraits.h>
|
||||
#include <vtkm/VecTraits.h>
|
||||
|
||||
namespace vtkm {
|
||||
namespace internal {
|
||||
|
||||
/// \brief A value class for returning setable values of an ArrayPortal
|
||||
///
|
||||
/// \c ArrayPortal classes have a pair of \c Get and \c Set methods that
|
||||
/// retreive and store values in the array. This is to make it easy to
|
||||
/// implement the \c ArrayPortal even it is not really an array. However, there
|
||||
/// are some cases where the code structure expects a reference to a value that
|
||||
/// can be set. For example, the \c IteratorFromArrayPortal class must return
|
||||
/// something from its * operator that behaves like a reference.
|
||||
///
|
||||
/// For cases of this nature \c ArrayPortalValueReference can be used. This
|
||||
/// class is constructured with an \c ArrayPortal and an index into the array.
|
||||
/// The object then behaves like a reference to the value in the array. If you
|
||||
/// set this reference object to a new value, it will call \c Set on the
|
||||
/// \c ArrayPortal to insert the value into the array.
|
||||
///
|
||||
template<typename ArrayPortalType>
|
||||
struct ArrayPortalValueReference
|
||||
{
|
||||
using ValueType = typename ArrayPortalType::ValueType;
|
||||
|
||||
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||
VTKM_EXEC_CONT
|
||||
ArrayPortalValueReference(const ArrayPortalType &portal, vtkm::Id index)
|
||||
: Portal(portal), Index(index) { }
|
||||
|
||||
VTKM_CONT
|
||||
void Swap( ArrayPortalValueReference<ArrayPortalType> &rhs ) throw()
|
||||
{
|
||||
//we need use the explicit type not a proxy temp object
|
||||
//A proxy temp object would point to the same underlying data structure
|
||||
//and would not hold the old value of *this once *this was set to rhs.
|
||||
const ValueType aValue = *this;
|
||||
*this = rhs;
|
||||
rhs = aValue;
|
||||
}
|
||||
|
||||
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||
VTKM_EXEC_CONT
|
||||
ArrayPortalValueReference<ArrayPortalType> &operator=(
|
||||
const ArrayPortalValueReference<ArrayPortalType> &rhs)
|
||||
{
|
||||
this->Portal.Set(this->Index, rhs.Portal.Get(rhs.Index));
|
||||
return *this;
|
||||
}
|
||||
|
||||
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||
VTKM_EXEC_CONT
|
||||
ValueType operator=(const ValueType& value)
|
||||
{
|
||||
this->Portal.Set(this->Index, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||
VTKM_EXEC_CONT
|
||||
operator ValueType(void) const
|
||||
{
|
||||
return this->Portal.Get(this->Index);
|
||||
}
|
||||
|
||||
const ArrayPortalType& Portal;
|
||||
vtkm::Id Index;
|
||||
};
|
||||
|
||||
|
||||
//implement a custom swap function, since the std::swap won't work
|
||||
//since we return RValues instead of Lvalues
|
||||
template<typename T>
|
||||
void swap( vtkm::internal::ArrayPortalValueReference<T> a,
|
||||
vtkm::internal::ArrayPortalValueReference<T> b)
|
||||
{
|
||||
a.Swap(b);
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace vtkm::internal
|
||||
|
||||
namespace vtkm {
|
||||
|
||||
// Make specialization for TypeTraits and VecTraits so that the reference
|
||||
// behaves the same as the value.
|
||||
|
||||
template<typename PortalType>
|
||||
struct TypeTraits<vtkm::internal::ArrayPortalValueReference<PortalType> >
|
||||
: vtkm::TypeTraits<typename vtkm::internal::ArrayPortalValueReference<PortalType>::ValueType>
|
||||
{ };
|
||||
|
||||
template<typename PortalType>
|
||||
struct VecTraits<vtkm::internal::ArrayPortalValueReference<PortalType> >
|
||||
: vtkm::VecTraits<typename vtkm::internal::ArrayPortalValueReference<PortalType>::ValueType>
|
||||
{ };
|
||||
|
||||
} // namespace vtkm
|
||||
|
||||
#endif //vtk_m_internal_ArrayPortalValueReference_h
|
@ -49,6 +49,7 @@ unset(VTKM_USE_DOUBLE_PRECISION)
|
||||
|
||||
set(headers
|
||||
ArrayPortalUniformPointCoordinates.h
|
||||
ArrayPortalValueReference.h
|
||||
Assume.h
|
||||
brigand.hpp
|
||||
ConfigureFor32.h
|
||||
|
@ -19,6 +19,7 @@
|
||||
##============================================================================
|
||||
|
||||
set(unit_tests
|
||||
UnitTestArrayPortalValueReference.cxx
|
||||
UnitTestConfigureFor32.cxx
|
||||
UnitTestConfigureFor64.cxx
|
||||
UnitTestFunctionInterface.cxx
|
||||
|
93
vtkm/internal/testing/UnitTestArrayPortalValueReference.cxx
Normal file
93
vtkm/internal/testing/UnitTestArrayPortalValueReference.cxx
Normal file
@ -0,0 +1,93 @@
|
||||
//============================================================================
|
||||
// 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.
|
||||
//
|
||||
// Copyright 2016 Sandia Corporation.
|
||||
// Copyright 2016 UT-Battelle, LLC.
|
||||
// Copyright 2016 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||
// the U.S. Government retains certain rights in this software.
|
||||
//
|
||||
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
||||
// Laboratory (LANL), the U.S. Government retains certain rights in
|
||||
// this software.
|
||||
//============================================================================
|
||||
|
||||
#include <vtkm/internal/ArrayPortalValueReference.h>
|
||||
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
|
||||
#include <vtkm/cont/testing/Testing.h>
|
||||
|
||||
namespace {
|
||||
|
||||
template<typename ArrayPortalType>
|
||||
void SetReference(
|
||||
vtkm::Id index,
|
||||
vtkm::internal::ArrayPortalValueReference<ArrayPortalType> ref)
|
||||
{
|
||||
using ValueType = typename ArrayPortalType::ValueType;
|
||||
ref = TestValue(index, ValueType());
|
||||
}
|
||||
|
||||
template<typename ArrayPortalType>
|
||||
void CheckReference(
|
||||
vtkm::Id index,
|
||||
vtkm::internal::ArrayPortalValueReference<ArrayPortalType> ref)
|
||||
{
|
||||
using ValueType = typename ArrayPortalType::ValueType;
|
||||
VTKM_TEST_ASSERT(test_equal(ref, TestValue(index, ValueType())),
|
||||
"Got bad value from reference.");
|
||||
}
|
||||
|
||||
static const vtkm::Id ARRAY_SIZE = 10;
|
||||
|
||||
struct DoTestForType
|
||||
{
|
||||
template<typename ValueType>
|
||||
VTKM_CONT
|
||||
void operator()(const ValueType &) const
|
||||
{
|
||||
vtkm::cont::ArrayHandle<ValueType> array;
|
||||
array.Allocate(ARRAY_SIZE);
|
||||
|
||||
std::cout << "Set array using reference" << std::endl;
|
||||
using PortalType =
|
||||
typename vtkm::cont::ArrayHandle<ValueType>::PortalControl;
|
||||
PortalType portal = array.GetPortalControl();
|
||||
for (vtkm::Id index = 0; index < ARRAY_SIZE; index++)
|
||||
{
|
||||
SetReference(
|
||||
index,
|
||||
vtkm::internal::ArrayPortalValueReference<PortalType>(portal,index));
|
||||
}
|
||||
|
||||
std::cout << "Check values" << std::endl;
|
||||
CheckPortal(portal);
|
||||
|
||||
std::cout << "Check references in set array." << std::endl;
|
||||
for (vtkm::Id index = 0; index < ARRAY_SIZE; index++)
|
||||
{
|
||||
CheckReference(
|
||||
index,
|
||||
vtkm::internal::ArrayPortalValueReference<PortalType>(portal,index));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void DoTest()
|
||||
{
|
||||
vtkm::testing::Testing::TryTypes(DoTestForType());
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
int UnitTestArrayPortalValueReference(int, char *[])
|
||||
{
|
||||
return vtkm::cont::testing::Testing::Run(DoTest);
|
||||
}
|
@ -283,8 +283,9 @@ public:
|
||||
const FieldType fieldValue1 = fieldIn[edgeVertex1];
|
||||
|
||||
//need to factor in outputCellId
|
||||
MetaData.InterpIdPortal.Set(outputPointId+triVertex,
|
||||
vtkm::make_Vec(indices[edgeVertex0], indices[edgeVertex1]));
|
||||
MetaData.InterpIdPortal.Set(
|
||||
outputPointId+triVertex,
|
||||
vtkm::Id2(indices[edgeVertex0], indices[edgeVertex1]));
|
||||
|
||||
vtkm::FloatDefault interpolant =
|
||||
static_cast<vtkm::FloatDefault>(iso - fieldValue0) /
|
||||
|
Loading…
Reference in New Issue
Block a user