Merge branch 'try-run-on-device' into 'master'
Add general purpose TryExecute The filters directory had a couple of classes designed to try executing filters on a list of devices until one succeeds. There was quite a bit of code duplication in these, and the code was inaccessible to other parts of VTK-m. This resolves both of these issues by moving the functionality to a TryExecute method located in the vtkm::cont package. See merge request !507
This commit is contained in:
commit
069fc69869
@ -131,14 +131,14 @@ public:
|
||||
typedef typename vtkm::VecTraits<FieldInType>::ComponentType FieldType;
|
||||
const FieldType iso = static_cast<FieldType>(this->IsoValue);
|
||||
|
||||
caseNumber= ((fieldIn[0] > this->IsoValue) |
|
||||
(fieldIn[1] > this->IsoValue) << 1 |
|
||||
(fieldIn[2] > this->IsoValue) << 2 |
|
||||
(fieldIn[3] > this->IsoValue) << 3 |
|
||||
(fieldIn[4] > this->IsoValue) << 4 |
|
||||
(fieldIn[5] > this->IsoValue) << 5 |
|
||||
(fieldIn[6] > this->IsoValue) << 6 |
|
||||
(fieldIn[7] > this->IsoValue) << 7);
|
||||
caseNumber= ((fieldIn[0] > iso) |
|
||||
(fieldIn[1] > iso) << 1 |
|
||||
(fieldIn[2] > iso) << 2 |
|
||||
(fieldIn[3] > iso) << 3 |
|
||||
(fieldIn[4] > iso) << 4 |
|
||||
(fieldIn[5] > iso) << 5 |
|
||||
(fieldIn[6] > iso) << 6 |
|
||||
(fieldIn[7] > iso) << 7);
|
||||
}
|
||||
};
|
||||
|
||||
@ -386,4 +386,4 @@ int main(int argc, char *argv[])
|
||||
//now actually execute the benchmarks
|
||||
return vtkm::benchmarking::BenchmarkTopologyAlgorithms
|
||||
<VTKM_DEFAULT_DEVICE_ADAPTER_TAG>::Run(benchmarks);
|
||||
}
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ set(headers
|
||||
DataSetFieldAdd.h
|
||||
DeviceAdapter.h
|
||||
DeviceAdapterAlgorithm.h
|
||||
DeviceAdapterListTag.h
|
||||
DeviceAdapterSerial.h
|
||||
DynamicArrayHandle.h
|
||||
DynamicCellSet.h
|
||||
@ -68,6 +69,7 @@ set(headers
|
||||
StorageImplicit.h
|
||||
StorageListTag.h
|
||||
Timer.h
|
||||
TryExecute.h
|
||||
)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
46
vtkm/cont/DeviceAdapterListTag.h
Normal file
46
vtkm/cont/DeviceAdapterListTag.h
Normal file
@ -0,0 +1,46 @@
|
||||
//============================================================================
|
||||
// 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 2016 Sandia Corporation.
|
||||
// Copyright 2016 UT-Battelle, LLC.
|
||||
// Copyright 2016 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_cont_DeviceAdapterListTag_h
|
||||
#define vtk_m_cont_DeviceAdapterListTag_h
|
||||
|
||||
#ifndef VTKM_DEFAULT_DEVICE_ADAPTER_LIST_TAG
|
||||
#define VTKM_DEFAULT_DEVICE_ADAPTER_LIST_TAG \
|
||||
::vtkm::cont::DeviceAdapterListTagCommon
|
||||
#endif
|
||||
|
||||
#include <vtkm/ListTag.h>
|
||||
|
||||
#include <vtkm/cont/DeviceAdapterSerial.h>
|
||||
#include <vtkm/cont/cuda/DeviceAdapterCuda.h>
|
||||
#include <vtkm/cont/tbb/DeviceAdapterTBB.h>
|
||||
|
||||
namespace vtkm {
|
||||
namespace cont {
|
||||
|
||||
struct DeviceAdapterListTagCommon
|
||||
: vtkm::ListTagBase<
|
||||
vtkm::cont::DeviceAdapterTagCuda,
|
||||
vtkm::cont::DeviceAdapterTagTBB,
|
||||
vtkm::cont::DeviceAdapterTagSerial> { };
|
||||
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
|
||||
#endif //vtk_m_cont_DeviceAdapterListTag_h
|
208
vtkm/cont/TryExecute.h
Normal file
208
vtkm/cont/TryExecute.h
Normal file
@ -0,0 +1,208 @@
|
||||
//============================================================================
|
||||
// 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 2016 Sandia Corporation.
|
||||
// Copyright 2016 UT-Battelle, LLC.
|
||||
// Copyright 2016 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_cont_TryExecute_h
|
||||
#define vtk_m_cont_TryExecute_h
|
||||
|
||||
#include <vtkm/cont/DeviceAdapterListTag.h>
|
||||
#include <vtkm/cont/ErrorControlBadAllocation.h>
|
||||
#include <vtkm/cont/ErrorControlBadType.h>
|
||||
#include <vtkm/cont/ErrorControlBadValue.h>
|
||||
|
||||
#include <vtkm/cont/internal/RuntimeDeviceTracker.h>
|
||||
|
||||
namespace vtkm {
|
||||
namespace cont {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename Functor, typename Device, bool DeviceAdapterValid>
|
||||
struct TryExecuteRunIfValid;
|
||||
|
||||
template<typename Functor, typename Device>
|
||||
struct TryExecuteRunIfValid<Functor, Device, false>
|
||||
{
|
||||
VTKM_CONT_EXPORT
|
||||
static bool Run(Functor &, vtkm::cont::internal::RuntimeDeviceTracker &) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Functor, typename Device>
|
||||
struct TryExecuteRunIfValid<Functor, Device, true>
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
|
||||
VTKM_CONT_EXPORT
|
||||
static bool Run(Functor &functor,
|
||||
vtkm::cont::internal::RuntimeDeviceTracker &tracker)
|
||||
{
|
||||
if (tracker.CanRunOn(Device()))
|
||||
{
|
||||
try
|
||||
{
|
||||
return functor(Device());
|
||||
}
|
||||
catch(vtkm::cont::ErrorControlBadAllocation e)
|
||||
{
|
||||
std::cerr << "caught ErrorControlBadAllocation " << e.GetMessage() << std::endl;
|
||||
//currently we only consider OOM errors worth disabling a device for
|
||||
//than we fallback to another device
|
||||
tracker.ReportAllocationFailure(Device(), e);
|
||||
}
|
||||
catch(vtkm::cont::ErrorControlBadType e)
|
||||
{
|
||||
//should bad type errors should stop the execution, instead of
|
||||
//deferring to another device adapter?
|
||||
std::cerr << "caught ErrorControlBadType : " << e.GetMessage() << std::endl;
|
||||
}
|
||||
catch(vtkm::cont::ErrorControlBadValue e)
|
||||
{
|
||||
//should bad value errors should stop the filter, instead of deferring
|
||||
//to another device adapter?
|
||||
std::cerr << "caught ErrorControlBadValue : " << e.GetMessage() << std::endl;
|
||||
}
|
||||
catch(vtkm::cont::Error e)
|
||||
{
|
||||
//general errors should be caught and let us try the next device adapter.
|
||||
std::cerr << "exception is: " << e.GetMessage() << std::endl;
|
||||
}
|
||||
catch (std::exception e)
|
||||
{
|
||||
std::cerr << "caught standard exception: " << e.what() << std::endl;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::cerr << "unknown exception caught" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// If we are here, then the functor was either never run or failed.
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename FunctorType>
|
||||
struct TryExecuteImpl
|
||||
{
|
||||
// Warning, these are a references. Make sure referenced objects do not go
|
||||
// out of scope.
|
||||
FunctorType &Functor;
|
||||
vtkm::cont::internal::RuntimeDeviceTracker &Tracker;
|
||||
|
||||
bool Success;
|
||||
|
||||
VTKM_CONT_EXPORT
|
||||
TryExecuteImpl(FunctorType &functor,
|
||||
vtkm::cont::internal::RuntimeDeviceTracker &tracker)
|
||||
: Functor(functor), Tracker(tracker), Success(false) { }
|
||||
|
||||
template<typename Device>
|
||||
VTKM_CONT_EXPORT
|
||||
bool operator()(Device)
|
||||
{
|
||||
if (!this->Success)
|
||||
{
|
||||
typedef vtkm::cont::DeviceAdapterTraits<Device> DeviceTraits;
|
||||
|
||||
this->Success =
|
||||
detail::TryExecuteRunIfValid<FunctorType,Device,DeviceTraits::Valid>
|
||||
::Run(this->Functor, this->Tracker);
|
||||
}
|
||||
|
||||
return this->Success;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// \brief Try to execute a functor on a list of devices until one succeeds.
|
||||
///
|
||||
/// This function takes a functor and a list of devices. It then tries to run
|
||||
/// the functor for each device (in the order given in the list) until the
|
||||
/// execution succeeds.
|
||||
///
|
||||
/// The functor parentheses operator should take exactly one argument, which is
|
||||
/// the \c DeviceAdapterTag to use. The functor should return a \c bool that is
|
||||
/// \c true if the execution succeeds, \c false if it fails. If an exception is
|
||||
/// thrown from the functor, then the execution is assumed to have failed.
|
||||
///
|
||||
/// This function also optionally takes a \c RuntimeDeviceTracker, which will
|
||||
/// monitor for certain failures across calls to TryExecute and skip trying
|
||||
/// devices with a history of failure.
|
||||
///
|
||||
/// This function returns \c true if the functor succeeded on a device,
|
||||
/// \c false otherwise.
|
||||
///
|
||||
/// If no device list is specified, then \c VTKM_DEFAULT_DEVICE_ADAPTER_LIST_TAG
|
||||
/// is used.
|
||||
///
|
||||
template<typename Functor, typename DeviceList>
|
||||
VTKM_CONT_EXPORT
|
||||
bool TryExecute(const Functor &functor,
|
||||
vtkm::cont::internal::RuntimeDeviceTracker &tracker,
|
||||
DeviceList)
|
||||
{
|
||||
detail::TryExecuteImpl<const Functor> internals(functor, tracker);
|
||||
vtkm::ListForEach(internals, DeviceList());
|
||||
return internals.Success;
|
||||
}
|
||||
template<typename Functor, typename DeviceList>
|
||||
VTKM_CONT_EXPORT
|
||||
bool TryExecute(Functor &functor,
|
||||
vtkm::cont::internal::RuntimeDeviceTracker &tracker,
|
||||
DeviceList)
|
||||
{
|
||||
detail::TryExecuteImpl<Functor> internals(functor, tracker);
|
||||
vtkm::ListForEach(internals, DeviceList());
|
||||
return internals.Success;
|
||||
}
|
||||
template<typename Functor, typename DeviceList>
|
||||
VTKM_CONT_EXPORT
|
||||
bool TryExecute(const Functor &functor, DeviceList)
|
||||
{
|
||||
vtkm::cont::internal::RuntimeDeviceTracker tracker;
|
||||
return vtkm::cont::TryExecute(functor, tracker, DeviceList());
|
||||
}
|
||||
template<typename Functor, typename DeviceList>
|
||||
VTKM_CONT_EXPORT
|
||||
bool TryExecute(Functor &functor, DeviceList)
|
||||
{
|
||||
vtkm::cont::internal::RuntimeDeviceTracker tracker;
|
||||
return vtkm::cont::TryExecute(functor, tracker, DeviceList());
|
||||
}
|
||||
template<typename Functor>
|
||||
VTKM_CONT_EXPORT
|
||||
bool TryExecute(const Functor &functor)
|
||||
{
|
||||
return vtkm::cont::TryExecute(functor,
|
||||
VTKM_DEFAULT_DEVICE_ADAPTER_LIST_TAG());
|
||||
}
|
||||
template<typename Functor>
|
||||
VTKM_CONT_EXPORT
|
||||
bool TryExecute(Functor &functor)
|
||||
{
|
||||
return vtkm::cont::TryExecute(functor,
|
||||
VTKM_DEFAULT_DEVICE_ADAPTER_LIST_TAG());
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
|
||||
#endif //vtk_m_cont_TryExecute_h
|
@ -36,6 +36,7 @@ set(headers
|
||||
FunctorsGeneral.h
|
||||
IteratorFromArrayPortal.h
|
||||
PointCoordinatesBase.h
|
||||
RuntimeDeviceTracker.h
|
||||
SimplePolymorphicContainer.h
|
||||
StorageError.h
|
||||
)
|
||||
|
@ -27,6 +27,6 @@
|
||||
/// point, you have to specify an appropriate DeviceAdapter or else get a
|
||||
/// compile error.
|
||||
///
|
||||
VTKM_VALID_DEVICE_ADAPTER(Error, VTKM_DEVICE_ADAPTER_ERROR);
|
||||
VTKM_INVALID_DEVICE_ADAPTER(Error, VTKM_DEVICE_ADAPTER_ERROR);
|
||||
|
||||
#endif //vtk_m_cont_internal_DeviceAdapterError_h
|
||||
|
@ -17,8 +17,8 @@
|
||||
// Laboratory (LANL), the U.S. Government retains certain rights in
|
||||
// this software.
|
||||
//============================================================================
|
||||
#ifndef vtk_m_filter_internal_RuntimeDeviceTracker_h
|
||||
#define vtk_m_filter_internal_RuntimeDeviceTracker_h
|
||||
#ifndef vtk_m_cont_internal_RuntimeDeviceTracker_h
|
||||
#define vtk_m_cont_internal_RuntimeDeviceTracker_h
|
||||
|
||||
#include <vtkm/cont/ErrorControlBadAllocation.h>
|
||||
#include <vtkm/cont/RuntimeDeviceInformation.h>
|
||||
@ -31,7 +31,7 @@
|
||||
#include <cstring>
|
||||
|
||||
namespace vtkm {
|
||||
namespace filter {
|
||||
namespace cont {
|
||||
namespace internal {
|
||||
|
||||
/// A class that can be used to determine if a given device adapter
|
||||
@ -54,6 +54,7 @@ public:
|
||||
/// machine.
|
||||
///
|
||||
template<typename DeviceAdapterTag>
|
||||
VTKM_CONT_EXPORT
|
||||
bool CanRunOn(DeviceAdapterTag) const
|
||||
{
|
||||
typedef vtkm::cont::DeviceAdapterTraits<DeviceAdapterTag> Traits;
|
||||
@ -64,6 +65,7 @@ public:
|
||||
///as being unusable for all future invocations of the instance of the filter.
|
||||
///
|
||||
template<typename DeviceAdapterTag>
|
||||
VTKM_CONT_EXPORT
|
||||
void ReportAllocationFailure(DeviceAdapterTag,
|
||||
const vtkm::cont::ErrorControlBadAllocation&)
|
||||
{
|
||||
@ -74,6 +76,7 @@ public:
|
||||
///Reset the tracker to its default state.
|
||||
/// Will discard any updates caused by reported failures.
|
||||
///
|
||||
VTKM_CONT_EXPORT
|
||||
void Reset()
|
||||
{
|
||||
std::memset(this->RuntimeValid, 0, sizeof(bool)*8 );
|
||||
@ -115,6 +118,6 @@ private:
|
||||
|
||||
}
|
||||
}
|
||||
} // namespace vtkm::filter::internal
|
||||
} // namespace vtkm::cont::internal
|
||||
|
||||
#endif //vtk_m_filter_internal_RuntimeDeviceTracker_h
|
@ -64,6 +64,7 @@ set(unit_tests
|
||||
UnitTestStorageImplicit.cxx
|
||||
UnitTestStorageListTag.cxx
|
||||
UnitTestTimer.cxx
|
||||
UnitTestTryExecute.cxx
|
||||
)
|
||||
|
||||
vtkm_unit_tests(SOURCES ${unit_tests})
|
||||
|
110
vtkm/cont/testing/UnitTestTryExecute.cxx
Normal file
110
vtkm/cont/testing/UnitTestTryExecute.cxx
Normal file
@ -0,0 +1,110 @@
|
||||
//============================================================================
|
||||
// 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 2016 Sandia Corporation.
|
||||
// Copyright 2016 UT-Battelle, LLC.
|
||||
// Copyright 2016 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.
|
||||
//============================================================================
|
||||
|
||||
#define VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_ERROR
|
||||
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/DeviceAdapterSerial.h>
|
||||
#include <vtkm/cont/TryExecute.h>
|
||||
|
||||
#include <vtkm/cont/internal/DeviceAdapterError.h>
|
||||
|
||||
#include <vtkm/cont/testing/Testing.h>
|
||||
|
||||
namespace {
|
||||
|
||||
static const vtkm::Id ARRAY_SIZE = 10;
|
||||
|
||||
struct TryExecuteTestFunctor
|
||||
{
|
||||
vtkm::IdComponent NumCalls;
|
||||
vtkm::cont::ArrayHandle<vtkm::FloatDefault> InArray;
|
||||
vtkm::cont::ArrayHandle<vtkm::FloatDefault> OutArray;
|
||||
|
||||
VTKM_CONT_EXPORT
|
||||
TryExecuteTestFunctor(vtkm::cont::ArrayHandle<vtkm::FloatDefault> inArray,
|
||||
vtkm::cont::ArrayHandle<vtkm::FloatDefault> outArray)
|
||||
: NumCalls(0), InArray(inArray), OutArray(outArray)
|
||||
{ }
|
||||
|
||||
template<typename Device>
|
||||
VTKM_CONT_EXPORT
|
||||
bool operator()(Device)
|
||||
{
|
||||
typedef vtkm::cont::DeviceAdapterAlgorithm<Device> Algorithm;
|
||||
Algorithm::Copy(this->InArray, this->OutArray);
|
||||
this->NumCalls++;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename DeviceList>
|
||||
void TryExecuteWithList(DeviceList, bool expectSuccess)
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::FloatDefault> inArray;
|
||||
vtkm::cont::ArrayHandle<vtkm::FloatDefault> outArray;
|
||||
|
||||
inArray.Allocate(ARRAY_SIZE);
|
||||
SetPortal(inArray.GetPortalControl());
|
||||
|
||||
TryExecuteTestFunctor functor(inArray, outArray);
|
||||
|
||||
bool result = vtkm::cont::TryExecute(functor, DeviceList());
|
||||
|
||||
if (expectSuccess)
|
||||
{
|
||||
VTKM_TEST_ASSERT(result, "Call returned failure when expected success.");
|
||||
VTKM_TEST_ASSERT(functor.NumCalls == 1, "Bad number of calls");
|
||||
CheckPortal(outArray.GetPortalConstControl());
|
||||
}
|
||||
else
|
||||
{
|
||||
VTKM_TEST_ASSERT(!result, "Call returned true when expected failure.");
|
||||
}
|
||||
}
|
||||
|
||||
static void Run()
|
||||
{
|
||||
typedef vtkm::cont::DeviceAdapterTagSerial ValidDevice;
|
||||
typedef vtkm::cont::DeviceAdapterTagError InvalidDevice;
|
||||
|
||||
std::cout << "Try a list with a single entry." << std::endl;
|
||||
typedef vtkm::ListTagBase<ValidDevice> SingleValidList;
|
||||
TryExecuteWithList(SingleValidList(), true);
|
||||
|
||||
std::cout << "Try a list with two valid devices." << std::endl;
|
||||
typedef vtkm::ListTagBase<ValidDevice,ValidDevice> DoubleValidList;
|
||||
TryExecuteWithList(DoubleValidList(), true);
|
||||
|
||||
std::cout << "Try a list with only invalid device." << std::endl;
|
||||
typedef vtkm::ListTagBase<InvalidDevice> SingleInvalidList;
|
||||
TryExecuteWithList(SingleInvalidList(), false);
|
||||
|
||||
std::cout << "Try a list with an invalid and valid device." << std::endl;
|
||||
typedef vtkm::ListTagBase<InvalidDevice,ValidDevice> InvalidAndValidList;
|
||||
TryExecuteWithList(InvalidAndValidList(), true);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
int UnitTestTryExecute(int, char*[])
|
||||
{
|
||||
return vtkm::cont::testing::Testing::Run(Run);
|
||||
}
|
@ -25,10 +25,10 @@
|
||||
#include <vtkm/cont/DynamicCellSet.h>
|
||||
#include <vtkm/cont/CoordinateSystem.h>
|
||||
#include <vtkm/cont/Field.h>
|
||||
#include <vtkm/cont/internal/RuntimeDeviceTracker.h>
|
||||
|
||||
#include <vtkm/filter/PolicyBase.h>
|
||||
#include <vtkm/filter/ResultDataSet.h>
|
||||
#include <vtkm/filter/internal/RuntimeDeviceTracker.h>
|
||||
|
||||
namespace vtkm {
|
||||
namespace filter {
|
||||
@ -90,7 +90,7 @@ private:
|
||||
std::string OutputFieldName;
|
||||
vtkm::Id CellSetIndex;
|
||||
vtkm::Id CoordinateSystemIndex;
|
||||
vtkm::filter::internal::RuntimeDeviceTracker Tracker;
|
||||
vtkm::cont::internal::RuntimeDeviceTracker Tracker;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -64,38 +64,48 @@ ResultDataSet FilterDataSet<Derived>::Execute(const vtkm::cont::DataSet &input,
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace detail {
|
||||
template<typename Derived, typename DerivedPolicy>
|
||||
struct FilterDataSetPrepareForExecutionFunctor
|
||||
{
|
||||
vtkm::filter::ResultDataSet Result;
|
||||
Derived *Self;
|
||||
const vtkm::cont::DataSet &Input;
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy> &Policy;
|
||||
|
||||
VTKM_CONT_EXPORT
|
||||
FilterDataSetPrepareForExecutionFunctor(
|
||||
Derived *self,
|
||||
const vtkm::cont::DataSet &input,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy> &policy)
|
||||
: Self(self), Input(input), Policy(policy)
|
||||
{ }
|
||||
|
||||
template<typename Device>
|
||||
VTKM_CONT_EXPORT
|
||||
bool operator()(Device)
|
||||
{
|
||||
this->Result = this->Self->DoExecute(this->Input, this->Policy, Device());
|
||||
return this->Result.IsValid();
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
template<typename Derived>
|
||||
template<typename DerivedPolicy>
|
||||
ResultDataSet FilterDataSet<Derived>::PrepareForExecution(const vtkm::cont::DataSet &input,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>& policy )
|
||||
ResultDataSet FilterDataSet<Derived>::PrepareForExecution(
|
||||
const vtkm::cont::DataSet &input,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>& policy )
|
||||
{
|
||||
typedef vtkm::cont::DeviceAdapterTagCuda CudaTag;
|
||||
typedef vtkm::cont::DeviceAdapterTagTBB TBBTag;
|
||||
typedef vtkm::cont::DeviceAdapterTagSerial SerialTag;
|
||||
// When we move to C++11, this could probably be an anonymous class
|
||||
detail::FilterDataSetPrepareForExecutionFunctor<Derived, DerivedPolicy>
|
||||
functor(static_cast<Derived*>(this), input, policy);
|
||||
|
||||
ResultDataSet result = run_if_valid<ResultDataSet>( static_cast<Derived*>(this),
|
||||
input,
|
||||
policy,
|
||||
this->Tracker,
|
||||
CudaTag() );
|
||||
if( !result.IsValid() )
|
||||
{
|
||||
result = run_if_valid<ResultDataSet>( static_cast<Derived*>(this),
|
||||
input,
|
||||
policy,
|
||||
this->Tracker,
|
||||
TBBTag() );
|
||||
}
|
||||
if( !result.IsValid() )
|
||||
{
|
||||
result = run_if_valid<ResultDataSet>( static_cast<Derived*>(this),
|
||||
input,
|
||||
policy,
|
||||
this->Tracker,
|
||||
SerialTag() );
|
||||
}
|
||||
vtkm::cont::TryExecute(functor,
|
||||
this->Tracker,
|
||||
typename DerivedPolicy::DeviceAdapterList());
|
||||
|
||||
return result;
|
||||
return functor.Result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -25,10 +25,10 @@
|
||||
#include <vtkm/cont/DynamicCellSet.h>
|
||||
#include <vtkm/cont/CoordinateSystem.h>
|
||||
#include <vtkm/cont/Field.h>
|
||||
#include <vtkm/cont/internal/RuntimeDeviceTracker.h>
|
||||
|
||||
#include <vtkm/filter/PolicyBase.h>
|
||||
#include <vtkm/filter/ResultDataSet.h>
|
||||
#include <vtkm/filter/internal/RuntimeDeviceTracker.h>
|
||||
|
||||
namespace vtkm {
|
||||
namespace filter {
|
||||
@ -117,7 +117,7 @@ private:
|
||||
std::string OutputFieldName;
|
||||
vtkm::Id CellSetIndex;
|
||||
vtkm::Id CoordinateSystemIndex;
|
||||
vtkm::filter::internal::RuntimeDeviceTracker Tracker;
|
||||
vtkm::cont::internal::RuntimeDeviceTracker Tracker;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -24,10 +24,10 @@
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/cont/CoordinateSystem.h>
|
||||
#include <vtkm/cont/Field.h>
|
||||
#include <vtkm/cont/internal/RuntimeDeviceTracker.h>
|
||||
|
||||
#include <vtkm/filter/PolicyBase.h>
|
||||
#include <vtkm/filter/ResultField.h>
|
||||
#include <vtkm/filter/internal/RuntimeDeviceTracker.h>
|
||||
|
||||
namespace vtkm {
|
||||
namespace filter {
|
||||
@ -88,7 +88,7 @@ private:
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
|
||||
|
||||
std::string OutputFieldName;
|
||||
vtkm::filter::internal::RuntimeDeviceTracker Tracker;
|
||||
vtkm::cont::internal::RuntimeDeviceTracker Tracker;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -23,10 +23,8 @@
|
||||
|
||||
#include <vtkm/filter/PolicyBase.h>
|
||||
#include <vtkm/cont/CellSetListTag.h>
|
||||
#include <vtkm/cont/DeviceAdapterListTag.h>
|
||||
#include <vtkm/cont/StorageListTag.h>
|
||||
#include <vtkm/cont/DeviceAdapterSerial.h>
|
||||
#include <vtkm/cont/cuda/DeviceAdapterCuda.h>
|
||||
#include <vtkm/cont/tbb/DeviceAdapterTBB.h>
|
||||
#include <vtkm/TypeListTag.h>
|
||||
|
||||
namespace vtkm {
|
||||
@ -46,10 +44,7 @@ public:
|
||||
typedef VTKM_DEFAULT_COORDINATE_SYSTEM_STORAGE_LIST_TAG CoordinateStorageList;
|
||||
|
||||
// List of backends to try in sequence (if one fails, the next is attempted).
|
||||
typedef vtkm::ListTagBase<
|
||||
::vtkm::cont::DeviceAdapterTagCuda,
|
||||
::vtkm::cont::DeviceAdapterTagTBB,
|
||||
::vtkm::cont::DeviceAdapterTagSerial> DeviceAdapterList;
|
||||
typedef VTKM_DEFAULT_DEVICE_ADAPTER_LIST_TAG DeviceAdapterList;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -21,7 +21,6 @@
|
||||
set(headers
|
||||
ResolveFieldTypeAndExecute.h
|
||||
ResolveFieldTypeAndMap.h
|
||||
RuntimeDeviceTracker.h
|
||||
)
|
||||
|
||||
vtkm_declare_headers(${headers})
|
||||
|
@ -6,9 +6,9 @@
|
||||
// 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.
|
||||
// Copyright 2016 Sandia Corporation.
|
||||
// Copyright 2016 UT-Battelle, LLC.
|
||||
// Copyright 2016 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.
|
||||
@ -21,268 +21,83 @@
|
||||
#define vtk_m_filter_internal_ResolveFieldTypeAndExecute_h
|
||||
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/cont/TryExecute.h>
|
||||
#include <vtkm/cont/internal/DeviceAdapterTag.h>
|
||||
#include <vtkm/cont/internal/RuntimeDeviceTracker.h>
|
||||
|
||||
#include <vtkm/filter/FieldMetadata.h>
|
||||
#include <vtkm/filter/PolicyBase.h>
|
||||
#include <vtkm/filter/internal/RuntimeDeviceTracker.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
template<typename ReturnType, bool> struct CanExecute;
|
||||
|
||||
template<typename ReturnType,
|
||||
typename ClassType,
|
||||
typename ArrayType,
|
||||
typename DerivedPolicy,
|
||||
typename DeviceAdapterTag
|
||||
>
|
||||
ReturnType run_if_valid(ClassType* c,
|
||||
const vtkm::cont::DataSet& ds,
|
||||
const ArrayType &field,
|
||||
const vtkm::filter::FieldMetadata& fieldMeta,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
|
||||
vtkm::filter::internal::RuntimeDeviceTracker& tracker,
|
||||
DeviceAdapterTag tag)
|
||||
{
|
||||
typedef vtkm::cont::DeviceAdapterTraits<
|
||||
DeviceAdapterTag> DeviceAdapterTraits;
|
||||
|
||||
typedef CanExecute<ReturnType, DeviceAdapterTraits::Valid> CanExecuteType;
|
||||
return CanExecuteType::Run(c,ds,field,fieldMeta,policy,tracker,tag);
|
||||
}
|
||||
|
||||
template<typename ReturnType,
|
||||
typename ClassType,
|
||||
typename DerivedPolicy,
|
||||
typename DeviceAdapterTag
|
||||
>
|
||||
ReturnType run_if_valid(ClassType* c,
|
||||
const vtkm::cont::DataSet& ds,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
|
||||
vtkm::filter::internal::RuntimeDeviceTracker& tracker,
|
||||
DeviceAdapterTag tag)
|
||||
{
|
||||
typedef vtkm::cont::DeviceAdapterTraits<
|
||||
DeviceAdapterTag> DeviceAdapterTraits;
|
||||
|
||||
typedef CanExecute<ReturnType, DeviceAdapterTraits::Valid> CanExecuteType;
|
||||
return CanExecuteType::Run(c,ds,policy,tracker,tag);
|
||||
}
|
||||
|
||||
|
||||
//Implementation that we call on device adapters we don't have support
|
||||
//enabled for
|
||||
template<typename ReturnType>
|
||||
struct CanExecute<ReturnType, false>
|
||||
{
|
||||
template<typename ClassType,
|
||||
typename ArrayType,
|
||||
typename DerivedPolicy,
|
||||
typename DeviceAdapterTag>
|
||||
static ReturnType Run(ClassType*,
|
||||
const vtkm::cont::DataSet &,
|
||||
const ArrayType &,
|
||||
const vtkm::filter::FieldMetadata&,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>&,
|
||||
vtkm::filter::internal::RuntimeDeviceTracker&,
|
||||
DeviceAdapterTag)
|
||||
{
|
||||
return ReturnType();
|
||||
}
|
||||
|
||||
template<typename ClassType,
|
||||
typename DerivedPolicy,
|
||||
typename DeviceAdapterTag>
|
||||
static ReturnType Run(ClassType*,
|
||||
const vtkm::cont::DataSet &,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>&,
|
||||
vtkm::filter::internal::RuntimeDeviceTracker&,
|
||||
DeviceAdapterTag)
|
||||
{
|
||||
return ReturnType();
|
||||
}
|
||||
};
|
||||
|
||||
//Implementation that we call on device adapters we do have support
|
||||
//enabled for
|
||||
template<typename ReturnType>
|
||||
struct CanExecute<ReturnType,true>
|
||||
{
|
||||
template<typename ClassType,
|
||||
typename ArrayType,
|
||||
typename DerivedPolicy,
|
||||
typename DeviceAdapterTag>
|
||||
static ReturnType Run(ClassType* c,
|
||||
const vtkm::cont::DataSet &input,
|
||||
const ArrayType &field,
|
||||
const vtkm::filter::FieldMetadata& fieldMeta,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
|
||||
vtkm::filter::internal::RuntimeDeviceTracker& tracker,
|
||||
DeviceAdapterTag tag)
|
||||
{
|
||||
const bool runtime_usable_device = tracker.CanRunOn(tag);
|
||||
|
||||
ReturnType result;
|
||||
if(runtime_usable_device)
|
||||
{
|
||||
try
|
||||
{
|
||||
result = c->DoExecute(input,field,fieldMeta,policy,tag);
|
||||
}
|
||||
catch(vtkm::cont::ErrorControlBadAllocation e)
|
||||
{
|
||||
std::cerr << "caught ErrorControlBadAllocation " << e.GetMessage() << std::endl;
|
||||
//currently we only consider OOM errors worth disabling a device for
|
||||
//than we fallback to another device
|
||||
tracker.ReportAllocationFailure(tag,e);
|
||||
}
|
||||
catch(vtkm::cont::ErrorControlBadType e)
|
||||
{
|
||||
//bad type errors should stop the filter, instead of deferring to
|
||||
//another device adapter
|
||||
std::cerr << "caught ErrorControlBadType : " << e.GetMessage() << std::endl;
|
||||
}
|
||||
catch(vtkm::cont::ErrorControlBadValue e)
|
||||
{
|
||||
//bad value errors should stop the filter, instead of deferring to
|
||||
//another device adapter
|
||||
std::cerr << "caught ErrorControlBadValue : " << e.GetMessage() << std::endl;
|
||||
}
|
||||
catch(vtkm::cont::Error e)
|
||||
{
|
||||
//general errors should be caught and let us try the next device adapter.
|
||||
std::cerr << "exception is: " << e.GetMessage() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename ClassType,
|
||||
typename DerivedPolicy,
|
||||
typename DeviceAdapterTag>
|
||||
static ReturnType Run(ClassType* c,
|
||||
const vtkm::cont::DataSet &input,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
|
||||
vtkm::filter::internal::RuntimeDeviceTracker& tracker,
|
||||
DeviceAdapterTag tag)
|
||||
{
|
||||
const bool runtime_usable_device = tracker.CanRunOn(tag);
|
||||
|
||||
ReturnType result;
|
||||
if(runtime_usable_device)
|
||||
{
|
||||
try
|
||||
{
|
||||
result = c->DoExecute(input,policy,tag);
|
||||
}
|
||||
catch(vtkm::cont::ErrorControlBadAllocation e)
|
||||
{
|
||||
std::cerr << "caught ErrorControlBadAllocation " << e.GetMessage() << std::endl;
|
||||
//currently we only consider OOM errors worth disabling a device for
|
||||
//than we fallback to another device
|
||||
tracker.ReportAllocationFailure(tag,e);
|
||||
}
|
||||
catch(vtkm::cont::ErrorControlBadType e)
|
||||
{
|
||||
//bad type errors should stop the filter, instead of deferring to
|
||||
//another device adapter
|
||||
std::cerr << "caught ErrorControlBadType : " << e.GetMessage() << std::endl;
|
||||
}
|
||||
catch(vtkm::cont::ErrorControlBadValue e)
|
||||
{
|
||||
//bad value errors should stop the filter, instead of deferring to
|
||||
//another device adapter
|
||||
std::cerr << "caught ErrorControlBadValue : " << e.GetMessage() << std::endl;
|
||||
}
|
||||
catch(vtkm::cont::Error e)
|
||||
{
|
||||
//general errors should be caught and let us try the next device adapter.
|
||||
std::cerr << "exception is: " << e.GetMessage() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace vtkm {
|
||||
namespace filter {
|
||||
namespace internal {
|
||||
|
||||
namespace
|
||||
template<typename Derived, typename DerivedPolicy, typename ResultType>
|
||||
struct ResolveFieldTypeAndExecute
|
||||
{
|
||||
template<typename Derived, typename DerivedPolicy, typename ResultType>
|
||||
struct ResolveFieldTypeAndExecute
|
||||
typedef ResolveFieldTypeAndExecute<Derived, DerivedPolicy, ResultType> Self;
|
||||
|
||||
Derived* DerivedClass;
|
||||
const vtkm::cont::DataSet &InputData;
|
||||
const vtkm::filter::FieldMetadata& Metadata;
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>& Policy;
|
||||
vtkm::cont::internal::RuntimeDeviceTracker& Tracker;
|
||||
ResultType& Result;
|
||||
|
||||
ResolveFieldTypeAndExecute(
|
||||
Derived* derivedClass,
|
||||
const vtkm::cont::DataSet &inputData,
|
||||
const vtkm::filter::FieldMetadata& fieldMeta,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
|
||||
vtkm::cont::internal::RuntimeDeviceTracker& tracker,
|
||||
ResultType& result):
|
||||
DerivedClass(derivedClass),
|
||||
InputData(inputData),
|
||||
Metadata(fieldMeta),
|
||||
Policy(policy),
|
||||
Tracker(tracker),
|
||||
Result(result)
|
||||
{
|
||||
typedef ResolveFieldTypeAndExecute<Derived, DerivedPolicy, ResultType> Self;
|
||||
|
||||
Derived* DerivedClass;
|
||||
const vtkm::cont::DataSet &InputData;
|
||||
const vtkm::filter::FieldMetadata& Metadata;
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>& Policy;
|
||||
vtkm::filter::internal::RuntimeDeviceTracker& Tracker;
|
||||
ResultType& Result;
|
||||
}
|
||||
|
||||
ResolveFieldTypeAndExecute(Derived* derivedClass,
|
||||
const vtkm::cont::DataSet &inputData,
|
||||
const vtkm::filter::FieldMetadata& fieldMeta,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
|
||||
vtkm::filter::internal::RuntimeDeviceTracker& tracker,
|
||||
ResultType& result):
|
||||
DerivedClass(derivedClass),
|
||||
InputData(inputData),
|
||||
Metadata(fieldMeta),
|
||||
Policy(policy),
|
||||
Tracker(tracker),
|
||||
Result(result)
|
||||
{
|
||||
private:
|
||||
|
||||
}
|
||||
template<typename T, typename StorageTag>
|
||||
struct ResolveFieldTypeAndExecuteForDevice
|
||||
{
|
||||
typedef vtkm::cont::ArrayHandle<T,StorageTag> FieldArrayHandle;
|
||||
ResolveFieldTypeAndExecuteForDevice(const Self& instance,
|
||||
const FieldArrayHandle& field) :
|
||||
Instance(instance), Field(field) {}
|
||||
|
||||
private:
|
||||
const Self& Instance;
|
||||
const vtkm::cont::ArrayHandle<T,StorageTag>& Field;
|
||||
|
||||
template<typename T, typename StorageTag>
|
||||
struct ResolveFieldTypeAndExecuteForDevice
|
||||
template <typename DeviceAdapterTag>
|
||||
bool operator()(DeviceAdapterTag tag) const
|
||||
{
|
||||
typedef vtkm::cont::ArrayHandle<T,StorageTag> FieldArrayHandle;
|
||||
ResolveFieldTypeAndExecuteForDevice(const Self& instance,
|
||||
const FieldArrayHandle& field) :
|
||||
Instance(instance), Field(field) {}
|
||||
|
||||
const Self& Instance;
|
||||
const vtkm::cont::ArrayHandle<T,StorageTag>& Field;
|
||||
|
||||
template <typename DeviceAdapterTag>
|
||||
void operator()(DeviceAdapterTag tag) const
|
||||
{
|
||||
if( !this->Instance.Result.IsValid() )
|
||||
{
|
||||
this->Instance.Result =
|
||||
run_if_valid<ResultType>( this->Instance.DerivedClass,
|
||||
this->Instance.InputData,
|
||||
this->Field,
|
||||
this->Instance.Metadata,
|
||||
this->Instance.Policy,
|
||||
this->Instance.Tracker,
|
||||
tag );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
template<typename T, typename StorageTag>
|
||||
void operator()(const vtkm::cont::ArrayHandle<T,StorageTag>& field) const
|
||||
{
|
||||
ResolveFieldTypeAndExecuteForDevice<T, StorageTag> doResolve(*this,field);
|
||||
ListForEach(doResolve, typename DerivedPolicy::DeviceAdapterList());
|
||||
this->Instance.Result =
|
||||
this->Instance.DerivedClass->DoExecute(this->Instance.InputData,
|
||||
this->Field,
|
||||
this->Instance.Metadata,
|
||||
this->Instance.Policy,
|
||||
tag );
|
||||
return this->Instance.Result.IsValid();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
template<typename T, typename StorageTag>
|
||||
void operator()(const vtkm::cont::ArrayHandle<T,StorageTag>& field) const
|
||||
{
|
||||
ResolveFieldTypeAndExecuteForDevice<T, StorageTag> doResolve(*this,field);
|
||||
vtkm::cont::TryExecute(doResolve,
|
||||
this->Tracker,
|
||||
typename DerivedPolicy::DeviceAdapterList());
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -6,9 +6,9 @@
|
||||
// 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.
|
||||
// Copyright 2016 Sandia Corporation.
|
||||
// Copyright 2016 UT-Battelle, LLC.
|
||||
// Copyright 2016 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.
|
||||
@ -21,11 +21,12 @@
|
||||
#define vtk_m_filter_internal_ResolveFieldTypeAndMap_h
|
||||
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/cont/TryExecute.h>
|
||||
#include <vtkm/cont/internal/DeviceAdapterTag.h>
|
||||
#include <vtkm/cont/internal/RuntimeDeviceTracker.h>
|
||||
|
||||
#include <vtkm/filter/FieldMetadata.h>
|
||||
#include <vtkm/filter/PolicyBase.h>
|
||||
#include <vtkm/filter/internal/RuntimeDeviceTracker.h>
|
||||
|
||||
//forward declarations needed
|
||||
namespace vtkm {
|
||||
@ -34,186 +35,78 @@ namespace filter {
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
template<bool> struct CanMap;
|
||||
|
||||
template<typename ClassType,
|
||||
typename ArrayType,
|
||||
typename DerivedPolicy,
|
||||
typename DeviceAdapterTag
|
||||
>
|
||||
bool map_if_valid(ClassType* c,
|
||||
vtkm::filter::ResultDataSet& input,
|
||||
const ArrayType &field,
|
||||
const vtkm::filter::FieldMetadata& fieldMeta,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
|
||||
vtkm::filter::internal::RuntimeDeviceTracker& tracker,
|
||||
DeviceAdapterTag tag)
|
||||
{
|
||||
typedef vtkm::cont::DeviceAdapterTraits<
|
||||
DeviceAdapterTag> DeviceAdapterTraits;
|
||||
|
||||
typedef CanMap<DeviceAdapterTraits::Valid> CanMapType;
|
||||
return CanMapType::Run(c,input,field,fieldMeta,policy,tracker,tag);
|
||||
}
|
||||
|
||||
|
||||
//Implementation that we call on device adapters we don't have support
|
||||
//enabled for
|
||||
template<>
|
||||
struct CanMap<false>
|
||||
{
|
||||
template<typename ClassType,
|
||||
typename ArrayType,
|
||||
typename DerivedPolicy,
|
||||
typename DeviceAdapterTag>
|
||||
static bool Run(ClassType*,
|
||||
vtkm::filter::ResultDataSet&,
|
||||
const ArrayType &,
|
||||
const vtkm::filter::FieldMetadata&,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>&,
|
||||
vtkm::filter::internal::RuntimeDeviceTracker&,
|
||||
DeviceAdapterTag)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
//Implementation that we call on device adapters we do have support
|
||||
//enabled for
|
||||
template<>
|
||||
struct CanMap<true>
|
||||
{
|
||||
template<typename ClassType,
|
||||
typename ArrayType,
|
||||
typename DerivedPolicy,
|
||||
typename DeviceAdapterTag>
|
||||
static bool Run(ClassType* c,
|
||||
vtkm::filter::ResultDataSet& input,
|
||||
const ArrayType &field,
|
||||
const vtkm::filter::FieldMetadata& fieldMeta,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
|
||||
vtkm::filter::internal::RuntimeDeviceTracker& tracker,
|
||||
DeviceAdapterTag tag)
|
||||
{
|
||||
const bool runtime_usable_device = tracker.CanRunOn(tag);
|
||||
|
||||
bool valid = false;
|
||||
if(runtime_usable_device)
|
||||
{
|
||||
try
|
||||
{
|
||||
valid = c->DoMapField(input,field,fieldMeta,policy,tag);
|
||||
}
|
||||
catch(vtkm::cont::ErrorControlBadAllocation e)
|
||||
{
|
||||
std::cerr << "caught ErrorControlBadAllocation " << e.GetMessage() << std::endl;
|
||||
//currently we only consider OOM errors worth disabling a device for
|
||||
//than we fallback to another device
|
||||
tracker.ReportAllocationFailure(tag,e);
|
||||
}
|
||||
catch(vtkm::cont::ErrorControlBadType e)
|
||||
{
|
||||
//bad type errors should stop the filter, instead of deferring to
|
||||
//another device adapter
|
||||
std::cerr << "caught ErrorControlBadType : " << e.GetMessage() << std::endl;
|
||||
}
|
||||
catch(vtkm::cont::ErrorControlBadValue e)
|
||||
{
|
||||
//bad value errors should stop the filter, instead of deferring to
|
||||
//another device adapter
|
||||
std::cerr << "caught ErrorControlBadValue : " << e.GetMessage() << std::endl;
|
||||
}
|
||||
catch(vtkm::cont::Error e)
|
||||
{
|
||||
//general errors should be caught and let us try the next device adapter.
|
||||
std::cerr << "exception is: " << e.GetMessage() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace vtkm {
|
||||
namespace filter {
|
||||
namespace internal {
|
||||
|
||||
namespace
|
||||
template<typename Derived, typename DerivedPolicy>
|
||||
struct ResolveFieldTypeAndMap
|
||||
{
|
||||
template<typename Derived, typename DerivedPolicy>
|
||||
struct ResolveFieldTypeAndMap
|
||||
typedef ResolveFieldTypeAndMap<Derived, DerivedPolicy> Self;
|
||||
|
||||
Derived* DerivedClass;
|
||||
vtkm::filter::ResultDataSet& InputResult;
|
||||
const vtkm::filter::FieldMetadata& Metadata;
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>& Policy;
|
||||
vtkm::cont::internal::RuntimeDeviceTracker& Tracker;
|
||||
bool& RanProperly;
|
||||
|
||||
|
||||
ResolveFieldTypeAndMap(Derived* derivedClass,
|
||||
vtkm::filter::ResultDataSet& inResult,
|
||||
const vtkm::filter::FieldMetadata& fieldMeta,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
|
||||
vtkm::cont::internal::RuntimeDeviceTracker& tracker,
|
||||
bool& ran):
|
||||
DerivedClass(derivedClass),
|
||||
InputResult(inResult),
|
||||
Metadata(fieldMeta),
|
||||
Policy(policy),
|
||||
Tracker(tracker),
|
||||
RanProperly(ran)
|
||||
{
|
||||
typedef ResolveFieldTypeAndMap<Derived, DerivedPolicy> Self;
|
||||
|
||||
Derived* DerivedClass;
|
||||
vtkm::filter::ResultDataSet& InputResult;
|
||||
const vtkm::filter::FieldMetadata& Metadata;
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>& Policy;
|
||||
vtkm::filter::internal::RuntimeDeviceTracker& Tracker;
|
||||
bool& RanProperly;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
ResolveFieldTypeAndMap(Derived* derivedClass,
|
||||
vtkm::filter::ResultDataSet& inResult,
|
||||
const vtkm::filter::FieldMetadata& fieldMeta,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
|
||||
vtkm::filter::internal::RuntimeDeviceTracker& tracker,
|
||||
bool& ran):
|
||||
DerivedClass(derivedClass),
|
||||
InputResult(inResult),
|
||||
Metadata(fieldMeta),
|
||||
Policy(policy),
|
||||
Tracker(tracker),
|
||||
RanProperly(ran)
|
||||
{
|
||||
template<typename T, typename StorageTag>
|
||||
struct ResolveFieldTypeAndMapForDevice
|
||||
{
|
||||
typedef vtkm::cont::ArrayHandle<T,StorageTag> FieldArrayHandle;
|
||||
ResolveFieldTypeAndMapForDevice(const Self& instance,
|
||||
const FieldArrayHandle& field) :
|
||||
Instance(instance), Field(field), Valid(false) {}
|
||||
|
||||
}
|
||||
const Self& Instance;
|
||||
const vtkm::cont::ArrayHandle<T,StorageTag>& Field;
|
||||
mutable bool Valid;
|
||||
|
||||
private:
|
||||
|
||||
template<typename T, typename StorageTag>
|
||||
struct ResolveFieldTypeAndMapForDevice
|
||||
template <typename DeviceAdapterTag>
|
||||
bool operator()(DeviceAdapterTag tag) const
|
||||
{
|
||||
typedef vtkm::cont::ArrayHandle<T,StorageTag> FieldArrayHandle;
|
||||
ResolveFieldTypeAndMapForDevice(const Self& instance,
|
||||
const FieldArrayHandle& field) :
|
||||
Instance(instance), Field(field), Valid(false) {}
|
||||
this->Valid =
|
||||
this->Instance.DerivedClass->DoMapField(this->Instance.InputResult,
|
||||
this->Field,
|
||||
this->Instance.Metadata,
|
||||
this->Instance.Policy,
|
||||
tag);
|
||||
|
||||
const Self& Instance;
|
||||
const vtkm::cont::ArrayHandle<T,StorageTag>& Field;
|
||||
mutable bool Valid;
|
||||
|
||||
template <typename DeviceAdapterTag>
|
||||
void operator()(DeviceAdapterTag tag) const
|
||||
{
|
||||
if( !this->Valid )
|
||||
{
|
||||
this->Valid = map_if_valid( this->Instance.DerivedClass,
|
||||
this->Instance.InputResult,
|
||||
this->Field,
|
||||
this->Instance.Metadata,
|
||||
this->Instance.Policy,
|
||||
this->Instance.Tracker,
|
||||
tag );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
template<typename T, typename StorageTag>
|
||||
void operator()(const vtkm::cont::ArrayHandle<T,StorageTag>& field) const
|
||||
{
|
||||
ResolveFieldTypeAndMapForDevice<T, StorageTag> doResolve(*this,field);
|
||||
ListForEach(doResolve, typename DerivedPolicy::DeviceAdapterList());
|
||||
this->RanProperly = doResolve.Valid;
|
||||
return this->Valid;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public:
|
||||
template<typename T, typename StorageTag>
|
||||
void operator()(const vtkm::cont::ArrayHandle<T,StorageTag>& field) const
|
||||
{
|
||||
ResolveFieldTypeAndMapForDevice<T, StorageTag> doResolve(*this,field);
|
||||
vtkm::cont::TryExecute(doResolve,
|
||||
this->Tracker,
|
||||
typename DerivedPolicy::DeviceAdapterList());
|
||||
this->RanProperly = doResolve.Valid;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -491,4 +491,19 @@ void CheckPortal(const PortalType &portal)
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets all the values in a given array portal to be the values returned
|
||||
/// by vtkm::testing::TestValue. The ArrayPortal must be allocated first.
|
||||
///
|
||||
template<typename PortalType>
|
||||
VTKM_CONT_EXPORT
|
||||
void SetPortal(const PortalType &portal)
|
||||
{
|
||||
typedef typename PortalType::ValueType ValueType;
|
||||
|
||||
for (vtkm::Id index = 0; index < portal.GetNumberOfValues(); index++)
|
||||
{
|
||||
portal.Set(index, TestValue(index, ValueType()));
|
||||
}
|
||||
}
|
||||
|
||||
#endif //vtk_m_testing_Testing_h
|
||||
|
Loading…
Reference in New Issue
Block a user