Support using Token calling PrepareForExecution in ExecutionObject

The old version of ExecutionObject (that only takes a device) is still
supported, but you will get a deprecated warning if that is what is
defined.

Supporing this also included sending vtkm::cont::Token through the
vtkm::cont::arg::Transport mechanism, which was a change that propogated
through a lot of code.
This commit is contained in:
Kenneth Moreland 2020-01-18 23:36:14 -07:00
parent ef3f544a67
commit 76ce9c87f0
64 changed files with 832 additions and 410 deletions

@ -14,6 +14,7 @@
#include <vtkm/cont/DeviceAdapterTag.h>
#include <vtkm/cont/ExecutionObjectBase.h>
#include <vtkm/cont/Token.h>
#include <vtkm/cont/TryExecute.h>
#include <vtkm/cont/internal/ArrayManagerExecution.h>
@ -26,15 +27,16 @@ namespace cont
namespace detail
{
template <typename Device, typename T>
inline auto DoPrepareArgForExec(T&& object, std::true_type)
inline auto DoPrepareArgForExec(T&& object, vtkm::cont::Token& token, std::true_type)
-> decltype(std::declval<T>().PrepareForExecution(Device()))
{
VTKM_IS_EXECUTION_OBJECT(T);
return vtkm::cont::internal::CallPrepareForExecution(object, Device{}, token);
return object.PrepareForExecution(Device{});
}
template <typename Device, typename T>
inline T&& DoPrepareArgForExec(T&& object, std::false_type)
inline T&& DoPrepareArgForExec(T&& object, vtkm::cont::Token&, std::false_type)
{
static_assert(!vtkm::cont::internal::IsExecutionObjectBase<T>::value,
"Internal error: failed to detect execution object.");
@ -42,12 +44,13 @@ inline T&& DoPrepareArgForExec(T&& object, std::false_type)
}
template <typename Device, typename T>
auto PrepareArgForExec(T&& object)
auto PrepareArgForExec(T&& object, vtkm::cont::Token& token)
-> decltype(DoPrepareArgForExec<Device>(std::forward<T>(object),
token,
vtkm::cont::internal::IsExecutionObjectBase<T>{}))
{
return DoPrepareArgForExec<Device>(std::forward<T>(object),
vtkm::cont::internal::IsExecutionObjectBase<T>{});
return DoPrepareArgForExec<Device>(
std::forward<T>(object), token, vtkm::cont::internal::IsExecutionObjectBase<T>{});
}
struct BitFieldToUnorderedSetFunctor
@ -58,8 +61,9 @@ struct BitFieldToUnorderedSetFunctor
VTKM_CONT bool operator()(Device, Args&&... args)
{
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
vtkm::cont::Token token;
this->Result = vtkm::cont::DeviceAdapterAlgorithm<Device>::BitFieldToUnorderedSet(
PrepareArgForExec<Device>(std::forward<Args>(args))...);
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
return true;
}
};
@ -70,8 +74,9 @@ struct CopyFunctor
VTKM_CONT bool operator()(Device, Args&&... args) const
{
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
vtkm::cont::Token token;
vtkm::cont::DeviceAdapterAlgorithm<Device>::Copy(
PrepareArgForExec<Device>(std::forward<Args>(args))...);
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
return true;
}
};
@ -83,8 +88,9 @@ struct CopyIfFunctor
VTKM_CONT bool operator()(Device, Args&&... args) const
{
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
vtkm::cont::Token token;
vtkm::cont::DeviceAdapterAlgorithm<Device>::CopyIf(
PrepareArgForExec<Device>(std::forward<Args>(args))...);
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
return true;
}
};
@ -102,8 +108,9 @@ struct CopySubRangeFunctor
VTKM_CONT bool operator()(Device, Args&&... args)
{
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
vtkm::cont::Token token;
valid = vtkm::cont::DeviceAdapterAlgorithm<Device>::CopySubRange(
PrepareArgForExec<Device>(std::forward<Args>(args))...);
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
return true;
}
};
@ -115,8 +122,10 @@ struct CountSetBitsFunctor
template <typename Device, typename... Args>
VTKM_CONT bool operator()(Device, Args&&... args)
{
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
vtkm::cont::Token token;
this->PopCount = vtkm::cont::DeviceAdapterAlgorithm<Device>::CountSetBits(
PrepareArgForExec<Device>(std::forward<Args>(args))...);
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
return true;
}
};
@ -126,8 +135,10 @@ struct FillFunctor
template <typename Device, typename... Args>
VTKM_CONT bool operator()(Device, Args&&... args)
{
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
vtkm::cont::Token token;
vtkm::cont::DeviceAdapterAlgorithm<Device>::Fill(
PrepareArgForExec<Device>(std::forward<Args>(args))...);
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
return true;
}
};
@ -139,8 +150,9 @@ struct LowerBoundsFunctor
VTKM_CONT bool operator()(Device, Args&&... args) const
{
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
vtkm::cont::Token token;
vtkm::cont::DeviceAdapterAlgorithm<Device>::LowerBounds(
PrepareArgForExec<Device>(std::forward<Args>(args))...);
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
return true;
}
};
@ -159,8 +171,9 @@ struct ReduceFunctor
VTKM_CONT bool operator()(Device, Args&&... args)
{
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
vtkm::cont::Token token;
result = vtkm::cont::DeviceAdapterAlgorithm<Device>::Reduce(
PrepareArgForExec<Device>(std::forward<Args>(args))...);
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
return true;
}
};
@ -171,8 +184,9 @@ struct ReduceByKeyFunctor
VTKM_CONT bool operator()(Device, Args&&... args) const
{
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
vtkm::cont::Token token;
vtkm::cont::DeviceAdapterAlgorithm<Device>::ReduceByKey(
PrepareArgForExec<Device>(std::forward<Args>(args))...);
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
return true;
}
};
@ -191,8 +205,9 @@ struct ScanInclusiveResultFunctor
VTKM_CONT bool operator()(Device, Args&&... args)
{
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
vtkm::cont::Token token;
result = vtkm::cont::DeviceAdapterAlgorithm<Device>::ScanInclusive(
PrepareArgForExec<Device>(std::forward<Args>(args))...);
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
return true;
}
};
@ -275,8 +290,9 @@ struct ScanInclusiveByKeyFunctor
VTKM_CONT bool operator()(Device, Args&&... args) const
{
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
vtkm::cont::Token token;
vtkm::cont::DeviceAdapterAlgorithm<Device>::ScanInclusiveByKey(
PrepareArgForExec<Device>(std::forward<Args>(args))...);
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
return true;
}
};
@ -295,8 +311,9 @@ struct ScanExclusiveFunctor
VTKM_CONT bool operator()(Device, Args&&... args)
{
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
vtkm::cont::Token token;
result = vtkm::cont::DeviceAdapterAlgorithm<Device>::ScanExclusive(
PrepareArgForExec<Device>(std::forward<Args>(args))...);
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
return true;
}
};
@ -309,8 +326,9 @@ struct ScanExclusiveByKeyFunctor
VTKM_CONT bool operator()(Device, Args&&... args) const
{
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
vtkm::cont::Token token;
vtkm::cont::DeviceAdapterAlgorithm<Device>::ScanExclusiveByKey(
PrepareArgForExec<Device>(std::forward<Args>(args))...);
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
return true;
}
};
@ -322,8 +340,9 @@ struct ScanExtendedFunctor
VTKM_CONT bool operator()(Device, Args&&... args)
{
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
vtkm::cont::Token token;
vtkm::cont::DeviceAdapterAlgorithm<Device>::ScanExtended(
PrepareArgForExec<Device>(std::forward<Args>(args))...);
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
return true;
}
};
@ -334,8 +353,9 @@ struct ScheduleFunctor
VTKM_CONT bool operator()(Device, Args&&... args)
{
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
vtkm::cont::Token token;
vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(
PrepareArgForExec<Device>(std::forward<Args>(args))...);
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
return true;
}
};
@ -346,8 +366,9 @@ struct SortFunctor
VTKM_CONT bool operator()(Device, Args&&... args) const
{
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
vtkm::cont::Token token;
vtkm::cont::DeviceAdapterAlgorithm<Device>::Sort(
PrepareArgForExec<Device>(std::forward<Args>(args))...);
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
return true;
}
};
@ -358,8 +379,9 @@ struct SortByKeyFunctor
VTKM_CONT bool operator()(Device, Args&&... args) const
{
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
vtkm::cont::Token token;
vtkm::cont::DeviceAdapterAlgorithm<Device>::SortByKey(
PrepareArgForExec<Device>(std::forward<Args>(args))...);
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
return true;
}
};
@ -381,8 +403,9 @@ struct TransformFunctor
VTKM_CONT bool operator()(Device, Args&&... args) const
{
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
vtkm::cont::Token token;
vtkm::cont::DeviceAdapterAlgorithm<Device>::Transform(
PrepareArgForExec<Device>(std::forward<Args>(args))...);
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
return true;
}
};
@ -393,8 +416,9 @@ struct UniqueFunctor
VTKM_CONT bool operator()(Device, Args&&... args) const
{
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
vtkm::cont::Token token;
vtkm::cont::DeviceAdapterAlgorithm<Device>::Unique(
PrepareArgForExec<Device>(std::forward<Args>(args))...);
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
return true;
}
};
@ -405,8 +429,9 @@ struct UpperBoundsFunctor
VTKM_CONT bool operator()(Device, Args&&... args) const
{
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
vtkm::cont::Token token;
vtkm::cont::DeviceAdapterAlgorithm<Device>::UpperBounds(
PrepareArgForExec<Device>(std::forward<Args>(args))...);
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
return true;
}
};

@ -235,7 +235,7 @@ ArrayHandle<T, S>::PrepareForInput(DeviceAdapterTag device, vtkm::cont::Token& t
this->PrepareForDevice(lock, device);
auto portal = this->Internals->GetExecutionArray(lock)->PrepareForInput(
!this->Internals->IsExecutionArrayValid(lock), device);
!this->Internals->IsExecutionArrayValid(lock), device, token);
this->Internals->SetExecutionArrayValid(lock, true);
@ -263,7 +263,8 @@ ArrayHandle<T, S>::PrepareForOutput(vtkm::Id numberOfValues,
this->Internals->SetControlArrayValid(lock, false);
this->PrepareForDevice(lock, device);
auto portal = this->Internals->GetExecutionArray(lock)->PrepareForOutput(numberOfValues, device);
auto portal =
this->Internals->GetExecutionArray(lock)->PrepareForOutput(numberOfValues, device, token);
// We are assuming that the calling code will fill the array using the
// iterators we are returning, so go ahead and mark the execution array as
@ -302,7 +303,7 @@ ArrayHandle<T, S>::PrepareForInPlace(DeviceAdapterTag device, vtkm::cont::Token&
this->PrepareForDevice(lock, device);
auto portal = this->Internals->GetExecutionArray(lock)->PrepareForInPlace(
!this->Internals->IsExecutionArrayValid(lock), device);
!this->Internals->IsExecutionArrayValid(lock), device, token);
this->Internals->SetExecutionArrayValid(lock, true);

@ -129,21 +129,21 @@ public:
vtkm::Id GetNumberOfValues() const { return this->Data.GetNumberOfBits(); }
VTKM_CONT
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData))
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData), vtkm::cont::Token& token)
{
return PortalConstExecution{ this->Data.PrepareForInput(Device{}) };
return PortalConstExecution{ this->Data.PrepareForInput(Device{}, token) };
}
VTKM_CONT
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData))
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData), vtkm::cont::Token& token)
{
return PortalExecution{ this->Data.PrepareForInPlace(Device{}) };
return PortalExecution{ this->Data.PrepareForInPlace(Device{}, token) };
}
VTKM_CONT
PortalExecution PrepareForOutput(vtkm::Id numberOfValues)
PortalExecution PrepareForOutput(vtkm::Id numberOfValues, vtkm::cont::Token& token)
{
return PortalExecution{ this->Data.PrepareForOutput(numberOfValues, Device{}) };
return PortalExecution{ this->Data.PrepareForOutput(numberOfValues, Device{}, token) };
}
VTKM_CONT

@ -14,6 +14,7 @@
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ErrorBadAllocation.h>
#include <vtkm/cont/Token.h>
namespace vtkm
{
@ -336,7 +337,7 @@ public:
}
VTKM_CONT
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData))
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData), vtkm::cont::Token&)
{
return PortalConstExecution(this->FirstArray.PrepareForInput(Device()),
this->SecondArray.PrepareForInput(Device()),
@ -344,7 +345,7 @@ public:
}
VTKM_CONT
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData))
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData), vtkm::cont::Token&)
{
throw vtkm::cont::ErrorBadAllocation(
"Cannot write to an ArrayHandleCartesianProduct. It does not make "
@ -352,7 +353,7 @@ public:
}
VTKM_CONT
PortalExecution PrepareForOutput(vtkm::Id vtkmNotUsed(numberOfValues))
PortalExecution PrepareForOutput(vtkm::Id vtkmNotUsed(numberOfValues), vtkm::cont::Token&)
{
throw vtkm::cont::ErrorBadAllocation(
"Cannot write to an ArrayHandleCartesianProduct. It does not make "

@ -132,27 +132,33 @@ struct ArrayTupleForEach
}
template <typename DeviceTag, typename PortalTuple>
VTKM_CONT static void PrepareForInput(const ArrayTuple& arrays, PortalTuple& portals)
VTKM_CONT static void PrepareForInput(const ArrayTuple& arrays,
PortalTuple& portals,
vtkm::cont::Token& token)
{
vtkmstd::get<Index>(portals) = vtkmstd::get<Index>(arrays).PrepareForInput(DeviceTag());
Next::template PrepareForInput<DeviceTag>(arrays, portals);
vtkmstd::get<Index>(portals) = vtkmstd::get<Index>(arrays).PrepareForInput(DeviceTag(), token);
Next::template PrepareForInput<DeviceTag>(arrays, portals, token);
}
template <typename DeviceTag, typename PortalTuple>
VTKM_CONT static void PrepareForInPlace(ArrayTuple& arrays, PortalTuple& portals)
VTKM_CONT static void PrepareForInPlace(ArrayTuple& arrays,
PortalTuple& portals,
vtkm::cont::Token& token)
{
vtkmstd::get<Index>(portals) = vtkmstd::get<Index>(arrays).PrepareForInPlace(DeviceTag());
Next::template PrepareForInPlace<DeviceTag>(arrays, portals);
vtkmstd::get<Index>(portals) =
vtkmstd::get<Index>(arrays).PrepareForInPlace(DeviceTag(), token);
Next::template PrepareForInPlace<DeviceTag>(arrays, portals, token);
}
template <typename DeviceTag, typename PortalTuple>
VTKM_CONT static void PrepareForOutput(ArrayTuple& arrays,
PortalTuple& portals,
vtkm::Id numValues)
vtkm::Id numValues,
vtkm::cont::Token& token)
{
vtkmstd::get<Index>(portals) =
vtkmstd::get<Index>(arrays).PrepareForOutput(numValues, DeviceTag());
Next::template PrepareForOutput<DeviceTag>(arrays, portals, numValues);
vtkmstd::get<Index>(arrays).PrepareForOutput(numValues, DeviceTag(), token);
Next::template PrepareForOutput<DeviceTag>(arrays, portals, numValues, token);
}
VTKM_CONT
@ -191,17 +197,17 @@ struct ArrayTupleForEach<Index, Index, ArrayTuple>
}
template <typename DeviceTag, typename PortalTuple>
VTKM_CONT static void PrepareForInput(const ArrayTuple&, PortalTuple&)
VTKM_CONT static void PrepareForInput(const ArrayTuple&, PortalTuple&, vtkm::cont::Token&)
{
}
template <typename DeviceTag, typename PortalTuple>
VTKM_CONT static void PrepareForInPlace(ArrayTuple&, PortalTuple&)
VTKM_CONT static void PrepareForInPlace(ArrayTuple&, PortalTuple&, vtkm::cont::Token&)
{
}
template <typename DeviceTag, typename PortalTuple>
VTKM_CONT static void PrepareForOutput(ArrayTuple&, PortalTuple&, vtkm::Id)
VTKM_CONT static void PrepareForOutput(ArrayTuple&, PortalTuple&, vtkm::Id, vtkm::cont::Token&)
{
}
@ -302,29 +308,30 @@ public:
template <typename DeviceTag>
VTKM_CONT static const typename ExecutionTypes<DeviceTag>::PortalConstTuple PrepareForInput(
const ArrayTuple& arrays)
const ArrayTuple& arrays,
vtkm::cont::Token& token)
{
typename ExecutionTypes<DeviceTag>::PortalConstTuple portals;
ForEachArray::template PrepareForInput<DeviceTag>(arrays, portals);
ForEachArray::template PrepareForInput<DeviceTag>(arrays, portals, token);
return portals;
}
template <typename DeviceTag>
VTKM_CONT static const typename ExecutionTypes<DeviceTag>::PortalTuple PrepareForInPlace(
ArrayTuple& arrays)
ArrayTuple& arrays,
vtkm::cont::Token& token)
{
typename ExecutionTypes<DeviceTag>::PortalTuple portals;
ForEachArray::template PrepareForInPlace<DeviceTag>(arrays, portals);
ForEachArray::template PrepareForInPlace<DeviceTag>(arrays, portals, token);
return portals;
}
template <typename DeviceTag>
VTKM_CONT static const typename ExecutionTypes<DeviceTag>::PortalTuple PrepareForOutput(
ArrayTuple& arrays,
vtkm::Id numValues)
VTKM_CONT static const typename ExecutionTypes<DeviceTag>::PortalTuple
PrepareForOutput(ArrayTuple& arrays, vtkm::Id numValues, vtkm::cont::Token& token)
{
typename ExecutionTypes<DeviceTag>::PortalTuple portals;
ForEachArray::template PrepareForOutput<DeviceTag>(arrays, portals, numValues);
ForEachArray::template PrepareForOutput<DeviceTag>(arrays, portals, numValues, token);
return portals;
}
};
@ -671,24 +678,24 @@ public:
vtkm::Id GetNumberOfValues() const { return this->Storage->GetNumberOfValues(); }
VTKM_CONT
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData)) const
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData), vtkm::cont::Token& token) const
{
return PortalConstExecution(
ControlTraits::template PrepareForInput<DeviceTag>(this->GetArrayTuple()));
ControlTraits::template PrepareForInput<DeviceTag>(this->GetArrayTuple(), token));
}
VTKM_CONT
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData))
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData), vtkm::cont::Token& token)
{
return PortalExecution(
ControlTraits::template PrepareForInPlace<DeviceTag>(this->GetArrayTuple()));
ControlTraits::template PrepareForInPlace<DeviceTag>(this->GetArrayTuple(), token));
}
VTKM_CONT
PortalExecution PrepareForOutput(vtkm::Id numValues)
PortalExecution PrepareForOutput(vtkm::Id numValues, vtkm::cont::Token& token)
{
return PortalExecution(
ControlTraits::template PrepareForOutput<DeviceTag>(this->GetArrayTuple(), numValues));
ControlTraits::template PrepareForOutput<DeviceTag>(this->GetArrayTuple(), numValues, token));
}
VTKM_CONT

@ -283,21 +283,21 @@ public:
}
VTKM_CONT
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData))
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData), vtkm::cont::Token& token)
{
return PortalConstExecution(this->array1.PrepareForInput(Device()),
this->array2.PrepareForInput(Device()));
return PortalConstExecution(this->array1.PrepareForInput(Device(), token),
this->array2.PrepareForInput(Device(), token));
}
VTKM_CONT
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData))
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData), vtkm::cont::Token& token)
{
return PortalExecution(this->array1.PrepareForInPlace(Device()),
this->array2.PrepareForInPlace(Device()));
return PortalExecution(this->array1.PrepareForInPlace(Device(), token),
this->array2.PrepareForInPlace(Device(), token));
}
VTKM_CONT
PortalExecution PrepareForOutput(vtkm::Id vtkmNotUsed(numberOfValues))
PortalExecution PrepareForOutput(vtkm::Id vtkmNotUsed(numberOfValues), vtkm::cont::Token&)
{
throw vtkm::cont::ErrorInternal("ArrayHandleConcatenate is derived and read-only. ");
}

@ -226,34 +226,34 @@ typename std::decay<ArrayT>::type::PortalConstControl GetPortalControlImpl(std::
template <typename ArrayT, typename Device>
typename std::decay<ArrayT>::type::template ExecutionTypes<Device>::Portal
GetPortalInPlaceImpl(std::true_type, ArrayT&& array, Device)
GetPortalInPlaceImpl(std::true_type, ArrayT&& array, Device, vtkm::cont::Token& token)
{
return array.PrepareForInPlace(Device{});
return array.PrepareForInPlace(Device{}, token);
}
template <typename ArrayT, typename Device>
typename std::decay<ArrayT>::type::template ExecutionTypes<Device>::PortalConst
GetPortalInPlaceImpl(std::false_type, ArrayT&& array, Device)
GetPortalInPlaceImpl(std::false_type, ArrayT&& array, Device, vtkm::cont::Token& token)
{
// ArrayT is read-only -- prepare for input instead.
return array.PrepareForInput(Device{});
return array.PrepareForInput(Device{}, token);
}
template <typename ArrayT, typename Device>
typename std::decay<ArrayT>::type::template ExecutionTypes<Device>::Portal
GetPortalOutputImpl(std::true_type, ArrayT&& array, Device)
GetPortalOutputImpl(std::true_type, ArrayT&& array, Device, vtkm::cont::Token& token)
{
// Prepare these for inplace usage instead -- we'll likely need to read
// from these in addition to writing.
return array.PrepareForInPlace(Device{});
return array.PrepareForInPlace(Device{}, token);
}
template <typename ArrayT, typename Device>
typename std::decay<ArrayT>::type::template ExecutionTypes<Device>::PortalConst
GetPortalOutputImpl(std::false_type, ArrayT&& array, Device)
GetPortalOutputImpl(std::false_type, ArrayT&& array, Device, vtkm::cont::Token& token)
{
// ArrayT is read-only -- prepare for input instead.
return array.PrepareForInput(Device{});
return array.PrepareForInput(Device{}, token);
}
} // namespace detail
@ -302,27 +302,26 @@ GetPortalConstControlType<typename std::decay<ArrayT>::type> GetPortalConstContr
}
template <typename ArrayT, typename Device>
GetPortalConstExecutionType<typename std::decay<ArrayT>::type, Device> GetPortalInput(
const ArrayT& array,
Device)
GetPortalConstExecutionType<typename std::decay<ArrayT>::type, Device>
GetPortalInput(const ArrayT& array, Device, vtkm::cont::Token& token)
{
return array.PrepareForInput(Device{});
return array.PrepareForInput(Device{}, token);
}
template <typename ArrayT, typename Device>
GetPortalExecutionType<typename std::decay<ArrayT>::type, Device> GetPortalInPlace(ArrayT&& array,
Device)
GetPortalExecutionType<typename std::decay<ArrayT>::type, Device>
GetPortalInPlace(ArrayT&& array, Device, vtkm::cont::Token& token)
{
return detail::GetPortalInPlaceImpl(
IsWritableArrayHandle<ArrayT>{}, std::forward<ArrayT>(array), Device{});
IsWritableArrayHandle<ArrayT>{}, std::forward<ArrayT>(array), Device{}, token);
}
template <typename ArrayT, typename Device>
GetPortalExecutionType<typename std::decay<ArrayT>::type, Device> GetPortalOutput(ArrayT&& array,
Device)
GetPortalExecutionType<typename std::decay<ArrayT>::type, Device>
GetPortalOutput(ArrayT&& array, Device, vtkm::cont::Token& token)
{
return detail::GetPortalOutputImpl(
IsWritableArrayHandle<ArrayT>{}, std::forward<ArrayT>(array), Device{});
IsWritableArrayHandle<ArrayT>{}, std::forward<ArrayT>(array), Device{}, token);
}
// Equivalent to std::true_type if *any* portal in PortalList can be written to.
@ -381,16 +380,16 @@ using GetPortalConstControlList =
brigand::list<decltype((GetPortalConstControl(std::declval<ArrayTs&>())))...>;
template <typename Device, typename... ArrayTs>
using GetPortalConstExecutionList =
brigand::list<decltype((GetPortalInput(std::declval<ArrayTs&>(), Device{})))...>;
using GetPortalConstExecutionList = brigand::list<decltype(
(GetPortalInput(std::declval<ArrayTs&>(), Device{}, std::declval<vtkm::cont::Token&>())))...>;
template <typename... ArrayTs>
using GetPortalControlList =
brigand::list<decltype((GetPortalControl(std::declval<ArrayTs&>())))...>;
template <typename Device, typename... ArrayTs>
using GetPortalExecutionList =
brigand::list<decltype((GetPortalInPlace(std::declval<ArrayTs&>(), Device{})))...>;
using GetPortalExecutionList = brigand::list<decltype(
(GetPortalInPlace(std::declval<ArrayTs&>(), Device{}, std::declval<vtkm::cont::Token&>())))...>;
template <typename DecoratorImplT, typename... ArrayTs>
struct DecoratorStorageTraits
@ -576,14 +575,15 @@ struct DecoratorStorageTraits
const ArrayTupleType& arrays,
vtkm::Id numValues,
List<Indices...>,
Device dev)
Device dev,
vtkm::cont::Token& token)
{
return CreatePortalDecorator<PortalConstExecutionType<Device>>(
numValues,
impl,
// Don't touch the following line unless you really, really have to. See
// note in MakePortalControl.
GetPortalInput(vtkmstd::get<Indices{}.value>(arrays), dev)...);
GetPortalInput(vtkmstd::get<Indices{}.value>(arrays), dev, token)...);
}
template <template <typename...> class List, typename... Indices, typename Device>
@ -591,14 +591,15 @@ struct DecoratorStorageTraits
ArrayTupleType& arrays,
vtkm::Id numValues,
List<Indices...>,
Device dev)
Device dev,
vtkm::cont::Token& token)
{
return CreatePortalDecorator<PortalExecutionType<Device>>(
numValues,
impl,
// Don't touch the following line unless you really, really have to. See
// note in MakePortalControl.
GetPortalInPlace(vtkmstd::get<Indices{}.value>(arrays), dev)...);
GetPortalInPlace(vtkmstd::get<Indices{}.value>(arrays), dev, token)...);
}
template <template <typename...> class List, typename... Indices, typename Device>
@ -606,14 +607,15 @@ struct DecoratorStorageTraits
ArrayTupleType& arrays,
vtkm::Id numValues,
List<Indices...>,
Device dev)
Device dev,
vtkm::cont::Token& token)
{
return CreatePortalDecorator<PortalExecutionType<Device>>(
numValues,
impl,
// Don't touch the following line unless you really, really have to. See
// note in MakePortalControl.
GetPortalOutput(vtkmstd::get<Indices{}.value>(arrays), dev)...);
GetPortalOutput(vtkmstd::get<Indices{}.value>(arrays), dev, token)...);
}
template <template <typename...> class List, typename... Indices>
@ -662,10 +664,11 @@ struct DecoratorStorageTraits
const ArrayTupleType& arrays,
vtkm::Id numValues,
List<std::size_t, Indices...>,
Device dev)
Device dev,
vtkm::cont::Token& token)
{
return CreatePortalDecorator<PortalConstExecutionType<Device>>(
numValues, impl, GetPortalInput(vtkmstd::get<Indices>(arrays), dev)...);
numValues, impl, GetPortalInput(vtkmstd::get<Indices>(arrays), dev, token)...);
}
template <template <typename, std::size_t...> class List, std::size_t... Indices, typename Device>
@ -673,10 +676,11 @@ struct DecoratorStorageTraits
ArrayTupleType& arrays,
vtkm::Id numValues,
List<std::size_t, Indices...>,
Device dev)
Device dev,
vtkm::cont::Token& token)
{
return CreatePortalDecorator<PortalExecutionType<Device>>(
numValues, impl, GetPortalInPlace(vtkmstd::get<Indices>(arrays), dev)...);
numValues, impl, GetPortalInPlace(vtkmstd::get<Indices>(arrays), dev, token)...);
}
template <template <typename, std::size_t...> class List, std::size_t... Indices, typename Device>
@ -684,10 +688,11 @@ struct DecoratorStorageTraits
ArrayTupleType& arrays,
vtkm::Id numValues,
List<std::size_t, Indices...>,
Device dev)
Device dev,
vtkm::cont::Token& token)
{
return CreatePortalDecorator<PortalExecutionType<Device>>(
numValues, impl, GetPortalOutput(vtkmstd::get<Indices>(arrays), dev)...);
numValues, impl, GetPortalOutput(vtkmstd::get<Indices>(arrays), dev, token)...);
}
template <template <typename, std::size_t...> class List, std::size_t... Indices>
@ -871,33 +876,36 @@ public:
vtkm::Id GetNumberOfValues() const { return this->Storage->GetNumberOfValues(); }
VTKM_CONT
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData)) const
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData), vtkm::cont::Token& token) const
{
return Traits::MakePortalInput(this->Storage->GetImplementation(),
this->Storage->GetArrayTuple(),
this->Storage->GetNumberOfValues(),
IndexList{},
Device{});
Device{},
token);
}
VTKM_CONT
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData))
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData), vtkm::cont::Token& token)
{
return Traits::MakePortalInPlace(this->Storage->GetImplementation(),
this->Storage->GetArrayTuple(),
this->Storage->GetNumberOfValues(),
IndexList{},
Device{});
Device{},
token);
}
VTKM_CONT
PortalExecution PrepareForOutput(vtkm::Id)
PortalExecution PrepareForOutput(vtkm::Id, vtkm::cont::Token& token)
{
return Traits::MakePortalOutput(this->Storage->GetImplementation(),
this->Storage->GetArrayTuple(),
this->Storage->GetNumberOfValues(),
IndexList{},
Device{});
Device{},
token);
}
VTKM_CONT

@ -148,21 +148,21 @@ public:
}
VTKM_CONT
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData))
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData), vtkm::cont::Token&)
{
throw vtkm::cont::ErrorBadValue("Input access not supported: "
"Cannot read from an ArrayHandleDiscard.");
}
VTKM_CONT
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData))
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData), vtkm::cont::Token&)
{
throw vtkm::cont::ErrorBadValue("InPlace access not supported: "
"Cannot read from an ArrayHandleDiscard.");
}
VTKM_CONT
PortalExecution PrepareForOutput(vtkm::Id numValues)
PortalExecution PrepareForOutput(vtkm::Id numValues, vtkm::cont::Token&)
{
VTKM_ASSERT(this->Internal != nullptr);
this->Internal->Allocate(numValues);

@ -212,21 +212,22 @@ public:
vtkm::Id GetNumberOfValues() const { return this->Array.GetNumberOfValues(); }
VTKM_CONT
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData))
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData), vtkm::cont::Token& token)
{
return PortalConstExecution(this->Array.PrepareForInput(Device()), this->Component);
return PortalConstExecution(this->Array.PrepareForInput(Device(), token), this->Component);
}
VTKM_CONT
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData))
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData), vtkm::cont::Token& token)
{
return PortalExecution(this->Array.PrepareForInPlace(Device()), this->Component);
return PortalExecution(this->Array.PrepareForInPlace(Device(), token), this->Component);
}
VTKM_CONT
PortalExecution PrepareForOutput(vtkm::Id numberOfValues)
PortalExecution PrepareForOutput(vtkm::Id numberOfValues, vtkm::cont::Token& token)
{
return PortalExecution(this->Array.PrepareForOutput(numberOfValues, Device()), this->Component);
return PortalExecution(this->Array.PrepareForOutput(numberOfValues, Device(), token),
this->Component);
}
VTKM_CONT

@ -256,32 +256,32 @@ public:
}
VTKM_CONT
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData))
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData), vtkm::cont::Token& token)
{
if (this->SourceArray.GetNumberOfValues() % NUM_COMPONENTS != 0)
{
throw vtkm::cont::ErrorBadValue(
"ArrayHandleGroupVec's source array does not divide evenly into Vecs.");
}
return PortalConstExecution(this->SourceArray.PrepareForInput(Device()));
return PortalConstExecution(this->SourceArray.PrepareForInput(Device(), token));
}
VTKM_CONT
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData))
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData), vtkm::cont::Token& token)
{
if (this->SourceArray.GetNumberOfValues() % NUM_COMPONENTS != 0)
{
throw vtkm::cont::ErrorBadValue(
"ArrayHandleGroupVec's source array does not divide evenly into Vecs.");
}
return PortalExecution(this->SourceArray.PrepareForInPlace(Device()));
return PortalExecution(this->SourceArray.PrepareForInPlace(Device(), token));
}
VTKM_CONT
PortalExecution PrepareForOutput(vtkm::Id numberOfValues)
PortalExecution PrepareForOutput(vtkm::Id numberOfValues, vtkm::cont::Token& token)
{
return PortalExecution(
this->SourceArray.PrepareForOutput(numberOfValues * NUM_COMPONENTS, Device()));
this->SourceArray.PrepareForOutput(numberOfValues * NUM_COMPONENTS, Device(), token));
}
VTKM_CONT

@ -312,27 +312,27 @@ public:
vtkm::Id GetNumberOfValues() const { return this->OffsetsArray.GetNumberOfValues(); }
VTKM_CONT
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData))
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData), vtkm::cont::Token& token)
{
return PortalConstExecution(this->SourceArray.PrepareForInput(Device()),
this->OffsetsArray.PrepareForInput(Device()));
return PortalConstExecution(this->SourceArray.PrepareForInput(Device(), token),
this->OffsetsArray.PrepareForInput(Device(), token));
}
VTKM_CONT
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData))
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData), vtkm::cont::Token& token)
{
return PortalExecution(this->SourceArray.PrepareForInPlace(Device()),
this->OffsetsArray.PrepareForInput(Device()));
return PortalExecution(this->SourceArray.PrepareForInPlace(Device(), token),
this->OffsetsArray.PrepareForInput(Device(), token));
}
VTKM_CONT
PortalExecution PrepareForOutput(vtkm::Id numberOfValues)
PortalExecution PrepareForOutput(vtkm::Id numberOfValues, vtkm::cont::Token& token)
{
// Cannot reallocate an ArrayHandleGroupVecVariable
VTKM_ASSERT(numberOfValues == this->OffsetsArray.GetNumberOfValues());
return PortalExecution(
this->SourceArray.PrepareForOutput(this->SourceArray.GetNumberOfValues(), Device()),
this->OffsetsArray.PrepareForInput(Device()));
this->SourceArray.PrepareForOutput(this->SourceArray.GetNumberOfValues(), Device(), token),
this->OffsetsArray.PrepareForInput(Device(), token));
}
VTKM_CONT

@ -354,20 +354,24 @@ public:
VTKM_CONT vtkm::Id GetNumberOfValues() const { return this->StoragePointer->GetNumberOfValues(); }
VTKM_CONT PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData))
VTKM_CONT PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData),
vtkm::cont::Token& token)
{
return this->StoragePointer->GetArrayHandleVariant().CastAndCall(PrepareForInputFunctor{});
return this->StoragePointer->GetArrayHandleVariant().CastAndCall(PrepareForInputFunctor{},
token);
}
VTKM_CONT PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData))
VTKM_CONT PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData),
vtkm::cont::Token& token)
{
return this->StoragePointer->GetArrayHandleVariant().CastAndCall(PrepareForInPlaceFunctor{});
return this->StoragePointer->GetArrayHandleVariant().CastAndCall(PrepareForInPlaceFunctor{},
token);
}
VTKM_CONT PortalExecution PrepareForOutput(vtkm::Id numberOfValues)
VTKM_CONT PortalExecution PrepareForOutput(vtkm::Id numberOfValues, vtkm::cont::Token& token)
{
return this->StoragePointer->GetArrayHandleVariant().CastAndCall(PrepareForOutputFunctor{},
numberOfValues);
return this->StoragePointer->GetArrayHandleVariant().CastAndCall(
PrepareForOutputFunctor{}, numberOfValues, token);
}
VTKM_CONT void RetrieveOutputData(StorageType* vtkmNotUsed(storage)) const
@ -393,27 +397,30 @@ private:
struct PrepareForInputFunctor
{
template <typename ArrayHandleType>
VTKM_CONT PortalConstExecution operator()(const ArrayHandleType& array)
VTKM_CONT PortalConstExecution operator()(const ArrayHandleType& array,
vtkm::cont::Token& token)
{
return PortalConstExecution(array.PrepareForInput(Device{}));
return PortalConstExecution(array.PrepareForInput(Device{}, token));
}
};
struct PrepareForInPlaceFunctor
{
template <typename ArrayHandleType>
VTKM_CONT PortalExecution operator()(ArrayHandleType& array)
VTKM_CONT PortalExecution operator()(ArrayHandleType& array, vtkm::cont::Token& token)
{
return PortalExecution(array.PrepareForInPlace(Device{}));
return PortalExecution(array.PrepareForInPlace(Device{}, token));
}
};
struct PrepareForOutputFunctor
{
template <typename ArrayHandleType>
VTKM_CONT PortalExecution operator()(ArrayHandleType& array, vtkm::Id numberOfValues)
VTKM_CONT PortalExecution operator()(ArrayHandleType& array,
vtkm::Id numberOfValues,
vtkm::cont::Token& token)
{
return PortalExecution(array.PrepareForOutput(numberOfValues, Device{}));
return PortalExecution(array.PrepareForOutput(numberOfValues, Device{}, token));
}
};
};

@ -234,21 +234,21 @@ public:
vtkm::Id GetNumberOfValues() const { return this->IndexArray.GetNumberOfValues(); }
VTKM_CONT
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData))
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData), vtkm::cont::Token& token)
{
return PortalConstExecution(this->IndexArray.PrepareForInput(Device()),
this->ValueArray.PrepareForInput(Device()));
return PortalConstExecution(this->IndexArray.PrepareForInput(Device(), token),
this->ValueArray.PrepareForInput(Device(), token));
}
VTKM_CONT
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData))
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData), vtkm::cont::Token& token)
{
return PortalExecution(this->IndexArray.PrepareForInput(Device()),
this->ValueArray.PrepareForInPlace(Device()));
return PortalExecution(this->IndexArray.PrepareForInput(Device(), token),
this->ValueArray.PrepareForInPlace(Device(), token));
}
VTKM_CONT
PortalExecution PrepareForOutput(vtkm::Id numberOfValues)
PortalExecution PrepareForOutput(vtkm::Id numberOfValues, vtkm::cont::Token& token)
{
if (numberOfValues != this->GetNumberOfValues())
{
@ -270,8 +270,8 @@ public:
}
return PortalExecution(
this->IndexArray.PrepareForInput(Device()),
this->ValueArray.PrepareForOutput(this->ValueArray.GetNumberOfValues(), Device()));
this->IndexArray.PrepareForInput(Device(), token),
this->ValueArray.PrepareForOutput(this->ValueArray.GetNumberOfValues(), Device(), token));
}
VTKM_CONT

@ -200,21 +200,21 @@ public:
vtkm::Id GetNumberOfValues() const { return this->Array.GetNumberOfValues(); }
VTKM_CONT
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData))
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData), vtkm::cont::Token& token)
{
return PortalConstExecution(this->Array.PrepareForInput(Device()));
return PortalConstExecution(this->Array.PrepareForInput(Device(), token));
}
VTKM_CONT
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData))
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData), vtkm::cont::Token& token)
{
return PortalExecution(this->Array.PrepareForInPlace(Device()));
return PortalExecution(this->Array.PrepareForInPlace(Device(), token));
}
VTKM_CONT
PortalExecution PrepareForOutput(vtkm::Id numberOfValues)
PortalExecution PrepareForOutput(vtkm::Id numberOfValues, vtkm::cont::Token& token)
{
return PortalExecution(this->Array.PrepareForOutput(numberOfValues, Device()));
return PortalExecution(this->Array.PrepareForOutput(numberOfValues, Device(), token));
}
VTKM_CONT

@ -349,27 +349,29 @@ public:
VTKM_CONT vtkm::Id GetNumberOfValues() const { return this->Storage->GetNumberOfValues(); }
VTKM_CONT PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData)) const
VTKM_CONT PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData),
vtkm::cont::Token& token) const
{
return detail::MakeSOAPortal<PortalConstExecution>(
this->Storage->GetArrays(), this->GetNumberOfValues(), [](const BaseArrayType& array) {
return array.PrepareForInput(Device{});
this->Storage->GetArrays(), this->GetNumberOfValues(), [&token](const BaseArrayType& array) {
return array.PrepareForInput(Device{}, token);
});
}
VTKM_CONT PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData)) const
VTKM_CONT PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData),
vtkm::cont::Token& token) const
{
return detail::MakeSOAPortal<PortalExecution>(
this->Storage->GetArrays(), this->GetNumberOfValues(), [](BaseArrayType& array) {
return array.PrepareForInPlace(Device{});
this->Storage->GetArrays(), this->GetNumberOfValues(), [&token](BaseArrayType& array) {
return array.PrepareForInPlace(Device{}, token);
});
}
VTKM_CONT PortalExecution PrepareForOutput(vtkm::Id numValues) const
VTKM_CONT PortalExecution PrepareForOutput(vtkm::Id numValues, vtkm::cont::Token& token) const
{
return detail::MakeSOAPortal<PortalExecution>(
this->Storage->GetArrays(), numValues, [numValues](BaseArrayType& array) {
return array.PrepareForOutput(numValues, Device{});
this->Storage->GetArrays(), numValues, [numValues, &token](BaseArrayType& array) {
return array.PrepareForOutput(numValues, Device{}, token);
});
}

@ -309,21 +309,22 @@ public:
vtkm::Id GetNumberOfValues() const { return this->Array.GetNumberOfValues(); }
VTKM_CONT
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData))
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData), vtkm::cont::Token& token)
{
return PortalConstExecution(this->Array.PrepareForInput(DeviceTag()), this->Map);
return PortalConstExecution(this->Array.PrepareForInput(DeviceTag(), token), this->Map);
}
VTKM_CONT
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData))
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData), vtkm::cont::Token& token)
{
return PortalExecution(this->Array.PrepareForInPlace(DeviceTag()), this->Map);
return PortalExecution(this->Array.PrepareForInPlace(DeviceTag(), token), this->Map);
}
VTKM_CONT
PortalExecution PrepareForOutput(vtkm::Id numberOfValues)
PortalExecution PrepareForOutput(vtkm::Id numberOfValues, vtkm::cont::Token& token)
{
return PortalExecution(this->Array.PrepareForOutput(numberOfValues, DeviceTag()), this->Map);
return PortalExecution(this->Array.PrepareForOutput(numberOfValues, DeviceTag(), token),
this->Map);
}
VTKM_CONT

@ -189,7 +189,7 @@ struct TransformFunctorManagerImpl<ProvidedFunctorType, std::false_type>
ProvidedFunctorType PrepareForControl() const { return this->Functor; }
template <typename Device>
VTKM_CONT ProvidedFunctorType PrepareForExecution(Device) const
VTKM_CONT ProvidedFunctorType PrepareForExecution(Device, vtkm::cont::Token&) const
{
return this->Functor;
}
@ -202,7 +202,8 @@ struct TransformFunctorManagerImpl<ProvidedFunctorType, std::true_type>
ProvidedFunctorType Functor;
// using FunctorType = decltype(std::declval<ProvidedFunctorType>().PrepareForControl());
using FunctorType = decltype(Functor.PrepareForControl());
// using FunctorType = decltype(Functor.PrepareForControl());
using FunctorType = vtkm::cont::internal::ControlObjectType<ProvidedFunctorType>;
TransformFunctorManagerImpl() = default;
@ -213,16 +214,17 @@ struct TransformFunctorManagerImpl<ProvidedFunctorType, std::true_type>
}
VTKM_CONT
auto PrepareForControl() const -> decltype(this->Functor.PrepareForControl())
auto PrepareForControl() const
-> decltype(vtkm::cont::internal::CallPrepareForControl(this->Functor))
{
return this->Functor.PrepareForControl();
return vtkm::cont::internal::CallPrepareForControl(this->Functor);
}
template <typename Device>
VTKM_CONT auto PrepareForExecution(Device device) const
-> decltype(this->Functor.PrepareForExecution(device))
VTKM_CONT auto PrepareForExecution(Device device, vtkm::cont::Token& token) const
-> decltype(vtkm::cont::internal::CallPrepareForExecution(this->Functor, device, token))
{
return this->Functor.PrepareForExecution(device);
return vtkm::cont::internal::CallPrepareForExecution(this->Functor, device, token);
}
};
@ -488,21 +490,21 @@ public:
vtkm::Id GetNumberOfValues() const { return this->Array.GetNumberOfValues(); }
VTKM_CONT
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData))
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData), vtkm::cont::Token& token)
{
return PortalConstExecution(this->Array.PrepareForInput(Device()),
this->Functor.PrepareForExecution(Device()));
return PortalConstExecution(this->Array.PrepareForInput(Device{}, token),
this->Functor.PrepareForExecution(Device{}, token));
}
VTKM_CONT
PortalExecution PrepareForInPlace(bool& vtkmNotUsed(updateData))
PortalExecution PrepareForInPlace(bool& vtkmNotUsed(updateData), vtkm::cont::Token&)
{
throw vtkm::cont::ErrorBadType("ArrayHandleTransform read only. "
"Cannot be used for in-place operations.");
}
VTKM_CONT
PortalExecution PrepareForOutput(vtkm::Id vtkmNotUsed(numberOfValues))
PortalExecution PrepareForOutput(vtkm::Id vtkmNotUsed(numberOfValues), vtkm::cont::Token&)
{
throw vtkm::cont::ErrorBadType("ArrayHandleTransform read only. Cannot be used as output.");
}
@ -573,27 +575,27 @@ public:
vtkm::Id GetNumberOfValues() const { return this->Array.GetNumberOfValues(); }
VTKM_CONT
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData))
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData), vtkm::cont::Token& token)
{
return PortalConstExecution(this->Array.PrepareForInput(Device()),
this->Functor.PrepareForExecution(Device()),
this->InverseFunctor.PrepareForExecution(Device()));
return PortalConstExecution(this->Array.PrepareForInput(Device{}, token),
this->Functor.PrepareForExecution(Device{}, token),
this->InverseFunctor.PrepareForExecution(Device{}, token));
}
VTKM_CONT
PortalExecution PrepareForInPlace(bool& vtkmNotUsed(updateData))
PortalExecution PrepareForInPlace(bool& vtkmNotUsed(updateData), vtkm::cont::Token& token)
{
return PortalExecution(this->Array.PrepareForInPlace(Device()),
this->Functor.PrepareForExecution(Device()),
this->InverseFunctor.PrepareForExecution(Device()));
return PortalExecution(this->Array.PrepareForInPlace(Device{}, token),
this->Functor.PrepareForExecution(Device{}, token),
this->InverseFunctor.PrepareForExecution(Device{}, token));
}
VTKM_CONT
PortalExecution PrepareForOutput(vtkm::Id numberOfValues)
PortalExecution PrepareForOutput(vtkm::Id numberOfValues, vtkm::cont::Token& token)
{
return PortalExecution(this->Array.PrepareForOutput(numberOfValues, Device()),
this->Functor.PrepareForExecution(Device()),
this->InverseFunctor.PrepareForExecution(Device()));
return PortalExecution(this->Array.PrepareForOutput(numberOfValues, Device{}, token),
this->Functor.PrepareForExecution(Device{}, token),
this->InverseFunctor.PrepareForExecution(Device{}, token));
}
VTKM_CONT

@ -242,21 +242,21 @@ public:
vtkm::Id GetNumberOfValues() const { return this->NumValues; }
VTKM_CONT
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData))
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData), vtkm::cont::Token& token)
{
return PortalConstExecution(
this->Array.PrepareForInput(Device()), this->StartIndex, this->NumValues);
this->Array.PrepareForInput(Device(), token), this->StartIndex, this->NumValues);
}
VTKM_CONT
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData))
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData), vtkm::cont::Token& token)
{
return PortalExecution(
this->Array.PrepareForInPlace(Device()), this->StartIndex, this->NumValues);
this->Array.PrepareForInPlace(Device(), token), this->StartIndex, this->NumValues);
}
VTKM_CONT
PortalExecution PrepareForOutput(vtkm::Id numberOfValues)
PortalExecution PrepareForOutput(vtkm::Id numberOfValues, vtkm::cont::Token& token)
{
if (numberOfValues != this->GetNumberOfValues())
{
@ -277,7 +277,8 @@ public:
"output of ArrayHandlePermutation.");
}
return PortalExecution(this->Array.PrepareForOutput(this->Array.GetNumberOfValues(), Device()),
return PortalExecution(
this->Array.PrepareForOutput(this->Array.GetNumberOfValues(), Device(), token),
this->StartIndex,
this->NumValues);
}

@ -257,24 +257,24 @@ public:
}
VTKM_CONT
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData))
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData), vtkm::cont::Token& token)
{
return PortalConstExecution(this->FirstArray.PrepareForInput(Device()),
this->SecondArray.PrepareForInput(Device()));
return PortalConstExecution(this->FirstArray.PrepareForInput(Device(), token),
this->SecondArray.PrepareForInput(Device(), token));
}
VTKM_CONT
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData))
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData), vtkm::cont::Token& token)
{
return PortalExecution(this->FirstArray.PrepareForInPlace(Device()),
this->SecondArray.PrepareForInPlace(Device()));
return PortalExecution(this->FirstArray.PrepareForInPlace(Device(), token),
this->SecondArray.PrepareForInPlace(Device(), token));
}
VTKM_CONT
PortalExecution PrepareForOutput(vtkm::Id numberOfValues)
PortalExecution PrepareForOutput(vtkm::Id numberOfValues, vtkm::cont::Token& token)
{
return PortalExecution(this->FirstArray.PrepareForOutput(numberOfValues, Device()),
this->SecondArray.PrepareForOutput(numberOfValues, Device()));
return PortalExecution(this->FirstArray.PrepareForOutput(numberOfValues, Device(), token),
this->SecondArray.PrepareForOutput(numberOfValues, Device(), token));
}
VTKM_CONT

@ -72,9 +72,19 @@ public:
}
template <typename Device>
VTKM_CONT vtkm::exec::AtomicArrayExecutionObject<T, Device> PrepareForExecution(Device) const
VTKM_CONT vtkm::exec::AtomicArrayExecutionObject<T, Device> PrepareForExecution(
Device,
vtkm::cont::Token& token) const
{
return vtkm::exec::AtomicArrayExecutionObject<T, Device>(this->Handle);
return vtkm::exec::AtomicArrayExecutionObject<T, Device>(this->Handle, token);
}
template <typename Device>
VTKM_CONT VTKM_DEPRECATED(1.6, "PrepareForExecution now requires a vtkm::cont::Token object.")
vtkm::exec::AtomicArrayExecutionObject<T, Device> PrepareForExecution(Device device) const
{
vtkm::cont::Token token;
return this->PrepareForExecution(device, token);
}
private:

@ -17,6 +17,7 @@
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/Logging.h>
#include <vtkm/Deprecated.h>
#include <vtkm/List.h>
#include <vtkm/Types.h>
@ -647,13 +648,23 @@ public:
/// execution environment.
template <typename DeviceAdapterTag>
VTKM_CONT typename ExecutionTypes<DeviceAdapterTag>::PortalConst PrepareForInput(
DeviceAdapterTag device) const
DeviceAdapterTag device,
vtkm::cont::Token& token) const
{
using PortalType = typename ExecutionTypes<DeviceAdapterTag>::PortalConst;
return PortalType{ this->Internals->Data.PrepareForInput(device),
return PortalType{ this->Internals->Data.PrepareForInput(device, token),
this->Internals->NumberOfBits };
}
template <typename DeviceAdapterTag>
VTKM_CONT VTKM_DEPRECATED(1.6, "PrepareForInput now requires a vtkm::cont::Token object.")
typename ExecutionTypes<DeviceAdapterTag>::PortalConst
PrepareForInput(DeviceAdapterTag device) const
{
vtkm::cont::Token token;
return this->PrepareForInput(device, token);
}
/// Prepares (allocates) this BitField to be used as an output from an
/// operation in the execution environment. The internal state of this class
/// is set to have valid data in the execution BitField with the assumption
@ -661,9 +672,8 @@ public:
/// object are called). Returns a portal that can be used in code running in
/// the execution environment.
template <typename DeviceAdapterTag>
VTKM_CONT typename ExecutionTypes<DeviceAdapterTag>::Portal PrepareForOutput(
vtkm::Id numBits,
DeviceAdapterTag device) const
VTKM_CONT typename ExecutionTypes<DeviceAdapterTag>::Portal
PrepareForOutput(vtkm::Id numBits, DeviceAdapterTag device, vtkm::cont::Token& token) const
{
using PortalType = typename ExecutionTypes<DeviceAdapterTag>::Portal;
const vtkm::Id numWords = this->BitsToAllocatedStorageWords(numBits);
@ -675,11 +685,20 @@ public:
static_cast<vtkm::UInt64>(static_cast<size_t>(numWords) * sizeof(WordTypeDefault)))
.c_str());
auto portal = this->Internals->Data.PrepareForOutput(numWords, device);
auto portal = this->Internals->Data.PrepareForOutput(numWords, device, token);
this->Internals->NumberOfBits = numBits;
return PortalType{ portal, numBits };
}
template <typename DeviceAdapterTag>
VTKM_CONT VTKM_DEPRECATED(1.6, "PrepareForOutput now requires a vtkm::cont::Token object.")
typename ExecutionTypes<DeviceAdapterTag>::Portal
PrepareForOutput(vtkm::Id numBits, DeviceAdapterTag device) const
{
vtkm::cont::Token token;
return this->PrepareForOutput(numBits, device, token);
}
/// Prepares this BitField to be used in an in-place operation (both as input
/// and output) in the execution environment. If necessary, copies data to
/// the execution environment. Can throw an exception if this BitField does
@ -687,13 +706,23 @@ public:
/// running in the execution environment.
template <typename DeviceAdapterTag>
VTKM_CONT typename ExecutionTypes<DeviceAdapterTag>::Portal PrepareForInPlace(
DeviceAdapterTag device) const
DeviceAdapterTag device,
vtkm::cont::Token& token) const
{
using PortalType = typename ExecutionTypes<DeviceAdapterTag>::Portal;
return PortalType{ this->Internals->Data.PrepareForInPlace(device),
return PortalType{ this->Internals->Data.PrepareForInPlace(device, token),
this->Internals->NumberOfBits };
}
template <typename DeviceAdapterTag>
VTKM_CONT VTKM_DEPRECATED(1.6, "PrepareForInPlace now requires a vtkm::cont::Token object.")
typename ExecutionTypes<DeviceAdapterTag>::Portal
PrepareForInPlace(DeviceAdapterTag device) const
{
vtkm::cont::Token token;
return this->PrepareForInPlace(device, token);
}
private:
/// Returns the number of words, padded out to respect BlockSize.
VTKM_CONT

@ -239,7 +239,18 @@ public:
template <typename Device, typename VisitTopology, typename IncidentTopology>
VTKM_CONT typename ExecutionTypes<Device, VisitTopology, IncidentTopology>::ExecObjectType
PrepareForInput(Device, VisitTopology, IncidentTopology) const;
PrepareForInput(Device, VisitTopology, IncidentTopology, vtkm::cont::Token&) const;
template <typename Device, typename VisitTopology, typename IncidentTopology>
VTKM_DEPRECATED(1.6, "Provide a vtkm::cont::Token object when calling PrepareForInput.")
VTKM_CONT typename ExecutionTypes<Device, VisitTopology, IncidentTopology>::ExecObjectType
PrepareForInput(Device device,
VisitTopology visitTopology,
IncidentTopology incidentTopology) const
{
vtkm::cont::Token token;
return this->PrepareForInput(device, visitTopology, incidentTopology, token);
}
template <typename VisitTopology, typename IncidentTopology>
VTKM_CONT const typename ConnectivityChooser<VisitTopology, IncidentTopology>::ShapesArrayType&
@ -464,6 +475,8 @@ public:
} // diy
/// @endcond SERIALIZATION
#ifndef vtk_m_cont_CellSetExplicit_hxx
#include <vtkm/cont/CellSetExplicit.hxx>
#endif //vtk_m_cont_CellSetExplicit_hxx
#endif //vtk_m_cont_CellSetExplicit_h

@ -363,7 +363,7 @@ template <typename SST, typename CST, typename OST>
template <typename Device, typename VisitTopology, typename IncidentTopology>
VTKM_CONT
auto CellSetExplicit<SST, CST, OST>
::PrepareForInput(Device, VisitTopology, IncidentTopology) const
::PrepareForInput(Device, VisitTopology, IncidentTopology, vtkm::cont::Token& token) const
-> typename ExecutionTypes<Device,
VisitTopology,
IncidentTopology>::ExecObjectType
@ -378,9 +378,9 @@ auto CellSetExplicit<SST, CST, OST>
VisitTopology,
IncidentTopology>::ExecObjectType;
return ExecObjType(connectivity.Shapes.PrepareForInput(Device{}),
connectivity.Connectivity.PrepareForInput(Device{}),
connectivity.Offsets.PrepareForInput(Device{}));
return ExecObjType(connectivity.Shapes.PrepareForInput(Device{}, token),
connectivity.Connectivity.PrepareForInput(Device{}, token),
connectivity.Offsets.PrepareForInput(Device{}, token));
}
//----------------------------------------------------------------------------

@ -103,12 +103,34 @@ public:
template <typename Device>
ConnectivityP2C<Device> PrepareForInput(Device,
vtkm::TopologyElementTagCell,
vtkm::TopologyElementTagPoint) const;
vtkm::TopologyElementTagPoint,
vtkm::cont::Token&) const;
template <typename Device>
ConnectivityC2P<Device> PrepareForInput(Device,
vtkm::TopologyElementTagPoint,
vtkm::TopologyElementTagCell) const;
vtkm::TopologyElementTagCell,
vtkm::cont::Token&) const;
template <typename Device>
VTKM_DEPRECATED(1.6, "Provide a vtkm::cont::Token object when calling PrepareForInput.")
ConnectivityP2C<Device> PrepareForInput(Device device,
vtkm::TopologyElementTagCell visitTopology,
vtkm::TopologyElementTagPoint incidentTopology) const
{
vtkm::cont::Token token;
return this->PrepareForInput(device, visitTopology, incidentTopology, token);
}
template <typename Device>
VTKM_DEPRECATED(1.6, "Provide a vtkm::cont::Token object when calling PrepareForInput.")
ConnectivityC2P<Device> PrepareForInput(Device device,
vtkm::TopologyElementTagPoint visitTopology,
vtkm::TopologyElementTagCell incidentTopology) const
{
vtkm::cont::Token token;
this->PrepareForInput(device, visitTopology, incidentTopology, token);
}
private:
template <typename Device>

@ -87,10 +87,11 @@ template <typename Device>
CellSetExtrude::ConnectivityP2C<Device> CellSetExtrude::PrepareForInput(
Device,
vtkm::TopologyElementTagCell,
vtkm::TopologyElementTagPoint) const
vtkm::TopologyElementTagPoint,
vtkm::cont::Token& token) const
{
return ConnectivityP2C<Device>(this->Connectivity.PrepareForInput(Device{}),
this->NextNode.PrepareForInput(Device{}),
return ConnectivityP2C<Device>(this->Connectivity.PrepareForInput(Device{}, token),
this->NextNode.PrepareForInput(Device{}, token),
this->NumberOfCellsPerPlane,
this->NumberOfPointsPerPlane,
this->NumberOfPlanes,
@ -102,16 +103,17 @@ template <typename Device>
VTKM_CONT CellSetExtrude::ConnectivityC2P<Device> CellSetExtrude::PrepareForInput(
Device,
vtkm::TopologyElementTagPoint,
vtkm::TopologyElementTagCell) const
vtkm::TopologyElementTagCell,
vtkm::cont::Token& token) const
{
if (!this->ReverseConnectivityBuilt)
{
const_cast<CellSetExtrude*>(this)->BuildReverseConnectivity(Device{});
}
return ConnectivityC2P<Device>(this->RConnectivity.PrepareForInput(Device{}),
this->ROffsets.PrepareForInput(Device{}),
this->RCounts.PrepareForInput(Device{}),
this->PrevNode.PrepareForInput(Device{}),
return ConnectivityC2P<Device>(this->RConnectivity.PrepareForInput(Device{}, token),
this->ROffsets.PrepareForInput(Device{}, token),
this->RCounts.PrepareForInput(Device{}, token),
this->PrevNode.PrepareForInput(Device{}, token),
this->NumberOfCellsPerPlane,
this->NumberOfPointsPerPlane,
this->NumberOfPlanes);

@ -442,21 +442,26 @@ public:
vtkm::TopologyElementTagCell,
vtkm::TopologyElementTagPoint>::ExecObjectType
PrepareForInput(Device device,
vtkm::TopologyElementTagCell from,
vtkm::TopologyElementTagPoint to) const
vtkm::TopologyElementTagCell visitTopology,
vtkm::TopologyElementTagPoint incidentTopology,
vtkm::cont::Token& token) const
{
using ConnectivityType = typename ExecutionTypes<Device,
vtkm::TopologyElementTagCell,
vtkm::TopologyElementTagPoint>::ExecObjectType;
return ConnectivityType(this->ValidCellIds.PrepareForInput(device),
this->FullCellSet.PrepareForInput(device, from, to));
return ConnectivityType(
this->ValidCellIds.PrepareForInput(device, token),
this->FullCellSet.PrepareForInput(device, visitTopology, incidentTopology, token));
}
template <typename Device>
VTKM_CONT typename ExecutionTypes<Device,
vtkm::TopologyElementTagPoint,
vtkm::TopologyElementTagCell>::ExecObjectType
PrepareForInput(Device device, vtkm::TopologyElementTagPoint, vtkm::TopologyElementTagCell) const
PrepareForInput(Device device,
vtkm::TopologyElementTagPoint,
vtkm::TopologyElementTagCell,
vtkm::cont::Token& token) const
{
if (!this->VisitPointsWithCells.ElementsValid)
{
@ -468,8 +473,17 @@ public:
using ConnectivityType = typename ExecutionTypes<Device,
vtkm::TopologyElementTagPoint,
vtkm::TopologyElementTagCell>::ExecObjectType;
return ConnectivityType(this->VisitPointsWithCells.Connectivity.PrepareForInput(device),
this->VisitPointsWithCells.Offsets.PrepareForInput(device));
return ConnectivityType(this->VisitPointsWithCells.Connectivity.PrepareForInput(device, token),
this->VisitPointsWithCells.Offsets.PrepareForInput(device, token));
}
template <typename Device, typename VisitTopology, typename IncidentTopology>
VTKM_CONT VTKM_DEPRECATED(1.6, "Provide a vtkm::cont::Token object when calling PrepareForInput.")
typename ExecutionTypes<Device, VisitTopology, IncidentTopology>::ExecObjectType
PrepareForInput(Device device, VisitTopology visitTopology, IncidentTopology incidentTopology)
{
vtkm::cont::Token token;
return this->PrepareForInput(device, visitTopology, incidentTopology, token);
}
VTKM_CONT

@ -115,7 +115,18 @@ public:
template <typename DeviceAdapter, typename VisitTopology, typename IncidentTopology>
typename ExecutionTypes<DeviceAdapter, VisitTopology, IncidentTopology>::ExecObjectType
PrepareForInput(DeviceAdapter, VisitTopology, IncidentTopology) const;
PrepareForInput(DeviceAdapter, VisitTopology, IncidentTopology, vtkm::cont::Token&) const;
template <typename DeviceAdapter, typename VisitTopology, typename IncidentTopology>
VTKM_DEPRECATED(1.6, "Provide a vtkm::cont::Token object when calling PrepareForInput.")
typename ExecutionTypes<DeviceAdapter, VisitTopology, IncidentTopology>::ExecObjectType
PrepareForInput(DeviceAdapter device,
VisitTopology visitTopology,
IncidentTopology incidentTopology) const
{
vtkm::cont::Token token;
return this->PrepareForInput(device, visitTopology, incidentTopology, token);
}
void PrintSummary(std::ostream& out) const override;

@ -31,7 +31,8 @@ typename CellSetStructured<DIMENSION>::template ExecutionTypes<DeviceAdapter,
IncidentTopology>::ExecObjectType
CellSetStructured<DIMENSION>::PrepareForInput(DeviceAdapter,
VisitTopology,
IncidentTopology) const
IncidentTopology,
vtkm::cont::Token&) const
{
using ConnectivityType =
typename ExecutionTypes<DeviceAdapter, VisitTopology, IncidentTopology>::ExecObjectType;

@ -55,18 +55,46 @@ struct HasPrepareForControl
{
};
} // namespace internal
}
} // namespace vtkm::cont
/// Checks that the argument is a proper execution object.
///
#define VTKM_IS_EXECUTION_AND_CONTROL_OBJECT(execObject) \
static_assert(::vtkm::cont::internal::IsExecutionAndControlObjectBase<execObject>::value, \
"Provided type is not a subclass of vtkm::cont::ExecutionAndControlObjectBase."); \
static_assert(::vtkm::cont::internal::HasPrepareForExecution<execObject>::value, \
static_assert(::vtkm::cont::internal::HasPrepareForExecution<execObject>::value || \
::vtkm::cont::internal::HasPrepareForExecutionDeprecated<execObject>::value, \
"Provided type does not have requisite PrepareForExecution method."); \
static_assert(::vtkm::cont::internal::HasPrepareForControl<execObject>::value, \
"Provided type does not have requisite PrepareForControl method.")
/// \brief Gets the object to use in the control environment from an ExecutionAndControlObject.
///
/// An execution and control object (that is, an object inheriting from
/// `vtkm::cont::ExecutionAndControlObjectBase`) is really a control object factory that generates
/// a objects to be used in either the execution environment or the control environment. This
/// function takes a subclass of `ExecutionAndControlObjectBase` and returns the control object.
///
template <typename T>
VTKM_CONT auto CallPrepareForControl(T&& execObject) -> decltype(execObject.PrepareForControl())
{
VTKM_IS_EXECUTION_AND_CONTROL_OBJECT(T);
return execObject.PrepareForControl();
}
/// \brief Gets the object to use in the control environment from an ExecutionAndControlObject.
///
/// An execution and control object (that is, an object inheriting from
/// `vtkm::cont::ExecutionAndControlObjectBase`) is really a control object factory that generates
/// a objects to be used in either the execution environment or the control environment. This
/// templated type gives the type for the class used in the control environment for a given
/// ExecutionAndControlObject.
///
template <typename ExecutionAndControlObject>
using ControlObjectType =
decltype(CallPrepareForControl(std::declval<ExecutionAndControlObject>()));
} // namespace internal
}
} // namespace vtkm::cont
#endif //vtk_m_cont_ExecutionAndControlObjectBase_h

@ -10,8 +10,11 @@
#ifndef vtk_m_cont_ExecutionObjectBase_h
#define vtk_m_cont_ExecutionObjectBase_h
#include <vtkm/Deprecated.h>
#include <vtkm/Types.h>
#include <vtkm/cont/Token.h>
#include <vtkm/cont/serial/internal/DeviceAdapterTagSerial.h>
namespace vtkm
@ -19,11 +22,12 @@ namespace vtkm
namespace cont
{
/// Base \c ExecutionObjectBase for execution objects to inherit from so that
/// Base `ExecutionObjectBase` for execution objects to inherit from so that
/// you can use an arbitrary object as a parameter in an execution environment
/// function. Any subclass of \c ExecutionObjectBase must implement a
/// \c PrepareForExecution method that takes a device adapter tag and returns
/// an object for that device.
/// function. Any subclass of `ExecutionObjectBase` must implement a
/// `PrepareForExecution` method that takes a device adapter tag and a
/// `vtkm::cont::Token` and then returns an object for that device. The object
/// must be valid as long as the `Token` is in scope.
///
struct ExecutionObjectBase
{
@ -36,6 +40,17 @@ namespace detail
{
struct CheckPrepareForExecution
{
template <typename T>
static auto check(T* p) -> decltype(p->PrepareForExecution(vtkm::cont::DeviceAdapterTagSerial{},
std::declval<vtkm::cont::Token&>()),
std::true_type());
template <typename T>
static auto check(...) -> std::false_type;
};
struct CheckPrepareForExecutionDeprecated
{
template <typename T>
static auto check(T* p)
@ -57,16 +72,92 @@ struct HasPrepareForExecution
{
};
} // namespace internal
}
} // namespace vtkm::cont
template <typename T>
struct HasPrepareForExecutionDeprecated
: decltype(
detail::CheckPrepareForExecutionDeprecated::check<typename std::decay<T>::type>(nullptr))
{
};
/// Checks that the argument is a proper execution object.
///
#define VTKM_IS_EXECUTION_OBJECT(execObject) \
static_assert(::vtkm::cont::internal::IsExecutionObjectBase<execObject>::value, \
"Provided type is not a subclass of vtkm::cont::ExecutionObjectBase."); \
static_assert(::vtkm::cont::internal::HasPrepareForExecution<execObject>::value, \
static_assert(::vtkm::cont::internal::HasPrepareForExecution<execObject>::value || \
::vtkm::cont::internal::HasPrepareForExecutionDeprecated<execObject>::value, \
"Provided type does not have requisite PrepareForExecution method.")
namespace detail
{
template <typename T, typename Device>
VTKM_CONT auto CallPrepareForExecutionImpl(T&& execObject,
Device device,
vtkm::cont::Token& token,
std::true_type,
std::false_type)
-> decltype(execObject.PrepareForExecution(device, token))
{
return execObject.PrepareForExecution(device, token);
}
template <typename T, typename Device>
VTKM_DEPRECATED(
1.6,
"ExecutionObjects now require a PrepareForExecution that takes a vtkm::cont::Token object."
"PrepareForExecution(Device) is deprecated. Implement PrepareForExecution(Device, Token).")
VTKM_CONT auto CallPrepareForExecutionImpl(T&& execObject,
Device device,
vtkm::cont::Token&,
std::false_type,
std::true_type)
-> decltype(execObject.PrepareForExecution(device))
{
return execObject.PrepareForExecution(device);
}
} // namespace detail
/// \brief Gets the object to use in the execution environment from an ExecutionObject.
///
/// An execution object (that is, an object inheriting from `vtkm::cont::ExecutionObjectBase`) is
/// really a control object factory that generates an object to be used in the execution
/// environment for a particular device. This function takes a subclass of `ExecutionObjectBase`
/// and returns the execution object for a given device.
///
template <typename T, typename Device>
VTKM_CONT auto CallPrepareForExecution(T&& execObject, Device device, vtkm::cont::Token& token)
-> decltype(detail::CallPrepareForExecutionImpl(std::forward<T>(execObject),
device,
token,
HasPrepareForExecution<T>{},
HasPrepareForExecutionDeprecated<T>{}))
{
VTKM_IS_EXECUTION_OBJECT(T);
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
return detail::CallPrepareForExecutionImpl(std::forward<T>(execObject),
device,
token,
HasPrepareForExecution<T>{},
HasPrepareForExecutionDeprecated<T>{});
}
/// \brief Gets the type of the execution-side object for an ExecutionObject.
///
/// An execution object (that is, an object inheriting from `vtkm::cont::ExecutionObjectBase`) is
/// really a control object factory that generates an object to be used in the execution
/// environment for a particular device. This templated type gives the type for the class used
/// in the execution environment for a given ExecutionObject and device.
///
template <typename ExecutionObject, typename Device>
using ExecutionObjectType = decltype(CallPrepareForExecution(std::declval<ExecutionObject>(),
Device{},
std::declval<vtkm::cont::Token&>()));
} // namespace internal
}
} // namespace vtkm::cont
#endif //vtk_m_cont_ExecutionObjectBase_h

@ -33,7 +33,9 @@ struct VTKM_ALWAYS_EXPORT ArrayPortalExtrudePlane
VTKM_EXEC_CONT
ArrayPortalExtrudePlane()
: Portal()
, NumberOfPlanes(0){};
, NumberOfPlanes(0)
{
}
ArrayPortalExtrudePlane(const PortalType& p, vtkm::Int32 numOfPlanes)
: Portal(p)
@ -248,7 +250,9 @@ struct VTKM_ALWAYS_EXPORT ArrayPortalExtrude
: Portal()
, NumberOfValues(0)
, NumberOfPlanes(0)
, UseCylindrical(false){};
, UseCylindrical(false)
{
}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
@ -484,24 +488,24 @@ public:
vtkm::Id GetNumberOfValues() const { return this->ControlData->GetNumberOfValues(); }
VTKM_CONT
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData))
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData), vtkm::cont::Token& token)
{
return PortalConstExecution(
this->ControlData->Array.PrepareForInput(Device()),
this->ControlData->Array.PrepareForInput(Device(), token),
static_cast<vtkm::Int32>(this->ControlData->Array.GetNumberOfValues()),
this->ControlData->GetNumberOfPlanes(),
this->ControlData->GetUseCylindrical());
}
VTKM_CONT
PortalExecution PrepareForInPlace(bool& vtkmNotUsed(updateData))
PortalExecution PrepareForInPlace(bool& vtkmNotUsed(updateData), vtkm::cont::Token&)
{
throw vtkm::cont::ErrorBadType("StorageExtrude read only. "
"Cannot be used for in-place operations.");
}
VTKM_CONT
PortalExecution PrepareForOutput(vtkm::Id vtkmNotUsed(numberOfValues))
PortalExecution PrepareForOutput(vtkm::Id vtkmNotUsed(numberOfValues), vtkm::cont::Token&)
{
throw vtkm::cont::ErrorBadType("StorageExtrude read only. Cannot be used as output.");
}

@ -15,6 +15,7 @@
#include <vtkm/cont/ArrayPortalToIterators.h>
#include <vtkm/cont/ErrorBadValue.h>
#include <vtkm/cont/Storage.h>
#include <vtkm/cont/Token.h>
#include <vtkm/cont/internal/ArrayTransfer.h>
@ -120,7 +121,7 @@ public:
vtkm::Id GetNumberOfValues() const { return this->Storage->GetNumberOfValues(); }
VTKM_CONT
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData))
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData), vtkm::cont::Token&)
{
return this->Storage->GetPortalConst();
}
@ -136,14 +137,14 @@ public:
VTKM_CONT
NO_OPTIMIZE_FUNC_ATTRIBUTE
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData))
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData), vtkm::cont::Token&)
{
throw vtkm::cont::ErrorBadValue("Implicit arrays cannot be used for output or in place.");
}
VTKM_CONT
NO_OPTIMIZE_FUNC_ATTRIBUTE
PortalExecution PrepareForOutput(vtkm::Id vtkmNotUsed(numberOfValues))
PortalExecution PrepareForOutput(vtkm::Id vtkmNotUsed(numberOfValues), vtkm::cont::Token&)
{
throw vtkm::cont::ErrorBadValue("Implicit arrays cannot be used for output.");
}

@ -412,17 +412,20 @@ struct ArrayTransfer<T, vtkm::cont::StorageTagVirtual, Device> : detail::ArrayTr
{
}
VTKM_CONT typename Superclass::PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData))
VTKM_CONT typename Superclass::PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData),
vtkm::cont::Token&)
{
return this->Superclass::PrepareForInput(Device());
}
VTKM_CONT typename Superclass::PortalExecution PrepareForOutput(vtkm::Id numberOfValues)
VTKM_CONT typename Superclass::PortalExecution PrepareForOutput(vtkm::Id numberOfValues,
vtkm::cont::Token&)
{
return this->Superclass::PrepareForOutput(numberOfValues, Device());
}
VTKM_CONT typename Superclass::PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData))
VTKM_CONT typename Superclass::PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData),
vtkm::cont::Token&)
{
return this->Superclass::PrepareForInPlace(Device());
}

@ -43,14 +43,15 @@ struct Transport<vtkm::cont::arg::TransportTagArrayIn, ContObjectType, Device>
VTKM_CONT ExecObjectType operator()(const ContObjectType& object,
const InputDomainType& vtkmNotUsed(inputDomain),
vtkm::Id inputRange,
vtkm::Id vtkmNotUsed(outputRange)) const
vtkm::Id vtkmNotUsed(outputRange),
vtkm::cont::Token& token) const
{
if (object.GetNumberOfValues() != inputRange)
{
throw vtkm::cont::ErrorBadValue("Input array to worklet invocation the wrong size.");
}
return object.PrepareForInput(Device());
return object.PrepareForInput(Device(), token);
}
};
}

@ -46,14 +46,15 @@ struct Transport<vtkm::cont::arg::TransportTagArrayInOut, ContObjectType, Device
VTKM_CONT ExecObjectType operator()(ContObjectType& object,
const InputDomainType& vtkmNotUsed(inputDomain),
vtkm::Id vtkmNotUsed(inputRange),
vtkm::Id outputRange) const
vtkm::Id outputRange,
vtkm::cont::Token& token) const
{
if (object.GetNumberOfValues() != outputRange)
{
throw vtkm::cont::ErrorBadValue("Input/output array to worklet invocation the wrong size.");
}
return object.PrepareForInPlace(Device());
return object.PrepareForInPlace(Device(), token);
}
};
}

@ -46,9 +46,10 @@ struct Transport<vtkm::cont::arg::TransportTagArrayOut, ContObjectType, Device>
VTKM_CONT ExecObjectType operator()(ContObjectType& object,
const InputDomainType& vtkmNotUsed(inputDomain),
vtkm::Id vtkmNotUsed(inputRange),
vtkm::Id outputRange) const
vtkm::Id outputRange,
vtkm::cont::Token& token) const
{
return object.PrepareForOutput(outputRange, Device());
return object.PrepareForOutput(outputRange, Device(), token);
}
};
}

@ -54,13 +54,14 @@ struct Transport<vtkm::cont::arg::TransportTagAtomicArray,
operator()(vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagBasic>& array,
const InputDomainType&,
vtkm::Id,
vtkm::Id) const
vtkm::Id,
vtkm::cont::Token& token) const
{
// Note: we ignore the size of the domain because the randomly accessed
// array might not have the same size depending on how the user is using
// the array.
ExecType obj(array);
return obj.PrepareForExecution(Device());
return obj.PrepareForExecution(Device(), token);
}
};

@ -38,10 +38,13 @@ struct Transport<vtkm::cont::arg::TransportTagBitFieldIn, vtkm::cont::BitField,
typename vtkm::cont::BitField::template ExecutionTypes<Device>::PortalConst;
template <typename InputDomainType>
VTKM_CONT ExecObjectType
operator()(vtkm::cont::BitField& field, const InputDomainType&, vtkm::Id, vtkm::Id) const
VTKM_CONT ExecObjectType operator()(vtkm::cont::BitField& field,
const InputDomainType&,
vtkm::Id,
vtkm::Id,
vtkm::cont::Token& token) const
{
return field.PrepareForInput(Device{});
return field.PrepareForInput(Device{}, token);
}
};
@ -51,12 +54,15 @@ struct Transport<vtkm::cont::arg::TransportTagBitFieldOut, vtkm::cont::BitField,
using ExecObjectType = typename vtkm::cont::BitField::template ExecutionTypes<Device>::Portal;
template <typename InputDomainType>
VTKM_CONT ExecObjectType
operator()(vtkm::cont::BitField& field, const InputDomainType&, vtkm::Id, vtkm::Id) const
VTKM_CONT ExecObjectType operator()(vtkm::cont::BitField& field,
const InputDomainType&,
vtkm::Id,
vtkm::Id,
vtkm::cont::Token& token) const
{
// This behaves similarly to WholeArray tags, where "Out" maps to InPlace
// since we don't want to reallocate or enforce size restrictions.
return field.PrepareForInPlace(Device{});
return field.PrepareForInPlace(Device{}, token);
}
};
@ -66,10 +72,13 @@ struct Transport<vtkm::cont::arg::TransportTagBitFieldInOut, vtkm::cont::BitFiel
using ExecObjectType = typename vtkm::cont::BitField::template ExecutionTypes<Device>::Portal;
template <typename InputDomainType>
VTKM_CONT ExecObjectType
operator()(vtkm::cont::BitField& field, const InputDomainType&, vtkm::Id, vtkm::Id) const
VTKM_CONT ExecObjectType operator()(vtkm::cont::BitField& field,
const InputDomainType&,
vtkm::Id,
vtkm::Id,
vtkm::cont::Token& token) const
{
return field.PrepareForInPlace(Device{});
return field.PrepareForInPlace(Device{}, token);
}
};
}

@ -47,10 +47,13 @@ struct Transport<vtkm::cont::arg::TransportTagCellSetIn<VisitTopology, IncidentT
std::declval<ContObjectType>().PrepareForInput(Device(), VisitTopology(), IncidentTopology()));
template <typename InputDomainType>
VTKM_CONT ExecObjectType
operator()(const ContObjectType& object, const InputDomainType&, vtkm::Id, vtkm::Id) const
VTKM_CONT ExecObjectType operator()(const ContObjectType& object,
const InputDomainType&,
vtkm::Id,
vtkm::Id,
vtkm::cont::Token& token) const
{
return object.PrepareForInput(Device(), VisitTopology(), IncidentTopology());
return object.PrepareForInput(Device(), VisitTopology(), IncidentTopology(), token);
}
};
}

@ -41,12 +41,15 @@ struct Transport<vtkm::cont::arg::TransportTagExecObject, ContObjectType, Device
// inherit from vtkm::cont::ExecutionObjectBase and have a PrepareForExecution method.
VTKM_IS_EXECUTION_OBJECT(ContObjectType);
using ExecObjectType = decltype(std::declval<ContObjectType>().PrepareForExecution(Device()));
using ExecObjectType = vtkm::cont::internal::ExecutionObjectType<ContObjectType, Device>;
template <typename InputDomainType>
VTKM_CONT ExecObjectType
operator()(ContObjectType& object, const InputDomainType&, vtkm::Id, vtkm::Id) const
VTKM_CONT ExecObjectType operator()(ContObjectType& object,
const InputDomainType&,
vtkm::Id,
vtkm::Id,
vtkm::cont::Token& token) const
{
return object.PrepareForExecution(Device());
return vtkm::cont::internal::CallPrepareForExecution(object, Device{}, token);
}
};
}

@ -84,14 +84,15 @@ struct Transport<vtkm::cont::arg::TransportTagTopologyFieldIn<TopologyElementTag
ExecObjectType operator()(const ContObjectType& object,
const vtkm::cont::CellSet& inputDomain,
vtkm::Id,
vtkm::Id) const
vtkm::Id,
vtkm::cont::Token& token) const
{
if (object.GetNumberOfValues() != detail::TopologyDomainSize(inputDomain, TopologyElementTag()))
{
throw vtkm::cont::ErrorBadValue("Input array to worklet invocation the wrong size.");
}
return object.PrepareForInput(Device());
return object.PrepareForInput(Device(), token);
}
};
}

@ -50,14 +50,17 @@ struct Transport<vtkm::cont::arg::TransportTagWholeArrayIn, ContObjectType, Devi
using ExecObjectType = vtkm::exec::ExecutionWholeArrayConst<ValueType, StorageTag, Device>;
template <typename InputDomainType>
VTKM_CONT ExecObjectType
operator()(ContObjectType& array, const InputDomainType&, vtkm::Id, vtkm::Id) const
VTKM_CONT ExecObjectType operator()(ContObjectType& array,
const InputDomainType&,
vtkm::Id,
vtkm::Id,
vtkm::cont::Token& token) const
{
// Note: we ignore the size of the domain because the randomly accessed
// array might not have the same size depending on how the user is using
// the array.
return ExecObjectType(array);
return ExecObjectType(array, token);
}
};
}

@ -52,14 +52,17 @@ struct Transport<vtkm::cont::arg::TransportTagWholeArrayInOut, ContObjectType, D
using ExecObjectType = vtkm::exec::ExecutionWholeArray<ValueType, StorageTag, Device>;
template <typename InputDomainType>
VTKM_CONT ExecObjectType
operator()(ContObjectType& array, const InputDomainType&, vtkm::Id, vtkm::Id) const
VTKM_CONT ExecObjectType operator()(ContObjectType& array,
const InputDomainType&,
vtkm::Id,
vtkm::Id,
vtkm::cont::Token& token) const
{
// Note: we ignore the size of the domain because the randomly accessed
// array might not have the same size depending on how the user is using
// the array.
return ExecObjectType(array);
return ExecObjectType(array, token);
}
};
}

@ -52,14 +52,17 @@ struct Transport<vtkm::cont::arg::TransportTagWholeArrayOut, ContObjectType, Dev
using ExecObjectType = vtkm::exec::ExecutionWholeArray<ValueType, StorageTag, Device>;
template <typename InputDomainType>
VTKM_CONT ExecObjectType
operator()(ContObjectType& array, const InputDomainType&, vtkm::Id, vtkm::Id) const
VTKM_CONT ExecObjectType operator()(ContObjectType& array,
const InputDomainType&,
vtkm::Id,
vtkm::Id,
vtkm::cont::Token& token) const
{
// Note: we ignore the size of the domain because the randomly accessed
// array might not have the same size depending on how the user is using
// the array.
return ExecObjectType(array, array.GetNumberOfValues());
return ExecObjectType(array, array.GetNumberOfValues(), token);
}
};
}

@ -58,8 +58,10 @@ struct TryArrayInType
vtkm::cont::arg::Transport<vtkm::cont::arg::TransportTagArrayIn, ArrayHandleType, Device>
transport;
vtkm::cont::Token token;
TestKernelIn<PortalType> kernel;
kernel.Portal = transport(handle, handle, ARRAY_SIZE, ARRAY_SIZE);
kernel.Portal = transport(handle, handle, ARRAY_SIZE, ARRAY_SIZE, token);
vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(kernel, ARRAY_SIZE);
}

@ -56,8 +56,10 @@ struct TryArrayInOutType
vtkm::cont::arg::Transport<vtkm::cont::arg::TransportTagArrayInOut, ArrayHandleType, Device>
transport;
vtkm::cont::Token token;
TestKernelInOut<PortalType> kernel;
kernel.Portal = transport(handle, handle, ARRAY_SIZE, ARRAY_SIZE);
kernel.Portal = transport(handle, handle, ARRAY_SIZE, ARRAY_SIZE, token);
vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(kernel, ARRAY_SIZE);

@ -50,9 +50,11 @@ struct TryArrayOutType
vtkm::cont::arg::Transport<vtkm::cont::arg::TransportTagArrayOut, ArrayHandleType, Device>
transport;
vtkm::cont::Token token;
TestKernelOut<PortalType> kernel;
kernel.Portal =
transport(handle, vtkm::cont::ArrayHandleIndex(ARRAY_SIZE), ARRAY_SIZE, ARRAY_SIZE);
transport(handle, vtkm::cont::ArrayHandleIndex(ARRAY_SIZE), ARRAY_SIZE, ARRAY_SIZE, token);
VTKM_TEST_ASSERT(handle.GetNumberOfValues() == ARRAY_SIZE,
"ArrayOut transport did not allocate array correctly.");

@ -71,8 +71,10 @@ void TransportWholeCellSetIn(Device)
Device>
transport;
vtkm::cont::Token token;
TestKernel<ExecObjectType> kernel;
kernel.CellSet = transport(contObject, nullptr, 1, 1);
kernel.CellSet = transport(contObject, nullptr, 1, 1, token);
vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(kernel, 1);
}

@ -73,8 +73,10 @@ void TryExecObjectTransport(Device)
vtkm::cont::arg::Transport<vtkm::cont::arg::TransportTagExecObject, TestExecutionObject, Device>
transport;
vtkm::cont::Token token;
TestKernel<Device> kernel;
kernel.Object = transport(contObject, nullptr, 1, 1);
kernel.Object = transport(contObject, nullptr, 1, 1, token);
vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(kernel, 1);
}

@ -123,25 +123,30 @@ struct TryWholeArrayType
ArrayHandleType array;
array.Allocate(ARRAY_SIZE);
vtkm::cont::Token token;
std::cout << "Check Transport WholeArrayOut" << std::endl;
TestOutKernel<typename OutTransportType::ExecObjectType> outKernel;
outKernel.Portal = OutTransportType()(array, nullptr, -1, -1);
outKernel.Portal = OutTransportType()(array, nullptr, -1, -1, token);
vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(outKernel, ARRAY_SIZE);
token.DetachFromAll();
CheckPortal(array.GetPortalConstControl());
std::cout << "Check Transport WholeArrayIn" << std::endl;
TestInKernel<typename InTransportType::ExecObjectType> inKernel;
inKernel.Portal = InTransportType()(array, nullptr, -1, -1);
inKernel.Portal = InTransportType()(array, nullptr, -1, -1, token);
vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(inKernel, ARRAY_SIZE);
token.DetachFromAll();
std::cout << "Check Transport WholeArrayInOut" << std::endl;
TestInOutKernel<typename InOutTransportType::ExecObjectType> inOutKernel;
inOutKernel.Portal = InOutTransportType()(array, nullptr, -1, -1);
inOutKernel.Portal = InOutTransportType()(array, nullptr, -1, -1, token);
vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(inOutKernel, ARRAY_SIZE);
token.DetachFromAll();
VTKM_TEST_ASSERT(array.GetNumberOfValues() == ARRAY_SIZE, "Array size wrong?");
for (vtkm::Id index = 0; index < ARRAY_SIZE; index++)
@ -169,11 +174,14 @@ struct TryAtomicArrayType
array.Allocate(1);
array.GetPortalControl().Set(0, 0);
vtkm::cont::Token token;
std::cout << "Check Transport AtomicArray" << std::endl;
TestAtomicKernel<typename TransportType::ExecObjectType> kernel(
TransportType()(array, nullptr, -1, -1));
TransportType()(array, nullptr, -1, -1, token));
vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(kernel, ARRAY_SIZE);
token.DetachFromAll();
T result = array.GetPortalConstControl().Get(0);
VTKM_TEST_ASSERT(result == ((ARRAY_SIZE - 1) * ARRAY_SIZE) / 2,

@ -75,7 +75,7 @@ public:
vtkm::Id GetNumberOfValues() const { return static_cast<vtkm::Id>(this->End - this->Begin); }
VTKM_CONT
PortalConstType PrepareForInput(bool updateData)
PortalConstType PrepareForInput(bool updateData, vtkm::cont::Token&)
{
try
{
@ -99,7 +99,7 @@ public:
}
VTKM_CONT
PortalType PrepareForInPlace(bool updateData)
PortalType PrepareForInPlace(bool updateData, vtkm::cont::Token&)
{
try
{
@ -123,7 +123,7 @@ public:
}
VTKM_CONT
PortalType PrepareForOutput(vtkm::Id numberOfValues)
PortalType PrepareForOutput(vtkm::Id numberOfValues, vtkm::cont::Token&)
{
try
{

@ -12,6 +12,7 @@
#include <vtkm/cont/ErrorInternal.h>
#include <vtkm/cont/Storage.h>
#include <vtkm/cont/Token.h>
#include <vtkm/cont/internal/ArrayTransfer.h>
@ -68,13 +69,13 @@ public:
/// Returns a constant array portal valid in the execution environment.
///
template <typename DeviceAdapter>
VTKM_CONT typename ExecutionTypes<DeviceAdapter>::PortalConst PrepareForInput(bool updateData,
DeviceAdapter)
VTKM_CONT typename ExecutionTypes<DeviceAdapter>::PortalConst
PrepareForInput(bool updateData, DeviceAdapter, vtkm::cont::Token& token)
{
this->VerifyDeviceAdapter(DeviceAdapter());
typename ExecutionTypes<DeviceAdapter>::PortalConst portal;
this->PrepareForInputImpl(updateData, &portal);
this->PrepareForInputImpl(updateData, &portal, token);
return portal;
}
@ -85,13 +86,13 @@ public:
/// Returns a read-write array portal valid in the execution environment.
///
template <typename DeviceAdapter>
VTKM_CONT typename ExecutionTypes<DeviceAdapter>::Portal PrepareForInPlace(bool updateData,
DeviceAdapter)
VTKM_CONT typename ExecutionTypes<DeviceAdapter>::Portal
PrepareForInPlace(bool updateData, DeviceAdapter, vtkm::cont::Token& token)
{
this->VerifyDeviceAdapter(DeviceAdapter());
typename ExecutionTypes<DeviceAdapter>::Portal portal;
this->PrepareForInPlaceImpl(updateData, &portal);
this->PrepareForInPlaceImpl(updateData, &portal, token);
return portal;
}
@ -103,13 +104,13 @@ public:
/// Returns a writable array portal valid in the execution environment.
///
template <typename DeviceAdapter>
VTKM_CONT typename ExecutionTypes<DeviceAdapter>::Portal PrepareForOutput(vtkm::Id numberOfValues,
DeviceAdapter)
VTKM_CONT typename ExecutionTypes<DeviceAdapter>::Portal
PrepareForOutput(vtkm::Id numberOfValues, DeviceAdapter, vtkm::cont::Token& token)
{
this->VerifyDeviceAdapter(DeviceAdapter());
typename ExecutionTypes<DeviceAdapter>::Portal portal;
this->PrepareForOutputImpl(numberOfValues, &portal);
this->PrepareForOutputImpl(numberOfValues, &portal, token);
return portal;
}
@ -153,11 +154,17 @@ public:
protected:
virtual vtkm::Id GetNumberOfValuesImpl() const = 0;
virtual void PrepareForInputImpl(bool updateData, void* portalExecutionVoid) = 0;
virtual void PrepareForInputImpl(bool updateData,
void* portalExecutionVoid,
vtkm::cont::Token& token) = 0;
virtual void PrepareForInPlaceImpl(bool updateData, void* portalExecutionVoid) = 0;
virtual void PrepareForInPlaceImpl(bool updateData,
void* portalExecutionVoid,
vtkm::cont::Token& token) = 0;
virtual void PrepareForOutputImpl(vtkm::Id numberOfValues, void* portalExecution) = 0;
virtual void PrepareForOutputImpl(vtkm::Id numberOfValues,
void* portalExecution,
vtkm::cont::Token& token) = 0;
virtual void RetrieveOutputDataImpl(StorageType* storage) const = 0;
@ -212,23 +219,25 @@ protected:
vtkm::Id GetNumberOfValuesImpl() const { return this->Transfer.GetNumberOfValues(); }
VTKM_CONT
void PrepareForInputImpl(bool updateData, void* portalExecutionVoid)
void PrepareForInputImpl(bool updateData, void* portalExecutionVoid, vtkm::cont::Token& token)
{
PortalConstExecution portal = this->Transfer.PrepareForInput(updateData);
PortalConstExecution portal = this->Transfer.PrepareForInput(updateData, token);
*reinterpret_cast<PortalConstExecution*>(portalExecutionVoid) = portal;
}
VTKM_CONT
void PrepareForInPlaceImpl(bool updateData, void* portalExecutionVoid)
void PrepareForInPlaceImpl(bool updateData, void* portalExecutionVoid, vtkm::cont::Token& token)
{
PortalExecution portal = this->Transfer.PrepareForInPlace(updateData);
PortalExecution portal = this->Transfer.PrepareForInPlace(updateData, token);
*reinterpret_cast<PortalExecution*>(portalExecutionVoid) = portal;
}
VTKM_CONT
void PrepareForOutputImpl(vtkm::Id numberOfValues, void* portalExecutionVoid)
void PrepareForOutputImpl(vtkm::Id numberOfValues,
void* portalExecutionVoid,
vtkm::cont::Token& token)
{
PortalExecution portal = this->Transfer.PrepareForOutput(numberOfValues);
PortalExecution portal = this->Transfer.PrepareForOutput(numberOfValues, token);
*reinterpret_cast<PortalExecution*>(portalExecutionVoid) = portal;
}

@ -53,7 +53,7 @@ public:
/// Returns the constant portal from the storage.
///
VTKM_CONT
PortalConstType PrepareForInput(bool vtkmNotUsed(uploadData)) const
PortalConstType PrepareForInput(bool vtkmNotUsed(uploadData), vtkm::cont::Token&) const
{
return this->Storage->GetPortalConst();
}
@ -61,12 +61,15 @@ public:
/// Returns the read-write portal from the storage.
///
VTKM_CONT
PortalType PrepareForInPlace(bool vtkmNotUsed(uploadData)) { return this->Storage->GetPortal(); }
PortalType PrepareForInPlace(bool vtkmNotUsed(uploadData), vtkm::cont::Token&)
{
return this->Storage->GetPortal();
}
/// Allocates data in the storage and return the portal to that.
///
VTKM_CONT
PortalType PrepareForOutput(vtkm::Id numberOfValues)
PortalType PrepareForOutput(vtkm::Id numberOfValues, vtkm::cont::Token&)
{
this->Storage->Allocate(numberOfValues);
return this->Storage->GetPortal();

@ -11,6 +11,7 @@
#define vtk_m_cont_internal_ArrayTransfer_h
#include <vtkm/cont/Storage.h>
#include <vtkm/cont/Token.h>
#include <vtkm/cont/internal/ArrayManagerExecution.h>
namespace vtkm
@ -78,9 +79,9 @@ public:
/// Returns a constant array portal valid in the execution environment.
///
VTKM_CONT
PortalConstExecution PrepareForInput(bool updateData)
PortalConstExecution PrepareForInput(bool updateData, vtkm::cont::Token& token)
{
return this->ArrayManager.PrepareForInput(updateData);
return this->ArrayManager.PrepareForInput(updateData, token);
}
/// Prepares the data for use as both input and output in the execution
@ -91,9 +92,9 @@ public:
/// Returns a read-write array portal valid in the execution environment.
///
VTKM_CONT
PortalExecution PrepareForInPlace(bool updateData)
PortalExecution PrepareForInPlace(bool updateData, vtkm::cont::Token& token)
{
return this->ArrayManager.PrepareForInPlace(updateData);
return this->ArrayManager.PrepareForInPlace(updateData, token);
}
/// Allocates an array in the execution environment of the specified size. If
@ -104,9 +105,9 @@ public:
/// Returns a writable array portal valid in the execution environment.
///
VTKM_CONT
PortalExecution PrepareForOutput(vtkm::Id numberOfValues)
PortalExecution PrepareForOutput(vtkm::Id numberOfValues, vtkm::cont::Token& token)
{
return this->ArrayManager.PrepareForOutput(numberOfValues);
return this->ArrayManager.PrepareForOutput(numberOfValues, token);
}
/// Allocates data in the given Storage and copies data held in the execution

@ -58,7 +58,8 @@ struct TemplatedTests
bool CheckManager(ArrayManagerType& manager, const ValueType& value)
{
return CheckPortal(manager.PrepareForInput(false), value);
vtkm::cont::Token token;
return CheckPortal(manager.PrepareForInput(false, token), value);
}
void InputData()
@ -71,11 +72,14 @@ struct TemplatedTests
ArrayManagerType executionArray(&storage);
vtkm::cont::Token token;
// Although the ArrayManagerExecutionShareWithControl class wraps the
// control array portal in a different array portal, it should still
// give the same iterator (to avoid any unnecessary indirection).
VTKM_TEST_ASSERT(vtkm::cont::ArrayPortalToIteratorBegin(storage.GetPortalConst()) ==
vtkm::cont::ArrayPortalToIteratorBegin(executionArray.PrepareForInput(true)),
VTKM_TEST_ASSERT(
vtkm::cont::ArrayPortalToIteratorBegin(storage.GetPortalConst()) ==
vtkm::cont::ArrayPortalToIteratorBegin(executionArray.PrepareForInput(true, token)),
"Execution array manager not holding control array iterators.");
VTKM_TEST_ASSERT(CheckManager(executionArray, INPUT_VALUE), "Did not get correct array back.");
@ -91,16 +95,18 @@ struct TemplatedTests
ArrayManagerType executionArray(&storage);
vtkm::cont::Token token;
// Although the ArrayManagerExecutionShareWithControl class wraps the
// control array portal in a different array portal, it should still
// give the same iterator (to avoid any unnecessary indirection).
VTKM_TEST_ASSERT(
vtkm::cont::ArrayPortalToIteratorBegin(storage.GetPortal()) ==
vtkm::cont::ArrayPortalToIteratorBegin(executionArray.PrepareForInPlace(true)),
vtkm::cont::ArrayPortalToIteratorBegin(executionArray.PrepareForInPlace(true, token)),
"Execution array manager not holding control array iterators.");
VTKM_TEST_ASSERT(
vtkm::cont::ArrayPortalToIteratorBegin(storage.GetPortalConst()) ==
vtkm::cont::ArrayPortalToIteratorBegin(executionArray.PrepareForInput(false)),
vtkm::cont::ArrayPortalToIteratorBegin(executionArray.PrepareForInput(false, token)),
"Execution array manager not holding control array iterators.");
VTKM_TEST_ASSERT(CheckManager(executionArray, INPUT_VALUE), "Did not get correct array back.");
@ -114,8 +120,10 @@ struct TemplatedTests
ArrayManagerType executionArray(&storage);
vtkm::cont::Token token;
vtkm::cont::ArrayPortalToIterators<typename ArrayManagerType::PortalType> iterators(
executionArray.PrepareForOutput(ARRAY_SIZE));
executionArray.PrepareForOutput(ARRAY_SIZE, token));
std::fill(iterators.GetBegin(), iterators.GetEnd(), OUTPUT_VALUE);
VTKM_TEST_ASSERT(CheckManager(executionArray, OUTPUT_VALUE), "Did not get correct array back.");

@ -44,21 +44,21 @@ public:
}
VTKM_CONT
PortalConstType PrepareForInput(bool updateData)
PortalConstType PrepareForInput(bool updateData, vtkm::cont::Token& token)
{
return this->Superclass::PrepareForInput(updateData);
return this->Superclass::PrepareForInput(updateData, token);
}
VTKM_CONT
PortalType PrepareForInPlace(bool updateData)
PortalType PrepareForInPlace(bool updateData, vtkm::cont::Token& token)
{
return this->Superclass::PrepareForInPlace(updateData);
return this->Superclass::PrepareForInPlace(updateData, token);
}
VTKM_CONT
PortalType PrepareForOutput(vtkm::Id numberOfValues)
PortalType PrepareForOutput(vtkm::Id numberOfValues, vtkm::cont::Token& token)
{
return this->Superclass::PrepareForOutput(numberOfValues);
return this->Superclass::PrepareForOutput(numberOfValues, token);
}
};

@ -45,21 +45,21 @@ public:
}
VTKM_CONT
PortalConstType PrepareForInput(bool updateData)
PortalConstType PrepareForInput(bool updateData, vtkm::cont::Token& token)
{
return this->Superclass::PrepareForInput(updateData);
return this->Superclass::PrepareForInput(updateData, token);
}
VTKM_CONT
PortalType PrepareForInPlace(bool updateData)
PortalType PrepareForInPlace(bool updateData, vtkm::cont::Token& token)
{
return this->Superclass::PrepareForInPlace(updateData);
return this->Superclass::PrepareForInPlace(updateData, token);
}
VTKM_CONT
PortalType PrepareForOutput(vtkm::Id numberOfValues)
PortalType PrepareForOutput(vtkm::Id numberOfValues, vtkm::cont::Token& token)
{
return this->Superclass::PrepareForOutput(numberOfValues);
return this->Superclass::PrepareForOutput(numberOfValues, token);
}
};

@ -69,6 +69,7 @@ public:
AtomicArrayExecutionObject() = default;
// This constructor is deprecated in VTK-m 1.6.
VTKM_CONT AtomicArrayExecutionObject(vtkm::cont::ArrayHandle<T> handle)
: Data{ handle.PrepareForInPlace(Device{}).GetIteratorBegin() }
, NumberOfValues{ handle.GetNumberOfValues() }
@ -79,6 +80,16 @@ public:
"GetIteratorBegin().");
}
VTKM_CONT AtomicArrayExecutionObject(vtkm::cont::ArrayHandle<T> handle, vtkm::cont::Token& token)
: Data{ handle.PrepareForInPlace(Device{}, token).GetIteratorBegin() }
, NumberOfValues{ handle.GetNumberOfValues() }
{
using PortalType = decltype(handle.PrepareForInPlace(Device{}, token));
VTKM_STATIC_ASSERT_MSG(HasPointerAccess<PortalType>::value,
"Source portal must return a pointer from "
"GetIteratorBegin().");
}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC
vtkm::Id GetNumberOfValues() const { return this->NumberOfValues; }

@ -41,18 +41,32 @@ public:
{
}
// This constructor is deprecated in VTK-m 1.6
VTKM_CONT
ExecutionWholeArray(HandleType& handle)
: Portal(handle.PrepareForInPlace(DeviceAdapterTag()))
{
}
// This constructor is deprecated in VTK-m 1.6
VTKM_CONT
ExecutionWholeArray(HandleType& handle, vtkm::Id length)
: Portal(handle.PrepareForOutput(length, DeviceAdapterTag()))
{
}
VTKM_CONT
ExecutionWholeArray(HandleType& handle, vtkm::cont::Token& token)
: Portal(handle.PrepareForInPlace(DeviceAdapterTag(), token))
{
}
VTKM_CONT
ExecutionWholeArray(HandleType& handle, vtkm::Id length, vtkm::cont::Token& token)
: Portal(handle.PrepareForOutput(length, DeviceAdapterTag(), token))
{
}
VTKM_EXEC
vtkm::Id GetNumberOfValues() const { return this->Portal.GetNumberOfValues(); }
@ -91,12 +105,19 @@ public:
{
}
// This constructor is deprecated in VTK-m 1.6
VTKM_CONT
ExecutionWholeArrayConst(const HandleType& handle)
: Portal(handle.PrepareForInput(DeviceAdapterTag()))
{
}
VTKM_CONT
ExecutionWholeArrayConst(const HandleType& handle, vtkm::cont::Token& token)
: Portal(handle.PrepareForInput(DeviceAdapterTag(), token))
{
}
VTKM_EXEC
vtkm::Id GetNumberOfValues() const { return this->Portal.GetNumberOfValues(); }

@ -284,8 +284,10 @@ private:
using ExecObjectParameters =
typename ParameterInterfaceType::template StaticTransformType<TransportFunctorType>::type;
vtkm::cont::Token token;
ExecObjectParameters execObjectParameters = parameters.StaticTransformCont(
TransportFunctorType(invocation.GetInputDomain(), inputRange, outputRange));
TransportFunctorType(invocation.GetInputDomain(), inputRange, outputRange, token));
// Get the arrays used for scattering input to output.
typename ScatterType::OutputToInputMapType outputToInputMap =

@ -141,12 +141,22 @@ public:
};
template <typename Device>
VTKM_CONT typename ExecutionTypes<Device>::Lookup PrepareForInput(Device) const
VTKM_CONT typename ExecutionTypes<Device>::Lookup PrepareForInput(Device device,
vtkm::cont::Token& token) const
{
return typename ExecutionTypes<Device>::Lookup(this->UniqueKeys.PrepareForInput(Device()),
this->SortedValuesMap.PrepareForInput(Device()),
this->Offsets.PrepareForInput(Device()),
this->Counts.PrepareForInput(Device()));
return
typename ExecutionTypes<Device>::Lookup(this->UniqueKeys.PrepareForInput(device, token),
this->SortedValuesMap.PrepareForInput(device, token),
this->Offsets.PrepareForInput(device, token),
this->Counts.PrepareForInput(device, token));
}
template <typename Device>
VTKM_CONT VTKM_DEPRECATED(1.6, "PrepareForInput now requires a vtkm::cont::Token object.")
typename ExecutionTypes<Device>::Lookup PrepareForInput(Device device) const
{
vtkm::cont::Token token;
return this->PrepareForInput(device, token);
}
VTKM_CONT
@ -221,14 +231,15 @@ struct Transport<vtkm::cont::arg::TransportTagKeysIn, vtkm::worklet::Keys<KeyTyp
ExecObjectType operator()(const ContObjectType& object,
const ContObjectType& inputDomain,
vtkm::Id,
vtkm::Id) const
vtkm::Id,
vtkm::cont::Token& token) const
{
if (object != inputDomain)
{
throw vtkm::cont::ErrorBadValue("A Keys object must be the input domain.");
}
return object.PrepareForInput(Device());
return object.PrepareForInput(Device(), token);
}
// If you get a compile error here, it means that you have used a KeysIn
@ -255,7 +266,8 @@ struct Transport<vtkm::cont::arg::TransportTagKeyedValuesIn, ArrayHandleType, De
VTKM_CONT ExecObjectType operator()(const ContObjectType& object,
const vtkm::worklet::Keys<KeyType>& keys,
vtkm::Id,
vtkm::Id) const
vtkm::Id,
vtkm::cont::Token& token) const
{
if (object.GetNumberOfValues() != keys.GetNumberOfValues())
{
@ -269,7 +281,7 @@ struct Transport<vtkm::cont::arg::TransportTagKeyedValuesIn, ArrayHandleType, De
// maintaining the resources it points to. However, the entire state of the
// portal should be self contained except for the data managed by the
// object argument, which should stay in scope.
return groupedArray.PrepareForInput(Device());
return groupedArray.PrepareForInput(Device(), token);
}
};
@ -290,7 +302,8 @@ struct Transport<vtkm::cont::arg::TransportTagKeyedValuesInOut, ArrayHandleType,
VTKM_CONT ExecObjectType operator()(ContObjectType object,
const vtkm::worklet::Keys<KeyType>& keys,
vtkm::Id,
vtkm::Id) const
vtkm::Id,
vtkm::cont::Token& token) const
{
if (object.GetNumberOfValues() != keys.GetNumberOfValues())
{
@ -304,7 +317,7 @@ struct Transport<vtkm::cont::arg::TransportTagKeyedValuesInOut, ArrayHandleType,
// maintaining the resources it points to. However, the entire state of the
// portal should be self contained except for the data managed by the
// object argument, which should stay in scope.
return groupedArray.PrepareForInPlace(Device());
return groupedArray.PrepareForInPlace(Device(), token);
}
};
@ -325,12 +338,13 @@ struct Transport<vtkm::cont::arg::TransportTagKeyedValuesOut, ArrayHandleType, D
VTKM_CONT ExecObjectType operator()(ContObjectType object,
const vtkm::worklet::Keys<KeyType>& keys,
vtkm::Id,
vtkm::Id) const
vtkm::Id,
vtkm::cont::Token& token) const
{
// The PrepareForOutput for ArrayHandleGroupVecVariable and
// ArrayHandlePermutation cannot determine the actual size expected for the
// target array (object), so we have to make sure it gets allocated here.
object.PrepareForOutput(keys.GetNumberOfValues(), Device());
object.PrepareForOutput(keys.GetNumberOfValues(), Device(), token);
PermutedArrayType permutedArray(keys.GetSortedValuesMap(), object);
GroupedArrayType groupedArray(permutedArray, keys.GetOffsets());
@ -339,7 +353,7 @@ struct Transport<vtkm::cont::arg::TransportTagKeyedValuesOut, ArrayHandleType, D
// maintaining the resources it points to. However, the entire state of the
// portal should be self contained except for the data managed by the
// object argument, which should stay in scope.
return groupedArray.PrepareForOutput(keys.GetInputRange(), Device());
return groupedArray.PrepareForOutput(keys.GetInputRange(), Device(), token);
}
};
}

@ -42,9 +42,11 @@ struct GradientScalarOutputExecutionObject
GradientScalarOutputExecutionObject() = default;
GradientScalarOutputExecutionObject(vtkm::cont::ArrayHandle<ValueType> gradient, vtkm::Id size)
GradientScalarOutputExecutionObject(vtkm::cont::ArrayHandle<ValueType> gradient,
vtkm::Id size,
vtkm::cont::Token& token)
{
this->GradientPortal = gradient.PrepareForOutput(size, DeviceAdapter());
this->GradientPortal = gradient.PrepareForOutput(size, DeviceAdapter(), token);
}
VTKM_SUPPRESS_EXEC_WARNINGS
@ -65,9 +67,11 @@ struct GradientScalarOutput : public vtkm::cont::ExecutionObjectBase
template <typename Device>
VTKM_CONT vtkm::exec::GradientScalarOutputExecutionObject<T, Device> PrepareForExecution(
Device) const
Device,
vtkm::cont::Token& token) const
{
return vtkm::exec::GradientScalarOutputExecutionObject<T, Device>(this->Gradient, this->Size);
return vtkm::exec::GradientScalarOutputExecutionObject<T, Device>(
this->Gradient, this->Size, token);
}
GradientScalarOutput() = default;
@ -113,7 +117,8 @@ struct GradientVecOutputExecutionObject
vtkm::cont::ArrayHandle<BaseTType> divergence,
vtkm::cont::ArrayHandle<vtkm::Vec<BaseTType, 3>> vorticity,
vtkm::cont::ArrayHandle<BaseTType> qcriterion,
vtkm::Id size)
vtkm::Id size,
vtkm::cont::Token& token)
{
this->SetGradient = g;
this->SetDivergence = d;
@ -123,19 +128,19 @@ struct GradientVecOutputExecutionObject
DeviceAdapter device;
if (g)
{
this->GradientPortal = gradient.PrepareForOutput(size, device);
this->GradientPortal = gradient.PrepareForOutput(size, device, token);
}
if (d)
{
this->DivergencePortal = divergence.PrepareForOutput(size, device);
this->DivergencePortal = divergence.PrepareForOutput(size, device, token);
}
if (v)
{
this->VorticityPortal = vorticity.PrepareForOutput(size, device);
this->VorticityPortal = vorticity.PrepareForOutput(size, device, token);
}
if (q)
{
this->QCriterionPortal = qcriterion.PrepareForOutput(size, device);
this->QCriterionPortal = qcriterion.PrepareForOutput(size, device, token);
}
}
@ -189,7 +194,8 @@ struct GradientVecOutput : public vtkm::cont::ExecutionObjectBase
template <typename Device>
VTKM_CONT vtkm::exec::GradientVecOutputExecutionObject<T, Device> PrepareForExecution(
Device) const
Device,
vtkm::cont::Token& token) const
{
return vtkm::exec::GradientVecOutputExecutionObject<T, Device>(this->G,
this->D,
@ -199,7 +205,8 @@ struct GradientVecOutput : public vtkm::cont::ExecutionObjectBase
this->Divergence,
this->Vorticity,
this->Qcriterion,
this->Size);
this->Size,
token);
}
GradientVecOutput() = default;
@ -276,18 +283,20 @@ struct TransportTagGradientOut
template <typename ContObjectType, typename Device>
struct Transport<vtkm::cont::arg::TransportTagGradientOut, ContObjectType, Device>
{
using ExecObjectFacotryType = vtkm::exec::GradientOutput<typename ContObjectType::ValueType>;
using ExecObjectType =
decltype(std::declval<ExecObjectFacotryType>().PrepareForExecution(Device()));
using ExecObjectFactoryType = vtkm::exec::GradientOutput<typename ContObjectType::ValueType>;
using ExecObjectType = decltype(
std::declval<ExecObjectFactoryType>().PrepareForExecution(Device(),
std::declval<vtkm::cont::Token&>()));
template <typename InputDomainType>
VTKM_CONT ExecObjectType operator()(ContObjectType object,
const InputDomainType& vtkmNotUsed(inputDomain),
vtkm::Id vtkmNotUsed(inputRange),
vtkm::Id outputRange) const
vtkm::Id outputRange,
vtkm::cont::Token& token) const
{
ExecObjectFacotryType ExecutionObjectFacotry = object.PrepareForOutput(outputRange);
return ExecutionObjectFacotry.PrepareForExecution(Device());
ExecObjectFactoryType ExecutionObjectFactory = object.PrepareForOutput(outputRange);
return ExecutionObjectFactory.PrepareForExecution(Device(), token);
}
};
}

@ -288,6 +288,7 @@ struct DispatcherBaseTransportFunctor
const InputDomainType& InputDomain; // Warning: this is a reference
vtkm::Id InputRange;
vtkm::Id OutputRange;
vtkm::cont::Token& Token; // Warning: this is a reference
// TODO: We need to think harder about how scheduling on 3D arrays works.
// Chances are we need to allow the transport for each argument to manage
@ -296,10 +297,12 @@ struct DispatcherBaseTransportFunctor
template <typename InputRangeType, typename OutputRangeType>
VTKM_CONT DispatcherBaseTransportFunctor(const InputDomainType& inputDomain,
const InputRangeType& inputRange,
const OutputRangeType& outputRange)
const OutputRangeType& outputRange,
vtkm::cont::Token& token)
: InputDomain(inputDomain)
, InputRange(FlatRange(inputRange))
, OutputRange(FlatRange(outputRange))
, Token(token)
{
}
@ -325,8 +328,11 @@ struct DispatcherBaseTransportFunctor
vtkm::cont::arg::Transport<TransportTag, T, Device> transport;
not_nullptr(invokeData, Index);
return transport(
as_ref(invokeData), as_ref(this->InputDomain), this->InputRange, this->OutputRange);
return transport(as_ref(invokeData),
as_ref(this->InputDomain),
this->InputRange,
this->OutputRange,
this->Token);
}
@ -710,6 +716,10 @@ private:
ThreadRangeType&& threadRange,
DeviceAdapter device) const
{
// This token represents the scope of the execution objects. It should
// exist as long as things run on the device.
vtkm::cont::Token token;
// The first step in invoking a worklet is to transport the arguments to
// the execution environment. The invocation object passed to this function
// contains the parameters passed to Invoke in the control environment. We
@ -730,7 +740,7 @@ private:
typename ParameterInterfaceType::template StaticTransformType<TransportFunctorType>::type;
ExecObjectParameters execObjectParameters = parameters.StaticTransformCont(
TransportFunctorType(invocation.GetInputDomain(), inputRange, outputRange));
TransportFunctorType(invocation.GetInputDomain(), inputRange, outputRange, token));
// Get the arrays used for scattering input to output.
typename ScatterType::OutputToInputMapType outputToInputMap =

@ -125,7 +125,8 @@ struct Transport<TestTransportTagIn, std::vector<vtkm::Id>, Device>
ExecObjectType operator()(const std::vector<vtkm::Id>& contData,
const std::vector<vtkm::Id>&,
vtkm::Id inputRange,
vtkm::Id outputRange) const
vtkm::Id outputRange,
vtkm::cont::Token&) const
{
VTKM_TEST_ASSERT(inputRange == ARRAY_SIZE, "Got unexpected size in test transport.");
VTKM_TEST_ASSERT(outputRange == ARRAY_SIZE, "Got unexpected size in test transport.");
@ -142,7 +143,8 @@ struct Transport<TestTransportTagOut, std::vector<vtkm::Id>, Device>
ExecObjectType operator()(const std::vector<vtkm::Id>& contData,
const std::vector<vtkm::Id>&,
vtkm::Id inputRange,
vtkm::Id outputRange) const
vtkm::Id outputRange,
vtkm::cont::Token&) const
{
VTKM_TEST_ASSERT(inputRange == ARRAY_SIZE, "Got unexpected size in test transport.");
VTKM_TEST_ASSERT(outputRange == ARRAY_SIZE, "Got unexpected size in test transport.");