suanPan
Loading...
Searching...
No Matches
suanPan.h
Go to the documentation of this file.
1/*******************************************************************************
2 * Copyright (C) 2017-2025 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 SUANSPAN_64BIT_INT
46#define ARMA_BLAS_64BIT_INT
47#endif
48
49#ifdef SUANPAN_MAGMA
50#ifndef SUANPAN_CUDA
51#undef SUANPAN_MAGMA
52#endif
53#endif
54
55// SUANPAN_WIN
56// WIN32 _WIN32 __WIN32 __WIN32__ --> MSVC GCC
57#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) || defined(__WIN32__)
58#ifndef SUANPAN_WIN
59#define SUANPAN_WIN
60#endif
61#endif
62
63// SUANPAN_WIN
64#if defined(WIN64) || defined(_WIN64) || defined(__WIN64) || defined(__WIN64__)
65#ifndef SUANPAN_WIN
66#define SUANPAN_WIN
67#endif
68#endif
69
70#ifdef SUANPAN_WIN
71#ifndef NOMINMAX
72#define NOMINMAX
73#endif
74#endif
75
76// SUANPAN_UNIX
77#if defined(unix) || defined(__unix__) || defined(__linux__) || defined(linux)
78#ifndef SUANPAN_UNIX
79#define SUANPAN_UNIX
80#endif
81#endif
82
83#ifdef SUANPAN_VERSION
84#undef SUANPAN_VERSION
85#endif
86#ifdef SUANPAN_COMPILER
87#undef SUANPAN_COMPILER
88#endif
89
90// SUANPAN_VERSION SUANPAN_COMPILER
91#ifdef __clang__
92// __clang__ --> clang
93#ifdef SUANPAN_VERSION
94#undef SUANPAN_VERSION
95#endif
96#define SUANPAN_VERSION __VERSION__
97#ifdef SUANPAN_COMPILER
98#undef SUANPAN_COMPILER
99#endif
100#define SUANPAN_COMPILER "CLANG"
101#define SUANPAN_CLANG
102#elif defined(__GNUG__)
103// __GNUG__ --> GCC
104#define SUANPAN_VERSION __VERSION__
105#define SUANPAN_COMPILER "GCC"
106#define SUANPAN_GCC
107#elif defined(_MSC_BUILD)
108// _MSC_BUILD --> MSVC
109#define SUANPAN_VERSION _MSC_FULL_VER
110#define SUANPAN_COMPILER "MSVC"
111#define SUANPAN_MSVC
112// unknown pragma 'GCC'
113#pragma warning(disable : 4068)
114// cuda unused local function
115#pragma warning(disable : 4505)
116// conditional expression is constant
117#pragma warning(disable : 4127)
118#elif defined(__ICC)
119// __ICC --> Intel C++
120#define SUANPAN_VERSION __ICC
121#define SUANPAN_COMPILER "INTEL"
122#define SUANPAN_INTEL
123#ifdef SUANPAN_WIN
124#undef SUANPAN_WIN
125#endif
126#ifndef SUANPAN_UNIX
127#define SUANPAN_UNIX
128#endif
129#elif defined(__ICL)
130// __ICL --> Intel C++
131#define SUANPAN_VERSION __ICL
132#define SUANPAN_COMPILER "INTEL"
133#define SUANPAN_INTEL
134#ifdef SUANPAN_UNIX
135#undef SUANPAN_UNIX
136#endif
137#ifndef SUANPAN_WIN
138#define SUANPAN_WIN
139#endif
140#endif
141
142// _USRDLL --> MSVC
143#ifdef _USRDLL
144#ifndef SUANPAN_DLL
145#define SUANPAN_DLL
146#endif
147#endif
148
149#ifdef SUANPAN_WIN
150// WIN MSVC GCC IMPORT
151#define SUANPAN_IMPORT extern "C" __declspec(dllimport)
152// WIN MSVC GCC EXPORT
153#define SUANPAN_EXPORT extern "C" __declspec(dllexport)
154#elif defined(SUANPAN_UNIX)
155// UNIX GCC IMPORT
156#define SUANPAN_IMPORT extern "C"
157// UNIX GCC EXPORT
158#define SUANPAN_EXPORT extern "C"
159#else
160// EMPTY
161#define SUANPAN_IMPORT extern "C"
162#define SUANPAN_EXPORT extern "C"
163#endif
164
165#ifdef SUANPAN_DLL
171#else
177#endif
178
179constexpr auto SUANPAN_EXIT = 1;
180constexpr auto SUANPAN_SUCCESS = 0;
181constexpr auto SUANPAN_FAIL = -1;
182
183// TWO IMPLEMENTATIONS
184#ifndef SUANPAN_WIN
185#define _strcmpi strcasecmp
186#endif
187
188#ifdef SUANPAN_MT
189#include <oneapi/tbb/parallel_for_each.h>
190#include <oneapi/tbb/parallel_sort.h>
191#define suanpan_sort tbb::parallel_sort
192#define suanpan_for_each tbb::parallel_for_each
193#else
194#define suanpan_sort std::sort
195#define suanpan_for_each std::for_each
196#endif
197
198#include <iostream>
199inline auto& SUANPAN_COUT = std::cout;
200inline auto& SUANPAN_CWRN = std::cout;
201inline auto& SUANPAN_CERR = std::cout;
202inline auto& SUANPAN_CFTL = std::cout;
203
204#define ARMA_COUT_STREAM SUANPAN_COUT
205#define ARMA_CERR_STREAM SUANPAN_COUT
206
207#include <armadillo/armadillo>
208// extra bits used in calling lapack subroutines
209#include <armadillo/ext_def_lapack.hpp>
210using namespace arma;
211
212#include <filesystem>
213namespace fs = std::filesystem;
214
215#ifdef SUANPAN_DISTRIBUTED
216#include <mpl/mpl.hpp>
217
218inline auto& comm_world{mpl::environment::comm_world()};
219inline const auto comm_rank{comm_world.rank()};
220inline const auto comm_size{comm_world.size()};
221
222template<typename T> concept mpl_floating_t = std::is_same_v<T, float> || std::is_same_v<T, double>;
223template<typename T> concept mpl_complex_t = std::is_same_v<T, std::complex<typename T::value_type>> && mpl_floating_t<typename T::value_type>;
224template<typename T> concept mpl_data_t = mpl_floating_t<T> || mpl_complex_t<T>;
225
226template<typename T> requires std::is_arithmetic_v<T> auto bcast_from_root(T object) {
227 comm_world.bcast(0, object);
228 return object;
229}
230
231template<mpl_data_t T> auto& bcast_from_root(const Mat<T>& object) {
232 comm_world.bcast(0, const_cast<T*>(object.memptr()), mpl::contiguous_layout<T>{object.n_elem});
233 return object;
234}
235
236template<typename T> requires std::is_arithmetic_v<T> auto allreduce(T object) {
237 comm_world.allreduce(mpl::plus<T>(), object);
238 return object;
239}
240
241template<mpl_data_t T> auto& allreduce(const Mat<T>& object) {
242 comm_world.allreduce(mpl::plus<T>(), const_cast<T*>(object.memptr()), mpl::contiguous_layout<T>{object.n_elem});
243 return object;
244}
245
246template<mpl_data_t T> auto& reduce(const Mat<T>& object) {
247 comm_world.reduce(mpl::plus<T>(), 0, const_cast<T*>(object.memptr()), mpl::contiguous_layout<T>{object.n_elem});
248 return object;
249}
250#else
251inline constexpr auto comm_rank{0};
252inline constexpr auto comm_size{1};
253
254template<typename T> auto bcast_from_root(T&& object) { return std::forward<T>(object); }
255
256template<typename T> auto allreduce(T&& object) { return std::forward<T>(object); }
257
258template<typename T> auto reduce(T&& object) { return std::forward<T>(object); }
259#endif
260
261#include <fmt/color.h>
262#include <mutex>
263
264namespace suanpan {
265 inline std::mutex print_mutex;
266
267 inline std::string pattern(const std::string_view header, const std::string_view file_name, const std::string_view format) {
268 std::string pattern;
269 // ReSharper disable once CppIfCanBeReplacedByConstexprIf
270 // ReSharper disable once CppDFAConstantConditions
271 if(comm_size > 1) {
272 // ReSharper disable once CppDFAUnreachableCode
273 pattern += "[P";
274 pattern += std::to_string(comm_rank);
275 pattern += "] ";
276 }
277 pattern += header;
278 pattern += fs::path(file_name).filename().string();
279 pattern += ":{} ~> ";
280 pattern += format;
281 return pattern;
282 }
283
284 template<typename... T> void debug(const std::string_view file_name, const int line, const std::string_view format_str, const T&... args) {
285 if(!SUANPAN_VERBOSE || !SUANPAN_PRINT) return;
286 const std::scoped_lock lock(print_mutex);
287 if(SUANPAN_COLOR) SUANPAN_COUT << fmt::vformat(fg(fmt::color::coral), pattern("[DEBUG] ", file_name, format_str), fmt::make_format_args(line, args...));
288 else SUANPAN_COUT << fmt::vformat(pattern("[DEBUG] ", file_name, format_str), fmt::make_format_args(line, args...));
289 }
290
291 template<typename... T> void warning(const std::string_view file_name, const int line, const std::string_view format_str, const T&... args) {
293 if(!SUANPAN_PRINT) return;
294 const std::scoped_lock lock(print_mutex);
295 if(SUANPAN_COLOR) SUANPAN_CWRN << fmt::vformat(fg(fmt::color::slate_blue), pattern("[WARNING] ", file_name, format_str), fmt::make_format_args(line, args...));
296 else SUANPAN_CWRN << fmt::vformat(pattern("[WARNING] ", file_name, format_str), fmt::make_format_args(line, args...));
297 }
298
299 template<typename... T> void error(const std::string_view file_name, const int line, const std::string_view format_str, const T&... args) {
301 if(!SUANPAN_PRINT) return;
302 const std::scoped_lock lock(print_mutex);
303 if(SUANPAN_COLOR) SUANPAN_CERR << fmt::vformat(fg(fmt::color::orange), pattern("[ERROR] ", file_name, format_str), fmt::make_format_args(line, args...));
304 else SUANPAN_CERR << fmt::vformat(pattern("[ERROR] ", file_name, format_str), fmt::make_format_args(line, args...));
305 }
306
307 template<typename... T> void fatal(const std::string_view file_name, const int line, const std::string_view format_str, const T&... args) {
308 if(!SUANPAN_PRINT) return;
309 const std::scoped_lock lock(print_mutex);
310 if(SUANPAN_COLOR) SUANPAN_CFTL << fmt::vformat(fg(fmt::color::violet), pattern("[FATAL] ", file_name, format_str), fmt::make_format_args(line, args...));
311 else SUANPAN_CFTL << fmt::vformat(pattern("[FATAL] ", file_name, format_str), fmt::make_format_args(line, args...));
312 }
313
314 template<typename... T> void info(const std::string_view format_sv, const T&... args) {
315 if(!SUANPAN_PRINT) return;
316 const std::scoped_lock lock(print_mutex);
317 if(SUANPAN_COLOR) SUANPAN_COUT << fmt::vformat(fg(fmt::color::green_yellow), format_sv, fmt::make_format_args(args...));
318 else SUANPAN_COUT << fmt::vformat(format_sv, fmt::make_format_args(args...));
319 }
320
321 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...)); }
322
323 template<typename T> std::string format(const Col<T>& in_vec) {
324 std::string output;
325 if(std::is_floating_point_v<T>)
326 for(const auto I : in_vec) output += format(" {: 1.4e}", I);
327 else
328 for(const auto I : in_vec) output += format(" {:6d}", I);
329 output += '\n';
330 return output;
331 }
332
333 template<typename T> void info(const Col<T>& in_vec) {
334 if(!SUANPAN_PRINT) return;
335 const std::scoped_lock lock(print_mutex);
336 if(SUANPAN_COLOR) SUANPAN_COUT << fmt::format(fg(fmt::color::green_yellow), format(in_vec));
337 else SUANPAN_COUT << format(in_vec);
338 }
339
340 template<typename T> void info(const std::string_view format_sv, const Col<T>& in_vec) {
341 if(!SUANPAN_PRINT) return;
342 std::string output{format(format_sv)};
343 if(format_sv.back() != '\t' && format_sv.back() != '\n') output += '\n';
344 output += format(in_vec);
345 const std::scoped_lock lock(print_mutex);
346 if(SUANPAN_COLOR) SUANPAN_COUT << fmt::format(fg(fmt::color::green_yellow), output);
347 else SUANPAN_COUT << output;
348 }
349
350 template<typename... T> void highlight(const std::string_view format_sv, const T&... args) {
351 if(!SUANPAN_PRINT) return;
352 const std::scoped_lock lock(print_mutex);
353 if(SUANPAN_COLOR) SUANPAN_COUT << fmt::vformat(fg(fmt::color::crimson), format_sv, fmt::make_format_args(args...));
354 else SUANPAN_COUT << fmt::vformat(format_sv, fmt::make_format_args(args...));
355 }
356} // namespace suanpan
357
358#ifdef SUANPAN_MSVC
359#pragma warning(disable : 4100)
360#endif
361#include <functional>
362
363inline void suanpan_assert(const std::function<void()>& F) {
364#ifdef SUANPAN_DEBUG
365 F();
366#endif
367}
368#ifdef SUANPAN_MSVC
369#pragma warning(default : 4100)
370#endif
371
372#define suanpan_info suanpan::info
373#define suanpan_highlight suanpan::highlight
374#define suanpan_debug(...) suanpan::debug(__FILE__, __LINE__, ##__VA_ARGS__)
375#define suanpan_warning(...) suanpan::warning(__FILE__, __LINE__, ##__VA_ARGS__)
376#define suanpan_error(...) suanpan::error(__FILE__, __LINE__, ##__VA_ARGS__)
377#define suanpan_fatal(...) suanpan::fatal(__FILE__, __LINE__, ##__VA_ARGS__)
378
379#include <memory>
380
381using std::shared_ptr;
382using std::unique_ptr;
383
384template<class T> concept sp_d = std::is_same_v<T, float> || std::is_same_v<T, double>;
385template<class T> concept sp_i = std::is_integral_v<T>;
386
387template<typename T, typename U> concept is_arma_mat = sp_d<T> && (std::is_convertible_v<std::remove_cvref_t<U>, Mat<T>> || std::is_convertible_v<std::remove_cvref_t<U>, SpMat<T>>);
388
389namespace suanpan {
390 template<class IN, class FN> requires requires(IN& x) { x.begin(); x.end(); } void for_all(IN& from, FN&& func) {
391 suanpan_for_each(from.begin(), from.end(), std::forward<FN>(func));
392 }
393} // namespace suanpan
394
395#if defined(SUANPAN_CLANG) && !defined(__cpp_lib_ranges)
396// as of clang 13, ranges support is not complete
397namespace std::ranges {
398 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)); }
399
400 template<class IN, class FN> FN for_each(IN& from, FN&& func) { return std::for_each(from.begin(), from.end(), std::forward<FN>(func)); }
401
402 template<class IN, class FN> bool any_of(const IN& from, FN&& func) { return std::any_of(from.cbegin(), from.cend(), std::forward<FN>(func)); }
403
404 template<class IN, class OUT> OUT copy(IN& from, OUT to) { return std::copy(from.begin(), from.end(), to); }
405} // namespace std::ranges
406#endif
407
408template<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"); }
409
410#endif
Definition suanPan.h:387
Definition suanPan.h:384
Definition suanPan.h:385
void object(unique_ptr< T > &new_object, const shared_ptr< DomainBase > &domain, const std::string &id, std::istringstream &command)
Definition ExternalModule.h:79
Definition SparseMatMAGMA.hpp:43
void info(const std::string_view format_sv, const T &... args)
Definition suanPan.h:314
void error(const std::string_view file_name, const int line, const std::string_view format_str, const T &... args)
Definition suanPan.h:299
void debug(const std::string_view file_name, const int line, const std::string_view format_str, const T &... args)
Definition suanPan.h:284
std::string format(const std::string_view format_str, const T &... args)
Definition suanPan.h:321
void warning(const std::string_view file_name, const int line, const std::string_view format_str, const T &... args)
Definition suanPan.h:291
void for_all(IN &from, FN &&func)
Definition suanPan.h:390
std::mutex print_mutex
Definition suanPan.h:265
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:307
std::string pattern(const std::string_view header, const std::string_view file_name, const std::string_view format)
Definition suanPan.h:267
void highlight(const std::string_view format_sv, const T &... args)
Definition suanPan.h:350
Definition tensor.h:120
auto allreduce(T &&object)
Definition suanPan.h:256
constexpr auto comm_rank
Definition suanPan.h:251
constexpr auto SUANPAN_SUCCESS
Definition suanPan.h:180
auto & SUANPAN_COUT
Definition suanPan.h:199
#define suanpan_for_each
Definition suanPan.h:195
SUANPAN_EXPORT bool SUANPAN_COLOR
Definition suanPan.h:174
#define SUANPAN_EXPORT
Definition suanPan.h:162
constexpr auto SUANPAN_EXIT
Definition suanPan.h:179
constexpr auto comm_size
Definition suanPan.h:252
auto & SUANPAN_CWRN
Definition suanPan.h:200
auto & SUANPAN_CFTL
Definition suanPan.h:202
void suanpan_assert(const std::function< void()> &F)
Definition suanPan.h:363
SUANPAN_EXPORT bool SUANPAN_PRINT
Definition suanPan.h:172
constexpr auto SUANPAN_FAIL
Definition suanPan.h:181
SUANPAN_EXPORT unsigned SUANPAN_ERROR_COUNT
Definition suanPan.h:176
enable_if2< is_arma_type< T1 >::value, typenameT1::pod_type >::result inf_norm(const T1 &X)
Definition suanPan.h:408
auto reduce(T &&object)
Definition suanPan.h:258
#define SUANPAN_IMPORT
Definition suanPan.h:161
SUANPAN_EXPORT bool SUANPAN_VERBOSE
Definition suanPan.h:173
SUANPAN_EXPORT unsigned SUANPAN_WARNING_COUNT
Definition suanPan.h:175
auto bcast_from_root(T &&object)
Definition suanPan.h:254
auto & SUANPAN_CERR
Definition suanPan.h:201