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 if(comm_size > 1) {
269 // ReSharper disable once CppDFAUnreachableCode
270 pattern += "[P";
271 pattern += std::to_string(comm_rank);
272 pattern += "] ";
273 }
274 pattern += header;
275 pattern += fs::path(file_name).filename().string();
276 pattern += ":{} ~> ";
277 pattern += format;
278 return pattern;
279 }
280
281 template<typename... T> void debug(const std::string_view file_name, const int line, const std::string_view format_str, const T&... args) {
282 if(!SUANPAN_VERBOSE || !SUANPAN_PRINT) return;
283 const std::scoped_lock lock(print_mutex);
284 if(SUANPAN_COLOR) SUANPAN_COUT << fmt::vformat(fg(fmt::color::coral), pattern("[DEBUG] ", file_name, format_str), fmt::make_format_args(line, args...));
285 else SUANPAN_COUT << fmt::vformat(pattern("[DEBUG] ", file_name, format_str), fmt::make_format_args(line, args...));
286 }
287
288 template<typename... T> void warning(const std::string_view file_name, const int line, const std::string_view format_str, const T&... args) {
290 if(!SUANPAN_PRINT) return;
291 const std::scoped_lock lock(print_mutex);
292 if(SUANPAN_COLOR) SUANPAN_CWRN << fmt::vformat(fg(fmt::color::slate_blue), pattern("[WARNING] ", file_name, format_str), fmt::make_format_args(line, args...));
293 else SUANPAN_CWRN << fmt::vformat(pattern("[WARNING] ", file_name, format_str), fmt::make_format_args(line, args...));
294 }
295
296 template<typename... T> void error(const std::string_view file_name, const int line, const std::string_view format_str, const T&... args) {
298 if(!SUANPAN_PRINT) return;
299 const std::scoped_lock lock(print_mutex);
300 if(SUANPAN_COLOR) SUANPAN_CERR << fmt::vformat(fg(fmt::color::orange), pattern("[ERROR] ", file_name, format_str), fmt::make_format_args(line, args...));
301 else SUANPAN_CERR << fmt::vformat(pattern("[ERROR] ", file_name, format_str), fmt::make_format_args(line, args...));
302 }
303
304 template<typename... T> void fatal(const std::string_view file_name, const int line, const std::string_view format_str, const T&... args) {
305 if(!SUANPAN_PRINT) return;
306 const std::scoped_lock lock(print_mutex);
307 if(SUANPAN_COLOR) SUANPAN_CFTL << fmt::vformat(fg(fmt::color::violet), pattern("[FATAL] ", file_name, format_str), fmt::make_format_args(line, args...));
308 else SUANPAN_CFTL << fmt::vformat(pattern("[FATAL] ", file_name, format_str), fmt::make_format_args(line, args...));
309 }
310
311 template<typename... T> void info(const std::string_view format_sv, const T&... args) {
312 if(!SUANPAN_PRINT) return;
313 const std::scoped_lock lock(print_mutex);
314 if(SUANPAN_COLOR) SUANPAN_COUT << fmt::vformat(fg(fmt::color::green_yellow), format_sv, fmt::make_format_args(args...));
315 else SUANPAN_COUT << fmt::vformat(format_sv, fmt::make_format_args(args...));
316 }
317
318 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...)); }
319
320 template<typename T> std::string format(const Col<T>& in_vec) {
321 std::string output;
322 if(std::is_floating_point_v<T>)
323 for(const auto I : in_vec) output += format(" {: 1.4e}", I);
324 else
325 for(const auto I : in_vec) output += format(" {:6d}", I);
326 output += '\n';
327 return output;
328 }
329
330 template<typename T> void info(const Col<T>& in_vec) {
331 if(!SUANPAN_PRINT) return;
332 const std::scoped_lock lock(print_mutex);
333 if(SUANPAN_COLOR) SUANPAN_COUT << fmt::format(fg(fmt::color::green_yellow), format(in_vec));
334 else SUANPAN_COUT << format(in_vec);
335 }
336
337 template<typename T> void info(const std::string_view format_sv, const Col<T>& in_vec) {
338 if(!SUANPAN_PRINT) return;
339 std::string output{format(format_sv)};
340 if(format_sv.back() != '\t' && format_sv.back() != '\n') output += '\n';
341 output += format(in_vec);
342 const std::scoped_lock lock(print_mutex);
343 if(SUANPAN_COLOR) SUANPAN_COUT << fmt::format(fg(fmt::color::green_yellow), output);
344 else SUANPAN_COUT << output;
345 }
346
347 template<typename... T> void highlight(const std::string_view format_sv, const T&... args) {
348 if(!SUANPAN_PRINT) return;
349 const std::scoped_lock lock(print_mutex);
350 if(SUANPAN_COLOR) SUANPAN_COUT << fmt::vformat(fg(fmt::color::crimson), format_sv, fmt::make_format_args(args...));
351 else SUANPAN_COUT << fmt::vformat(format_sv, fmt::make_format_args(args...));
352 }
353} // namespace suanpan
354
355#ifdef SUANPAN_MSVC
356#pragma warning(disable : 4100)
357#endif
358#include <functional>
359
360inline void suanpan_assert(const std::function<void()>& F) {
361#ifdef SUANPAN_DEBUG
362 F();
363#endif
364}
365#ifdef SUANPAN_MSVC
366#pragma warning(default : 4100)
367#endif
368
369#define suanpan_info suanpan::info
370#define suanpan_highlight suanpan::highlight
371#define suanpan_debug(...) suanpan::debug(__FILE__, __LINE__, ##__VA_ARGS__)
372#define suanpan_warning(...) suanpan::warning(__FILE__, __LINE__, ##__VA_ARGS__)
373#define suanpan_error(...) suanpan::error(__FILE__, __LINE__, ##__VA_ARGS__)
374#define suanpan_fatal(...) suanpan::fatal(__FILE__, __LINE__, ##__VA_ARGS__)
375
376#include <memory>
377
378using std::shared_ptr;
379using std::unique_ptr;
380using std::weak_ptr;
381
382using std::make_shared;
383using std::make_unique;
384
385using std::exception;
386using std::invalid_argument;
387using std::logic_error;
388using std::out_of_range;
389
390using std::istringstream;
391using std::ostringstream;
392using std::string;
393
394template<class T> concept sp_d = std::is_same_v<T, float> || std::is_same_v<T, double>;
395template<class T> concept sp_i = std::is_integral_v<T>;
396
397template<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>>);
398
399namespace suanpan {
400 template<class IN, class FN> requires requires(IN& x) { x.begin(); x.end(); } void for_all(IN& from, FN&& func) {
401 suanpan_for_each(from.begin(), from.end(), std::forward<FN>(func));
402 }
403} // namespace suanpan
404
405#if defined(SUANPAN_CLANG) && !defined(__cpp_lib_ranges)
406// as of clang 13, ranges support is not complete
407namespace std::ranges {
408 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)); }
409
410 template<class IN, class FN> FN for_each(IN& from, FN&& func) { return std::for_each(from.begin(), from.end(), std::forward<FN>(func)); }
411
412 template<class IN, class OUT> OUT copy(IN& from, OUT to) { return std::copy(from.begin(), from.end(), to); }
413} // namespace std::ranges
414#endif
415
416template<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"); }
417
418#endif
Definition suanPan.h:397
Definition suanPan.h:394
Definition suanPan.h:395
Definition MatrixModifier.hpp:36
void info(const std::string_view format_sv, const T &... args)
Definition suanPan.h:311
void error(const std::string_view file_name, const int line, const std::string_view format_str, const T &... args)
Definition suanPan.h:296
void debug(const std::string_view file_name, const int line, const std::string_view format_str, const T &... args)
Definition suanPan.h:281
std::string format(const std::string_view format_str, const T &... args)
Definition suanPan.h:318
void warning(const std::string_view file_name, const int line, const std::string_view format_str, const T &... args)
Definition suanPan.h:288
void for_all(IN &from, FN &&func)
Definition suanPan.h:400
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:304
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:347
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:360
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:416
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