Implement a way to pass a portal to worklet as a parameter.

This is built ontop of the ExecutionObjectBase work, and is designed to show
other developers how they can create custom objects that are shared among
all worklets, but are passed as parameters to the worklet.
This commit is contained in:
Robert Maynard 2015-06-15 10:20:51 -04:00
parent 6ca2308e5f
commit d7e85bb6ae
4 changed files with 230 additions and 0 deletions

@ -20,6 +20,7 @@
set(headers
ExecutionObjectBase.h
ExecutionWholeArray.h
ExplicitConnectivity.h
FunctorBase.h
TopologyData.h

@ -0,0 +1,103 @@
//============================================================================
// 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.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_exec_ExecutionWholeArray_h
#define vtk_m_exec_ExecutionWholeArray_h
#include <vtkm/cont/DeviceAdapter.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/exec/ExecutionObjectBase.h>
namespace vtkm {
namespace exec {
/// \c ExecutionWholeArray is an execution object that allows an array handle
/// content to be a parameter in an execution environment
/// function. This can be used to allow worklets to have a shared search
/// structure
///
template<typename T,
typename StorageTag = VTKM_DEFAULT_STORAGE_TAG,
typename DeviceAdapterTag = VTKM_DEFAULT_DEVICE_ADAPTER_TAG
>
class ExecutionWholeArray : public vtkm::exec::ExecutionObjectBase
{
public:
VTKM_CONT_EXPORT
ExecutionWholeArray( ):
Portal( )
{
}
VTKM_CONT_EXPORT
ExecutionWholeArray( const vtkm::cont::ArrayHandle<T,StorageTag>& handle,
vtkm::Id length ):
Portal( handle.PrepareForInPlace(length, DeviceAdapterTag()) )
{
}
VTKM_EXEC_EXPORT
T Get(vtkm::Id index) const { return this->Portal.Get(index); }
VTKM_EXEC_EXPORT
void Set(vtkm::Id index, const T& t) const { return this->Portal.Set(index, t); }
private:
typedef vtkm::cont::ArrayHandle<T,StorageTag> HandleType;
typedef typename HandleType::template ExecutionTypes<DeviceAdapterTag>::Portal PortalType;
PortalType Portal;
};
/// \c ExecutionWholeArrayConst is an execution object that allows an array handle
/// content to be a parameter in an execution environment
/// function. This can be used to allow worklets to have a shared search
/// structure
///
template<typename T,
typename StorageTag = VTKM_DEFAULT_STORAGE_TAG,
typename DeviceAdapterTag = VTKM_DEFAULT_DEVICE_ADAPTER_TAG
>
class ExecutionWholeArrayConst : public vtkm::exec::ExecutionObjectBase
{
public:
VTKM_CONT_EXPORT
ExecutionWholeArrayConst( ):
Portal( )
{
}
VTKM_CONT_EXPORT
ExecutionWholeArrayConst( const vtkm::cont::ArrayHandle<T,StorageTag>& handle):
Portal( handle.PrepareForInput( DeviceAdapterTag() ) )
{
}
VTKM_EXEC_EXPORT
T Get(vtkm::Id index) const { return this->Portal.Get(index); }
private:
typedef vtkm::cont::ArrayHandle<T,StorageTag> HandleType;
typedef typename HandleType::template ExecutionTypes<DeviceAdapterTag>::PortalConst PortalType;
PortalType Portal;
};
}
} // namespace vtkm::exec
#endif //vtk_m_exec_ExecutionObjectBase_h

@ -22,6 +22,7 @@ set(unit_tests
UnitTestCellAverage.cxx
UnitTestPointElevation.cxx
UnitTestWorkletMapField.cxx
UnitTestWorkletMapFieldExecArg.cxx
UnitTestWorkletMapFieldMultiParam.cxx
UnitTestWorkletMapTopologyExplicit.cxx
UnitTestWorkletMapTopologyRegular.cxx

@ -0,0 +1,125 @@
//============================================================================
// 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.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleCounting.h>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/exec/ExecutionWholeArray.h>
#include <vtkm/cont/testing/Testing.h>
namespace map_exec_field{
namespace worklets {
class TestWorklet : public vtkm::worklet::WorkletMapField
{
public:
typedef void ControlSignature( FieldIn<>, ExecObject, FieldOut<>);
typedef void ExecutionSignature(_1, _2, _3);
template<typename T, typename StorageTag>
VTKM_EXEC_EXPORT
void operator()(const vtkm::Id &index,
const vtkm::exec::ExecutionWholeArrayConst<T,StorageTag> &execArg,
T& out) const
{
if (!test_equal(execArg.Get(index), TestValue(index, T()) + T(100)))
{
this->RaiseError("Got wrong input value.");
}
out = execArg.Get(index) - T(100);
}
template<typename T1, typename T2>
VTKM_EXEC_EXPORT
void operator()(const vtkm::Id &, const T1 &, const T2 &) const
{
this->RaiseError("Cannot call this worklet with different types.");
}
};
} // worklet namespace
static const vtkm::Id ARRAY_SIZE = 10;
template<typename WorkletType>
struct DoTestWorklet
{
template<typename T>
VTKM_CONT_EXPORT
void operator()(T) const
{
std::cout << "Set up data." << std::endl;
T inputArray[ARRAY_SIZE];
for (vtkm::Id index = 0; index < ARRAY_SIZE; index++)
{
inputArray[index] = TestValue(index, T()) + T(100);
}
vtkm::cont::ArrayHandleCounting<vtkm::Id> counting(0,ARRAY_SIZE);
vtkm::cont::ArrayHandle<T> inputHandle =
vtkm::cont::make_ArrayHandle(inputArray, ARRAY_SIZE);
vtkm::cont::ArrayHandle<T> outputHandle;
std::cout << "Create and run dispatcher." << std::endl;
vtkm::worklet::DispatcherMapField<WorkletType> dispatcher;
dispatcher.Invoke(counting,
vtkm::exec::ExecutionWholeArrayConst<T>(inputHandle),
outputHandle);
std::cout << "Check result." << std::endl;
CheckPortal(outputHandle.GetPortalConstControl());
std::cout << "Repeat with dynamic arrays." << std::endl;
// Clear out output array.
outputHandle = vtkm::cont::ArrayHandle<T>();
vtkm::cont::DynamicArrayHandle outputDynamic(outputHandle);
dispatcher.Invoke(counting,
vtkm::exec::ExecutionWholeArrayConst<T>(inputHandle),
outputDynamic);
CheckPortal(outputHandle.GetPortalConstControl());
}
};
void TestWorkletMapFieldExecArg()
{
typedef vtkm::cont::internal::DeviceAdapterTraits<
VTKM_DEFAULT_DEVICE_ADAPTER_TAG> DeviceAdapterTraits;
std::cout << "Testing Worklet with ExecutionWholeArray on device adapter: "
<< DeviceAdapterTraits::GetId() << std::endl;
std::cout << "--- Worklet accepting all types." << std::endl;
vtkm::testing::Testing::TryTypes(
map_exec_field::DoTestWorklet< worklets::TestWorklet >(),
vtkm::TypeListTagCommon());
}
} // anonymous namespace
int UnitTestWorkletMapFieldExecArg(int, char *[])
{
return vtkm::cont::testing::Testing::Run(map_exec_field::TestWorkletMapFieldExecArg);
}