FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
runtime.cpp
1// FEAT3: Finite Element Analysis Toolbox, Version 3
2// Copyright (C) 2010 by Stefan Turek & the FEAT group
3// FEAT3 is released under the GNU General Public License version 3,
4// see the file 'copyright.txt' in the top level directory for details.
5
7#include <kernel/runtime.hpp>
9#include <kernel/util/dist.hpp>
10#include <kernel/util/memory_pool.hpp>
11#include <kernel/util/os_windows.hpp>
13#ifdef FEAT_HAVE_DEATH_HANDLER
14#include <death_handler.h>
15#endif
16
17#include <cstdlib>
18#include <fstream>
19#include <cstring>
20#include <cstdlib>
21
22#if defined(__linux) || defined(__unix__)
23#include <sys/types.h>
24#include <unistd.h>
25#include <execinfo.h>
26#endif
27
28#ifdef FEAT_HAVE_MPI
29#include <mpi.h>
30#endif
31
32#ifdef FEAT_HAVE_CUDA
33#include <kernel/util/cuda_util.hpp>
34#endif
35
36#ifdef FEAT_HAVE_CUDSS
37#include <cudss.h>
38#endif
39
40using namespace FEAT;
41
42// static member initialization
43bool Runtime::_initialized = false;
44bool Runtime::_finalized = false;
45bool Runtime::SyncGuard::sync_on = true;
46
47#ifdef FEAT_HAVE_CUDSS
48static cudssHandle_t feat_cudss_handle = nullptr;
49#endif
50
51void Runtime::initialize(int& argc, char**& argv)
52{
57#if defined(_WIN32) && defined(FEAT_TESTING_VC)
60#endif
61
62 if (_initialized)
63 {
64 std::cerr << "ERROR: Runtime::initialize called twice!\n";
65 std::cerr.flush();
67 }
68 if (_finalized)
69 {
70 std::cerr << "ERROR: Runtime::initialize called after Runtime::finalize!\n";
71 std::cerr.flush();
73 }
74
75 // initialize Dist operations
76 if(!Dist::initialize(argc, argv))
77 {
78 std::cerr << "ERROR: Failed to initialize Dist operations!\n";
79 std::cerr.flush();
81 }
82
83 // get the MPI world comm rank of this process
84 const int my_rank = Dist::Comm::world().rank();
85
86 // initialize likwid marker api
88 // initialize memory pool for main memory
90
91#ifdef FEAT_HAVE_CUDA
92 // initialize memory pool for CUDA memory
93 Util::cuda_initialize(my_rank, 1, 1, Util::cuda_get_device_count());
94 Util::cuda_set_blocksize(256, 256, 256, 256, 256, 128);
95#endif
96
97#ifdef FEAT_HAVE_CUDSS
98 if(CUDSS_STATUS_SUCCESS != cudssCreate(&feat_cudss_handle))
99 {
100 std::cerr << "ERROR: Failed to initialize cuDSS handle!\n";
101 std::cerr.flush();
103 }
104#endif
105
106 // check whether '---debug [<ranks...>]' option is given
107 // if so, then trigger a breakpoint for the specified ranks
108 for(int iarg = 1; iarg < argc; ++iarg)
109 {
110 if(strcmp(argv[iarg], "---build-info") == 0)
111 {
112 // dump some information about our build to the console
113 if(my_rank == 0)
114 {
115 std::cout << "--- FEAT BUILD INFORMATION ---\n";
116 // 123456789-123456789-123456789-
117 std::cout << "__cplusplus...................: " << __cplusplus << "\n";
118#ifdef __STDC_VERSION__
119 std::cout << "__STDC_VERSION__..............: " << __STDC_VERSION__ << "\n";
120#else
121 std::cout << "__STDC_VERSION__..............: -N/A-\n";
122#endif
123#ifdef __STDC_HOSTED__
124 std::cout << "__STDC_HOSTED__...............: " << __STDC_HOSTED__ << "\n";
125#else
126 std::cout << "__STDC_HOSTED__...............: -N/A-\n";
127#endif
128#ifdef __STDCPP_THREADS__
129 std::cout << "__STDCPP_THREADS__............: " << __STDCPP_THREADS__ << "\n";
130#else
131 std::cout << "__STDCPP_THREADS__............: -N/A-\n";
132#endif
133#ifdef _OPENMP
134 std::cout << "_OPENMP.......................: yes\n";
135#else
136 std::cout << "_OPENMP.......................: no\n";
137#endif
138 std::cout << "FEAT Version..................: " << FEAT::version_major << "." << FEAT::version_minor << "." << FEAT::version_patch << "\n";
139#ifdef FEAT_GIT_SHA1
140 std::cout << "FEAT_GIT_SHA1.................: " << FEAT_GIT_SHA1 << "\n";
141#else
142 std::cout << "FEAT_GIT_SHA1.................: -N/A-\n";
143#endif
144#ifdef FEAT_BUILD_ID
145 std::cout << "FEAT_BUILD_ID.................: " << FEAT_BUILD_ID << "\n";
146#else
147 std::cout << "FEAT_BUILD_ID.................: -N/A-\n";
148#endif
149#ifdef FEAT_SOURCE_DIR
150 std::cout << "FEAT_SOURCE_DIR...............: " << FEAT_SOURCE_DIR << "\n";
151#else
152 std::cout << "FEAT_SOURCE_DIR...............: -N/A-\n";
153#endif
154#ifdef FEAT_BUILD_DIR
155 std::cout << "FEAT_BUILD_DIR................: " << FEAT_BUILD_DIR << "\n";
156#else
157 std::cout << "FEAT_BUILD_DIR................: -N/A-\n";
158#endif
159#ifdef FEAT_COMPILER
160 std::cout << "FEAT_COMPILER.................: " << FEAT_COMPILER << "\n";
161#else
162 std::cout << "FEAT_COMPILER.................: -N/A-\n";
163#endif
164#ifdef FEAT_COMPILER_GNU
165 std::cout << "FEAT_COMPILER_GNU.............: " << FEAT_COMPILER_GNU << "\n";
166#else
167 std::cout << "FEAT_COMPILER_GNU.............: -N/A-\n";
168#endif
169#ifdef FEAT_COMPILER_CLANG
170 std::cout << "FEAT_COMPILER_CLANG...........: " << FEAT_COMPILER_CLANG << "\n";
171#else
172 std::cout << "FEAT_COMPILER_CLANG...........: -N/A-\n";
173#endif
174#ifdef FEAT_COMPILER_CRAY
175 std::cout << "FEAT_COMPILER_CRAY............: " << FEAT_COMPILER_CRAY << "\n";
176#else
177 std::cout << "FEAT_COMPILER_CRAY............: -N/A-\n";
178#endif
179#ifdef FEAT_COMPILER_INTEL
180 std::cout << "FEAT_COMPILER_INTEL...........: " << FEAT_COMPILER_INTEL << "\n";
181#else
182 std::cout << "FEAT_COMPILER_INTEL...........: -N/A-\n";
183#endif
184#ifdef FEAT_COMPILER_MICROSOFT
185 std::cout << "FEAT_COMPILER_MICROSOFT.......: " << FEAT_COMPILER_MICROSOFT << "\n";
186#else
187 std::cout << "FEAT_COMPILER_MICROSOFT.......: -N/A-\n";
188#endif
189#ifdef FEAT_DEBUG_MODE
190 std::cout << "FEAT_DEBUG_MODE...............: yes\n";
191#else
192 std::cout << "FEAT_DEBUG_MODE...............: no\n";
193#endif
194#ifdef FEAT_EICKT
195 std::cout << "FEAT_EICKT....................: yes\n";
196#else
197 std::cout << "FEAT_EICKT....................: no\n";
198#endif
199#ifdef FEAT_INDEX_U32
200 std::cout << "FEAT_INDEX_U32................: yes\n";
201#else
202 std::cout << "FEAT_INDEX_U32................: no\n";
203#endif
204#ifdef FEAT_MPI_THREAD_MULTIPLE
205 std::cout << "FEAT_MPI_THREAD_MULTIPLE......: yes\n";
206#else
207 std::cout << "FEAT_MPI_THREAD_MULTIPLE......: no\n";
208#endif
209#ifdef FEAT_NO_CONFIG
210 std::cout << "FEAT_NO_CONFIG................: yes\n";
211#else
212 std::cout << "FEAT_NO_CONFIG................: no\n";
213#endif
214#ifdef FEAT_OVERRIDE_MPI_OPS
215 std::cout << "FEAT_OVERRIDE_MPI_OPS.........: yes\n";
216#else
217 std::cout << "FEAT_OVERRIDE_MPI_OPS.........: no\n";
218#endif
219#ifdef FEAT_USE_MKL_SPARSE_EXECUTOR
220 std::cout << "FEAT_USE_MKL_SPARSE_EXECUTOR..: yes\n";
221#else
222 std::cout << "FEAT_USE_MKL_SPARSE_EXECUTOR..: no\n";
223#endif
224#ifdef FEAT_UNROLL_BANDED
225 std::cout << "FEAT_UNROLL_BANDED............: yes\n";
226#else
227 std::cout << "FEAT_UNROLL_BANDED............: no\n";
228#endif
229#ifdef FEAT_HAVE_ALGLIB
230 std::cout << "FEAT_HAVE_ALGLIB..............: yes\n";
231#else
232 std::cout << "FEAT_HAVE_ALGLIB..............: no\n";
233#endif
234#ifdef FEAT_HAVE_BOOST
235 std::cout << "FEAT_HAVE_BOOST...............: yes\n";
236#else
237 std::cout << "FEAT_HAVE_BOOST...............: no\n";
238#endif
239#ifdef FEAT_HAVE_CGAL
240 std::cout << "FEAT_HAVE_CGAL................: yes\n";
241#else
242 std::cout << "FEAT_HAVE_CGAL................: no\n";
243#endif
244#ifdef FEAT_HAVE_CUDA
245 std::cout << "FEAT_HAVE_CUDA................: yes\n";
246#else
247 std::cout << "FEAT_HAVE_CUDA................: no\n";
248#endif
249#ifdef FEAT_HAVE_CUDSS
250 std::cout << "FEAT_HAVE_CUDSS...............: yes\n";
251#else
252 std::cout << "FEAT_HAVE_CUDSS...............: no\n";
253#endif
254#ifdef FEAT_HAVE_DEATH_HANDLER
255 std::cout << "FEAT_HAVE_DEATH_HANDLER.......: yes\n";
256#else
257 std::cout << "FEAT_HAVE_DEATH_HANDLER.......: no\n";
258#endif
259#ifdef FEAT_HAVE_FPARSER
260 std::cout << "FEAT_HAVE_FPARSER.............: yes\n";
261#else
262 std::cout << "FEAT_HAVE_FPARSER.............: no\n";
263#endif
264#ifdef FEAT_HAVE_FLOATX
265 std::cout << "FEAT_HAVE_FLOATX..............: yes\n";
266#else
267 std::cout << "FEAT_HAVE_FLOATX..............: no\n";
268#endif
269#ifdef FEAT_HAVE_HALFMATH
270 std::cout << "FEAT_HAVE_HALFMATH............: yes\n";
271#else
272 std::cout << "FEAT_HAVE_HALFMATH............: no\n";
273#endif
274#ifdef FEAT_HAVE_HYPRE
275 std::cout << "FEAT_HAVE_HYPRE...............: yes\n";
276#else
277 std::cout << "FEAT_HAVE_HYPRE...............: no\n";
278#endif
279#ifdef FEAT_HAVE_METIS
280 std::cout << "FEAT_HAVE_METIS...............: yes\n";
281#else
282 std::cout << "FEAT_HAVE_METIS...............: no\n";
283#endif
284#ifdef FEAT_HAVE_MKL
285 std::cout << "FEAT_HAVE_MKL.................: yes\n";
286#else
287 std::cout << "FEAT_HAVE_MKL.................: no\n";
288#endif
289#ifdef FEAT_HAVE_MPI
290 std::cout << "FEAT_HAVE_MPI.................: yes\n";
291#else
292 std::cout << "FEAT_HAVE_MPI.................: no\n";
293#endif
294#ifdef FEAT_HAVE_OMP
295 std::cout << "FEAT_HAVE_OMP.................: yes\n";
296#else
297 std::cout << "FEAT_HAVE_OMP.................: no\n";
298#endif
299#ifdef FEAT_HAVE_PARMETIS
300 std::cout << "FEAT_HAVE_PARMETIS............: yes\n";
301#else
302 std::cout << "FEAT_HAVE_PARMETIS............: no\n";
303#endif
304#ifdef FEAT_HAVE_PMP
305 std::cout << "FEAT_HAVE_PMP.................: yes\n";
306#else
307 std::cout << "FEAT_HAVE_PMP.................: no\n";
308#endif
309#ifdef FEAT_HAVE_QUADMATH
310 std::cout << "FEAT_HAVE_QUADMATH............: yes\n";
311#else
312 std::cout << "FEAT_HAVE_QUADMATH............: no\n";
313#endif
314#ifdef FEAT_HAVE_SUITESPARSE
315 std::cout << "FEAT_HAVE_SUITESPARSE.........: yes\n";
316#else
317 std::cout << "FEAT_HAVE_SUITESPARSE.........: no\n";
318#endif
319#ifdef FEAT_HAVE_SUPERLU_DIST
320 std::cout << "FEAT_HAVE_SUPERLU_DIST........: yes\n";
321#else
322 std::cout << "FEAT_HAVE_SUPERLU_DIST........: no\n";
323#endif
324#ifdef FEAT_HAVE_TRIANGLE
325 std::cout << "FEAT_HAVE_TRIANGLE............: yes\n";
326#else
327 std::cout << "FEAT_HAVE_TRIANGLE............: no\n";
328#endif
329#ifdef FEAT_HAVE_TRILINOS
330 std::cout << "FEAT_HAVE_TRILINOS............: yes\n";
331#else
332 std::cout << "FEAT_HAVE_TRILINOS............: no\n";
333#endif
334#ifdef FEAT_HAVE_UMFPACK
335 std::cout << "FEAT_HAVE_UMFPACK.............: yes\n";
336#else
337 std::cout << "FEAT_HAVE_UMFPACK.............: no\n";
338#endif
339#ifdef FEAT_HAVE_ZFP
340 std::cout << "FEAT_HAVE_ZFP.................: yes\n";
341#else
342 std::cout << "FEAT_HAVE_ZFP.................: no\n";
343#endif
344#ifdef FEAT_HAVE_ZLIB
345 std::cout << "FEAT_HAVE_ZLIB................: yes\n";
346#else
347 std::cout << "FEAT_HAVE_ZLIB................: no\n";
348#endif
349#ifdef FEAT_HAVE_ZOLTAN
350 std::cout << "FEAT_HAVE_ZOLTAN..............: yes\n";
351#else
352 std::cout << "FEAT_HAVE_ZOLTAN..............: no\n";
353#endif
354 std::cout << "--- END OF FEAT BUILD INFORMATION ---\n";
355 std::cout.flush();
356 }
357 }
358
359 if(strcmp(argv[iarg], "---print-pid") == 0)
360 {
361#ifdef FEAT_HAVE_MPI
362#if defined(_WIN32)
363 std::cout << "Process ID " << std::setw(6) << Windows::get_current_process_id() << " runs rank " << my_rank << "\n";
364#elif defined(__linux) || defined(__unix__)
365 std::cout << "Process ID " << std::setw(6) << getpid() << " runs rank " << my_rank << "\n";
366#endif // defined(_WIN32)
367#else // no FEAT_HAVE_MPI
368#if defined(_WIN32)
369 std::cout << "Process ID " << std::setw(6) << Windows::get_current_process_id() << "\n";
370#elif defined(__linux) || defined(__unix__)
371 std::cout << "Process ID " << std::setw(6) << getpid() << "\n";
372#endif // defined(_WIN32)
373#endif // FEAT_HAVE_MPI
374 std::cout.flush();
375 }
376
377#ifdef FEAT_COMPILER_MICROSOFT
378 if(strcmp(argv[iarg], "---debug-break") == 0)
379 {
380#ifdef FEAT_HAVE_MPI
381 // in an MPI case, the ranks to debug have to be specified
382 for(++iarg; iarg < argc; ++iarg)
383 {
384 char* endptr = nullptr;
385 int irank = int(std::strtol(argv[iarg], &endptr, 0));
386 if((endptr != argv[iarg]) && (*endptr == '\0'))
387 {
388 if(irank == my_rank)
389 {
390 __debugbreak();
391 break;
392 }
393 }
394 else // argv[iarg] could not be parsed as a number
395 {
396 --iarg;
397 break;
398 }
399 }
400#else // no FEAT_HAVE_MPI
401 __debugbreak();
402#endif // FEAT_HAVE_MPI
403 continue;
404 }
405#endif // FEAT_COMPILER_MICROSOFT
406 }
407
408 _initialized = true;
409 // finally initialize Syncguard
410 SyncGuard::sync_on = true;
411}
412
413void Runtime::abort(bool dump_call_stack)
414{
415 if(dump_call_stack)
416 {
417#if defined(__linux) || defined(__unix__)
418#if defined(FEAT_HAVE_DEATH_HANDLER) and not defined(FEAT_HAVE_MPI)
419 Debug::DeathHandler death_handler;
420#else
421 // https://www.gnu.org/software/libc/manual/html_node/Backtraces.html
422 void* buffer[1024];
423 auto bt_size = backtrace(buffer, 1024);
424 char** bt_symb = backtrace_symbols(buffer, bt_size);
425 if((bt_size > 0) && (bt_symb != nullptr))
426 {
427 fprintf(stderr, "\nCall-Stack Back-Trace:\n");
428 fprintf(stderr, "----------------------\n");
429 for(decltype(bt_size) i(0); i < bt_size; ++i)
430 fprintf(stderr, "%s\n", bt_symb[i]);
431 fflush(stderr);
432 }
433#endif
434#elif defined(_WIN32)
436#endif
437 }
438
439#ifdef FEAT_HAVE_MPI
440 ::MPI_Abort(MPI_COMM_WORLD, 1);
441#endif
442 std::abort();
443}
444
446{
447 if (!_initialized)
448 {
449 std::cerr << "ERROR: Runtime::finalize called before Runtime::initialize!\n";
450 std::cerr.flush();
452 }
453 if (_finalized)
454 {
455 std::cerr << "ERROR: Runtime::finalize called twice!\n";
456 std::cerr.flush();
458 }
459
461
462#ifdef FEAT_HAVE_CUDSS
463 cudssDestroy(feat_cudss_handle);
464#endif
465
466#ifdef FEAT_HAVE_CUDA
467 Util::cuda_finalize();
468#endif
469
470 // finalize Dist operations
472 // finalize Likwid markerAPI
474
475 // reset device, which is/can be nesessary to have sanitizer and profiler work properly
476 // this should not be called, if there are other cuda contexts live while FEAT is finalized,
477 // for example if MPI is initilized by another library which shares the same process, or a feat app
478 // is called by another app without reinitializing the cuda device
479#if defined(FEAT_HAVE_CUDA) && defined(FEAT_FINALIZE_RESETS_DEVICE)
480 Util::cuda_reset_device();
481#endif
482 _finalized = true;
483
484 // return successful exit code
485 return EXIT_SUCCESS;
486}
487
489{
490#ifdef FEAT_HAVE_CUDSS
491 return feat_cudss_handle;
492#else
493 return nullptr;
494#endif
495}
FEAT Kernel base header.
int rank() const
Returns the rank of this process in this communicator.
Definition: dist.hpp:1494
static Comm world()
Returns a copy of the world communicator.
Definition: dist.cpp:429
static void initialize()
Setup memory pools.
Definition: memory_pool.hpp:61
static void finalize()
Shutdown memory pool and clean up allocated memory pools.
Definition: memory_pool.hpp:66
static int finalize()
FEAT finalization.
Definition: runtime.cpp:445
static bool _finalized
signals, if finalize was called
Definition: runtime.hpp:31
static void * get_cudss_handle()
Returns the unique cuDSS third-party library handle.
Definition: runtime.cpp:488
static bool _initialized
signals, if initialize was called
Definition: runtime.hpp:28
static void initialize(int &argc, char **&argv)
FEAT initialization.
Definition: runtime.cpp:51
static void abort(bool dump_call_stack=true)
FEAT abortion.
Definition: runtime.cpp:413
#define FEAT_MARKER_INIT
Init the marker api.
#define FEAT_MARKER_CLOSE
Finalize marker api, writes data to file, only call once.
bool initialize(int &argc, char **&argv)
Initializes the distributed communication system.
Definition: dist.cpp:105
void finalize()
Finalizes the distributed communication system.
Definition: dist.cpp:148
void install_seh_filter()
Installs custom Windows Structured-Exception-Handler filter.
Definition: os_windows.cpp:208
void dump_call_stack_to_stderr()
Dumps the call-stack to stderr.
Definition: os_windows.cpp:152
void disable_error_prompts()
Disables Windows error dialog boxes.
Definition: os_windows.cpp:214
unsigned long get_current_process_id()
Returns the Windows process ID for the current process.
Definition: os_windows.cpp:222
FEAT namespace.
Definition: adjactor.hpp:12
static constexpr int version_major
FEAT major version number.
static constexpr int version_patch
FEAT patch version number.
static constexpr int version_minor
FEAT minor version number.