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>
208using namespace arma;
209
210#include <filesystem>
211namespace fs = std::filesystem;
212
213#ifdef SUANPAN_DISTRIBUTED
214#include <mpl/mpl.hpp>
215
216inline auto& comm_world{mpl::environment::comm_world()};
217inline const auto comm_rank{comm_world.rank()};
218inline const auto comm_size{comm_world.size()};
219
220template<typename T> concept mpl_floating_t = std::is_same_v<T, float> || std::is_same_v<T, double>;
221template<typename T> concept mpl_complex_t = std::is_same_v<T, std::complex<typename T::value_type>> && mpl_floating_t<typename T::value_type>;
222template<typename T> concept mpl_data_t = mpl_floating_t<T> || mpl_complex_t<T>;
223
224template<typename T> requires std::is_arithmetic_v<T> auto bcast_from_root(T object) {
225 comm_world.bcast(0, object);
226 return object;
227}
228
229template<mpl_data_t T> auto& bcast_from_root(const Mat<T>& object) {
230 comm_world.bcast(0, const_cast<T*>(object.memptr()), mpl::contiguous_layout<T>{object.n_elem});
231 return object;
232}
233
234template<typename T> requires std::is_arithmetic_v<T> auto allreduce(T object) {
235 comm_world.allreduce(mpl::plus<T>(), object);
236 return object;
237}
238
239template<mpl_data_t T> auto& allreduce(const Mat<T>& object) {
240 comm_world.allreduce(mpl::plus<T>(), const_cast<T*>(object.memptr()), mpl::contiguous_layout<T>{object.n_elem});
241 return object;
242}
243
244template<mpl_data_t T> auto& reduce(const Mat<T>& object) {
245 comm_world.reduce(mpl::plus<T>(), 0, const_cast<T*>(object.memptr()), mpl::contiguous_layout<T>{object.n_elem});
246 return object;
247}
248#else
249inline constexpr auto comm_rank{0};
250inline constexpr auto comm_size{1};
251
252template<typename T> auto bcast_from_root(T&& object) { return std::forward<T>(object); }
253
254template<typename T> auto allreduce(T&& object) { return std::forward<T>(object); }
255
256template<typename T> auto reduce(T&& object) { return std::forward<T>(object); }
257#endif
258
259#include <fmt/color.h>
260#include <mutex>
261
262namespace suanpan {
263 inline std::mutex print_mutex;
264
265 inline std::string pattern(const std::string_view header, const std::string_view file_name, const std::string_view format) {
266 std::string pattern;
267 // ReSharper disable once CppIfCanBeReplacedByConstexprIf
268 // ReSharper disable once CppDFAConstantConditions
269 if(comm_size > 1) {
270 // ReSharper disable once CppDFAUnreachableCode
271 pattern += "[P";
272 pattern += std::to_string(comm_rank);
273 pattern += "] ";
274 }
275 pattern += header;
276 pattern += fs::path(file_name).filename().string();
277 pattern += ":{} ~> ";
278 pattern += format;
279 return pattern;
280 }
281
282 template<typename... T> void debug(const std::string_view file_name, const int line, const std::string_view format_str, const T&... args) {
283 if(!SUANPAN_VERBOSE || !SUANPAN_PRINT) return;
284 const std::scoped_lock lock(print_mutex);
285 if(SUANPAN_COLOR) SUANPAN_COUT << fmt::vformat(fg(fmt::color::coral), pattern("[DEBUG] ", file_name, format_str), fmt::make_format_args(line, args...));
286 else SUANPAN_COUT << fmt::vformat(pattern("[DEBUG] ", file_name, format_str), fmt::make_format_args(line, args...));
287 }
288
289 template<typename... T> void warning(const std::string_view file_name, const int line, const std::string_view format_str, const T&... args) {
291 if(!SUANPAN_PRINT) return;
292 const std::scoped_lock lock(print_mutex);
293 if(SUANPAN_COLOR) SUANPAN_CWRN << fmt::vformat(fg(fmt::color::slate_blue), pattern("[WARNING] ", file_name, format_str), fmt::make_format_args(line, args...));
294 else SUANPAN_CWRN << fmt::vformat(pattern("[WARNING] ", file_name, format_str), fmt::make_format_args(line, args...));
295 }
296
297 template<typename... T> void error(const std::string_view file_name, const int line, const std::string_view format_str, const T&... args) {
299 if(!SUANPAN_PRINT) return;
300 const std::scoped_lock lock(print_mutex);
301 if(SUANPAN_COLOR) SUANPAN_CERR << fmt::vformat(fg(fmt::color::orange), pattern("[ERROR] ", file_name, format_str), fmt::make_format_args(line, args...));
302 else SUANPAN_CERR << fmt::vformat(pattern("[ERROR] ", file_name, format_str), fmt::make_format_args(line, args...));
303 }
304
305 template<typename... T> void fatal(const std::string_view file_name, const int line, const std::string_view format_str, const T&... args) {
306 if(!SUANPAN_PRINT) return;
307 const std::scoped_lock lock(print_mutex);
308 if(SUANPAN_COLOR) SUANPAN_CFTL << fmt::vformat(fg(fmt::color::violet), pattern("[FATAL] ", file_name, format_str), fmt::make_format_args(line, args...));
309 else SUANPAN_CFTL << fmt::vformat(pattern("[FATAL] ", file_name, format_str), fmt::make_format_args(line, args...));
310 }
311
312 template<typename... T> void info(const std::string_view format_sv, const T&... args) {
313 if(!SUANPAN_PRINT) return;
314 const std::scoped_lock lock(print_mutex);
315 if(SUANPAN_COLOR) SUANPAN_COUT << fmt::vformat(fg(fmt::color::green_yellow), format_sv, fmt::make_format_args(args...));
316 else SUANPAN_COUT << fmt::vformat(format_sv, fmt::make_format_args(args...));
317 }
318
319 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...)); }
320
321 template<typename T> std::string format(const Col<T>& in_vec) {
322 std::string output;
323 if(std::is_floating_point_v<T>)
324 for(const auto I : in_vec) output += format(" {: 1.4e}", I);
325 else
326 for(const auto I : in_vec) output += format(" {:6d}", I);
327 output += '\n';
328 return output;
329 }
330
331 template<typename T> void info(const Col<T>& in_vec) {
332 if(!SUANPAN_PRINT) return;
333 const std::scoped_lock lock(print_mutex);
334 if(SUANPAN_COLOR) SUANPAN_COUT << fmt::format(fg(fmt::color::green_yellow), format(in_vec));
335 else SUANPAN_COUT << format(in_vec);
336 }
337
338 template<typename T> void info(const std::string_view format_sv, const Col<T>& in_vec) {
339 if(!SUANPAN_PRINT) return;
340 std::string output{format(format_sv)};
341 if(format_sv.back() != '\t' && format_sv.back() != '\n') output += '\n';
342 output += format(in_vec);
343 const std::scoped_lock lock(print_mutex);
344 if(SUANPAN_COLOR) SUANPAN_COUT << fmt::format(fg(fmt::color::green_yellow), output);
345 else SUANPAN_COUT << output;
346 }
347
348 template<typename... T> void highlight(const std::string_view format_sv, const T&... args) {
349 if(!SUANPAN_PRINT) return;
350 const std::scoped_lock lock(print_mutex);
351 if(SUANPAN_COLOR) SUANPAN_COUT << fmt::vformat(fg(fmt::color::crimson), format_sv, fmt::make_format_args(args...));
352 else SUANPAN_COUT << fmt::vformat(format_sv, fmt::make_format_args(args...));
353 }
354} // namespace suanpan
355
356#ifdef SUANPAN_MSVC
357#pragma warning(disable : 4100)
358#endif
359#include <functional>
360
361inline void suanpan_assert(const std::function<void()>& F) {
362#ifdef SUANPAN_DEBUG
363 F();
364#endif
365}
366#ifdef SUANPAN_MSVC
367#pragma warning(default : 4100)
368#endif
369
370#define suanpan_info suanpan::info
371#define suanpan_highlight suanpan::highlight
372#define suanpan_debug(...) suanpan::debug(__FILE__, __LINE__, ##__VA_ARGS__)
373#define suanpan_warning(...) suanpan::warning(__FILE__, __LINE__, ##__VA_ARGS__)
374#define suanpan_error(...) suanpan::error(__FILE__, __LINE__, ##__VA_ARGS__)
375#define suanpan_fatal(...) suanpan::fatal(__FILE__, __LINE__, ##__VA_ARGS__)
376
377#include <memory>
378
379using std::shared_ptr;
380using std::unique_ptr;
381
382template<class T> concept sp_d = std::is_same_v<T, float> || std::is_same_v<T, double>;
383template<class T> concept sp_i = std::is_integral_v<T>;
384
385template<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>>);
386
387namespace suanpan {
388 template<class IN, class FN> requires requires(IN& x) { x.begin(); x.end(); } void for_all(IN& from, FN&& func) {
389 suanpan_for_each(from.begin(), from.end(), std::forward<FN>(func));
390 }
391} // namespace suanpan
392
393#if defined(SUANPAN_CLANG) && !defined(__cpp_lib_ranges)
394// as of clang 13, ranges support is not complete
395namespace std::ranges {
396 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)); }
397
398 template<class IN, class FN> FN for_each(IN& from, FN&& func) { return std::for_each(from.begin(), from.end(), std::forward<FN>(func)); }
399
400 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)); }
401
402 template<class IN, class OUT> OUT copy(IN& from, OUT to) { return std::copy(from.begin(), from.end(), to); }
403} // namespace std::ranges
404#endif
405
406template<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"); }
407
408#endif
Definition suanPan.h:385
Definition suanPan.h:382
Definition suanPan.h:383
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:312
void error(const std::string_view file_name, const int line, const std::string_view format_str, const T &... args)
Definition suanPan.h:297
void debug(const std::string_view file_name, const int line, const std::string_view format_str, const T &... args)
Definition suanPan.h:282
std::string format(const std::string_view format_str, const T &... args)
Definition suanPan.h:319
void warning(const std::string_view file_name, const int line, const std::string_view format_str, const T &... args)
Definition suanPan.h:289
void for_all(IN &from, FN &&func)
Definition suanPan.h:388
std::mutex print_mutex
Definition suanPan.h:263
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:305
std::string pattern(const std::string_view header, const std::string_view file_name, const std::string_view format)
Definition suanPan.h:265
void highlight(const std::string_view format_sv, const T &... args)
Definition suanPan.h:348
Definition tensor.h:122
auto allreduce(T &&object)
Definition suanPan.h:254
constexpr auto comm_rank
Definition suanPan.h:249
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:250
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:361
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:406
auto reduce(T &&object)
Definition suanPan.h:256
#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:252
auto & SUANPAN_CERR
Definition suanPan.h:201