mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-16 17:22:55 +00:00
Merge topic 'vtkm-abort'
42c6959be Add Abort execution feature Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !2974
This commit is contained in:
commit
d05afa72f5
22
docs/changelog/vtkm-abort.md
Normal file
22
docs/changelog/vtkm-abort.md
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# Add initial support for aborting execution
|
||||||
|
|
||||||
|
VTK-m now has preliminary support for aborting execution. The per-thread instances of
|
||||||
|
`RuntimeDeviceTracker` have a functor called `AbortChecker`. This functor can be set using
|
||||||
|
`RuntimeDeviceTracker::SetAbortChecker()` and cleared by `RuntimeDeviceTracker::ClearAbortChecker()`
|
||||||
|
The abort checker functor should return `true` if an abort is requested for the thread,
|
||||||
|
otherwise, it should return `false`.
|
||||||
|
|
||||||
|
Before launching a new task, `TaskExecute` calls the functor to see if an abort is requested,
|
||||||
|
and If so, throws an exception of type `vtkm::cont::ErrorUserAbort`.
|
||||||
|
|
||||||
|
Any code that wants to use the abort feature, should set an appropriate `AbortChecker`
|
||||||
|
functor for the target thread. Then any piece of code that has parts that can execute on
|
||||||
|
the device should be put under a `try-catch` block. Any clean-up that is required for an
|
||||||
|
aborted execution should be handled in a `catch` block that handles exceptions of type
|
||||||
|
`vtkm::cont::ErrorUserAbort`.
|
||||||
|
|
||||||
|
The limitation of this implementation is that it is control-side only. The check for abort
|
||||||
|
is done before launching a new device task. Once execution has begun on the device, there is
|
||||||
|
currently no way to abort that. Therefore, this feature is only useful for aborting code
|
||||||
|
that is made up of several smaller device task launches (Which is the case for most
|
||||||
|
worklets and filters in VTK-m)
|
@ -94,6 +94,7 @@ set(headers
|
|||||||
ErrorExecution.h
|
ErrorExecution.h
|
||||||
ErrorFilterExecution.h
|
ErrorFilterExecution.h
|
||||||
ErrorInternal.h
|
ErrorInternal.h
|
||||||
|
ErrorUserAbort.h
|
||||||
ExecutionAndControlObjectBase.h
|
ExecutionAndControlObjectBase.h
|
||||||
ExecutionObjectBase.h
|
ExecutionObjectBase.h
|
||||||
Field.h
|
Field.h
|
||||||
|
42
vtkm/cont/ErrorUserAbort.h
Normal file
42
vtkm/cont/ErrorUserAbort.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
//============================================================================
|
||||||
|
// 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_cont_ErrorUserAbort_h
|
||||||
|
#define vtk_m_cont_ErrorUserAbort_h
|
||||||
|
|
||||||
|
#include <vtkm/cont/Error.h>
|
||||||
|
|
||||||
|
namespace vtkm
|
||||||
|
{
|
||||||
|
namespace cont
|
||||||
|
{
|
||||||
|
|
||||||
|
VTKM_SILENCE_WEAK_VTABLE_WARNING_START
|
||||||
|
|
||||||
|
/// This class is thrown when vtk-m detects a request for aborting execution
|
||||||
|
/// in the current thread
|
||||||
|
///
|
||||||
|
class VTKM_ALWAYS_EXPORT ErrorUserAbort : public Error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ErrorUserAbort()
|
||||||
|
: Error(Message, true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static constexpr const char* Message = "User abort detected.";
|
||||||
|
};
|
||||||
|
|
||||||
|
VTKM_SILENCE_WEAK_VTABLE_WARNING_END
|
||||||
|
|
||||||
|
}
|
||||||
|
} // namespace vtkm::cont
|
||||||
|
|
||||||
|
#endif // vtk_m_cont_ErrorUserAbort_h
|
@ -35,6 +35,7 @@ struct RuntimeDeviceTrackerInternals
|
|||||||
|
|
||||||
std::array<bool, VTKM_MAX_DEVICE_ADAPTER_ID> RuntimeAllowed;
|
std::array<bool, VTKM_MAX_DEVICE_ADAPTER_ID> RuntimeAllowed;
|
||||||
bool ThreadFriendlyMemAlloc = false;
|
bool ThreadFriendlyMemAlloc = false;
|
||||||
|
std::function<bool()> AbortChecker;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -186,6 +187,28 @@ VTKM_CONT void RuntimeDeviceTracker::CopyStateFrom(const vtkm::cont::RuntimeDevi
|
|||||||
*(this->Internals) = *tracker.Internals;
|
*(this->Internals) = *tracker.Internals;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VTKM_CONT
|
||||||
|
void RuntimeDeviceTracker::SetAbortChecker(const std::function<bool()>& func)
|
||||||
|
{
|
||||||
|
this->Internals->AbortChecker = func;
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT
|
||||||
|
bool RuntimeDeviceTracker::CheckForAbortRequest() const
|
||||||
|
{
|
||||||
|
if (this->Internals->AbortChecker)
|
||||||
|
{
|
||||||
|
return this->Internals->AbortChecker();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT
|
||||||
|
void RuntimeDeviceTracker::ClearAbortChecker()
|
||||||
|
{
|
||||||
|
this->Internals->AbortChecker = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
VTKM_CONT
|
VTKM_CONT
|
||||||
void RuntimeDeviceTracker::PrintSummary(std::ostream& out) const
|
void RuntimeDeviceTracker::PrintSummary(std::ostream& out) const
|
||||||
{
|
{
|
||||||
@ -228,25 +251,6 @@ ScopedRuntimeDeviceTracker::ScopedRuntimeDeviceTracker(
|
|||||||
VTKM_LOG_S(vtkm::cont::LogLevel::DevicesEnabled, "Entering scoped runtime region");
|
VTKM_LOG_S(vtkm::cont::LogLevel::DevicesEnabled, "Entering scoped runtime region");
|
||||||
}
|
}
|
||||||
|
|
||||||
VTKM_CONT
|
|
||||||
ScopedRuntimeDeviceTracker::ScopedRuntimeDeviceTracker(vtkm::cont::DeviceAdapterId device,
|
|
||||||
RuntimeDeviceTrackerMode mode)
|
|
||||||
: ScopedRuntimeDeviceTracker(GetRuntimeDeviceTracker())
|
|
||||||
{
|
|
||||||
if (mode == RuntimeDeviceTrackerMode::Force)
|
|
||||||
{
|
|
||||||
this->ForceDevice(device);
|
|
||||||
}
|
|
||||||
else if (mode == RuntimeDeviceTrackerMode::Enable)
|
|
||||||
{
|
|
||||||
this->ResetDevice(device);
|
|
||||||
}
|
|
||||||
else if (mode == RuntimeDeviceTrackerMode::Disable)
|
|
||||||
{
|
|
||||||
this->DisableDevice(device);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VTKM_CONT
|
VTKM_CONT
|
||||||
ScopedRuntimeDeviceTracker::ScopedRuntimeDeviceTracker(
|
ScopedRuntimeDeviceTracker::ScopedRuntimeDeviceTracker(
|
||||||
vtkm::cont::DeviceAdapterId device,
|
vtkm::cont::DeviceAdapterId device,
|
||||||
@ -268,6 +272,14 @@ ScopedRuntimeDeviceTracker::ScopedRuntimeDeviceTracker(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VTKM_CONT ScopedRuntimeDeviceTracker::ScopedRuntimeDeviceTracker(
|
||||||
|
const std::function<bool()>& abortChecker,
|
||||||
|
const vtkm::cont::RuntimeDeviceTracker& tracker)
|
||||||
|
: ScopedRuntimeDeviceTracker(tracker)
|
||||||
|
{
|
||||||
|
this->SetAbortChecker(abortChecker);
|
||||||
|
}
|
||||||
|
|
||||||
VTKM_CONT
|
VTKM_CONT
|
||||||
ScopedRuntimeDeviceTracker::~ScopedRuntimeDeviceTracker()
|
ScopedRuntimeDeviceTracker::~ScopedRuntimeDeviceTracker()
|
||||||
{
|
{
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include <vtkm/cont/ErrorBadDevice.h>
|
#include <vtkm/cont/ErrorBadDevice.h>
|
||||||
#include <vtkm/cont/RuntimeDeviceInformation.h>
|
#include <vtkm/cont/RuntimeDeviceInformation.h>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace vtkm
|
namespace vtkm
|
||||||
@ -123,6 +124,18 @@ public:
|
|||||||
///
|
///
|
||||||
VTKM_CONT void CopyStateFrom(const vtkm::cont::RuntimeDeviceTracker& tracker);
|
VTKM_CONT void CopyStateFrom(const vtkm::cont::RuntimeDeviceTracker& tracker);
|
||||||
|
|
||||||
|
///@{
|
||||||
|
/// \brief Set/Clear the abort checker functor.
|
||||||
|
///
|
||||||
|
/// If set the abort checker functor is called by \c TryExecute before scheduling
|
||||||
|
/// a task on a device from the associated the thread. If the functor returns
|
||||||
|
/// \e true, an exception is thrown.
|
||||||
|
VTKM_CONT void SetAbortChecker(const std::function<bool()>& func);
|
||||||
|
VTKM_CONT void ClearAbortChecker();
|
||||||
|
///@}
|
||||||
|
|
||||||
|
VTKM_CONT bool CheckForAbortRequest() const;
|
||||||
|
|
||||||
VTKM_CONT void PrintSummary(std::ostream& out) const;
|
VTKM_CONT void PrintSummary(std::ostream& out) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -149,82 +162,7 @@ private:
|
|||||||
void LogEnabledDevices() const;
|
void LogEnabledDevices() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
///----------------------------------------------------------------------------
|
||||||
enum struct RuntimeDeviceTrackerMode
|
|
||||||
{
|
|
||||||
Force,
|
|
||||||
Enable,
|
|
||||||
Disable
|
|
||||||
};
|
|
||||||
|
|
||||||
/// A class that can be used to determine or modify which device adapter
|
|
||||||
/// VTK-m algorithms should be run on. This class captures the state
|
|
||||||
/// of the per-thread device adapter and will revert any changes applied
|
|
||||||
/// during its lifetime on destruction.
|
|
||||||
///
|
|
||||||
///
|
|
||||||
struct VTKM_CONT_EXPORT ScopedRuntimeDeviceTracker : public vtkm::cont::RuntimeDeviceTracker
|
|
||||||
{
|
|
||||||
/// Construct a ScopedRuntimeDeviceTracker where the state of the active devices
|
|
||||||
/// for the current thread are determined by the parameters to the constructor.
|
|
||||||
///
|
|
||||||
/// 'Force'
|
|
||||||
/// - Force-Enable the provided single device adapter
|
|
||||||
/// - Force-Enable all device adapters when using vtkm::cont::DeviceAdaterTagAny
|
|
||||||
/// 'Enable'
|
|
||||||
/// - Enable the provided single device adapter if it was previously disabled
|
|
||||||
/// - Enable all device adapters that are currently disabled when using
|
|
||||||
/// vtkm::cont::DeviceAdaterTagAny
|
|
||||||
/// 'Disable'
|
|
||||||
/// - Disable the provided single device adapter
|
|
||||||
/// - Disable all device adapters when using vtkm::cont::DeviceAdaterTagAny
|
|
||||||
///
|
|
||||||
/// Constructor is not thread safe
|
|
||||||
VTKM_CONT ScopedRuntimeDeviceTracker(
|
|
||||||
vtkm::cont::DeviceAdapterId device,
|
|
||||||
RuntimeDeviceTrackerMode mode = RuntimeDeviceTrackerMode::Force);
|
|
||||||
|
|
||||||
/// Construct a ScopedRuntimeDeviceTracker associated with the thread
|
|
||||||
/// associated with the provided tracker. The active devices
|
|
||||||
/// for the current thread are determined by the parameters to the constructor.
|
|
||||||
///
|
|
||||||
/// 'Force'
|
|
||||||
/// - Force-Enable the provided single device adapter
|
|
||||||
/// - Force-Enable all device adapters when using vtkm::cont::DeviceAdaterTagAny
|
|
||||||
/// 'Enable'
|
|
||||||
/// - Enable the provided single device adapter if it was previously disabled
|
|
||||||
/// - Enable all device adapters that are currently disabled when using
|
|
||||||
/// vtkm::cont::DeviceAdaterTagAny
|
|
||||||
/// 'Disable'
|
|
||||||
/// - Disable the provided single device adapter
|
|
||||||
/// - Disable all device adapters when using vtkm::cont::DeviceAdaterTagAny
|
|
||||||
///
|
|
||||||
/// Any modifications to the ScopedRuntimeDeviceTracker will effect what
|
|
||||||
/// ever thread the \c tracker is associated with, which might not be
|
|
||||||
/// the thread which ScopedRuntimeDeviceTracker was constructed on.
|
|
||||||
///
|
|
||||||
/// Constructor is not thread safe
|
|
||||||
VTKM_CONT ScopedRuntimeDeviceTracker(vtkm::cont::DeviceAdapterId device,
|
|
||||||
RuntimeDeviceTrackerMode mode,
|
|
||||||
const vtkm::cont::RuntimeDeviceTracker& tracker);
|
|
||||||
|
|
||||||
/// Construct a ScopedRuntimeDeviceTracker associated with the thread
|
|
||||||
/// associated with the provided tracker.
|
|
||||||
///
|
|
||||||
/// Any modifications to the ScopedRuntimeDeviceTracker will effect what
|
|
||||||
/// ever thread the \c tracker is associated with, which might not be
|
|
||||||
/// the thread which ScopedRuntimeDeviceTracker was constructed on.
|
|
||||||
///
|
|
||||||
/// Constructor is not thread safe
|
|
||||||
VTKM_CONT ScopedRuntimeDeviceTracker(const vtkm::cont::RuntimeDeviceTracker& tracker);
|
|
||||||
|
|
||||||
/// Destructor is not thread safe
|
|
||||||
VTKM_CONT ~ScopedRuntimeDeviceTracker();
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::unique_ptr<detail::RuntimeDeviceTrackerInternals> SavedState;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// \brief Get the \c RuntimeDeviceTracker for the current thread.
|
/// \brief Get the \c RuntimeDeviceTracker for the current thread.
|
||||||
///
|
///
|
||||||
/// Many features in VTK-m will attempt to run algorithms on the "best
|
/// Many features in VTK-m will attempt to run algorithms on the "best
|
||||||
@ -236,6 +174,66 @@ private:
|
|||||||
VTKM_CONT_EXPORT
|
VTKM_CONT_EXPORT
|
||||||
VTKM_CONT
|
VTKM_CONT
|
||||||
vtkm::cont::RuntimeDeviceTracker& GetRuntimeDeviceTracker();
|
vtkm::cont::RuntimeDeviceTracker& GetRuntimeDeviceTracker();
|
||||||
|
|
||||||
|
enum struct RuntimeDeviceTrackerMode
|
||||||
|
{
|
||||||
|
Force,
|
||||||
|
Enable,
|
||||||
|
Disable
|
||||||
|
};
|
||||||
|
|
||||||
|
///----------------------------------------------------------------------------
|
||||||
|
/// A class to create a scoped runtime device tracker object. This object captures the state
|
||||||
|
/// of the per-thread device tracker and will revert any changes applied
|
||||||
|
/// during its lifetime on destruction.
|
||||||
|
///
|
||||||
|
struct VTKM_CONT_EXPORT ScopedRuntimeDeviceTracker : public vtkm::cont::RuntimeDeviceTracker
|
||||||
|
{
|
||||||
|
/// Construct a ScopedRuntimeDeviceTracker associated with the thread,
|
||||||
|
/// associated with the provided tracker (defaults to current thread's tracker).
|
||||||
|
///
|
||||||
|
/// Any modifications to the ScopedRuntimeDeviceTracker will effect what
|
||||||
|
/// ever thread the \c tracker is associated with, which might not be
|
||||||
|
/// the thread on which the ScopedRuntimeDeviceTracker was constructed.
|
||||||
|
///
|
||||||
|
/// Constructors are not thread safe
|
||||||
|
/// @{
|
||||||
|
///
|
||||||
|
VTKM_CONT ScopedRuntimeDeviceTracker(
|
||||||
|
const vtkm::cont::RuntimeDeviceTracker& tracker = GetRuntimeDeviceTracker());
|
||||||
|
|
||||||
|
/// Use this constructor to modify the state of the device adapters associated with
|
||||||
|
/// the provided tracker. Use \p mode with \p device as follows:
|
||||||
|
///
|
||||||
|
/// 'Force' (default)
|
||||||
|
/// - Force-Enable the provided single device adapter
|
||||||
|
/// - Force-Enable all device adapters when using vtkm::cont::DeviceAdaterTagAny
|
||||||
|
/// 'Enable'
|
||||||
|
/// - Enable the provided single device adapter if it was previously disabled
|
||||||
|
/// - Enable all device adapters that are currently disabled when using
|
||||||
|
/// vtkm::cont::DeviceAdaterTagAny
|
||||||
|
/// 'Disable'
|
||||||
|
/// - Disable the provided single device adapter
|
||||||
|
/// - Disable all device adapters when using vtkm::cont::DeviceAdaterTagAny
|
||||||
|
///
|
||||||
|
VTKM_CONT ScopedRuntimeDeviceTracker(
|
||||||
|
vtkm::cont::DeviceAdapterId device,
|
||||||
|
RuntimeDeviceTrackerMode mode = RuntimeDeviceTrackerMode::Force,
|
||||||
|
const vtkm::cont::RuntimeDeviceTracker& tracker = GetRuntimeDeviceTracker());
|
||||||
|
|
||||||
|
/// Use this constructor to set the abort checker functor for the provided tracker.
|
||||||
|
///
|
||||||
|
VTKM_CONT ScopedRuntimeDeviceTracker(
|
||||||
|
const std::function<bool()>& abortChecker,
|
||||||
|
const vtkm::cont::RuntimeDeviceTracker& tracker = GetRuntimeDeviceTracker());
|
||||||
|
|
||||||
|
/// Destructor is not thread safe
|
||||||
|
VTKM_CONT ~ScopedRuntimeDeviceTracker();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<detail::RuntimeDeviceTrackerInternals> SavedState;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
} // namespace vtkm::cont
|
} // namespace vtkm::cont
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include <vtkm/cont/ErrorBadType.h>
|
#include <vtkm/cont/ErrorBadType.h>
|
||||||
#include <vtkm/cont/ErrorBadValue.h>
|
#include <vtkm/cont/ErrorBadValue.h>
|
||||||
#include <vtkm/cont/ErrorFilterExecution.h>
|
#include <vtkm/cont/ErrorFilterExecution.h>
|
||||||
|
#include <vtkm/cont/ErrorUserAbort.h>
|
||||||
#include <vtkm/cont/RuntimeDeviceTracker.h>
|
#include <vtkm/cont/RuntimeDeviceTracker.h>
|
||||||
|
|
||||||
namespace vtkm
|
namespace vtkm
|
||||||
@ -55,6 +56,13 @@ VTKM_CONT_EXPORT void HandleTryExecuteException(vtkm::cont::DeviceAdapterId devi
|
|||||||
VTKM_LOG_TRYEXECUTE_FAIL("ErrorBadValue (" << e.GetMessage() << ")", functorName, deviceId);
|
VTKM_LOG_TRYEXECUTE_FAIL("ErrorBadValue (" << e.GetMessage() << ")", functorName, deviceId);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
catch (vtkm::cont::ErrorUserAbort& e)
|
||||||
|
{
|
||||||
|
VTKM_LOG_S(vtkm::cont::LogLevel::Info,
|
||||||
|
e.GetMessage() << " Aborting: " << functorName << ", on device "
|
||||||
|
<< deviceId.GetName());
|
||||||
|
throw;
|
||||||
|
}
|
||||||
catch (vtkm::cont::Error& e)
|
catch (vtkm::cont::Error& e)
|
||||||
{
|
{
|
||||||
VTKM_LOG_TRYEXECUTE_FAIL(e.GetMessage(), functorName, deviceId);
|
VTKM_LOG_TRYEXECUTE_FAIL(e.GetMessage(), functorName, deviceId);
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include <vtkm/cont/DeviceAdapterList.h>
|
#include <vtkm/cont/DeviceAdapterList.h>
|
||||||
#include <vtkm/cont/DeviceAdapterTag.h>
|
#include <vtkm/cont/DeviceAdapterTag.h>
|
||||||
|
#include <vtkm/cont/ErrorUserAbort.h>
|
||||||
#include <vtkm/cont/Logging.h>
|
#include <vtkm/cont/Logging.h>
|
||||||
#include <vtkm/cont/RuntimeDeviceTracker.h>
|
#include <vtkm/cont/RuntimeDeviceTracker.h>
|
||||||
|
|
||||||
@ -40,6 +41,11 @@ inline bool TryExecuteIfValid(std::true_type,
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if (tracker.CheckForAbortRequest())
|
||||||
|
{
|
||||||
|
throw vtkm::cont::ErrorUserAbort{};
|
||||||
|
}
|
||||||
|
|
||||||
return f(tag, std::forward<Args>(args)...);
|
return f(tag, std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
|
@ -122,6 +122,12 @@ if(TARGET vtkm_filter_field_conversion)
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(TARGET vtkm_filter_contour)
|
||||||
|
list(APPEND unit_tests_device
|
||||||
|
UnitTestAbort.cxx
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
vtkm_unit_tests(SOURCES ${unit_tests} DEVICE_SOURCES ${unit_tests_device})
|
vtkm_unit_tests(SOURCES ${unit_tests} DEVICE_SOURCES ${unit_tests_device})
|
||||||
|
|
||||||
#add distributed tests i.e.test to run with MPI
|
#add distributed tests i.e.test to run with MPI
|
||||||
|
105
vtkm/cont/testing/UnitTestAbort.cxx
Normal file
105
vtkm/cont/testing/UnitTestAbort.cxx
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
//============================================================================
|
||||||
|
// 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.
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
#include <vtkm/cont/ErrorUserAbort.h>
|
||||||
|
#include <vtkm/cont/RuntimeDeviceTracker.h>
|
||||||
|
#include <vtkm/cont/testing/Testing.h>
|
||||||
|
#include <vtkm/filter/contour/Contour.h>
|
||||||
|
#include <vtkm/source/Wavelet.h>
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
// A function that checks for abort request.
|
||||||
|
// This function will be called by `TryExecute` befaure lauching a device task
|
||||||
|
// to check if abort has been requested.
|
||||||
|
// For this test case, we are using a simple logic of returning true for the
|
||||||
|
// `abortAt`th check.
|
||||||
|
// If this test is failing, one of the things to check would be to see if the
|
||||||
|
// `Contour` filter has changed such that it no longer has atleast `abortAt`
|
||||||
|
// task invocations.
|
||||||
|
bool ShouldAbort()
|
||||||
|
{
|
||||||
|
static int abortCheckCounter = 0;
|
||||||
|
static constexpr int abortAt = 5;
|
||||||
|
if (++abortCheckCounter >= abortAt)
|
||||||
|
{
|
||||||
|
std::cout << "Abort check " << abortCheckCounter << ": true\n";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Abort check " << abortCheckCounter << ": false\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TestAbort()
|
||||||
|
{
|
||||||
|
vtkm::source::Wavelet wavelet;
|
||||||
|
wavelet.SetExtent(vtkm::Id3(-15), vtkm::Id3(16));
|
||||||
|
auto input = wavelet.Execute();
|
||||||
|
|
||||||
|
auto range = input.GetField("RTData").GetRange().ReadPortal().Get(0);
|
||||||
|
std::vector<vtkm::Float64> isovals;
|
||||||
|
static constexpr int numDivs = 5;
|
||||||
|
for (int i = 1; i < numDivs - 1; ++i)
|
||||||
|
{
|
||||||
|
auto v = range.Min +
|
||||||
|
(static_cast<vtkm::Float64>(i) *
|
||||||
|
((range.Max - range.Min) / static_cast<vtkm::Float64>(numDivs)));
|
||||||
|
isovals.push_back(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
vtkm::filter::contour::Contour contour;
|
||||||
|
contour.SetActiveField("RTData");
|
||||||
|
contour.SetIsoValues(isovals);
|
||||||
|
|
||||||
|
// First we will run the filter with the abort function set
|
||||||
|
std::cout << "Run #1 with the abort function set\n";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
vtkm::cont::ScopedRuntimeDeviceTracker tracker(ShouldAbort);
|
||||||
|
|
||||||
|
auto result = contour.Execute(input);
|
||||||
|
|
||||||
|
// execution shouldn't reach here
|
||||||
|
VTKM_TEST_FAIL("Error: filter execution was not aborted. Result: ",
|
||||||
|
result.GetNumberOfPoints(),
|
||||||
|
" points and ",
|
||||||
|
result.GetNumberOfCells(),
|
||||||
|
" triangles");
|
||||||
|
}
|
||||||
|
catch (const vtkm::cont::ErrorUserAbort& e)
|
||||||
|
{
|
||||||
|
std::cout << "Execution was successfully aborted\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now run the filter without the abort function
|
||||||
|
std::cout << "Run #2 without the abort function set\n";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
auto result = contour.Execute(input);
|
||||||
|
std::cout << "Success: filter execution was not aborted. Result: " << result.GetNumberOfPoints()
|
||||||
|
<< " points and " << result.GetNumberOfCells() << " triangles\n";
|
||||||
|
}
|
||||||
|
catch (const vtkm::cont::ErrorUserAbort& e)
|
||||||
|
{
|
||||||
|
VTKM_TEST_FAIL("Execution was unexpectedly aborted");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} // anon namespace
|
||||||
|
|
||||||
|
int UnitTestAbort(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
return vtkm::cont::testing::Testing::Run(TestAbort, argc, argv);
|
||||||
|
}
|
@ -9,6 +9,7 @@ DEPENDS
|
|||||||
OPTIONAL_DEPENDS
|
OPTIONAL_DEPENDS
|
||||||
vtkm_loguru
|
vtkm_loguru
|
||||||
TEST_OPTIONAL_DEPENDS
|
TEST_OPTIONAL_DEPENDS
|
||||||
|
vtkm_filter_contour
|
||||||
vtkm_filter_field_conversion
|
vtkm_filter_field_conversion
|
||||||
TEST_DEPENDS
|
TEST_DEPENDS
|
||||||
vtkm_source
|
vtkm_source
|
||||||
|
Loading…
Reference in New Issue
Block a user