suanPan
suanPan.h
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright (C) 2017-2023 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 // SUANPAN_WIN
46 // WIN32 _WIN32 __WIN32 __WIN32__ --> MSVC GCC
47 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32) || defined(__WIN32__)
48 #ifndef SUANPAN_WIN
49 #define SUANPAN_WIN
50 #endif
51 #endif
52 
53 // SUANPAN_WIN
54 #if defined(WIN64) || defined(_WIN64) || defined(__WIN64) || defined(__WIN64__)
55 #ifndef SUANPAN_WIN
56 #define SUANPAN_WIN
57 #endif
58 #endif
59 
60 #ifdef SUANPAN_WIN
61 #ifndef NOMINMAX
62 #define NOMINMAX
63 #endif
64 #endif
65 
66 // SUANPAN_UNIX
67 #if defined(unix) || defined(__unix__) || defined(__linux__) || defined(linux)
68 #ifndef SUANPAN_UNIX
69 #define SUANPAN_UNIX
70 #endif
71 #endif
72 
73 #ifdef SUANPAN_VERSION
74 #undef SUANPAN_VERSION
75 #endif
76 #ifdef SUANPAN_COMPILER
77 #undef SUANPAN_COMPILER
78 #endif
79 
80 // SUANPAN_VERSION SUANPAN_COMPILER
81 #ifdef __clang__
82 // __clang__ --> clang
83 #ifdef SUANPAN_VERSION
84 #undef SUANPAN_VERSION
85 #endif
86 #define SUANPAN_VERSION __VERSION__
87 #ifdef SUANPAN_COMPILER
88 #undef SUANPAN_COMPILER
89 #endif
90 #define SUANPAN_COMPILER "CLANG"
91 #define SUANPAN_CLANG
92 #elif defined(__GNUG__)
93 // __GNUG__ --> GCC
94 #define SUANPAN_VERSION __VERSION__
95 #define SUANPAN_COMPILER "GCC"
96 #define SUANPAN_GCC
97 #elif defined(_MSC_BUILD)
98 // _MSC_BUILD --> MSVC
99 #define SUANPAN_VERSION _MSC_FULL_VER
100 #define SUANPAN_COMPILER "MSVC"
101 #define SUANPAN_MSVC
102 // cuda unused local function
103 #pragma warning(disable : 4505)
104 #elif defined(__ICC)
105 // __ICC --> Intel C++
106 #define SUANPAN_VERSION __ICC
107 #define SUANPAN_COMPILER "INTEL"
108 #define SUANPAN_INTEL
109 #ifdef SUANPAN_WIN
110 #undef SUANPAN_WIN
111 #endif
112 #ifndef SUANPAN_UNIX
113 #define SUANPAN_UNIX
114 #endif
115 #elif defined(__ICL)
116 // __ICL --> Intel C++
117 #define SUANPAN_VERSION __ICL
118 #define SUANPAN_COMPILER "INTEL"
119 #define SUANPAN_INTEL
120 #ifdef SUANPAN_UNIX
121 #undef SUANPAN_UNIX
122 #endif
123 #ifndef SUANPAN_WIN
124 #define SUANPAN_WIN
125 #endif
126 #endif
127 
128 // _USRDLL --> MSVC
129 #ifdef _USRDLL
130 #ifndef SUANPAN_DLL
131 #define SUANPAN_DLL
132 #endif
133 #endif
134 
135 #ifdef SUANPAN_WIN
136 // WIN MSVC GCC IMPORT
137 #define SUANPAN_IMPORT extern "C" __declspec(dllimport)
138 // WIN MSVC GCC EXPORT
139 #define SUANPAN_EXPORT extern "C" __declspec(dllexport)
140 #elif defined(SUANPAN_UNIX)
141 // UNIX GCC IMPORT
142 #define SUANPAN_IMPORT extern "C"
143 // UNIX GCC EXPORT
144 #define SUANPAN_EXPORT extern "C"
145 #else
146 // EMPTY
147 #define SUANPAN_IMPORT extern "C"
148 #define SUANPAN_EXPORT extern "C"
149 #endif
150 
151 #ifdef SUANPAN_DLL
155 #else
159 #endif
160 
161 constexpr auto SUANPAN_EXIT = 1;
162 constexpr auto SUANPAN_SUCCESS = 0;
163 constexpr auto SUANPAN_FAIL = -1;
164 
165 // TWO IMPLEMENTATIONS
166 #ifndef SUANPAN_WIN
167 #define _strcmpi strcasecmp
168 #endif
169 
170 #ifdef SUANPAN_MT
171 #include <tbb/parallel_for_each.h>
172 #include <tbb/parallel_sort.h>
173 #define suanpan_sort tbb::parallel_sort
174 #define suanpan_for_each tbb::parallel_for_each
175 #else
176 #define suanpan_sort std::sort
177 #define suanpan_for_each std::for_each
178 #endif
179 
180 #include <iostream>
181 inline auto& SUANPAN_COUT = std::cout;
182 inline auto& SUANPAN_CWRN = std::cout;
183 inline auto& SUANPAN_CERR = std::cout;
184 inline auto& SUANPAN_CFTL = std::cout;
185 
186 #define ARMA_COUT_STREAM SUANPAN_COUT
187 #define ARMA_CERR_STREAM SUANPAN_COUT
188 
189 #include <armadillo/armadillo>
190 using namespace arma;
191 
192 #include <filesystem>
193 namespace fs = std::filesystem;
194 
195 #include <fmt/color.h>
196 #include <mutex>
197 
198 namespace suanpan {
199  inline std::mutex print_mutex;
200 
201  inline std::string pattern(const std::string_view header, const std::string_view& file_name, const std::string_view& format) {
202  std::string pattern{header};
203  pattern += fs::path(file_name).filename().string();
204  pattern += ":{:<6d}";
205  pattern += format;
206  return pattern;
207  }
208 
209  template<typename... T> void debug(const std::string_view file_name, const int line, const std::string_view format_str, const T&... args) {
210  if(!SUANPAN_VERBOSE || !SUANPAN_PRINT) return;
211  const std::scoped_lock lock(print_mutex);
212  if(SUANPAN_COLOR) SUANPAN_COUT << fmt::vformat(fg(fmt::color::coral), pattern("[DEBUG] ", file_name, format_str), fmt::make_format_args(line, args...));
213  else SUANPAN_COUT << fmt::vformat(pattern("[DEBUG] ", file_name, format_str), fmt::make_format_args(line, args...));
214  }
215 
216  template<typename... T> void warning(const std::string_view file_name, const int line, const std::string_view format_str, const T&... args) {
217  if(!SUANPAN_PRINT) return;
218  const std::scoped_lock lock(print_mutex);
219  if(SUANPAN_COLOR) SUANPAN_CWRN << fmt::vformat(fg(fmt::color::slate_blue), pattern("[WARNING] ", file_name, format_str), fmt::make_format_args(line, args...));
220  else SUANPAN_CWRN << fmt::vformat(pattern("[WARNING] ", file_name, format_str), fmt::make_format_args(line, args...));
221  }
222 
223  template<typename... T> void error(const std::string_view file_name, const int line, const std::string_view format_str, const T&... args) {
224  if(!SUANPAN_PRINT) return;
225  const std::scoped_lock lock(print_mutex);
226  if(SUANPAN_COLOR) SUANPAN_CERR << fmt::vformat(fg(fmt::color::orange), pattern("[ERROR] ", file_name, format_str), fmt::make_format_args(line, args...));
227  else SUANPAN_CERR << fmt::vformat(pattern("[ERROR] ", file_name, format_str), fmt::make_format_args(line, args...));
228  }
229 
230  template<typename... T> void fatal(const std::string_view file_name, const int line, const std::string_view format_str, const T&... args) {
231  if(!SUANPAN_PRINT) return;
232  const std::scoped_lock lock(print_mutex);
233  if(SUANPAN_COLOR) SUANPAN_CFTL << fmt::vformat(fg(fmt::color::violet), pattern("[FATAL] ", file_name, format_str), fmt::make_format_args(line, args...));
234  else SUANPAN_CFTL << fmt::vformat(pattern("[FATAL] ", file_name, format_str), fmt::make_format_args(line, args...));
235  }
236 
237  template<typename... T> void info(const std::string_view format_str, const T&... args) {
238  if(!SUANPAN_PRINT) return;
239  const std::scoped_lock lock(print_mutex);
240  if(SUANPAN_COLOR) SUANPAN_COUT << fmt::vformat(fg(fmt::color::green_yellow), format_str, fmt::make_format_args(args...));
241  else SUANPAN_COUT << fmt::vformat(format_str, fmt::make_format_args(args...));
242  }
243 
244  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...)); }
245 
246  template<typename T> std::string format(const Col<T>& in_vec) {
247  std::string output;
248  if(std::is_floating_point_v<T>) for(const auto I : in_vec) output += format(" {: 1.4e}", I);
249  else for(const auto I : in_vec) output += format(" {:6d}", I);
250  output += '\n';
251  return output;
252  }
253 
254  template<typename T> void info(const Col<T>& in_vec) {
255  if(!SUANPAN_PRINT) return;
256  const std::scoped_lock lock(print_mutex);
257  if(SUANPAN_COLOR) SUANPAN_COUT << fmt::format(fg(fmt::color::green_yellow), format(in_vec));
258  else SUANPAN_COUT << format(in_vec);
259  }
260 
261  template<typename T> void info(const std::string_view format_str, const Col<T>& in_vec) {
262  if(!SUANPAN_PRINT) return;
263  std::string output = format(format_str);
264  if(format_str.back() != '\t' && format_str.back() != '\n') output += '\n';
265  output += format(in_vec);
266  const std::scoped_lock lock(print_mutex);
267  if(SUANPAN_COLOR) SUANPAN_COUT << fmt::format(fg(fmt::color::green_yellow), output);
268  else SUANPAN_COUT << output;
269  }
270 
271  template<typename... T> void highlight(const std::string_view format_str, const T&... args) {
272  if(!SUANPAN_PRINT) return;
273  const std::scoped_lock lock(print_mutex);
274  if(SUANPAN_COLOR) SUANPAN_COUT << fmt::vformat(fg(fmt::color::crimson), format_str, fmt::make_format_args(args...));
275  else SUANPAN_COUT << fmt::vformat(format_str, fmt::make_format_args(args...));
276  }
277 }
278 
279 #ifdef SUANPAN_MSVC
280 #pragma warning(disable : 4100)
281 #endif
282 #include <functional>
283 
284 inline void suanpan_assert(const std::function<void()>& F) {
285 #ifdef SUANPAN_DEBUG
286  F();
287 #endif
288 }
289 #ifdef SUANPAN_MSVC
290 #pragma warning(default : 4100)
291 #endif
292 
293 #define suanpan_info suanpan::info
294 #define suanpan_highlight suanpan::highlight
295 #define suanpan_debug(...) suanpan::debug(__FILE__, __LINE__, ##__VA_ARGS__)
296 #define suanpan_warning(...) suanpan::warning(__FILE__, __LINE__, ##__VA_ARGS__)
297 #define suanpan_error(...) suanpan::error(__FILE__, __LINE__, ##__VA_ARGS__)
298 #define suanpan_fatal(...) suanpan::fatal(__FILE__, __LINE__, ##__VA_ARGS__)
299 
300 #include <memory>
301 
302 using std::shared_ptr;
303 using std::unique_ptr;
304 using std::weak_ptr;
305 
306 using std::make_shared;
307 using std::make_unique;
308 
309 using std::exception;
310 using std::invalid_argument;
311 using std::logic_error;
312 using std::out_of_range;
313 
314 using std::istringstream;
315 using std::ostringstream;
316 using std::string;
317 
318 template<class T> concept sp_d = std::is_floating_point_v<T>;
319 template<class T> concept sp_i = std::is_integral_v<T>;
320 
321 namespace suanpan {
322  template<class IN, class FN> void for_all(IN& from, FN&& func) {
323  suanpan_for_each(from.begin(), from.end(), std::forward<FN>(func));
324  }
325 }
326 
327 #if defined(SUANPAN_CLANG) && !defined(__cpp_lib_ranges)
328 // as of clang 13, ranges support is not complete
329 namespace std::ranges {
330  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)); }
331 
332  template<class IN, class FN> FN for_each(IN& from, FN&& func) { return std::for_each(from.begin(), from.end(), std::forward<FN>(func)); }
333 
334  template<class IN, class OUT> OUT copy(IN& from, OUT to) { return std::copy(from.begin(), from.end(), to); }
335 } // namespace std::ranges
336 #endif
337 
338 #endif
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:201
void error(const std::string_view file_name, const int line, const std::string_view format_str, const T &... args)
Definition: suanPan.h:223
void debug(const std::string_view file_name, const int line, const std::string_view format_str, const T &... args)
Definition: suanPan.h:209
void warning(const std::string_view file_name, const int line, const std::string_view format_str, const T &... args)
Definition: suanPan.h:216
void info(const std::string_view format_str, const Col< T > &in_vec)
Definition: suanPan.h:261
void highlight(const std::string_view format_str, const T &... args)
Definition: suanPan.h:271
std::mutex print_mutex
Definition: suanPan.h:199
void for_all(IN &from, FN &&func)
Definition: suanPan.h:322
void fatal(const std::string_view file_name, const int line, const std::string_view format_str, const T &... args)
Definition: suanPan.h:230
std::string format(const Col< T > &in_vec)
Definition: suanPan.h:246
Definition: tensor.h:103
concept sp_d
Definition: suanPan.h:318
constexpr auto SUANPAN_SUCCESS
Definition: suanPan.h:162
auto & SUANPAN_COUT
Definition: suanPan.h:181
#define suanpan_for_each
Definition: suanPan.h:177
SUANPAN_EXPORT bool SUANPAN_COLOR
Definition: suanPan.h:158
#define SUANPAN_EXPORT
Definition: suanPan.h:148
constexpr auto SUANPAN_EXIT
Definition: suanPan.h:161
auto & SUANPAN_CWRN
Definition: suanPan.h:182
auto & SUANPAN_CFTL
Definition: suanPan.h:184
void suanpan_assert(const std::function< void()> &F)
Definition: suanPan.h:284
SUANPAN_EXPORT bool SUANPAN_PRINT
Definition: suanPan.h:156
constexpr auto SUANPAN_FAIL
Definition: suanPan.h:163
#define SUANPAN_IMPORT
Definition: suanPan.h:147
SUANPAN_EXPORT bool SUANPAN_VERBOSE
Definition: suanPan.h:157
concept sp_i
Definition: suanPan.h:319
auto & SUANPAN_CERR
Definition: suanPan.h:183