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 
171 constexpr auto SUANPAN_EXIT = 1;
172 constexpr auto SUANPAN_SUCCESS = 0;
173 constexpr 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>
191 inline auto& SUANPAN_COUT = std::cout;
192 inline auto& SUANPAN_CWRN = std::cout;
193 inline auto& SUANPAN_CERR = std::cout;
194 inline 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>
200 using namespace arma;
201 
202 #include <filesystem>
203 namespace fs = std::filesystem;
204 
205 #include <fmt/color.h>
206 #include <mutex>
207 
208 namespace 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) {
235  SUANPAN_ERROR_COUNT += 1;
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 
296 inline 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 
314 using std::shared_ptr;
315 using std::unique_ptr;
316 using std::weak_ptr;
317 
318 using std::make_shared;
319 using std::make_unique;
320 
321 using std::exception;
322 using std::invalid_argument;
323 using std::logic_error;
324 using std::out_of_range;
325 
326 using std::istringstream;
327 using std::ostringstream;
328 using std::string;
329 
330 template<class T> concept sp_d = std::is_floating_point_v<T>;
331 template<class T> concept sp_i = std::is_integral_v<T>;
332 
333 namespace 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
342 namespace 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 
351 template<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
requires requires(T *copyable)
Definition: ResourceHolder.h:31
Definition: MatrixModifier.hpp:36
std::string pattern(const std::string_view header, const std::string_view &file_name, const std::string_view &format)
Definition: suanPan.h:211
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
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 info(const std::string_view format_str, const Col< T > &in_vec)
Definition: suanPan.h:273
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 format(const Col< T > &in_vec)
Definition: suanPan.h:258
double norm(const vec &)
Definition: tensor.cpp:370
Definition: tensor.h:120
concept sp_d
Definition: suanPan.h:330
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
enable_if2< is_arma_type< T1 >::value, typename T1::pod_type >::result inf_norm(const T1 &X)
Definition: suanPan.h:351
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
#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
concept sp_i
Definition: suanPan.h:331
auto & SUANPAN_CERR
Definition: suanPan.h:193