2014-10-21 16:51:07 +00:00
|
|
|
//============================================================================
|
|
|
|
// Copyright (c) Kitware, Inc.
|
|
|
|
// All rights reserved.
|
|
|
|
// See LICENSE.txt for details.
|
|
|
|
// This software is distributed WITHOUT ANY WARRANTY; without even
|
|
|
|
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
|
|
// PURPOSE. See the above copyright notice for more information.
|
|
|
|
//
|
|
|
|
// Copyright 2014 Sandia Corporation.
|
|
|
|
// Copyright 2014 UT-Battelle, LLC.
|
2015-05-21 12:09:22 +00:00
|
|
|
// Copyright 2014 Los Alamos National Security.
|
2014-10-21 16:51:07 +00:00
|
|
|
//
|
|
|
|
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
|
|
|
// the U.S. Government retains certain rights in this software.
|
|
|
|
//
|
|
|
|
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
|
|
|
// Laboratory (LANL), the U.S. Government retains certain rights in
|
|
|
|
// this software.
|
|
|
|
//============================================================================
|
|
|
|
#ifndef vtk_m_worklet_internal_DispatcherBase_h
|
|
|
|
#define vtk_m_worklet_internal_DispatcherBase_h
|
|
|
|
|
|
|
|
#include <vtkm/internal/FunctionInterface.h>
|
|
|
|
#include <vtkm/internal/Invocation.h>
|
|
|
|
|
|
|
|
#include <vtkm/cont/DeviceAdapter.h>
|
2014-10-22 21:15:14 +00:00
|
|
|
#include <vtkm/cont/ErrorControlBadType.h>
|
2014-10-21 16:51:07 +00:00
|
|
|
|
2014-10-23 14:28:50 +00:00
|
|
|
#include <vtkm/cont/arg/ControlSignatureTagBase.h>
|
2014-10-21 16:51:07 +00:00
|
|
|
#include <vtkm/cont/arg/Transport.h>
|
2014-10-22 21:15:14 +00:00
|
|
|
#include <vtkm/cont/arg/TypeCheck.h>
|
2014-10-21 16:51:07 +00:00
|
|
|
|
|
|
|
#include <vtkm/cont/internal/DynamicTransform.h>
|
|
|
|
|
2014-10-23 14:28:50 +00:00
|
|
|
#include <vtkm/exec/arg/ExecutionSignatureTagBase.h>
|
|
|
|
|
2014-10-21 16:51:07 +00:00
|
|
|
#include <vtkm/exec/internal/WorkletInvokeFunctor.h>
|
|
|
|
|
2015-08-12 19:08:45 +00:00
|
|
|
VTKM_THIRDPARTY_PRE_INCLUDE
|
2014-10-21 16:51:07 +00:00
|
|
|
#include <boost/mpl/assert.hpp>
|
|
|
|
#include <boost/static_assert.hpp>
|
|
|
|
#include <boost/type_traits/is_base_of.hpp>
|
2014-10-22 21:15:14 +00:00
|
|
|
#include <boost/utility/enable_if.hpp>
|
2015-08-12 19:08:45 +00:00
|
|
|
VTKM_THIRDPARTY_POST_INCLUDE
|
2014-10-22 21:15:14 +00:00
|
|
|
|
|
|
|
#include <sstream>
|
2014-10-21 16:51:07 +00:00
|
|
|
|
|
|
|
namespace vtkm {
|
|
|
|
namespace worklet {
|
|
|
|
namespace internal {
|
|
|
|
|
|
|
|
namespace detail {
|
|
|
|
|
2015-07-17 12:49:43 +00:00
|
|
|
// This code is actually taking an error found at compile-time and not
|
|
|
|
// reporting it until run-time. This seems strange at first, but this
|
|
|
|
// behavior is actually important. With dynamic arrays and similar dynamic
|
|
|
|
// classes, there may be types that are technically possible (such as using a
|
|
|
|
// vector where a scalar is expected) but in reality never happen. Thus, for
|
|
|
|
// these unsupported combinations we just silently halt the compiler from
|
|
|
|
// attempting to create code for these errant conditions and throw a run-time
|
|
|
|
// error if one every tries to create one.
|
|
|
|
inline void PrintFailureMessage(int, boost::true_type) {}
|
|
|
|
inline void PrintFailureMessage(int index, boost::false_type)
|
|
|
|
{
|
|
|
|
std::stringstream message;
|
|
|
|
message << "Encountered bad type for parameter "
|
|
|
|
<< index
|
|
|
|
<< " when calling Invoke on a dispatcher.";
|
|
|
|
throw vtkm::cont::ErrorControlBadType(message.str());
|
|
|
|
}
|
|
|
|
|
2014-10-23 14:28:50 +00:00
|
|
|
// Checks that an argument in a ControlSignature is a valid control signature
|
|
|
|
// tag. Causes a compile error otherwise.
|
|
|
|
struct DispatcherBaseControlSignatureTagCheck
|
|
|
|
{
|
2015-01-14 01:26:13 +00:00
|
|
|
template<typename ControlSignatureTag, vtkm::IdComponent Index>
|
2014-10-23 14:28:50 +00:00
|
|
|
struct ReturnType {
|
|
|
|
// If you get a compile error here, it means there is something that is
|
|
|
|
// not a valid control signature tag in a worklet's ControlSignature.
|
|
|
|
VTKM_IS_CONTROL_SIGNATURE_TAG(ControlSignatureTag);
|
|
|
|
typedef ControlSignatureTag type;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
// Checks that an argument in a ExecutionSignature is a valid execution
|
|
|
|
// signature tag. Causes a compile error otherwise.
|
|
|
|
struct DispatcherBaseExecutionSignatureTagCheck
|
|
|
|
{
|
2015-01-14 01:26:13 +00:00
|
|
|
template<typename ExecutionSignatureTag, vtkm::IdComponent Index>
|
2014-10-23 14:28:50 +00:00
|
|
|
struct ReturnType {
|
|
|
|
// If you get a compile error here, it means there is something that is not
|
|
|
|
// a valid execution signature tag in a worklet's ExecutionSignature.
|
|
|
|
VTKM_IS_EXECUTION_SIGNATURE_TAG(ExecutionSignatureTag);
|
|
|
|
typedef ExecutionSignatureTag type;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
// Used in the dynamic cast to check to make sure that the type passed into
|
|
|
|
// the Invoke method matches the type accepted by the ControlSignature.
|
2015-01-14 01:26:13 +00:00
|
|
|
template<typename ContinueFunctor,
|
|
|
|
typename TypeCheckTag,
|
|
|
|
vtkm::IdComponent Index>
|
2014-10-22 21:15:14 +00:00
|
|
|
struct DispatcherBaseTypeCheckFunctor
|
|
|
|
{
|
|
|
|
const ContinueFunctor &Continue;
|
|
|
|
|
|
|
|
VTKM_CONT_EXPORT
|
2015-01-14 01:26:13 +00:00
|
|
|
DispatcherBaseTypeCheckFunctor(const ContinueFunctor &continueFunc)
|
|
|
|
: Continue(continueFunc) { }
|
2014-10-22 21:15:14 +00:00
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
VTKM_CONT_EXPORT
|
2015-07-17 12:49:43 +00:00
|
|
|
void operator()(const T &x) const
|
2014-10-22 21:15:14 +00:00
|
|
|
{
|
2015-07-17 12:49:43 +00:00
|
|
|
typedef boost::integral_constant<bool,
|
|
|
|
vtkm::cont::arg::TypeCheck<TypeCheckTag,T>::value> CanContinueTagType;
|
|
|
|
|
|
|
|
vtkm::worklet::internal::detail::PrintFailureMessage(Index,CanContinueTagType());
|
|
|
|
this->WillContinue(x, CanContinueTagType());
|
2014-10-22 21:15:14 +00:00
|
|
|
}
|
|
|
|
|
2015-07-17 12:49:43 +00:00
|
|
|
private:
|
2014-10-22 21:15:14 +00:00
|
|
|
template<typename T>
|
|
|
|
VTKM_CONT_EXPORT
|
2015-07-17 12:49:43 +00:00
|
|
|
void WillContinue(const T &x, boost::true_type) const
|
2014-10-22 21:15:14 +00:00
|
|
|
{
|
2015-07-17 12:49:43 +00:00
|
|
|
this->Continue(x);
|
2014-10-22 21:15:14 +00:00
|
|
|
}
|
2015-07-17 12:49:43 +00:00
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
VTKM_CONT_EXPORT
|
|
|
|
void WillContinue(const T&, boost::false_type) const
|
|
|
|
{ }
|
2014-10-22 21:15:14 +00:00
|
|
|
};
|
|
|
|
|
2014-10-23 14:28:50 +00:00
|
|
|
// Uses vtkm::cont::internal::DynamicTransform and the DynamicTransformCont
|
|
|
|
// method of FunctionInterface to convert all DynamicArrayHandles and any
|
|
|
|
// other arguments declaring themselves as dynamic to static versions.
|
2015-01-14 01:26:13 +00:00
|
|
|
template<typename ControlInterface>
|
2014-10-22 21:15:14 +00:00
|
|
|
struct DispatcherBaseDynamicTransform
|
|
|
|
{
|
2015-01-14 01:26:13 +00:00
|
|
|
template<typename InputType,
|
|
|
|
typename ContinueFunctor,
|
|
|
|
vtkm::IdComponent Index>
|
2014-10-22 21:15:14 +00:00
|
|
|
VTKM_CONT_EXPORT
|
2015-01-14 01:26:13 +00:00
|
|
|
void operator()(const InputType &input,
|
|
|
|
const ContinueFunctor &continueFunc,
|
|
|
|
vtkm::internal::IndexTag<Index> indexTag) const
|
2014-10-22 21:15:14 +00:00
|
|
|
{
|
2015-01-14 01:26:13 +00:00
|
|
|
typedef typename ControlInterface::template ParameterType<Index>::type
|
|
|
|
ControlSignatureTag;
|
2014-10-22 21:15:14 +00:00
|
|
|
|
|
|
|
typedef DispatcherBaseTypeCheckFunctor<
|
2015-01-14 01:26:13 +00:00
|
|
|
ContinueFunctor, typename ControlSignatureTag::TypeCheckTag, Index>
|
2014-10-22 21:15:14 +00:00
|
|
|
TypeCheckFunctor;
|
2015-01-14 01:26:13 +00:00
|
|
|
|
|
|
|
vtkm::cont::internal::DynamicTransform basicDynamicTransform;
|
|
|
|
|
|
|
|
basicDynamicTransform(input, TypeCheckFunctor(continueFunc), indexTag);
|
2014-10-22 21:15:14 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2014-10-23 14:28:50 +00:00
|
|
|
// A functor called at the end of the dynamic transform to call the next
|
|
|
|
// step in the dynamic transform.
|
2014-10-21 16:51:07 +00:00
|
|
|
template<typename DispatcherBaseType>
|
|
|
|
struct DispatcherBaseDynamicTransformHelper
|
|
|
|
{
|
|
|
|
const DispatcherBaseType *Dispatcher;
|
|
|
|
|
|
|
|
VTKM_CONT_EXPORT
|
|
|
|
DispatcherBaseDynamicTransformHelper(const DispatcherBaseType *dispatcher)
|
|
|
|
: Dispatcher(dispatcher) { }
|
|
|
|
|
|
|
|
template<typename FunctionInterface>
|
|
|
|
VTKM_CONT_EXPORT
|
|
|
|
void operator()(const FunctionInterface ¶meters) const {
|
|
|
|
this->Dispatcher->DynamicTransformInvoke(parameters);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2014-10-23 14:28:50 +00:00
|
|
|
// A functor used in a StaticCast of a FunctionInterface to transport arguments
|
|
|
|
// from the control environment to the execution environment.
|
2015-01-14 01:26:13 +00:00
|
|
|
template<typename ControlInterface, typename Device>
|
2014-10-21 16:51:07 +00:00
|
|
|
struct DispatcherBaseTransportFunctor
|
|
|
|
{
|
|
|
|
vtkm::Id NumInstances;
|
|
|
|
|
2015-05-05 14:46:23 +00:00
|
|
|
VTKM_CONT_EXPORT
|
2014-10-21 16:51:07 +00:00
|
|
|
DispatcherBaseTransportFunctor(vtkm::Id numInstances)
|
|
|
|
: NumInstances(numInstances) { }
|
|
|
|
|
2015-05-05 14:46:23 +00:00
|
|
|
// 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
|
|
|
|
// 3D indices (for example, allocate a 3D array instead of a 1D array).
|
|
|
|
// But for now, just treat all transports as 1D arrays.
|
|
|
|
VTKM_CONT_EXPORT
|
|
|
|
DispatcherBaseTransportFunctor(vtkm::Id3 dimensions)
|
|
|
|
: NumInstances(dimensions[0]*dimensions[1]*dimensions[2]) { }
|
|
|
|
|
2015-01-14 01:26:13 +00:00
|
|
|
template<typename ControlParameter, vtkm::IdComponent Index>
|
2014-10-21 16:51:07 +00:00
|
|
|
struct InvokeTypes {
|
2015-01-14 01:26:13 +00:00
|
|
|
typedef typename ControlInterface::template ParameterType<Index>::type
|
|
|
|
ControlSignatureTag;
|
|
|
|
typedef typename ControlSignatureTag::TransportTag TransportTag;
|
2014-10-21 16:51:07 +00:00
|
|
|
typedef vtkm::cont::arg::Transport<TransportTag,ControlParameter,Device>
|
|
|
|
TransportType;
|
|
|
|
};
|
|
|
|
|
2015-01-14 01:26:13 +00:00
|
|
|
template<typename ControlParameter, vtkm::IdComponent Index>
|
2014-10-21 16:51:07 +00:00
|
|
|
struct ReturnType {
|
2015-01-14 01:26:13 +00:00
|
|
|
typedef typename InvokeTypes<ControlParameter, Index>::
|
|
|
|
TransportType::ExecObjectType type;
|
2014-10-21 16:51:07 +00:00
|
|
|
};
|
|
|
|
|
2015-01-14 01:26:13 +00:00
|
|
|
template<typename ControlParameter, vtkm::IdComponent Index>
|
2014-10-21 16:51:07 +00:00
|
|
|
VTKM_CONT_EXPORT
|
2015-01-14 01:26:13 +00:00
|
|
|
typename ReturnType<ControlParameter, Index>::type
|
|
|
|
operator()(const ControlParameter &invokeData,
|
|
|
|
vtkm::internal::IndexTag<Index>) const {
|
|
|
|
typename InvokeTypes<ControlParameter, Index>::TransportType transport;
|
|
|
|
return transport(invokeData, this->NumInstances);
|
2014-10-21 16:51:07 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace detail
|
|
|
|
|
|
|
|
/// Base class for all dispatcher classes. Every worklet type should have its
|
|
|
|
/// own dispatcher.
|
|
|
|
///
|
|
|
|
template<typename DerivedClass,
|
|
|
|
typename WorkletType,
|
|
|
|
typename BaseWorkletType,
|
|
|
|
typename Device>
|
|
|
|
class DispatcherBase
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
typedef DispatcherBase<DerivedClass,WorkletType,BaseWorkletType,Device> MyType;
|
|
|
|
|
|
|
|
friend struct detail::DispatcherBaseDynamicTransformHelper<MyType>;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
typedef vtkm::internal::FunctionInterface<
|
|
|
|
typename WorkletType::ControlSignature> ControlInterface;
|
|
|
|
typedef vtkm::internal::FunctionInterface<
|
|
|
|
typename WorkletType::ExecutionSignature> ExecutionInterface;
|
|
|
|
|
|
|
|
static const vtkm::IdComponent NUM_INVOKE_PARAMS = ControlInterface::ARITY;
|
|
|
|
|
2014-10-23 14:28:50 +00:00
|
|
|
private:
|
|
|
|
// We don't really need these types, but declaring them checks the arguments
|
|
|
|
// of the control and execution signatures.
|
|
|
|
typedef typename ControlInterface::
|
|
|
|
template StaticTransformType<
|
|
|
|
detail::DispatcherBaseControlSignatureTagCheck>::type
|
|
|
|
ControlSignatureCheck;
|
|
|
|
typedef typename ExecutionInterface::
|
|
|
|
template StaticTransformType<
|
|
|
|
detail::DispatcherBaseExecutionSignatureTagCheck>::type
|
|
|
|
ExecutionSignatureCheck;
|
|
|
|
|
2014-10-21 16:51:07 +00:00
|
|
|
template<typename Signature>
|
|
|
|
VTKM_CONT_EXPORT
|
|
|
|
void StartInvoke(
|
|
|
|
const vtkm::internal::FunctionInterface<Signature> ¶meters) const
|
|
|
|
{
|
|
|
|
typedef vtkm::internal::FunctionInterface<Signature> ParameterInterface;
|
2015-09-17 05:34:49 +00:00
|
|
|
|
|
|
|
VTKM_THIRDPARTY_PRE_INCLUDE
|
2014-10-21 16:51:07 +00:00
|
|
|
BOOST_STATIC_ASSERT_MSG(ParameterInterface::ARITY == NUM_INVOKE_PARAMS,
|
|
|
|
"Dispatcher Invoke called with wrong number of arguments.");
|
|
|
|
BOOST_MPL_ASSERT(( boost::is_base_of<BaseWorkletType,WorkletType> ));
|
2015-09-17 05:34:49 +00:00
|
|
|
VTKM_THIRDPARTY_POST_INCLUDE
|
2014-10-21 16:51:07 +00:00
|
|
|
|
2014-10-22 21:15:14 +00:00
|
|
|
// As we do the dynamic transform, we are also going to check the static
|
|
|
|
// type against the TypeCheckTag in the ControlSignature tags. To do this,
|
|
|
|
// the check needs access to both the parameter (in the parameters
|
|
|
|
// argument) and the ControlSignature tags (in the ControlInterface type).
|
2015-01-14 01:26:13 +00:00
|
|
|
// To make this possible, we call DynamicTransform with a functor containing
|
|
|
|
// the control signature tags. It uses the index provided by the
|
|
|
|
// dynamic transform mechanism to get the right tag and make sure that
|
|
|
|
// the dynamic type is correct. (This prevents the compiler from expanding
|
|
|
|
// worklets with types that should not be.)
|
|
|
|
parameters.DynamicTransformCont(
|
|
|
|
detail::DispatcherBaseDynamicTransform<ControlInterface>(),
|
2014-10-21 16:51:07 +00:00
|
|
|
detail::DispatcherBaseDynamicTransformHelper<MyType>(this));
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename Signature>
|
|
|
|
VTKM_CONT_EXPORT
|
|
|
|
void DynamicTransformInvoke(
|
|
|
|
const vtkm::internal::FunctionInterface<Signature> ¶meters) const
|
|
|
|
{
|
|
|
|
// TODO: Check parameters
|
|
|
|
static const vtkm::IdComponent INPUT_DOMAIN_INDEX =
|
|
|
|
WorkletType::InputDomain::INDEX;
|
|
|
|
reinterpret_cast<const DerivedClass *>(this)->DoInvoke(
|
|
|
|
vtkm::internal::make_Invocation<INPUT_DOMAIN_INDEX>(
|
|
|
|
parameters, ControlInterface(), ExecutionInterface()));
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
// Implementation of the Invoke method is in this generated file.
|
|
|
|
#include <vtkm/worklet/internal/DispatcherBaseDetailInvoke.h>
|
|
|
|
|
|
|
|
protected:
|
|
|
|
VTKM_CONT_EXPORT
|
|
|
|
DispatcherBase(const WorkletType &worklet) : Worklet(worklet) { }
|
|
|
|
|
|
|
|
template<typename Invocation>
|
|
|
|
VTKM_CONT_EXPORT
|
|
|
|
void BasicInvoke(const Invocation &invocation, vtkm::Id numInstances) const
|
|
|
|
{
|
|
|
|
this->InvokeTransportParameters(invocation, numInstances);
|
|
|
|
}
|
|
|
|
|
2015-06-22 13:07:27 +00:00
|
|
|
template<typename Invocation>
|
|
|
|
VTKM_CONT_EXPORT
|
|
|
|
void BasicInvoke(const Invocation &invocation, vtkm::Id2 dimensions) const
|
|
|
|
{
|
|
|
|
vtkm::Id3 dim3d(dimensions[0], dimensions[1], 1);
|
|
|
|
this->InvokeTransportParameters(invocation, dim3d);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-05-05 14:46:23 +00:00
|
|
|
template<typename Invocation>
|
|
|
|
VTKM_CONT_EXPORT
|
|
|
|
void BasicInvoke(const Invocation &invocation, vtkm::Id3 dimensions) const
|
|
|
|
{
|
|
|
|
this->InvokeTransportParameters(invocation, dimensions);
|
|
|
|
}
|
|
|
|
|
2014-10-21 16:51:07 +00:00
|
|
|
WorkletType Worklet;
|
|
|
|
|
|
|
|
private:
|
|
|
|
// These are not implemented. Dispatchers cannot be copied.
|
|
|
|
DispatcherBase(const MyType &);
|
|
|
|
void operator=(const MyType &);
|
|
|
|
|
2015-05-05 14:46:23 +00:00
|
|
|
template<typename Invocation, typename RangeType>
|
2014-10-21 16:51:07 +00:00
|
|
|
VTKM_CONT_EXPORT
|
|
|
|
void InvokeTransportParameters(const Invocation &invocation,
|
2015-05-05 14:46:23 +00:00
|
|
|
RangeType range) const
|
2014-10-21 16:51:07 +00:00
|
|
|
{
|
2015-01-14 01:26:13 +00:00
|
|
|
// The first step in invoking a worklet is to transport the arguments to
|
|
|
|
// the execution environment. The invocation object passed to this function
|
2014-10-21 16:51:07 +00:00
|
|
|
// contains the parameters passed to Invoke in the control environment. We
|
|
|
|
// will use the template magic in the FunctionInterface class to invoke the
|
2015-01-14 01:26:13 +00:00
|
|
|
// appropriate Transport class on each parameter and get a list of
|
|
|
|
// execution objects (corresponding to the arguments of the Invoke in the
|
|
|
|
// control environment) in a FunctionInterface. Specifically, we use a
|
|
|
|
// static transform of the FunctionInterface to call the transport on each
|
|
|
|
// argument and return the corresponding execution environment object.
|
|
|
|
typedef typename Invocation::ParameterInterface ParameterInterfaceType;
|
|
|
|
const ParameterInterfaceType ¶meters = invocation.Parameters;
|
|
|
|
|
|
|
|
typedef detail::DispatcherBaseTransportFunctor<
|
|
|
|
typename Invocation::ControlInterface, Device> TransportFunctorType;
|
|
|
|
typedef typename ParameterInterfaceType::template StaticTransformType<
|
|
|
|
TransportFunctorType>::type ExecObjectParameters;
|
|
|
|
|
2014-10-21 16:51:07 +00:00
|
|
|
ExecObjectParameters execObjectParameters =
|
2015-05-05 14:46:23 +00:00
|
|
|
parameters.StaticTransformCont(TransportFunctorType(range));
|
2014-10-21 16:51:07 +00:00
|
|
|
|
|
|
|
// Replace the parameters in the invocation with the execution object and
|
|
|
|
// pass to next step of Invoke.
|
|
|
|
this->InvokeSchedule(invocation.ChangeParameters(execObjectParameters),
|
2015-05-05 14:46:23 +00:00
|
|
|
range);
|
2014-10-21 16:51:07 +00:00
|
|
|
}
|
|
|
|
|
2015-05-05 14:46:23 +00:00
|
|
|
template<typename Invocation, typename RangeType>
|
2014-10-21 16:51:07 +00:00
|
|
|
VTKM_CONT_EXPORT
|
2015-05-05 14:46:23 +00:00
|
|
|
void InvokeSchedule(const Invocation &invocation, RangeType range) const
|
2014-10-21 16:51:07 +00:00
|
|
|
{
|
|
|
|
// The WorkletInvokeFunctor class handles the magic of fetching values
|
|
|
|
// for each instance and calling the worklet's function. So just create
|
|
|
|
// a WorkletInvokeFunctor and schedule it with the device adapter.
|
|
|
|
typedef vtkm::exec::internal::WorkletInvokeFunctor<WorkletType,Invocation>
|
|
|
|
WorkletInvokeFunctorType;
|
|
|
|
WorkletInvokeFunctorType workletFunctor =
|
|
|
|
WorkletInvokeFunctorType(this->Worklet, invocation);
|
|
|
|
|
|
|
|
typedef vtkm::cont::DeviceAdapterAlgorithm<Device> Algorithm;
|
2015-03-20 18:41:54 +00:00
|
|
|
|
2015-05-05 14:46:23 +00:00
|
|
|
Algorithm::Schedule(workletFunctor, range);
|
2014-10-21 16:51:07 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} // namespace vtkm::worklet::internal
|
|
|
|
|
|
|
|
#endif //vtk_m_worklet_internal_DispatcherBase_h
|