forked from GazzolaLab/PyElastica
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
478 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/// \file | ||
/// Defines function ErrorHandling::abort. | ||
|
||
#pragma once | ||
|
||
#include <cstdio> | ||
#include <cstdlib> | ||
#include <exception> | ||
#include <string> | ||
|
||
namespace Parallel { | ||
/// Abort the program with an error message. | ||
[[noreturn]] inline void abort(const std::string& message) { | ||
printf("%s", message.c_str()); | ||
std::exit(EXIT_SUCCESS); | ||
|
||
// the following call is never reached, but suppresses the warning that | ||
// a 'noreturn' functions does return | ||
std::terminate(); // LCOV_EXCL_LINE | ||
} | ||
} // namespace Parallel |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
// Distributed under the MIT License. | ||
// See LICENSE.txt for details. | ||
|
||
#include "ErrorHandling/AbortWithErrorMessage.hpp" | ||
|
||
#include <cstdio> | ||
#include <sstream> | ||
|
||
#include "ErrorHandling/Abort.hpp" | ||
|
||
void abort_with_error_message(const char* expression, const char* file, | ||
const int line, const char* pretty_function, | ||
const std::string& message) { | ||
std::ostringstream os; | ||
os << "\n" | ||
<< "############ ASSERT FAILED ############\n" | ||
// << "Node: " << Parallel::my_node() << " Proc: " << | ||
// Parallel::my_proc() | ||
// << "\n" | ||
<< "Line: " << line << " of " << file << "\n" | ||
<< "'" << expression << "' violated!\n" | ||
<< "Function: " << pretty_function << "\n" | ||
<< message << "\n" | ||
<< "############ ASSERT FAILED ############\n" | ||
<< "\n"; | ||
// We use printf instead of abort to print the error message because in the | ||
// case of an executable not using Charm++'s main function the call to abort | ||
// will segfault before anything is printed. | ||
printf("%s", os.str().c_str()); | ||
Parallel::abort(""); | ||
} | ||
|
||
void abort_with_error_message(const char* file, const int line, | ||
const char* pretty_function, | ||
const std::string& message) { | ||
std::ostringstream os; | ||
os << "\n" | ||
<< "############ ERROR ############\n" | ||
// << "Node: " << Parallel::my_node() << " Proc: " << | ||
// Parallel::my_proc() | ||
// << "\n" | ||
<< "Line: " << line << " of " << file << "\n" | ||
<< "Function: " << pretty_function << "\n" | ||
<< message << "\n" | ||
<< "############ ERROR ############\n" | ||
<< "\n"; | ||
// We use printf instead of abort to print the error message because in the | ||
// case of an executable not using Charm++'s main function the call to abort | ||
// will segfault before anything is printed. | ||
// printf("%s", os.c_str()); | ||
printf("%s", os.str().c_str()); | ||
Parallel::abort(""); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// Distributed under the MIT License. | ||
// See LICENSE.txt for details. | ||
|
||
/// \file | ||
/// Declares function abort_with_error_message | ||
|
||
#pragma once | ||
|
||
#include <string> | ||
|
||
/// \ingroup ErrorHandlingGroup | ||
/// Compose an error message with an expression and abort the program. | ||
[[noreturn]] void abort_with_error_message(const char* expression, | ||
const char* file, int line, | ||
const char* pretty_function, | ||
const std::string& message); | ||
|
||
/// \ingroup ErrorHandlingGroup | ||
/// Compose an error message and abort the program. | ||
[[noreturn]] void abort_with_error_message(const char* file, int line, | ||
const char* pretty_function, | ||
const std::string& message); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// Distributed under the MIT License. | ||
// See LICENSE.txt for details. | ||
|
||
/// \file | ||
/// Defines macro ASSERT. | ||
|
||
#pragma once | ||
|
||
#include <sstream> | ||
#include <string> | ||
|
||
#include "ErrorHandling/Abort.hpp" | ||
#include "ErrorHandling/AbortWithErrorMessage.hpp" | ||
#include "ErrorHandling/FloatingPointExceptions.hpp" | ||
|
||
/*! | ||
* \ingroup ErrorHandlingGroup | ||
* \brief Assert that an expression should be true. | ||
* | ||
* If the preprocessor macro ELASTICA_DEBUG is defined and the expression is | ||
* false, an error message is printed to the standard error stream, and the | ||
* program aborts. ASSERT should be used to catch coding errors as it does | ||
* nothing in production code. | ||
* \param a the expression that must be true | ||
* \param m the error message as an ostream | ||
*/ | ||
//#ifdef ELASTICA_DEBUG | ||
#ifndef NDEBUG | ||
// isocpp.org recommends using an `if (true)` instead of a `do | ||
// while(false)` for macros because the latter can mess with inlining | ||
// in some (old?) compilers: | ||
// https://isocpp.org/wiki/faq/misc-technical-issues#macros-with-multi-stmts | ||
// https://isocpp.org/wiki/faq/misc-technical-issues#macros-with-if | ||
// However, Intel's reachability analyzer (as of version 16.0.3 | ||
// 20160415) can't figure out that the else branch and everything | ||
// after it is unreachable, causing warnings (and possibly suboptimal | ||
// code generation). | ||
#define ELASTICA_ASSERT(a, m) \ | ||
do { \ | ||
if (!(a)) { \ | ||
disable_floating_point_exceptions(); \ | ||
std::ostringstream avoid_name_collisions_ASSERT; \ | ||
/* clang-tidy: macro arg in parentheses */ \ | ||
avoid_name_collisions_ASSERT << m; /* NOLINT */ \ | ||
abort_with_error_message(#a, __FILE__, __LINE__, \ | ||
static_cast<const char*>(__PRETTY_FUNCTION__), \ | ||
avoid_name_collisions_ASSERT.str()); \ | ||
} \ | ||
} while (false) | ||
#else | ||
#define ELASTICA_ASSERT(a, m) \ | ||
do { \ | ||
if (false) { \ | ||
static_cast<void>(a); \ | ||
disable_floating_point_exceptions(); \ | ||
std::ostringstream avoid_name_collisions_ASSERT; \ | ||
/* clang-tidy: macro arg in parentheses */ \ | ||
avoid_name_collisions_ASSERT << m; /* NOLINT */ \ | ||
static_cast<void>(avoid_name_collisions_ASSERT); \ | ||
enable_floating_point_exceptions(); \ | ||
} \ | ||
} while (false) | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// Distributed under the MIT License. | ||
// See LICENSE.txt for details. | ||
|
||
#include "ErrorHandling/Breakpoint.hpp" | ||
|
||
#include <csignal> | ||
|
||
void breakpoint() { | ||
// We send ourselves a SIGTRAP and ignore it. If we're not being | ||
// traced (e.g. being run in a debugger), that doesn't do much, but if we are | ||
// then the tracer (debugger) can see the signal delivery. We don't reset the | ||
// signal handler afterwards in case this is called on multiple threads; we | ||
// don't want one thread reenabling the default handler just before another | ||
// calls raise(). | ||
struct sigaction handler {}; | ||
handler.sa_handler = SIG_IGN; // NOLINT | ||
handler.sa_flags = 0; | ||
sigemptyset(&handler.sa_mask); | ||
sigaction(SIGTRAP, &handler, nullptr); | ||
raise(SIGTRAP); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
/// \file | ||
/// Defines function ErrorHandling::breakpoint. | ||
|
||
#pragma once | ||
|
||
/*! | ||
* \brief Raise `SIGTRAP` so that debuggers will trap. | ||
*/ | ||
void breakpoint(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# Distributed under the MIT License. See LICENSE.txt for details. | ||
|
||
set(LIBRARY ErrorHandling) | ||
|
||
add_elastica_library(${LIBRARY}) | ||
|
||
elastica_target_sources( | ||
${LIBRARY} | ||
PRIVATE | ||
AbortWithErrorMessage.cpp | ||
Breakpoint.cpp | ||
FloatingPointExceptions.cpp | ||
NestedExceptions.cpp | ||
) | ||
|
||
elastica_target_headers( | ||
${LIBRARY} | ||
INCLUDE_DIRECTORY ${CMAKE_SOURCE_DIR}/elastica | ||
AbortWithErrorMessage.hpp | ||
Abort.hpp | ||
Assert.hpp | ||
Breakpoint.hpp | ||
Error.hpp | ||
ExpectsAndEnsures.hpp | ||
Exit.hpp | ||
FloatingPointExceptions.hpp | ||
NestedExceptions.hpp | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// Reused from SpECTRE : https://spectre-code.org/ | ||
// Distributed under the MIT License. | ||
// See LICENSE.txt for details. | ||
|
||
#pragma once | ||
|
||
#include <sstream> | ||
#include <string> | ||
|
||
#include "ErrorHandling/Abort.hpp" | ||
#include "ErrorHandling/AbortWithErrorMessage.hpp" | ||
#include "ErrorHandling/Breakpoint.hpp" | ||
#include "ErrorHandling/FloatingPointExceptions.hpp" | ||
|
||
/*! | ||
* \ingroup ErrorHandlingGroup | ||
* \brief prints an error message to the standard error stream and aborts the | ||
* program. | ||
* | ||
* ERROR should not be used for coding errors, but instead for user errors | ||
* or failure modes of numerical algorithms. An acceptable use for error is also | ||
* in the default case of a switch statement. | ||
* \param m an arbitrary output stream. | ||
*/ | ||
// isocpp.org recommends using an `if (true)` instead of a `do | ||
// while(false)` for macros because the latter can mess with inlining | ||
// in some (old?) compilers: | ||
// https://isocpp.org/wiki/faq/misc-technical-issues#macros-with-multi-stmts | ||
// https://isocpp.org/wiki/faq/misc-technical-issues#macros-with-if | ||
// However, Intel's reachability analyzer (as of version 16.0.3 | ||
// 20160415) can't figure out that the else branch and everything | ||
// after it is unreachable, causing warnings (and possibly suboptimal | ||
// code generation). | ||
#define ERROR(m) \ | ||
do { \ | ||
disable_floating_point_exceptions(); \ | ||
std::ostringstream avoid_name_collisions_ERROR; \ | ||
/* clang-tidy: macro arg in parentheses */ \ | ||
avoid_name_collisions_ERROR << m; /* NOLINT */ \ | ||
abort_with_error_message(__FILE__, __LINE__, \ | ||
static_cast<const char*>(__PRETTY_FUNCTION__), \ | ||
avoid_name_collisions_ERROR.str()); \ | ||
} while (false) | ||
|
||
/*! | ||
* \ingroup ErrorHandlingGroup | ||
* \brief prints an error message to the standard error and aborts the | ||
* program. | ||
* | ||
* CERROR is just like ERROR and so the same guidelines apply. However, because | ||
* it does not use std::stringstream it can be used in some constexpr | ||
* functions where ERROR cannot be. | ||
* \param m error message as a string, may need to use string literals | ||
*/ | ||
#define CERROR(m) \ | ||
do { \ | ||
breakpoint(); \ | ||
using std::string_literals::operator""s; \ | ||
Parallel::abort("\n################ ERROR ################\nLine: "s + \ | ||
std::to_string(__LINE__) + " of file '"s + __FILE__ + \ | ||
"'\n"s + m + /* NOLINT */ \ | ||
"\n#######################################\n"s); \ | ||
} while (false) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
/// \file | ||
/// Defines function ErrorHandling::abort. | ||
|
||
#pragma once | ||
|
||
#include <exception> | ||
|
||
namespace Parallel { | ||
/// Abort the program with an error message. | ||
[[noreturn]] inline void exit() { | ||
std::exit(EXIT_SUCCESS); | ||
// the following call is never reached, but suppresses the warning that | ||
// a 'noreturn' functions does return | ||
std::terminate(); // LCOV_EXCL_LINE | ||
} | ||
} // namespace Parallel |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
// Distributed under the MIT License. | ||
// See LICENSE.txt for details. | ||
|
||
/// \file | ||
/// Defines macros Expects and Ensures | ||
|
||
#pragma once | ||
|
||
#include "ErrorHandling/Error.hpp" | ||
|
||
// part of GSL, but GSL depends on Expects and Ensures... | ||
#ifndef UNLIKELY | ||
#if defined(__clang__) || defined(__GNUC__) | ||
#define UNLIKELY(x) __builtin_expect(!!(x), 0) | ||
#else | ||
#define UNLIKELY(x) (x) | ||
#endif | ||
#endif | ||
|
||
// part of GSL, but GSL depends on Expects and Ensures... | ||
#ifndef LIKELY | ||
#if defined(__clang__) || defined(__GNUC__) | ||
#define LIKELY(x) __builtin_expect(!!(x), 1) | ||
#else | ||
#define LIKELY(x) (x) | ||
#endif | ||
#endif | ||
|
||
/*! | ||
* \ingroup ErrorHandlingGroup | ||
* \brief check expectation of pre-conditions of a function | ||
* | ||
* The Expects macro sets the preconditions to a function's arguments, it is a | ||
* contract (C++20) that must be satisfied. See the CppCoreGuidelines for | ||
* details. | ||
* \param cond the expression that is expected to be true | ||
*/ | ||
#if defined(ELASTICA_DEBUG) || defined(EXPECTS_ENSURES) | ||
#define Expects(cond) \ | ||
if (UNLIKELY(!(cond))) { \ | ||
CERROR("Expects violated: "s + #cond); \ | ||
} else \ | ||
static_cast<void>(0) | ||
#else | ||
#define Expects(cond) \ | ||
if (false) { \ | ||
static_cast<void>(cond); \ | ||
} else \ | ||
static_cast<void>(0) | ||
#endif | ||
|
||
/*! | ||
* \ingroup ErrorHandlingGroup | ||
* \brief Check that a post-condition of a function is true | ||
* | ||
* The Ensures macro sets the postconditions of function, it is a contract | ||
* (C++20) that must be satisfied. See the CppCoreGuidelines for details. | ||
* \param cond the expression that is expected to be true | ||
*/ | ||
#if defined(ELASTICA_DEBUG) || defined(EXPECTS_ENSURES) | ||
#define Ensures(cond) \ | ||
if (UNLIKELY(!(cond))) { \ | ||
CERROR("Ensures violated: "s + #cond); \ | ||
} else \ | ||
static_cast<void>(0) | ||
#else | ||
#define Ensures(cond) \ | ||
if (false) { \ | ||
static_cast<void>(cond); \ | ||
} else \ | ||
static_cast<void>(0) | ||
#endif |
Oops, something went wrong.