mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-10-08 11:29:02 +00:00
4f9fa08fa1
The `ArrayHandleStreaming` class stems from an old research project experimenting with bringing data from an `ArrayHandle` in parts and overlapping device transfer and execution. It works, but only in very limited contexts. Thus, it is not actually used today. Plus, the feature requires global indexing to be permutated throughout the worklet dispatching classes of VTK-m for no further reason. Because it is not really used, there are other more promising approaches on the horizon, and it makes further scheduling improvements difficult, we are removing this functionality.
306 lines
10 KiB
C++
306 lines
10 KiB
C++
//============================================================================
|
|
// 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.
|
|
//============================================================================
|
|
|
|
#ifndef vtk_m_exec_serial_internal_TaskTiling_h
|
|
#define vtk_m_exec_serial_internal_TaskTiling_h
|
|
|
|
#include <vtkm/exec/TaskBase.h>
|
|
|
|
//Todo: rename this header to TaskInvokeWorkletDetail.h
|
|
#include <vtkm/exec/internal/WorkletInvokeFunctorDetail.h>
|
|
|
|
namespace vtkm
|
|
{
|
|
namespace exec
|
|
{
|
|
namespace serial
|
|
{
|
|
namespace internal
|
|
{
|
|
|
|
template <typename WType>
|
|
VTKM_NEVER_EXPORT void TaskTilingSetErrorBuffer(
|
|
void* w,
|
|
const vtkm::exec::internal::ErrorMessageBuffer& buffer)
|
|
{
|
|
using WorkletType = typename std::remove_cv<WType>::type;
|
|
WorkletType* const worklet = static_cast<WorkletType*>(w);
|
|
worklet->SetErrorMessageBuffer(buffer);
|
|
}
|
|
|
|
template <typename WType, typename IType>
|
|
VTKM_NEVER_EXPORT void TaskTiling1DExecute(void* w, void* const v, vtkm::Id start, vtkm::Id end)
|
|
{
|
|
using WorkletType = typename std::remove_cv<WType>::type;
|
|
using InvocationType = typename std::remove_cv<IType>::type;
|
|
|
|
WorkletType const* const worklet = static_cast<WorkletType*>(w);
|
|
InvocationType const* const invocation = static_cast<InvocationType*>(v);
|
|
|
|
for (vtkm::Id index = start; index < end; ++index)
|
|
{
|
|
//Todo: rename this function to DoTaskInvokeWorklet
|
|
vtkm::exec::internal::detail::DoWorkletInvokeFunctor(
|
|
*worklet,
|
|
*invocation,
|
|
worklet->GetThreadIndices(index,
|
|
invocation->OutputToInputMap,
|
|
invocation->VisitArray,
|
|
invocation->ThreadToOutputMap,
|
|
invocation->GetInputDomain()));
|
|
}
|
|
}
|
|
|
|
template <typename FType>
|
|
VTKM_NEVER_EXPORT void FunctorTiling1DExecute(void* f, void* const, vtkm::Id start, vtkm::Id end)
|
|
{
|
|
using FunctorType = typename std::remove_cv<FType>::type;
|
|
FunctorType const* const functor = static_cast<FunctorType*>(f);
|
|
|
|
for (vtkm::Id index = start; index < end; ++index)
|
|
{
|
|
functor->operator()(index);
|
|
}
|
|
}
|
|
|
|
template <typename WType, typename IType>
|
|
VTKM_NEVER_EXPORT void TaskTiling3DExecute(void* w,
|
|
void* const v,
|
|
const vtkm::Id3& maxSize,
|
|
vtkm::Id istart,
|
|
vtkm::Id iend,
|
|
vtkm::Id j,
|
|
vtkm::Id k)
|
|
{
|
|
using WorkletType = typename std::remove_cv<WType>::type;
|
|
using InvocationType = typename std::remove_cv<IType>::type;
|
|
|
|
WorkletType const* const worklet = static_cast<WorkletType*>(w);
|
|
InvocationType const* const invocation = static_cast<InvocationType*>(v);
|
|
|
|
vtkm::Id3 index(istart, j, k);
|
|
auto threadIndex1D = index[0] + maxSize[0] * (index[1] + maxSize[1] * index[2]);
|
|
for (vtkm::Id i = istart; i < iend; ++i, ++threadIndex1D)
|
|
{
|
|
index[0] = i;
|
|
//Todo: rename this function to DoTaskInvokeWorklet
|
|
vtkm::exec::internal::detail::DoWorkletInvokeFunctor(
|
|
*worklet,
|
|
*invocation,
|
|
worklet->GetThreadIndices(threadIndex1D,
|
|
index,
|
|
invocation->OutputToInputMap,
|
|
invocation->VisitArray,
|
|
invocation->ThreadToOutputMap,
|
|
invocation->GetInputDomain()));
|
|
}
|
|
}
|
|
|
|
template <typename FType>
|
|
VTKM_NEVER_EXPORT void FunctorTiling3DExecute(void* f,
|
|
void* const,
|
|
const vtkm::Id3& vtkmNotUsed(maxSize),
|
|
vtkm::Id istart,
|
|
vtkm::Id iend,
|
|
vtkm::Id j,
|
|
vtkm::Id k)
|
|
{
|
|
using FunctorType = typename std::remove_cv<FType>::type;
|
|
FunctorType const* const functor = static_cast<FunctorType*>(f);
|
|
|
|
vtkm::Id3 index(istart, j, k);
|
|
for (vtkm::Id i = istart; i < iend; ++i)
|
|
{
|
|
index[0] = i;
|
|
functor->operator()(index);
|
|
}
|
|
}
|
|
|
|
// TaskTiling1D represents an execution pattern for a worklet
|
|
// that is best expressed in terms of single dimension iteration space. TaskTiling1D
|
|
// also states that for best performance a linear consecutive range of values
|
|
// should be given to the worklet for optimal performance.
|
|
//
|
|
// Note: The worklet and invocation must have a lifetime that is at least
|
|
// as long as the Task
|
|
class VTKM_NEVER_EXPORT TaskTiling1D : public vtkm::exec::TaskBase
|
|
{
|
|
public:
|
|
TaskTiling1D()
|
|
: Worklet(nullptr)
|
|
, Invocation(nullptr)
|
|
{
|
|
}
|
|
|
|
/// This constructor supports general functors that which have a call
|
|
/// operator with the signature:
|
|
/// operator()(vtkm::Id)
|
|
template <typename FunctorType>
|
|
TaskTiling1D(FunctorType& functor)
|
|
: Worklet(nullptr)
|
|
, Invocation(nullptr)
|
|
, ExecuteFunction(nullptr)
|
|
, SetErrorBufferFunction(nullptr)
|
|
{
|
|
//Setup the execute and set error buffer function pointers
|
|
this->ExecuteFunction = &FunctorTiling1DExecute<FunctorType>;
|
|
this->SetErrorBufferFunction = &TaskTilingSetErrorBuffer<FunctorType>;
|
|
|
|
//Bind the Worklet to void*
|
|
this->Worklet = (void*)&functor;
|
|
}
|
|
|
|
/// This constructor supports any vtkm worklet and the associated invocation
|
|
/// parameters that go along with it
|
|
template <typename WorkletType, typename InvocationType>
|
|
TaskTiling1D(WorkletType& worklet, InvocationType& invocation)
|
|
: Worklet(nullptr)
|
|
, Invocation(nullptr)
|
|
, ExecuteFunction(nullptr)
|
|
, SetErrorBufferFunction(nullptr)
|
|
{
|
|
//Setup the execute and set error buffer function pointers
|
|
this->ExecuteFunction = &TaskTiling1DExecute<WorkletType, InvocationType>;
|
|
this->SetErrorBufferFunction = &TaskTilingSetErrorBuffer<WorkletType>;
|
|
|
|
//Bind the Worklet and Invocation to void*
|
|
this->Worklet = (void*)&worklet;
|
|
this->Invocation = (void*)&invocation;
|
|
}
|
|
|
|
/// explicit Copy constructor.
|
|
/// Note this required so that compilers don't use the templated constructor
|
|
/// as the copy constructor which will cause compile issues
|
|
TaskTiling1D(TaskTiling1D& task)
|
|
: Worklet(task.Worklet)
|
|
, Invocation(task.Invocation)
|
|
, ExecuteFunction(task.ExecuteFunction)
|
|
, SetErrorBufferFunction(task.SetErrorBufferFunction)
|
|
{
|
|
}
|
|
|
|
TaskTiling1D(TaskTiling1D&& task) = default;
|
|
|
|
void SetErrorMessageBuffer(const vtkm::exec::internal::ErrorMessageBuffer& buffer)
|
|
{
|
|
this->SetErrorBufferFunction(this->Worklet, buffer);
|
|
}
|
|
|
|
void operator()(vtkm::Id start, vtkm::Id end) const
|
|
{
|
|
this->ExecuteFunction(this->Worklet, this->Invocation, start, end);
|
|
}
|
|
|
|
protected:
|
|
void* Worklet;
|
|
void* Invocation;
|
|
|
|
using ExecuteSignature = void (*)(void*, void* const, vtkm::Id, vtkm::Id);
|
|
ExecuteSignature ExecuteFunction;
|
|
|
|
using SetErrorBufferSignature = void (*)(void*, const vtkm::exec::internal::ErrorMessageBuffer&);
|
|
SetErrorBufferSignature SetErrorBufferFunction;
|
|
};
|
|
|
|
// TaskTiling3D represents an execution pattern for a worklet
|
|
// that is best expressed in terms of an 3 dimensional iteration space. TaskTiling3D
|
|
// also states that for best performance a linear consecutive range of values
|
|
// in the X dimension should be given to the worklet for optimal performance.
|
|
//
|
|
// Note: The worklet and invocation must have a lifetime that is at least
|
|
// as long as the Task
|
|
class VTKM_NEVER_EXPORT TaskTiling3D : public vtkm::exec::TaskBase
|
|
{
|
|
public:
|
|
TaskTiling3D()
|
|
: Worklet(nullptr)
|
|
, Invocation(nullptr)
|
|
{
|
|
}
|
|
|
|
/// This constructor supports general functors that which have a call
|
|
/// operator with the signature:
|
|
/// operator()(vtkm::Id)
|
|
template <typename FunctorType>
|
|
TaskTiling3D(FunctorType& functor)
|
|
: Worklet(nullptr)
|
|
, Invocation(nullptr)
|
|
, ExecuteFunction(nullptr)
|
|
, SetErrorBufferFunction(nullptr)
|
|
{
|
|
//Setup the execute and set error buffer function pointers
|
|
this->ExecuteFunction = &FunctorTiling3DExecute<FunctorType>;
|
|
this->SetErrorBufferFunction = &TaskTilingSetErrorBuffer<FunctorType>;
|
|
|
|
//Bind the Worklet to void*
|
|
this->Worklet = (void*)&functor;
|
|
}
|
|
|
|
template <typename WorkletType, typename InvocationType>
|
|
TaskTiling3D(WorkletType& worklet, InvocationType& invocation)
|
|
: Worklet(nullptr)
|
|
, Invocation(nullptr)
|
|
, ExecuteFunction(nullptr)
|
|
, SetErrorBufferFunction(nullptr)
|
|
{
|
|
// Setup the execute and set error buffer function pointers
|
|
this->ExecuteFunction = &TaskTiling3DExecute<WorkletType, InvocationType>;
|
|
this->SetErrorBufferFunction = &TaskTilingSetErrorBuffer<WorkletType>;
|
|
|
|
// At this point we bind the Worklet and Invocation to void*
|
|
this->Worklet = (void*)&worklet;
|
|
this->Invocation = (void*)&invocation;
|
|
}
|
|
|
|
/// explicit Copy constructor.
|
|
/// Note this required so that compilers don't use the templated constructor
|
|
/// as the copy constructor which will cause compile issues
|
|
TaskTiling3D(TaskTiling3D& task)
|
|
: Worklet(task.Worklet)
|
|
, Invocation(task.Invocation)
|
|
, ExecuteFunction(task.ExecuteFunction)
|
|
, SetErrorBufferFunction(task.SetErrorBufferFunction)
|
|
{
|
|
}
|
|
|
|
TaskTiling3D(TaskTiling3D&& task) = default;
|
|
|
|
void SetErrorMessageBuffer(const vtkm::exec::internal::ErrorMessageBuffer& buffer)
|
|
{
|
|
this->SetErrorBufferFunction(this->Worklet, buffer);
|
|
}
|
|
|
|
void operator()(const vtkm::Id3& maxSize,
|
|
vtkm::Id istart,
|
|
vtkm::Id iend,
|
|
vtkm::Id j,
|
|
vtkm::Id k) const
|
|
{
|
|
this->ExecuteFunction(this->Worklet, this->Invocation, maxSize, istart, iend, j, k);
|
|
}
|
|
|
|
protected:
|
|
void* Worklet;
|
|
void* Invocation;
|
|
|
|
using ExecuteSignature =
|
|
void (*)(void*, void* const, const vtkm::Id3&, vtkm::Id, vtkm::Id, vtkm::Id, vtkm::Id);
|
|
ExecuteSignature ExecuteFunction;
|
|
|
|
using SetErrorBufferSignature = void (*)(void*, const vtkm::exec::internal::ErrorMessageBuffer&);
|
|
SetErrorBufferSignature SetErrorBufferFunction;
|
|
};
|
|
}
|
|
}
|
|
}
|
|
} // vtkm::exec::serial::internal
|
|
|
|
#endif //vtk_m_exec_serial_internal_TaskTiling_h
|