Nektar++
Loading...
Searching...
No Matches
ErrorUtil.hpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: ErrorUtil.hpp
4//
5// For more information, please see: http://www.nektar.info
6//
7// The MIT License
8//
9// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10// Department of Aeronautics, Imperial College London (UK), and Scientific
11// Computing and Imaging Institute, University of Utah (USA).
12//
13// Permission is hereby granted, free of charge, to any person obtaining a
14// copy of this software and associated documentation files (the "Software"),
15// to deal in the Software without restriction, including without limitation
16// the rights to use, copy, modify, merge, publish, distribute, sublicense,
17// and/or sell copies of the Software, and to permit persons to whom the
18// Software is furnished to do so, subject to the following conditions:
19//
20// The above copyright notice and this permission notice shall be included
21// in all copies or substantial portions of the Software.
22//
23// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29// DEALINGS IN THE SOFTWARE.
30//
31// Description: error related utilities
32//
33///////////////////////////////////////////////////////////////////////////////
34#ifndef ERRORUTIL_HPP
35#define ERRORUTIL_HPP
36
37#include <iostream>
38#include <stdexcept>
39#include <string>
40
42
43#if defined(NEKTAR_USE_MPI)
44#include <mpi.h>
45#endif
46
47#ifndef _WIN32
48#include <execinfo.h>
49#endif
50
51namespace Nektar
52{
53
55{
56public:
57 class NekError : public std::runtime_error
58 {
59 public:
60 NekError(const std::string &message) : std::runtime_error(message)
61 {
62 }
63 };
64
66 {
69 };
70
71 inline static void SetErrorStream(std::ostream &o)
72 {
73 m_outStream = &o;
74 }
75
76 inline static void SetPrintBacktrace(bool b)
77 {
79 }
80
81 inline static bool HasCustomErrorStream()
82 {
83 return m_outStream != &std::cerr;
84 }
85
86 inline static void Error(ErrType type, [[maybe_unused]] const char *routine,
87 [[maybe_unused]] int lineNumber, const char *msg,
88 unsigned int level,
89 [[maybe_unused]] bool DoComm = false)
90 {
91 // The user of outStream is primarily for the unit tests. The unit
92 // tests often generate errors on purpose to make sure invalid usage is
93 // flagged appropriately. Printing the error messages to cerr made the
94 // unit test output hard to parse.
95
96 std::string baseMsg =
97 "Level " + std::to_string(level) + " assertion violation\n";
98#if defined(NEKTAR_DEBUG) || defined(NEKTAR_FULLDEBUG)
99 baseMsg += "Where : " + std::string(routine) + "[" +
100 std::to_string(lineNumber) + "]\nMessage : ";
101#endif
102 baseMsg += std::string(msg);
103
104 // Default rank is zero. If MPI used and initialised, populate with
105 // the correct rank. Messages are only printed on rank zero.
106 int rank = 0;
107#if defined(NEKTAR_USE_MPI) && !defined(NEKTAR_USE_CWIPI)
108 int flag = 0;
109 if (DoComm)
110 {
111 MPI_Initialized(&flag);
112 if (flag)
113 {
114 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
115 }
116 }
117#endif
118
119 std::string btMessage("");
120#if defined(NEKTAR_FULLDEBUG)
121#ifndef _WIN32
123 {
124 void *btArray[40];
125 int btSize;
126 char **btStrings;
127
128 btSize = backtrace(btArray, 40);
129 btStrings = backtrace_symbols(btArray, btSize);
130
131 for (int i = 0; i < btSize; ++i)
132 {
133 btMessage += std::string(btStrings[i]) + "\n";
134 }
135 free(btStrings);
136 }
137#endif
138#endif
139
140 switch (type)
141 {
142 case efatal:
143 if (!rank)
144 {
146 {
147 (*m_outStream) << btMessage;
148 }
149 (*m_outStream)
150 << std::endl
151 << "\033[31mFatal : \033[0m" << baseMsg << std::endl
152 << std::endl;
153 }
154
155#if defined(NEKTAR_USE_MPI) && !defined(NEKTAR_USE_CWIPI)
156 if (DoComm)
157 {
158 if (flag)
159 {
160 MPI_Barrier(MPI_COMM_WORLD);
161 }
162 }
163#endif
164 throw NekError(baseMsg);
165 break;
166 case ewarning:
167 if (!rank)
168 {
170 {
171 (*m_outStream) << btMessage;
172 }
173 (*m_outStream)
174 << std::endl
175 << "\033[36mWarning : \033[0m" << baseMsg << std::endl
176 << std::endl;
177 }
178 break;
179 default:
180 (*m_outStream) << std::endl
181 << "\033[35mUnknown warning type: \033[0m"
182 << baseMsg << std::endl
183 << std::endl;
184 }
185 }
186
187 inline static void Error(ErrType type, const char *routine, int lineNumber,
188 const std::string &msg, unsigned int level)
189 {
190 Error(type, routine, lineNumber, msg.c_str(), level);
191 }
192
193 inline static void Error(ErrType type, const char *routine, int lineNumber,
194 const char *msg)
195 {
196 Error(type, routine, lineNumber, msg, 0);
197 }
198
199private:
200 LIB_UTILITIES_EXPORT static std::ostream *m_outStream;
202};
203
204/// Assert Level 0 -- Fundamental assert which
205/// is used whether in FULLDEBUG, DEBUG or OPT
206/// compilation mode. This level assert is
207/// considered code critical, even under
208/// optimized compilation.
209
210#define NEKERROR(type, msg) \
211 Nektar::ErrorUtil::Error(type, __FILE__, __LINE__, msg, 0);
212
213#define ROOTONLY_NEKERROR(type, msg) \
214 Nektar::ErrorUtil::Error(type, __FILE__, __LINE__, msg, 0, true);
215
216#define ASSERTL0(condition, msg) \
217 if (!(condition)) \
218 { \
219 Nektar::ErrorUtil::Error(Nektar::ErrorUtil::efatal, __FILE__, \
220 __LINE__, msg, 0); \
221 }
222
223#define WARNINGL0(condition, msg) \
224 if (!(condition)) \
225 { \
226 Nektar::ErrorUtil::Error(Nektar::ErrorUtil::ewarning, __FILE__, \
227 __LINE__, msg, 0); \
228 }
229
230/// Assert Level 1 -- Debugging which is used whether in FULLDEBUG or
231/// DEBUG compilation mode. This level assert is designed for aiding
232/// in standard debug (-g) mode
233#if defined(NEKTAR_DEBUG) || defined(NEKTAR_FULLDEBUG)
234
235#define ASSERTL1(condition, msg) \
236 if (!(condition)) \
237 { \
238 Nektar::ErrorUtil::Error(Nektar::ErrorUtil::efatal, __FILE__, \
239 __LINE__, msg, 1); \
240 }
241
242#define WARNINGL1(condition, msg) \
243 if (!(condition)) \
244 { \
245 Nektar::ErrorUtil::Error(Nektar::ErrorUtil::ewarning, __FILE__, \
246 __LINE__, msg, 1); \
247 }
248
249#else // defined(NEKTAR_DEBUG) || defined(NEKTAR_FULLDEBUG)
250#define ASSERTL1(condition, msg)
251#define WARNINGL1(condition, msg)
252#endif // defined(NEKTAR_DEBUG) || defined(NEKTAR_FULLDEBUG)
253
254/// Assert Level 2 -- Debugging which is used FULLDEBUG compilation
255/// mode. This level assert is designed to provide addition safety
256/// checks within the code (such as bounds checking, etc.).
257#ifdef NEKTAR_FULLDEBUG
258
259#define ASSERTL2(condition, msg) \
260 if (!(condition)) \
261 { \
262 Nektar::ErrorUtil::Error(Nektar::ErrorUtil::efatal, __FILE__, \
263 __LINE__, msg, 2); \
264 }
265#define WARNINGL2(condition, msg) \
266 if (!(condition)) \
267 { \
268 Nektar::ErrorUtil::Error(Nektar::ErrorUtil::ewarning, __FILE__, \
269 __LINE__, msg, 2); \
270 }
271
272#else // NEKTAR_FULLDEBUG
273#define ASSERTL2(condition, msg)
274#define WARNINGL2(condition, msg)
275#endif // NEKTAR_FULLDEBUG
276
277} // namespace Nektar
278
279#endif // ERRORUTIL_HPP
#define LIB_UTILITIES_EXPORT
NekError(const std::string &message)
Definition ErrorUtil.hpp:60
static bool m_printBacktrace
static void Error(ErrType type, const char *routine, int lineNumber, const char *msg, unsigned int level, bool DoComm=false)
Definition ErrorUtil.hpp:86
static void Error(ErrType type, const char *routine, int lineNumber, const char *msg)
static std::ostream * m_outStream
static void SetPrintBacktrace(bool b)
Definition ErrorUtil.hpp:76
static void Error(ErrType type, const char *routine, int lineNumber, const std::string &msg, unsigned int level)
static void SetErrorStream(std::ostream &o)
Definition ErrorUtil.hpp:71
static bool HasCustomErrorStream()
Definition ErrorUtil.hpp:81
STL namespace.