Merge topic 'propagate_id3_to_shared_indices'

8de216c0 Propagate vtkm::Id3 scheduling down to the ThreadIndex classes.

Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: Kenneth Moreland <kmorel@sandia.gov>
Merge-request: !240
This commit is contained in:
Robert Maynard 2015-10-20 12:25:50 -04:00 committed by Kitware Robot
commit 876ef118cc
9 changed files with 132 additions and 45 deletions

@ -31,9 +31,9 @@
#include <vtkm/cont/cuda/internal/MakeThrustIterator.h> #include <vtkm/cont/cuda/internal/MakeThrustIterator.h>
#include <vtkm/cont/cuda/internal/ThrustExceptionHandler.h> #include <vtkm/cont/cuda/internal/ThrustExceptionHandler.h>
#include <vtkm/exec/cuda/internal/WrappedOperators.h>
#include <vtkm/exec/internal/ErrorMessageBuffer.h> #include <vtkm/exec/internal/ErrorMessageBuffer.h>
#include <vtkm/exec/internal/WorkletInvokeFunctor.h> #include <vtkm/exec/internal/WorkletInvokeFunctor.h>
#include <vtkm/exec/cuda/internal/WrappedOperators.h>
// Disable warnings we check vtkm for but Thrust does not. // Disable warnings we check vtkm for but Thrust does not.
VTKM_THIRDPARTY_PRE_INCLUDE VTKM_THIRDPARTY_PRE_INCLUDE
@ -98,18 +98,16 @@ template<class FunctorType>
__global__ __global__
void Schedule3DIndexKernel(FunctorType functor, dim3 size) void Schedule3DIndexKernel(FunctorType functor, dim3 size)
{ {
const vtkm::Id x = blockIdx.x*blockDim.x + threadIdx.x; const vtkm::Id3 index(
const vtkm::Id y = blockIdx.y*blockDim.y + threadIdx.y; blockIdx.x*blockDim.x + threadIdx.x,
const vtkm::Id z = blockIdx.z*blockDim.z + threadIdx.z; blockIdx.y*blockDim.y + threadIdx.y,
blockIdx.z*blockDim.z + threadIdx.z
if (x >= size.x || y >= size.y || z >= size.z) );
if (index[0] >= size.x || index[1] >= size.y || index[2] >= size.z)
{ {
return; return;
} }
functor( index );
//now convert back to flat memory
const int idx = x + size.x*(y + size.y*z);
functor( idx );
} }
template<typename T, typename BinaryOperationType > template<typename T, typename BinaryOperationType >

@ -258,7 +258,8 @@ private:
: Functor(functor) { } : Functor(functor) { }
//needed for when calling from schedule on a range //needed for when calling from schedule on a range
VTKM_EXEC_EXPORT void operator()(vtkm::Id index) const template<typename T>
VTKM_EXEC_EXPORT void operator()(const T& index) const
{ {
this->Functor(index); this->Functor(index);
} }
@ -309,17 +310,18 @@ public:
DeviceAdapterAlgorithm<Device>::ScheduleKernel<Functor> kernel(functor); DeviceAdapterAlgorithm<Device>::ScheduleKernel<Functor> kernel(functor);
//use a const variable to hint to compiler this doesn't change vtkm::Id3 index;
for(vtkm::Id k=0; k < rangeMax[2]; ++k) for(vtkm::Id k=0; k < rangeMax[2]; ++k)
{ {
vtkm::Id index = k * rangeMax[1] * rangeMax[0]; index[2] = k;
for(vtkm::Id j=0; j < rangeMax[1]; ++j) for(vtkm::Id j=0; j < rangeMax[1]; ++j)
{ {
index[1] = j;
for(vtkm::Id i=0; i < rangeMax[0]; ++i) for(vtkm::Id i=0; i < rangeMax[0]; ++i)
{ {
kernel( index + i ); index[0] = i;
kernel( index );
} }
index += rangeMax[0];
} }
} }

@ -20,18 +20,17 @@
#ifndef vtk_m_cont_tbb_internal_DeviceAdapterAlgorithmTBB_h #ifndef vtk_m_cont_tbb_internal_DeviceAdapterAlgorithmTBB_h
#define vtk_m_cont_tbb_internal_DeviceAdapterAlgorithmTBB_h #define vtk_m_cont_tbb_internal_DeviceAdapterAlgorithmTBB_h
#include <vtkm/cont/internal/IteratorFromArrayPortal.h>
#include <vtkm/cont/tbb/internal/DeviceAdapterTagTBB.h>
#include <vtkm/cont/tbb/internal/ArrayManagerExecutionTBB.h>
#include <vtkm/exec/internal/ErrorMessageBuffer.h>
#include <vtkm/Extent.h>
#include <vtkm/cont/ArrayHandle.h> #include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleIndex.h> #include <vtkm/cont/ArrayHandleIndex.h>
#include <vtkm/cont/ArrayHandleZip.h> #include <vtkm/cont/ArrayHandleZip.h>
#include <vtkm/cont/DeviceAdapterAlgorithm.h> #include <vtkm/cont/DeviceAdapterAlgorithm.h>
#include <vtkm/cont/ErrorExecution.h> #include <vtkm/cont/ErrorExecution.h>
#include <vtkm/cont/internal/DeviceAdapterAlgorithmGeneral.h> #include <vtkm/cont/internal/DeviceAdapterAlgorithmGeneral.h>
#include <vtkm/cont/internal/IteratorFromArrayPortal.h>
#include <vtkm/cont/tbb/internal/ArrayManagerExecutionTBB.h>
#include <vtkm/cont/tbb/internal/DeviceAdapterTagTBB.h>
#include <vtkm/exec/internal/ErrorMessageBuffer.h>
#include <vtkm/Extent.h>
VTKM_THIRDPARTY_PRE_INCLUDE VTKM_THIRDPARTY_PRE_INCLUDE
#include <boost/type_traits/remove_reference.hpp> #include <boost/type_traits/remove_reference.hpp>
@ -466,17 +465,18 @@ private:
void operator()(const ::tbb::blocked_range3d<vtkm::Id> &range) const { void operator()(const ::tbb::blocked_range3d<vtkm::Id> &range) const {
try try
{ {
vtkm::Id3 index;
for( vtkm::Id k=range.pages().begin(); k!=range.pages().end(); ++k) for( vtkm::Id k=range.pages().begin(); k!=range.pages().end(); ++k)
{ {
vtkm::Id index = k * this->Dims[1] * this->Dims[0]; index[2] = k;
index += range.rows().begin() * this->Dims[0];
for( vtkm::Id j=range.rows().begin(); j!=range.rows().end(); ++j) for( vtkm::Id j=range.rows().begin(); j!=range.rows().end(); ++j)
{ {
index[1] = j;
for( vtkm::Id i=range.cols().begin(); i!=range.cols().end(); ++i) for( vtkm::Id i=range.cols().begin(); i!=range.cols().end(); ++i)
{ {
this->Functor(index + i); index[0] = i;
this->Functor( index );
} }
index += this->Dims[0];
} }
} }
} }

@ -129,17 +129,30 @@ public:
struct ClearArrayKernel struct ClearArrayKernel
{ {
VTKM_CONT_EXPORT VTKM_CONT_EXPORT
ClearArrayKernel(const IdPortalType &array) : Array(array) { } ClearArrayKernel(const IdPortalType &array) : Array(array), Dims() { }
VTKM_CONT_EXPORT
ClearArrayKernel(const IdPortalType &array,
const vtkm::Id3& dims) : Array(array), Dims(dims) { }
VTKM_EXEC_EXPORT void operator()(vtkm::Id index) const VTKM_EXEC_EXPORT void operator()(vtkm::Id index) const
{ {
this->Array.Set(index, OFFSET); this->Array.Set(index, OFFSET);
} }
VTKM_EXEC_EXPORT void operator()(vtkm::Id3 index) const
{
//convert from id3 to id
vtkm::Id flatIndex =
index[0]+ this->Dims[0]*(index[1]+ this->Dims[1]*index[2]);
this->operator()(flatIndex);
}
VTKM_CONT_EXPORT void SetErrorMessageBuffer( VTKM_CONT_EXPORT void SetErrorMessageBuffer(
const vtkm::exec::internal::ErrorMessageBuffer &) { } const vtkm::exec::internal::ErrorMessageBuffer &) { }
IdPortalType Array; IdPortalType Array;
vtkm::Id3 Dims;
}; };
struct ClearArrayMapKernel //: public vtkm::exec::WorkletMapField struct ClearArrayMapKernel //: public vtkm::exec::WorkletMapField
@ -158,17 +171,31 @@ public:
struct AddArrayKernel struct AddArrayKernel
{ {
VTKM_CONT_EXPORT VTKM_CONT_EXPORT
AddArrayKernel(const IdPortalType &array) : Array(array) { } AddArrayKernel(const IdPortalType &array) : Array(array), Dims() { }
VTKM_CONT_EXPORT
AddArrayKernel(const IdPortalType &array,
const vtkm::Id3& dims) : Array(array), Dims(dims) { }
VTKM_EXEC_EXPORT void operator()(vtkm::Id index) const VTKM_EXEC_EXPORT void operator()(vtkm::Id index) const
{ {
this->Array.Set(index, this->Array.Get(index) + index); this->Array.Set(index, this->Array.Get(index) + index);
} }
VTKM_EXEC_EXPORT void operator()(vtkm::Id3 index) const
{
//convert from id3 to id
vtkm::Id flatIndex =
index[0]+ this->Dims[0]*(index[1]+ this->Dims[1]*index[2]);
this->operator()(flatIndex);
}
VTKM_CONT_EXPORT void SetErrorMessageBuffer( VTKM_CONT_EXPORT void SetErrorMessageBuffer(
const vtkm::exec::internal::ErrorMessageBuffer &) { } const vtkm::exec::internal::ErrorMessageBuffer &) { }
IdPortalType Array; IdPortalType Array;
vtkm::Id3 Dims;
}; };
struct OneErrorKernel struct OneErrorKernel
@ -486,11 +513,11 @@ private:
std::cout << "Running clear." << std::endl; std::cout << "Running clear." << std::endl;
Algorithm::Schedule( Algorithm::Schedule(
ClearArrayKernel(manager.PrepareForOutput( ClearArrayKernel(manager.PrepareForOutput(
DIM_SIZE * DIM_SIZE * DIM_SIZE)), DIM_SIZE * DIM_SIZE * DIM_SIZE), maxRange),
maxRange); maxRange);
std::cout << "Running add." << std::endl; std::cout << "Running add." << std::endl;
Algorithm::Schedule(AddArrayKernel(manager.PrepareForInPlace(false)), Algorithm::Schedule(AddArrayKernel(manager.PrepareForInPlace(false), maxRange),
maxRange); maxRange);
std::cout << "Checking results." << std::endl; std::cout << "Checking results." << std::endl;

@ -138,6 +138,18 @@ vtkm::Id3 InflateTo3D(vtkm::Id index)
return vtkm::Id3(index, 0, 0); return vtkm::Id3(index, 0, 0);
} }
VTKM_EXEC_EXPORT
vtkm::Id3 Deflate(const vtkm::Id3& index, vtkm::Id3)
{
return index;
}
VTKM_EXEC_EXPORT
vtkm::Id2 Deflate(const vtkm::Id3& index, vtkm::Id2)
{
return vtkm::Id2(index[0], index[1]);
}
} // namespace detail } // namespace detail
// Specialization for structured connectivity types. // Specialization for structured connectivity types.
@ -146,7 +158,6 @@ template<typename FromTopology,
vtkm::IdComponent Dimension> vtkm::IdComponent Dimension>
class ThreadIndicesTopologyMap< class ThreadIndicesTopologyMap<
vtkm::exec::ConnectivityStructured<FromTopology,ToTopology,Dimension> > vtkm::exec::ConnectivityStructured<FromTopology,ToTopology,Dimension> >
: public vtkm::exec::arg::ThreadIndicesBasic
{ {
typedef vtkm::exec::arg::ThreadIndicesBasic Superclass; typedef vtkm::exec::arg::ThreadIndicesBasic Superclass;
typedef vtkm::exec::ConnectivityStructured<FromTopology,ToTopology,Dimension> typedef vtkm::exec::ConnectivityStructured<FromTopology,ToTopology,Dimension>
@ -160,7 +171,6 @@ public:
template<typename Invocation> template<typename Invocation>
VTKM_EXEC_EXPORT VTKM_EXEC_EXPORT
ThreadIndicesTopologyMap(vtkm::Id threadIndex, const Invocation &invocation) ThreadIndicesTopologyMap(vtkm::Id threadIndex, const Invocation &invocation)
: Superclass(threadIndex, invocation)
{ {
// The connectivity is stored in the invocation parameter at the given // The connectivity is stored in the invocation parameter at the given
// input domain index. If this class is being used correctly, the type // input domain index. If this class is being used correctly, the type
@ -169,9 +179,33 @@ public:
// set its input domain incorrectly. // set its input domain incorrectly.
const ConnectivityType &connectivity = invocation.GetInputDomain(); const ConnectivityType &connectivity = invocation.GetInputDomain();
this->LogicalIndex = connectivity.FlatToLogicalToIndex(this->GetIndex()); const LogicalIndexType logicalIndex = connectivity.FlatToLogicalToIndex(threadIndex);
this->IndicesFrom = connectivity.GetIndices(this->LogicalIndex);
this->CellShape = connectivity.GetCellShape(this->GetIndex()); this->Index = threadIndex;
this->LogicalIndex = logicalIndex;
this->IndicesFrom = connectivity.GetIndices(logicalIndex);
this->CellShape = connectivity.GetCellShape(threadIndex);
}
template<typename Invocation>
VTKM_EXEC_EXPORT
ThreadIndicesTopologyMap(vtkm::Id3 threadIndex, const Invocation &invocation)
{
// The connectivity is stored in the invocation parameter at the given
// input domain index. If this class is being used correctly, the type
// of the domain will match the connectivity type used here. If there is
// a compile error here about a type mismatch, chances are a worklet has
// set its input domain incorrectly.
const ConnectivityType &connectivity = invocation.GetInputDomain();
const LogicalIndexType logicalIndex = detail::Deflate(threadIndex, LogicalIndexType());
const vtkm::Id index = connectivity.LogicalToFlatToIndex(logicalIndex);
this->Index = index;
this->LogicalIndex = logicalIndex;
this->IndicesFrom = connectivity.GetIndices(logicalIndex);
this->CellShape = connectivity.GetCellShape(index);
} }
/// \brief The logical index into the input domain. /// \brief The logical index into the input domain.
@ -185,6 +219,18 @@ public:
return this->LogicalIndex; return this->LogicalIndex;
} }
/// \brief The index into the input domain.
///
/// This index refers to the input element (array value, cell, etc.) that
/// this thread is being invoked for. This is the typical index used during
/// fetches.
///
VTKM_EXEC_EXPORT
vtkm::Id GetIndex() const
{
return this->Index;
}
/// \brief The 3D index into the input domain. /// \brief The 3D index into the input domain.
/// ///
/// Overloads the implementation in the base class to return the 3D index /// Overloads the implementation in the base class to return the 3D index
@ -217,6 +263,7 @@ public:
CellShapeTag GetCellShape() const { return this->CellShape; } CellShapeTag GetCellShape() const { return this->CellShape; }
private: private:
vtkm::Id Index;
LogicalIndexType LogicalIndex; LogicalIndexType LogicalIndex;
IndicesFromType IndicesFrom; IndicesFromType IndicesFrom;
CellShapeTag CellShape; CellShapeTag CellShape;

@ -50,8 +50,9 @@ public:
} }
VTKM_SUPPRESS_EXEC_WARNINGS VTKM_SUPPRESS_EXEC_WARNINGS
template<typename T>
VTKM_EXEC_EXPORT VTKM_EXEC_EXPORT
void operator()(vtkm::Id index) const void operator()(T index) const
{ {
detail::DoWorkletInvokeFunctor(this->Worklet, detail::DoWorkletInvokeFunctor(this->Worklet,
this->Invocation, this->Invocation,

@ -340,15 +340,15 @@ public:
} }
VTKM_EXEC_CONT_EXPORT VTKM_EXEC_CONT_EXPORT
const vtkm::Id3 GetPointDimensions() const const vtkm::Id3& GetPointDimensions() const
{ {
return this->PointDimensions; return this->PointDimensions;
} }
VTKM_EXEC_CONT_EXPORT VTKM_EXEC_CONT_EXPORT
vtkm::Id3 GetCellDimensions() const const vtkm::Id3& GetCellDimensions() const
{ {
return this->PointDimensions - vtkm::Id3(1); return this->CellDimensions;
} }
VTKM_EXEC_CONT_EXPORT VTKM_EXEC_CONT_EXPORT
@ -359,11 +359,11 @@ public:
//returns an id3 to signal what kind of scheduling to use //returns an id3 to signal what kind of scheduling to use
VTKM_EXEC_CONT_EXPORT VTKM_EXEC_CONT_EXPORT
vtkm::Id3 GetSchedulingRange(vtkm::TopologyElementTagCell) const { const vtkm::Id3& GetSchedulingRange(vtkm::TopologyElementTagCell) const {
return this->GetCellDimensions(); return this->GetCellDimensions();
} }
VTKM_EXEC_CONT_EXPORT VTKM_EXEC_CONT_EXPORT
vtkm::Id3 GetSchedulingRange(vtkm::TopologyElementTagPoint) const { const vtkm::Id3& GetSchedulingRange(vtkm::TopologyElementTagPoint) const {
return this->GetPointDimensions(); return this->GetPointDimensions();
} }
@ -535,10 +535,9 @@ public:
VTKM_EXEC_CONT_EXPORT VTKM_EXEC_CONT_EXPORT
vtkm::Id LogicalToFlatCellIndex(const vtkm::Id3 &logicalCellIndex) const vtkm::Id LogicalToFlatCellIndex(const vtkm::Id3 &logicalCellIndex) const
{ {
vtkm::Id3 cellDimensions = this->GetCellDimensions();
return logicalCellIndex[0] return logicalCellIndex[0]
+ cellDimensions[0]*(logicalCellIndex[1] + this->CellDimensions[0]*(logicalCellIndex[1]
+ cellDimensions[1]*logicalCellIndex[2]); + this->CellDimensions[1]*logicalCellIndex[2]);
} }
private: private:

@ -142,10 +142,10 @@ public:
/// Topology map worklets use topology map indices. /// Topology map worklets use topology map indices.
/// ///
template<typename Invocation> template<typename T, typename Invocation>
VTKM_EXEC_EXPORT VTKM_EXEC_EXPORT
vtkm::exec::arg::ThreadIndicesTopologyMap<typename Invocation::InputDomainType> vtkm::exec::arg::ThreadIndicesTopologyMap<typename Invocation::InputDomainType>
GetThreadIndices(vtkm::Id threadIndex, const Invocation &invocation) const GetThreadIndices(const T& threadIndex, const Invocation &invocation) const
{ {
return vtkm::exec::arg::ThreadIndicesTopologyMap<typename Invocation::InputDomainType>( return vtkm::exec::arg::ThreadIndicesTopologyMap<typename Invocation::InputDomainType>(
threadIndex, invocation); threadIndex, invocation);

@ -167,6 +167,19 @@ public:
{ {
return vtkm::exec::arg::ThreadIndicesBasic(threadIndex, invocation); return vtkm::exec::arg::ThreadIndicesBasic(threadIndex, invocation);
} }
/// \brief Creates a \c ThreadIndices object.
///
/// Worklet types can add additional indices by returning different object
/// types.
///
template<typename T, typename Invocation>
VTKM_EXEC_EXPORT
vtkm::exec::arg::ThreadIndicesBasic
GetThreadIndices(const T& threadIndex, const Invocation &invocation) const
{
return vtkm::exec::arg::ThreadIndicesBasic(threadIndex, invocation);
}
}; };
} }