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

@ -1,46 +1,52 @@
/* ---------------------------------------------------------------------------- /* ----------------------------------------------------------------------------
* GTSAM Copyright 2010, Georgia Tech Research Corporation, * GTSAM Copyright 2010, Georgia Tech Research Corporation,
* Atlanta, Georgia 30332-0415 * Atlanta, Georgia 30332-0415
* All Rights Reserved * All Rights Reserved
* Authors: Frank Dellaert, et al. (see THANKS for the full author list) * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
* See LICENSE for the license information * See LICENSE for the license information
* -------------------------------------------------------------------------- */ * -------------------------------------------------------------------------- */
/** /**
* @file types.h * @file types.h
* @brief Typedefs for easier changing of types * @brief Typedefs for easier changing of types
* @author Richard Roberts * @author Richard Roberts
* @date Aug 21, 2010 * @date Aug 21, 2010
* @addtogroup base * @addtogroup base
*/ */
#pragma once #pragma once
#include <gtsam/dllexport.h> #include <gtsam/dllexport.h>
#include <gtsam/config.h>
#include <cstddef>
#include <cstddef>
#include <string>
#include <boost/function/function1.hpp> #include <string>
#include <boost/range/concepts.hpp> #include <boost/function/function1.hpp>
#include <boost/range/concepts.hpp>
namespace gtsam { #include <boost/optional.hpp>
/// Integer variable index type #ifdef GTSAM_USE_TBB
typedef size_t Index; #include <tbb/tbb_exception.h>
#endif
/** A function to convert indices to strings, for example by translating back
* to a nonlinear key and then to a Symbol. */ namespace gtsam {
typedef boost::function<std::string(Index)> IndexFormatter;
/// Integer variable index type
GTSAM_EXPORT std::string _defaultIndexFormatter(Index j); typedef size_t Index;
/** The default IndexFormatter outputs the index */ /** A function to convert indices to strings, for example by translating back
static const IndexFormatter DefaultIndexFormatter = &_defaultIndexFormatter; * to a nonlinear key and then to a Symbol. */
typedef boost::function<std::string(Index)> IndexFormatter;
GTSAM_EXPORT std::string _defaultIndexFormatter(Index j);
/** The default IndexFormatter outputs the index */
static const IndexFormatter DefaultIndexFormatter = &_defaultIndexFormatter;
/// Integer nonlinear key type /// Integer nonlinear key type
typedef size_t Key; typedef size_t Key;
@ -59,93 +65,179 @@ namespace gtsam {
/// The index type for Eigen objects /// The index type for Eigen objects
typedef ptrdiff_t DenseIndex; typedef ptrdiff_t DenseIndex;
/** /* ************************************************************************* */
* Helper class that uses templates to select between two types based on /**
* whether TEST_TYPE is const or not. * Helper class that uses templates to select between two types based on
*/ * whether TEST_TYPE is const or not.
template<typename TEST_TYPE, typename BASIC_TYPE, typename AS_NON_CONST, */
typename AS_CONST> template<typename TEST_TYPE, typename BASIC_TYPE, typename AS_NON_CONST,
struct const_selector { typename AS_CONST>
}; struct const_selector {
};
/** Specialization for the non-const version */
template<typename BASIC_TYPE, typename AS_NON_CONST, typename AS_CONST> /** Specialization for the non-const version */
struct const_selector<BASIC_TYPE, BASIC_TYPE, AS_NON_CONST, AS_CONST> { template<typename BASIC_TYPE, typename AS_NON_CONST, typename AS_CONST>
typedef AS_NON_CONST type; struct const_selector<BASIC_TYPE, BASIC_TYPE, AS_NON_CONST, AS_CONST> {
}; typedef AS_NON_CONST type;
};
/** Specialization for the const version */
template<typename BASIC_TYPE, typename AS_NON_CONST, typename AS_CONST> /** Specialization for the const version */
struct const_selector<const BASIC_TYPE, BASIC_TYPE, AS_NON_CONST, AS_CONST> { template<typename BASIC_TYPE, typename AS_NON_CONST, typename AS_CONST>
typedef AS_CONST type; struct const_selector<const BASIC_TYPE, BASIC_TYPE, AS_NON_CONST, AS_CONST> {
}; typedef AS_CONST type;
};
/**
* 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 /**
* constructor. * 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
template<typename T, T defaultValue> * constructor.
struct ValueWithDefault { */
T value; template<typename T, T defaultValue>
struct ValueWithDefault {
/** Default constructor, initialize to default value supplied in template argument */ T value;
ValueWithDefault() : value(defaultValue) {}
/** Default constructor, initialize to default value supplied in template argument */
/** Initialize to the given value */ ValueWithDefault() : value(defaultValue) {}
ValueWithDefault(const T& _value) : value(_value) {}
/** Initialize to the given value */
/** Operator to access the value */ ValueWithDefault(const T& _value) : value(_value) {}
T& operator*() { return value; }
/** Operator to access the value */
/** Implicit conversion allows use in if statements for bool type, etc. */ T& operator*() { return value; }
operator T() const { return value; }
}; /** Implicit conversion allows use in if statements for bool type, etc. */
operator T() const { return value; }
/** A helper class that behaves as a container with one element, and works with };
* boost::range */
template<typename T> /* ************************************************************************* */
class ListOfOneContainer { /** A helper class that behaves as a container with one element, and works with
T element_; * boost::range */
public: template<typename T>
typedef T value_type; class ListOfOneContainer {
typedef const T* const_iterator; T element_;
typedef T* iterator; public:
ListOfOneContainer(const T& element) : element_(element) {} typedef T value_type;
const T* begin() const { return &element_; } typedef const T* const_iterator;
const T* end() const { return &element_ + 1; } typedef T* iterator;
T* begin() { return &element_; } ListOfOneContainer(const T& element) : element_(element) {}
T* end() { return &element_ + 1; } const T* begin() const { return &element_; }
size_t size() const { return 1; } const T* end() const { return &element_ + 1; }
}; T* begin() { return &element_; }
T* end() { return &element_ + 1; }
BOOST_CONCEPT_ASSERT((boost::RandomAccessRangeConcept<ListOfOneContainer<int> >)); size_t size() const { return 1; }
};
/** Factory function for ListOfOneContainer to enable ListOfOne(e) syntax. */
template<typename T> BOOST_CONCEPT_ASSERT((boost::RandomAccessRangeConcept<ListOfOneContainer<int> >));
ListOfOneContainer<T> ListOfOne(const T& element) {
return ListOfOneContainer<T>(element); /** Factory function for ListOfOneContainer to enable ListOfOne(e) syntax. */
} template<typename T>
ListOfOneContainer<T> ListOfOne(const T& element) {
/** An assertion that throws an exception if NDEBUG is not defined and return ListOfOneContainer<T>(element);
* evaluates to an empty statement otherwise. */ }
#ifdef NDEBUG
#define assert_throw(CONDITION, EXCEPTION) ((void)0) /* ************************************************************************* */
#else /// Base exception type that uses tbb_exception if GTSAM is compiled with TBB.
#define assert_throw(CONDITION, EXCEPTION) \ template<class DERIVED>
if(!(CONDITION)) { \ class ThreadsafeException :
throw (EXCEPTION); \ #ifdef GTSAM_USE_TBB
} public tbb::tbb_exception
#endif #else
public std::exception
} #endif
{
#ifdef _MSC_VER private:
#ifdef GTSAM_USE_TBB
// Define some common g++ functions and macros we use that MSVC does not have 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
#define assert_throw(CONDITION, EXCEPTION) ((void)0)
#else
#define assert_throw(CONDITION, EXCEPTION) \
if (!(CONDITION)) { \
throw (EXCEPTION); \
}
#endif
#ifdef _MSC_VER
// Define some common g++ functions and macros we use that MSVC does not have
#include <boost/math/special_functions/fpclassify.hpp> #include <boost/math/special_functions/fpclassify.hpp>
namespace std { namespace std {
template<typename T> inline int isfinite(T a) { template<typename T> inline int isfinite(T a) {
@ -176,4 +268,7 @@ namespace std {
#ifdef max #ifdef max
#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) {}
}; };
} }