suanPan
suanPan.h
Go to the documentation of this file.
1/*******************************************************************************
2 * Copyright (C) 2017-2024 Theodore Chang
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 ******************************************************************************/
17
18#ifndef SUANPAN_H
19#define SUANPAN_H
20
21// SUANPAN_DEBUG
22// _DEBUG --> MSVC
23// DEBUG --> GCC
24#if defined(_DEBUG) || defined(DEBUG) || !defined(NDEBUG)
25#define SUANPAN_DEBUG
26#define SUANPAN_EXTRA_DEBUG
27#else
28#define ARMA_NO_DEBUG
29#endif
30
31#ifdef SUANPAN_SUPERLUMT
32#define ARMA_DONT_USE_SUPERLU
33#else
34#define ARMA_USE_SUPERLU
35#endif
36
37#ifdef SUANPAN_MKL
38#define MKL_DIRECT_CALL
39#endif
40
41#ifdef SUANPAN_HDF5
42#define ARMA_USE_HDF5
43#endif
44
45#ifdef SUANPAN_MAGMA
46#ifndef SUANPAN_CUDA
47#undef SUANPAN_MAGMA
48#endif
49#endif
50
51// SUANPAN_WIN
52// WIN32 _WIN32 __WIN32 __WIN32__ --> MSVC GCC
53#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) || defined(__WIN32__)
54#ifndef SUANPAN_WIN
55#define SUANPAN_WIN
56#endif
57#endif
58
59// SUANPAN_WIN
60#if defined(WIN64) || defined(_WIN64) || defined(__WIN64) || defined(__WIN64__)
61#ifndef SUANPAN_WIN
62#define SUANPAN_WIN
63#endif
64#endif
65
66#ifdef SUANPAN_WIN
67#ifndef NOMINMAX
68#define NOMINMAX
69#endif
70#endif
71
72// SUANPAN_UNIX
73#if defined(unix) || defined(__unix__) || defined(__linux__) || defined(linux)
74#ifndef SUANPAN_UNIX
75#define SUANPAN_UNIX
76#endif
77#endif
78
79#ifdef SUANPAN_VERSION
80#undef SUANPAN_VERSION
81#endif
82#ifdef SUANPAN_COMPILER
83#undef SUANPAN_COMPILER
84#endif
85
86// SUANPAN_VERSION SUANPAN_COMPILER
87#ifdef __clang__
88// __clang__ --> clang
89#ifdef SUANPAN_VERSION
90#undef SUANPAN_VERSION
91#endif
92#define SUANPAN_VERSION __VERSION__
93#ifdef SUANPAN_COMPILER
94#undef SUANPAN_COMPILER
95#endif
96#define SUANPAN_COMPILER "CLANG"
97#define SUANPAN_CLANG
98#elif defined(__GNUG__)
99// __GNUG__ --> GCC
100#define SUANPAN_VERSION __VERSION__
101#define SUANPAN_COMPILER "GCC"
102#define SUANPAN_GCC
103#elif defined(_MSC_BUILD)
104// _MSC_BUILD --> MSVC
105#define SUANPAN_VERSION _MSC_FULL_VER
106#define SUANPAN_COMPILER "MSVC"
107#define SUANPAN_MSVC
108// cuda unused local function
109#pragma warning(disable : 4505)
110#elif defined(__ICC)
111// __ICC --> Intel C++
112#define SUANPAN_VERSION __ICC
113#define SUANPAN_COMPILER "INTEL"
114#define SUANPAN_INTEL
115#ifdef SUANPAN_WIN
116#undef SUANPAN_WIN
117#endif
118#ifndef SUANPAN_UNIX
119#define SUANPAN_UNIX
120#endif
121#elif defined(__ICL)
122// __ICL --> Intel C++
123#define SUANPAN_VERSION __ICL
124#define SUANPAN_COMPILER "INTEL"
125#define SUANPAN_INTEL
126#ifdef SUANPAN_UNIX
127#undef SUANPAN_UNIX
128#endif
129#ifndef SUANPAN_WIN
130#define SUANPAN_WIN
131#endif
132#endif
133
134// _USRDLL --> MSVC
135#ifdef _USRDLL
136#ifndef SUANPAN_DLL
137#define SUANPAN_DLL
138#endif
139#endif
140
141#ifdef SUANPAN_WIN
142// WIN MSVC GCC IMPORT
143#define SUANPAN_IMPORT extern "C" __declspec(dllimport)
144// WIN MSVC GCC EXPORT
145#define SUANPAN_EXPORT extern "C" __declspec(dllexport)
146#elif defined(SUANPAN_UNIX)
147// UNIX GCC IMPORT
148#define SUANPAN_IMPORT extern "C"
149// UNIX GCC EXPORT
150#define SUANPAN_EXPORT extern "C"
151#else
152// EMPTY
153#define SUANPAN_IMPORT extern "C"
154#define SUANPAN_EXPORT extern "C"
155#endif
156
157#ifdef SUANPAN_DLL
163#else
169#endif
170
171constexpr auto SUANPAN_EXIT = 1;
172constexpr auto SUANPAN_SUCCESS = 0;
173constexpr auto SUANPAN_FAIL = -1;
174
175// TWO IMPLEMENTATIONS
176#ifndef SUANPAN_WIN
177#define _strcmpi strcasecmp
178#endif
179
180#ifdef SUANPAN_MT
181#include <oneapi/tbb/parallel_for_each.h>
182#include <oneapi/tbb/parallel_sort.h>
183#define suanpan_sort tbb::parallel_sort
184#define suanpan_for_each tbb::parallel_for_each
185#else
186#define suanpan_sort std::sort
187#define suanpan_for_each std::for_each
188#endif
189
190#include <iostream>
191inline auto& SUANPAN_COUT = std::cout;
192inline auto& SUANPAN_CWRN = std::cout;
193inline auto& SUANPAN_CERR = std::cout;
194inline auto& SUANPAN_CFTL = std::cout;
195
196#define ARMA_COUT_STREAM SUANPAN_COUT
197#define ARMA_CERR_STREAM SUANPAN_COUT
198
199#include <armadillo/armadillo>
200using namespace arma;
201
202#include <filesystem>
203namespace fs = std::filesystem;
204
205#include <fmt/color.h>
206#include <mutex>
207
208namespace suanpan {
209 inline std::mutex print_mutex;
210
211 inline std::string pattern(const std::string_view header, const std::string_view file_name, const std::string_view format) {
212 std::string pattern{header};
213 pattern += fs::path(file_name).filename().string();
214 pattern += ":{} ~> ";
215 pattern += format;
216 return pattern;
217 }
218
219 template<typename... T> void debug(const std::string_view file_name, const int line, const std::string_view format_str, const T&... args) {
220 if(!SUANPAN_VERBOSE || !SUANPAN_PRINT) return;
221 const std::scoped_lock lock(print_mutex);
222 if(SUANPAN_COLOR) SUANPAN_COUT << fmt::vformat(fg(fmt::color::coral), pattern("[DEBUG] ", file_name, format_str), fmt::make_format_args(line, args...));
223 else SUANPAN_COUT << fmt::vformat(pattern("[DEBUG] ", file_name, format_str), fmt::make_format_args(line, args...));
224 }
225
226 template<typename... T> void warning(const std::string_view file_name, const int line, const std::string_view format_str, const T&... args) {
228 if(!SUANPAN_PRINT) return;
229 const std::scoped_lock lock(print_mutex);
230 if(SUANPAN_COLOR) SUANPAN_CWRN << fmt::vformat(fg(fmt::color::slate_blue), pattern("[WARNING] ", file_name, format_str), fmt::make_format_args(line, args...));
231 else SUANPAN_CWRN << fmt::vformat(pattern("[WARNING] ", file_name, format_str), fmt::make_format_args(line, args...));
232 }
233
234 template<typename... T> void error(const std::string_view file_name, const int line, const std::string_view format_str, const T&... args) {
236 if(!SUANPAN_PRINT) return;
237 const std::scoped_lock lock(print_mutex);
238 if(SUANPAN_COLOR) SUANPAN_CERR << fmt::vformat(fg(fmt::color::orange), pattern("[ERROR] ", file_name, format_str), fmt::make_format_args(line, args...));
239 else SUANPAN_CERR << fmt::vformat(pattern("[ERROR] ", file_name, format_str), fmt::make_format_args(line, args...));
240 }
241
242 template<typename... T> void fatal(const std::string_view file_name, const int line, const std::string_view format_str, const T&... args) {
243 if(!SUANPAN_PRINT) return;
244 const std::scoped_lock lock(print_mutex);
245 if(SUANPAN_COLOR) SUANPAN_CFTL << fmt::vformat(fg(fmt::color::violet), pattern("[FATAL] ", file_name, format_str), fmt::make_format_args(line, args...));
246 else SUANPAN_CFTL << fmt::vformat(pattern("[FATAL] ", file_name, format_str), fmt::make_format_args(line, args...));
247 }
248
249 template<typename... T> void info(const std::string_view format_str, const T&... args) {
250 if(!SUANPAN_PRINT) return;
251 const std::scoped_lock lock(print_mutex);
252 if(SUANPAN_COLOR) SUANPAN_COUT << fmt::vformat(fg(fmt::color::green_yellow), format_str, fmt::make_format_args(args...));
253 else SUANPAN_COUT << fmt::vformat(format_str, fmt::make_format_args(args...));
254 }
255
256 template<typename... T> std::string format(const std::string_view format_str, const T&... args) { return fmt::vformat(format_str, fmt::make_format_args(args...)); }
257
258 template<typename T> std::string format(const Col<T>& in_vec) {
259 std::string output;
260 if(std::is_floating_point_v<T>) for(const auto I : in_vec) output += format(" {: 1.4e}", I);
261 else for(const auto I : in_vec) output += format(" {:6d}", I);
262 output += '\n';
263 return output;
264 }
265
266 template<typename T> void info(const Col<T>& in_vec) {
267 if(!SUANPAN_PRINT) return;
268 const std::scoped_lock lock(print_mutex);
269 if(SUANPAN_COLOR) SUANPAN_COUT << fmt::format(fg(fmt::color::green_yellow), format(in_vec));
270 else SUANPAN_COUT << format(in_vec);
271 }
272
273 template<typename T> void info(const std::string_view format_str, const Col<T>& in_vec) {
274 if(!SUANPAN_PRINT) return;
275 std::string output = format(format_str);
276 if(format_str.back() != '\t' && format_str.back() != '\n') output += '\n';
277 output += format(in_vec);
278 const std::scoped_lock lock(print_mutex);
279 if(SUANPAN_COLOR) SUANPAN_COUT << fmt::format(fg(fmt::color::green_yellow), output);
280 else SUANPAN_COUT << output;
281 }
282
283 template<typename... T> void highlight(const std::string_view format_str, const T&... args) {
284 if(!SUANPAN_PRINT) return;
285 const std::scoped_lock lock(print_mutex);
286 if(SUANPAN_COLOR) SUANPAN_COUT << fmt::vformat(fg(fmt::color::crimson), format_str, fmt::make_format_args(args...));
287 else SUANPAN_COUT << fmt::vformat(format_str, fmt::make_format_args(args...));
288 }
289}
290
291#ifdef SUANPAN_MSVC
292#pragma warning(disable : 4100)
293#endif
294#include <functional>
295
296inline void suanpan_assert(const std::function<void()>& F) {
297#ifdef SUANPAN_DEBUG
298 F();
299#endif
300}
301#ifdef SUANPAN_MSVC
302#pragma warning(default : 4100)
303#endif
304
305#define suanpan_info suanpan::info
306#define suanpan_highlight suanpan::highlight
307#define suanpan_debug(...) suanpan::debug(__FILE__, __LINE__, ##__VA_ARGS__)
308#define suanpan_warning(...) suanpan::warning(__FILE__, __LINE__, ##__VA_ARGS__)
309#define suanpan_error(...) suanpan::error(__FILE__, __LINE__, ##__VA_ARGS__)
310#define suanpan_fatal(...) suanpan::fatal(__FILE__, __LINE__, ##__VA_ARGS__)
311
312#include <memory>
313
314using std::shared_ptr;
315using std::unique_ptr;
316using std::weak_ptr;
317
318using std::make_shared;
319using std::make_unique;
320
321using std::exception;
322using std::invalid_argument;
323using std::logic_error;
324using std::out_of_range;
325
326using std::istringstream;
327using std::ostringstream;
328using std::string;
329
330template<class T> concept sp_d = std::is_floating_point_v<T>;
331template<class T> concept sp_i = std::is_integral_v<T>;
332
333namespace suanpan {
334 template<class IN, class FN> requires requires(IN& x) { x.begin(); x.end(); }
335 void for_all(IN& from, FN&& func) {
336 suanpan_for_each(from.begin(), from.end(), std::forward<FN>(func));
337 }
338}
339
340#if defined(SUANPAN_CLANG) && !defined(__cpp_lib_ranges)
341// as of clang 13, ranges support is not complete
342namespace std::ranges {
343 template<class IN, class OUT, class FN> OUT transform(IN& from, OUT to, FN&& func) { return std::transform(from.begin(), from.end(), to, std::forward<FN>(func)); }
344
345 template<class IN, class FN> FN for_each(IN& from, FN&& func) { return std::for_each(from.begin(), from.end(), std::forward<FN>(func)); }
346
347 template<class IN, class OUT> OUT copy(IN& from, OUT to) { return std::copy(from.begin(), from.end(), to); }
348} // namespace std::ranges
349#endif
350
351template<typename T1> [[nodiscard]] typename enable_if2<is_arma_type<T1>::value, typename T1::pod_type>::result inf_norm(const T1& X) { return arma::norm(X, "inf"); }
352
353#endif
Definition: suanPan.h:330
Definition: suanPan.h:331
Definition: MatrixModifier.hpp:36
void error(const std::string_view file_name, const int line, const std::string_view format_str, const T &... args)
Definition: suanPan.h:234
void debug(const std::string_view file_name, const int line, const std::string_view format_str, const T &... args)
Definition: suanPan.h:219
std::string format(const std::string_view format_str, const T &... args)
Definition: suanPan.h:256
void info(const std::string_view format_str, const T &... args)
Definition: suanPan.h:249
void warning(const std::string_view file_name, const int line, const std::string_view format_str, const T &... args)
Definition: suanPan.h:226
void for_all(IN &from, FN &&func)
Definition: suanPan.h:335
void highlight(const std::string_view format_str, const T &... args)
Definition: suanPan.h:283
std::mutex print_mutex
Definition: suanPan.h:209
void for_each(const IT start, const IT end, F &&FN)
Definition: utility.h:28
void fatal(const std::string_view file_name, const int line, const std::string_view format_str, const T &... args)
Definition: suanPan.h:242
std::string pattern(const std::string_view header, const std::string_view file_name, const std::string_view format)
Definition: suanPan.h:211
std::string format(const Col< T > &in_vec)
Definition: suanPan.h:258
double norm(const vec &)
Definition: tensor.cpp:370
Definition: tensor.h:120
constexpr auto SUANPAN_SUCCESS
Definition: suanPan.h:172
auto & SUANPAN_COUT
Definition: suanPan.h:191
#define suanpan_for_each
Definition: suanPan.h:187
SUANPAN_EXPORT bool SUANPAN_COLOR
Definition: suanPan.h:166
#define SUANPAN_EXPORT
Definition: suanPan.h:154
constexpr auto SUANPAN_EXIT
Definition: suanPan.h:171
auto & SUANPAN_CWRN
Definition: suanPan.h:192
auto & SUANPAN_CFTL
Definition: suanPan.h:194
void suanpan_assert(const std::function< void()> &F)
Definition: suanPan.h:296
SUANPAN_EXPORT bool SUANPAN_PRINT
Definition: suanPan.h:164
constexpr auto SUANPAN_FAIL
Definition: suanPan.h:173
SUANPAN_EXPORT unsigned SUANPAN_ERROR_COUNT
Definition: suanPan.h:168
enable_if2< is_arma_type< T1 >::value, typenameT1::pod_type >::result inf_norm(const T1 &X)
Definition: suanPan.h:351
#define SUANPAN_IMPORT
Definition: suanPan.h:153
SUANPAN_EXPORT bool SUANPAN_VERBOSE
Definition: suanPan.h:165
SUANPAN_EXPORT unsigned SUANPAN_WARNING_COUNT
Definition: suanPan.h:167
auto & SUANPAN_CERR
Definition: suanPan.h:193