SpECTRE Documentation Coverage Report
Current view: top level - Utilities/ErrorHandling - Error.hpp Hit Total Coverage
Commit: 1f2210958b4f38fdc0400907ee7c6d5af5111418 Lines: 4 4 100.0 %
Date: 2025-12-05 05:03:31
Legend: Lines: hit not hit

          Line data    Source code
       1           1 : // Distributed under the MIT License.
       2             : // See LICENSE.txt for details.
       3             : 
       4             : /// \file
       5             : /// Defines macro ERROR.
       6             : 
       7             : #pragma once
       8             : 
       9             : #include <iomanip>
      10             : #include <string>
      11             : 
      12             : #include "Utilities/ErrorHandling/AbortWithErrorMessage.hpp"
      13             : #include "Utilities/ErrorHandling/Breakpoint.hpp"
      14             : #include "Utilities/ErrorHandling/Exceptions.hpp"
      15             : #include "Utilities/ErrorHandling/FloatingPointExceptions.hpp"
      16             : #include "Utilities/ForceInline.hpp"
      17             : #include "Utilities/Literals.hpp"
      18             : #include "Utilities/MakeString.hpp"
      19             : #include "Utilities/System/Abort.hpp"
      20             : 
      21             : namespace Error_detail {
      22             : // You can't use ScopedFpeState (a non-literal type) in a constexpr
      23             : // function, but you can call another function that uses it.
      24             : template <typename ExceptionTypeToThrow, typename F>
      25             : [[noreturn]] SPECTRE_ALWAYS_INLINE void abort_without_fpes(
      26             :     const char* file, const int line, const char* const pretty_function,
      27             :     F&& message) {
      28             :   const ScopedFpeState disable_fpes(false);
      29             :   abort_with_error_message<ExceptionTypeToThrow>(file, line, pretty_function,
      30             :                                                  message());
      31             : }
      32             : }  // namespace Error_detail
      33             : 
      34             : /*!
      35             :  * \ingroup ErrorHandlingGroup
      36             :  * \brief prints an error message to the standard error stream and aborts the
      37             :  * program.
      38             :  *
      39             :  * ERROR should not be used for coding errors, but instead for user errors
      40             :  * or failure modes of numerical algorithms. An acceptable use for error is also
      41             :  * in the default case of a switch statement.
      42             :  *
      43             :  * \details
      44             :  * The implementation is specialized so that in compile time contexts, a short
      45             :  * error message will be thrown, but in runtime contexts, a more verbose error
      46             :  * will be printed. This specialization of throwing a short error at compile
      47             :  * time greatly reduces the compile time and memory consumption during debug
      48             :  * builds of deep and heavily inlined `TensorExpression` tree traversals.
      49             :  *
      50             :  * To accomplish this, `__builtin_is_constant_evaluated()` is used directly
      51             :  * instead of calling a wrapper function because calling a wrapper was found to
      52             :  * slightly increase the compile time and memory usage of large
      53             :  * `TensorExpression`s when compiling in debug mode.
      54             :  *
      55             :  * \param m an arbitrary output stream.
      56             :  */
      57             : // isocpp.org recommends using an `if (true)` instead of a `do
      58             : // while(false)` for macros because the latter can mess with inlining
      59             : // in some (old?) compilers:
      60             : // https://isocpp.org/wiki/faq/misc-technical-issues#macros-with-multi-stmts
      61             : // https://isocpp.org/wiki/faq/misc-technical-issues#macros-with-if
      62             : // However, Intel's reachability analyzer (as of version 16.0.3
      63             : // 20160415) can't figure out that the else branch and everything
      64             : // after it is unreachable, causing warnings (and possibly suboptimal
      65             : // code generation).
      66             : #ifdef __CUDA_ARCH__
      67             : #if defined(__clang__) && defined(__CUDA__)
      68             : #define ERROR(m)                                              \
      69             :   printf("Error in file %s on line %d.", __FILE__, __LINE__); \
      70             :   __builtin_trap();
      71             : #else
      72             : #define ERROR(m)                                              \
      73             :   printf("Error in file %s on line %d.", __FILE__, __LINE__); \
      74             :   __trap();
      75             : #endif
      76             : #else
      77           1 : #define ERROR(m)                                                             \
      78             :   do {                                                                       \
      79             :     if (__builtin_is_constant_evaluated()) {                                 \
      80             :       throw std::runtime_error("Failed");                                    \
      81             :     } else {                                                                 \
      82             :       Error_detail::abort_without_fpes<SpectreError>(                        \
      83             :           __FILE__, __LINE__, static_cast<const char*>(__PRETTY_FUNCTION__), \
      84             :           [&]() -> std::string {                                             \
      85             :             return MakeString{} << std::setprecision(18) << std::scientific  \
      86             :                                 << m;                                        \
      87             :           });                                                                \
      88             :     }                                                                        \
      89             :   } while (false)
      90             : #endif
      91             : 
      92             : /*!
      93             :  * \ingroup ErrorHandlingGroup
      94             :  * \brief Same as ERROR but will throw `EXCEPTION_TYPE` instead of
      95             :  * `SpectreError`.
      96             :  *
      97             :  * \note Any exception types used must have an associated explicit
      98             :  * instantiation in `Utilities/ErrorHandling/AbortWithErrorMessage.cpp`
      99             :  */
     100             : #ifdef __CUDA_ARCH__
     101             : #if defined(__clang__) && defined(__CUDA__)
     102             : #define ERROR_AS(m, EXCEPTION_TYPE)                           \
     103             :   printf("Error in file %s on line %d.", __FILE__, __LINE__); \
     104             :   __builtin_trap();
     105             : #else
     106             : #define ERROR_AS(m, EXCEPTION_TYPE)                           \
     107             :   printf("Error in file %s on line %d.", __FILE__, __LINE__); \
     108             :   __trap();
     109             : #endif
     110             : #else
     111           1 : #define ERROR_AS(m, EXCEPTION_TYPE)                                          \
     112             :   do {                                                                       \
     113             :     if (__builtin_is_constant_evaluated()) {                                 \
     114             :       throw std::runtime_error("Failed");                                    \
     115             :     } else {                                                                 \
     116             :       Error_detail::abort_without_fpes<EXCEPTION_TYPE>(                      \
     117             :           __FILE__, __LINE__, static_cast<const char*>(__PRETTY_FUNCTION__), \
     118             :           [&]() -> std::string {                                             \
     119             :             return MakeString{} << std::setprecision(18) << std::scientific  \
     120             :                                 << m;                                        \
     121             :           });                                                                \
     122             :     }                                                                        \
     123             :   } while (false)
     124             : #endif
     125             : 
     126             : /*!
     127             :  * \ingroup ErrorHandlingGroup
     128             :  * \brief Same as ERROR but does not print a backtrace. Intended to be used for
     129             :  * user errors, such as incorrect values in an input file.
     130             :  */
     131             : #ifdef __CUDA_ARCH__
     132             : #if defined(__clang__) && defined(__CUDA__)
     133             : #define ERROR_NO_TRACE(m)                                     \
     134             :   printf("Error in file %s on line %d.", __FILE__, __LINE__); \
     135             :   __builtin_trap();
     136             : #else
     137             : #define ERROR_NO_TRACE(m)                                     \
     138             :   printf("Error in file %s on line %d.", __FILE__, __LINE__); \
     139             :   __trap();
     140             : #endif
     141             : #else
     142           1 : #define ERROR_NO_TRACE(m)                                                    \
     143             :   do {                                                                       \
     144             :     if (__builtin_is_constant_evaluated()) {                                 \
     145             :       throw std::runtime_error("Failed");                                    \
     146             :     } else {                                                                 \
     147             :       const ScopedFpeState disable_fpes_ERROR(false);                        \
     148             :       abort_with_error_message_no_trace(                                     \
     149             :           __FILE__, __LINE__, static_cast<const char*>(__PRETTY_FUNCTION__), \
     150             :           MakeString{} << std::setprecision(18) << std::scientific << m);    \
     151             :     }                                                                        \
     152             :   } while (false)
     153             : #endif

Generated by: LCOV version 1.14