Fixed exception handling with TBB

release/4.3a0
Richard Roberts 2013-08-21 22:15:36 +00:00
parent d7559b8d98
commit f43c9557b9
4 changed files with 236 additions and 139 deletions

View File

@ -140,7 +140,9 @@ set_property(SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/slam/dataset.cpp"
# Special cases # Special cases
if(MSVC) if(MSVC)
set_property(SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/slam/serialization.cpp" set_property(SOURCE
"${CMAKE_CURRENT_SOURCE_DIR}/slam/serialization.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/nonlinear/ISAM2.cpp"
APPEND PROPERTY COMPILE_FLAGS "/bigobj") APPEND PROPERTY COMPILE_FLAGS "/bigobj")
endif() endif()

View File

@ -20,12 +20,18 @@
#pragma once #pragma once
#include <gtsam/dllexport.h> #include <gtsam/dllexport.h>
#include <gtsam/config.h>
#include <cstddef> #include <cstddef>
#include <string> #include <string>
#include <boost/function/function1.hpp> #include <boost/function/function1.hpp>
#include <boost/range/concepts.hpp> #include <boost/range/concepts.hpp>
#include <boost/optional.hpp>
#ifdef GTSAM_USE_TBB
#include <tbb/tbb_exception.h>
#endif
namespace gtsam { namespace gtsam {
@ -61,6 +67,7 @@ namespace gtsam {
typedef ptrdiff_t DenseIndex; typedef ptrdiff_t DenseIndex;
/* ************************************************************************* */
/** /**
* Helper class that uses templates to select between two types based on * Helper class that uses templates to select between two types based on
* whether TEST_TYPE is const or not. * whether TEST_TYPE is const or not.
@ -82,6 +89,7 @@ namespace gtsam {
typedef AS_CONST type; typedef AS_CONST type;
}; };
/* ************************************************************************* */
/** /**
* Helper struct that encapsulates a value with a default, this is just used * Helper struct that encapsulates a value with a default, this is just used
* as a member object so you don't have to specify defaults in the class * as a member object so you don't have to specify defaults in the class
@ -104,6 +112,7 @@ namespace gtsam {
operator T() const { return value; } operator T() const { return value; }
}; };
/* ************************************************************************* */
/** A helper class that behaves as a container with one element, and works with /** A helper class that behaves as a container with one element, and works with
* boost::range */ * boost::range */
template<typename T> template<typename T>
@ -129,19 +138,102 @@ namespace gtsam {
return ListOfOneContainer<T>(element); return ListOfOneContainer<T>(element);
} }
/** An assertion that throws an exception if NDEBUG is not defined and /* ************************************************************************* */
* evaluates to an empty statement otherwise. */ /// Base exception type that uses tbb_exception if GTSAM is compiled with TBB.
template<class DERIVED>
class ThreadsafeException :
#ifdef GTSAM_USE_TBB
public tbb::tbb_exception
#else
public std::exception
#endif
{
private:
#ifdef GTSAM_USE_TBB
typedef tbb::tbb_exception Base;
#else
typedef std::exception Base;
#endif
protected:
bool dynamic_; ///< Whether this object was moved
boost::optional<std::string> description_; ///< Optional description
/// Default constructor is protected - may only be created from derived classes
ThreadsafeException() : dynamic_(false) {}
/// Copy constructor is protected - may only be created from derived classes
ThreadsafeException(const ThreadsafeException& other) : Base(other), dynamic_(false) {}
/// Construct with description string
ThreadsafeException(const std::string& description) : dynamic_(false), description_(description) {}
public:
// Implement functions for tbb_exception
#ifdef GTSAM_USE_TBB
virtual tbb::tbb_exception* move() {
DERIVED* clone = ::new DERIVED(static_cast<DERIVED&>(*this));
clone->dynamic_ = true;
return clone;
}
virtual void destroy() throw() {
if (dynamic_)
::delete this;
}
virtual void throw_self() {
throw *this; }
virtual const char* name() const throw() {
return typeid(DERIVED).name(); }
#endif
virtual const char* what() const throw() {
return description_ ? description_->c_str() : ""; }
};
/* ************************************************************************* */
/// Threadsafe runtime error exception
class RuntimeErrorThreadsafe : public ThreadsafeException<RuntimeErrorThreadsafe>
{
public:
/// Construct with a string describing the exception
RuntimeErrorThreadsafe(const std::string& description) : ThreadsafeException(description) {}
};
/* ************************************************************************* */
/// Threadsafe runtime error exception
class OutOfRangeThreadsafe : public ThreadsafeException<OutOfRangeThreadsafe>
{
public:
/// Construct with a string describing the exception
OutOfRangeThreadsafe(const std::string& description) : ThreadsafeException(description) {}
};
/* ************************************************************************* */
/// Threadsafe invalid argument exception
class InvalidArgumentThreadsafe : public ThreadsafeException<InvalidArgumentThreadsafe>
{
public:
/// Construct with a string describing the exception
InvalidArgumentThreadsafe(const std::string& description) : ThreadsafeException(description) {}
};
}
/* ************************************************************************* */
/** An assertion that throws an exception if NDEBUG is not defined and
* evaluates to an empty statement otherwise. */
#ifdef NDEBUG #ifdef NDEBUG
#define assert_throw(CONDITION, EXCEPTION) ((void)0) #define assert_throw(CONDITION, EXCEPTION) ((void)0)
#else #else
#define assert_throw(CONDITION, EXCEPTION) \ #define assert_throw(CONDITION, EXCEPTION) \
if(!(CONDITION)) { \ if (!(CONDITION)) { \
throw (EXCEPTION); \ throw (EXCEPTION); \
} }
#endif #endif
}
#ifdef _MSC_VER #ifdef _MSC_VER
// Define some common g++ functions and macros we use that MSVC does not have // Define some common g++ functions and macros we use that MSVC does not have
@ -177,3 +269,6 @@ namespace std {
#undef max #undef max
#endif #endif
#ifdef ERROR
#undef ERROR
#endif

View File

@ -24,9 +24,9 @@
namespace gtsam { namespace gtsam {
class GTSAM_EXPORT CheiralityException: public std::runtime_error { class GTSAM_EXPORT CheiralityException: public ThreadsafeException<CheiralityException> {
public: public:
CheiralityException() : std::runtime_error("Cheirality Exception") {} CheiralityException() : ThreadsafeException("Cheirality Exception") {}
}; };
/** /**

View File

@ -92,7 +92,7 @@ namespace gtsam {
ordered in elimination order and occupy scalars in the same way as ordered in elimination order and occupy scalars in the same way as
described for Jacobian columns in the previous bullet. described for Jacobian columns in the previous bullet.
*/ */
class IndeterminantLinearSystemException : public std::exception { class IndeterminantLinearSystemException : public ThreadsafeException<IndeterminantLinearSystemException> {
Index j_; Index j_;
mutable std::string what_; mutable std::string what_;
public: public:
@ -117,7 +117,7 @@ on gtsam::IndeterminantLinearSystemException for more information.\n";
/* ************************************************************************* */ /* ************************************************************************* */
/** An exception indicating that the noise model dimension passed into a /** An exception indicating that the noise model dimension passed into a
* JacobianFactor has a different dimensionality than the factor. */ * JacobianFactor has a different dimensionality than the factor. */
class GTSAM_EXPORT InvalidNoiseModel : public std::exception { class GTSAM_EXPORT InvalidNoiseModel : public ThreadsafeException<InvalidNoiseModel> {
public: public:
const DenseIndex factorDims; ///< The dimensionality of the factor const DenseIndex factorDims; ///< The dimensionality of the factor
const DenseIndex noiseModelDims; ///< The dimensionality of the noise model const DenseIndex noiseModelDims; ///< The dimensionality of the noise model
@ -135,7 +135,7 @@ on gtsam::IndeterminantLinearSystemException for more information.\n";
/* ************************************************************************* */ /* ************************************************************************* */
/** An exception indicating that a matrix block passed into a /** An exception indicating that a matrix block passed into a
* JacobianFactor has a different dimensionality than the factor. */ * JacobianFactor has a different dimensionality than the factor. */
class GTSAM_EXPORT InvalidMatrixBlock : public std::exception { class GTSAM_EXPORT InvalidMatrixBlock : public ThreadsafeException<InvalidMatrixBlock> {
public: public:
const DenseIndex factorRows; ///< The dimensionality of the factor const DenseIndex factorRows; ///< The dimensionality of the factor
const DenseIndex blockRows; ///< The dimensionality of the noise model const DenseIndex blockRows; ///< The dimensionality of the noise model
@ -151,9 +151,9 @@ on gtsam::IndeterminantLinearSystemException for more information.\n";
}; };
/* ************************************************************************* */ /* ************************************************************************* */
class InvalidDenseElimination : public std::invalid_argument { class InvalidDenseElimination : public ThreadsafeException<InvalidDenseElimination> {
public: public:
InvalidDenseElimination(const char *message) : std::invalid_argument(message) {} InvalidDenseElimination(const char *message) : ThreadsafeException(message) {}
}; };
} }