IgANet
IGAnets - Isogeometric Analysis Networks
Loading...
Searching...
No Matches
core.hpp
Go to the documentation of this file.
1
15#pragma once
16
17#include <iganet/core/config.hpp>
18
19#include <array>
20#include <fstream>
21#include <iostream>
22#include <string_view>
23#include <tuple>
24
26
27#ifdef IGANET_WITH_OPENMP
28#include <omp.h>
29#endif
30
31#ifdef IGANET_WITH_MPI
32#ifndef USE_C10D_MPI
33#error "Torch must be compiled with USE_DISTRIBUTED=1, USE_MPI=1, USE_C10_MPI=1"
34#endif
35#include <torch/csrc/distributed/c10d/ProcessGroupMPI.hpp>
36#endif
37
38#include <torch/csrc/api/include/torch/types.h>
39#include <torch/torch.h>
40
41#ifdef IGANET_WITH_CUDA
42#include <c10/cuda/CUDACachingAllocator.h>
43#include <c10/cuda/CUDAFunctions.h>
44#endif
45
46#ifdef IGANET_WITH_HIP
47#include <c10/hip/HIPCachingAllocator.h>
48#include <c10/hip/HIPFunctions.h>
49#endif
50
51#ifdef IGANET_WITH_GISMO
52#include <gismo.h>
53#include <gsModeling/gsSurfaceReparameterization.h>
54
55#ifdef gsElasticity_ENABLED
56#include <gsElasticity/src/gsElasticityAssembler.h>
57#include <gsElasticity/src/gsGeoUtils.h>
58#include <gsElasticity/src/gsMassAssembler.h>
59#endif
60#endif
61
62#undef real_t
63#undef index_t
64#undef short_t
65
66#ifdef IGANET_WITH_MATPLOT
67#include <matplot/matplot.h>
68#endif
69
70// This header file needs to be included after all other header files have been included
72
73namespace iganet {
74
76using short_t = short int;
77
78namespace literals {
79
84inline short_t operator""_s(unsigned long long value) { return value; };
87inline int8_t operator""_i8(unsigned long long value) { return value; };
90inline int16_t operator""_i16(unsigned long long value) { return value; };
93inline int32_t operator""_i32(unsigned long long value) { return value; };
96inline int64_t operator""_i64(unsigned long long value) { return value; };
98} // namespace literals
99
100// clang-format off
102enum class log : short_t {
103 none = 0,
104 fatal = 1,
105 error = 2,
106 warning = 3,
107 info = 4,
108 debug = 5,
109 verbose = 6
110};
111// clang-format on
112
113namespace logging {
115class NullStreamBuffer : public std::streambuf {
116public:
120 int overflow(int c) override { return traits_type::not_eof(c); }
121};
122
124class NullOStream : public std::ostream {
125public:
128
129private:
131};
132} // namespace logging
133
135inline struct {
136private:
138 std::ostream &outputStream = std::cout;
139
141 logging::NullOStream nullStream;
142
144 std::ofstream outputFile;
145
147 enum log level = log::info;
148
149public:
152 void setLogLevel(enum log level) { this->level = level; }
153
156 void setLogFile(const std::string &filename) {
157 outputFile = std::ofstream(filename);
158 outputStream.rdbuf(outputFile.rdbuf());
159 }
160
165 std::ostream &operator()(enum log level = log::info) {
166 if (this->level >= level)
167 switch (level) {
168 case (log::fatal):
169 return outputStream << "[FATAL ERROR] ";
170 case (log::error):
171 return outputStream << "[ERROR] ";
172 case (log::warning):
173 return outputStream << "[WARNING] ";
174 case (log::info):
175 return outputStream << "[INFO] ";
176 case (log::debug):
177 return outputStream << "[DEBUG] ";
178 case (log::verbose):
179 return outputStream << "[VERBOSE] ";
180 default:
181 return nullStream;
182 }
183 else
184 return nullStream;
185 }
187
193inline std::string memory_summary(c10::DeviceIndex device =
194#ifdef CUDA_VERSION
195 c10::cuda::current_device()
196#elif HIP_VERSION
197 c10::hip::current_device()
198#else
199 0
200#endif
201) {
202
203 std::ostringstream os;
204
205#if defined(CUDA_VERSION) || defined(HIP_VERSION)
206
207 auto _format_size = [](int64_t bytes) -> std::string {
208 if (bytes == 0)
209 return "0 B";
210
211 constexpr std::array<std::string_view, 6> prefixes{
212 "B", "KiB", "MiB", "GiB", "TiB", "PiB"};
213 int64_t n = std::floor(std::max(0.0, std::log2(static_cast<double>(bytes) /
214 static_cast<double>(768))) /
215 static_cast<double>(10));
216
217 return std::to_string((int64_t)(bytes / std::pow(1024, n))) + " " +
218 std::string(prefixes[n]);
219 };
220
221#if TORCH_VERSION_MAJOR > 2 || \
222 (TORCH_VERSION_MAJOR == 2 && TORCH_VERSION_MINOR > 4)
223 using namespace c10::CachingDeviceAllocator;
224#endif
225
226#ifdef CUDA_VERSION
227 using namespace c10::cuda::CUDACachingAllocator;
228#elif HIP_VERSION
229 using namespace c10::hip::HIPCachingAllocator;
230#endif
231
232 DeviceStats deviceStats = getDeviceStats(device);
233
234 os << "|====================================================================="
235 "======|\n"
236#ifdef CUDA_VERSION
237 << "| LibTorch CUDA memory summary, device ID "
238#elif HIP_VERSION
239 << "| LibTorch ROCm memory summary, device ID "
240#endif
241 << std::setw(18) << std::left << static_cast<int>(device) << "|\n"
242 << "|---------------------------------------------------------------------"
243 "------|\n"
244#ifdef CUDA_VERSION
245 << "| CUDA OOMs: "
246#elif HIP_VERSION
247 << "| ROCm OOMs: "
248#endif
249 << std::setw(13) << std::left << deviceStats.num_ooms
250#ifdef CUDA_VERSION
251 << "| cudaMalloc retries: "
252#elif HIP_VERSION
253 << "| hipMalloc retries: "
254#endif
255 << std::setw(10) << std::left << deviceStats.num_alloc_retries << "|\n"
256 << "|====================================================================="
257 "======|\n"
258 << "| Metric | Cur Usage | Peak Usage | Tot Alloc | Tot "
259 "Freed |\n"
260 << "|---------------------------------------------------------------------"
261 "------|\n"
262 << "| Allocated memory | " << std::setw(10) << std::right
263 << _format_size(
264 deviceStats
265 .allocated_bytes[static_cast<std::size_t>(StatType::AGGREGATE)]
266 .current)
267 << " | " << std::setw(10) << std::right
268 << _format_size(
269 deviceStats
270 .allocated_bytes[static_cast<std::size_t>(StatType::AGGREGATE)]
271 .peak)
272 << " | " << std::setw(10) << std::right
273 << _format_size(
274 deviceStats
275 .allocated_bytes[static_cast<std::size_t>(StatType::AGGREGATE)]
276 .allocated)
277 << " | " << std::setw(10) << std::right
278 << _format_size(
279 deviceStats
280 .allocated_bytes[static_cast<std::size_t>(StatType::AGGREGATE)]
281 .freed)
282 << " |\n"
283 << "| from large pool | " << std::setw(10) << std::right
284 << _format_size(
285 deviceStats
286 .allocated_bytes[static_cast<std::size_t>(StatType::LARGE_POOL)]
287 .current)
288 << " | " << std::setw(10) << std::right
289 << _format_size(
290 deviceStats
291 .allocated_bytes[static_cast<std::size_t>(StatType::LARGE_POOL)]
292 .peak)
293 << " | " << std::setw(10) << std::right
294 << _format_size(
295 deviceStats
296 .allocated_bytes[static_cast<std::size_t>(StatType::LARGE_POOL)]
297 .allocated)
298 << " | " << std::setw(10) << std::right
299 << _format_size(
300 deviceStats
301 .allocated_bytes[static_cast<std::size_t>(StatType::LARGE_POOL)]
302 .freed)
303 << " |\n"
304 << "| from small pool | " << std::setw(10) << std::right
305 << _format_size(
306 deviceStats
307 .allocated_bytes[static_cast<std::size_t>(StatType::SMALL_POOL)]
308 .current)
309 << " | " << std::setw(10) << std::right
310 << _format_size(
311 deviceStats
312 .allocated_bytes[static_cast<std::size_t>(StatType::SMALL_POOL)]
313 .peak)
314 << " | " << std::setw(10) << std::right
315 << _format_size(
316 deviceStats
317 .allocated_bytes[static_cast<std::size_t>(StatType::SMALL_POOL)]
318 .allocated)
319 << " | " << std::setw(10) << std::right
320 << _format_size(
321 deviceStats
322 .allocated_bytes[static_cast<std::size_t>(StatType::SMALL_POOL)]
323 .freed)
324 << " |\n"
325 << "|---------------------------------------------------------------------"
326 "------|\n"
327 << "| Active memory | " << std::setw(10) << std::right
328 << _format_size(
329 deviceStats
330 .active_bytes[static_cast<std::size_t>(StatType::AGGREGATE)]
331 .current)
332 << " | " << std::setw(10) << std::right
333 << _format_size(
334 deviceStats
335 .active_bytes[static_cast<std::size_t>(StatType::AGGREGATE)]
336 .peak)
337 << " | " << std::setw(10) << std::right
338 << _format_size(
339 deviceStats
340 .active_bytes[static_cast<std::size_t>(StatType::AGGREGATE)]
341 .allocated)
342 << " | " << std::setw(10) << std::right
343 << _format_size(
344 deviceStats
345 .active_bytes[static_cast<std::size_t>(StatType::AGGREGATE)]
346 .freed)
347 << " |\n"
348 << "| from large pool | " << std::setw(10) << std::right
349 << _format_size(
350 deviceStats
351 .active_bytes[static_cast<std::size_t>(StatType::LARGE_POOL)]
352 .current)
353 << " | " << std::setw(10) << std::right
354 << _format_size(
355 deviceStats
356 .active_bytes[static_cast<std::size_t>(StatType::LARGE_POOL)]
357 .peak)
358 << " | " << std::setw(10) << std::right
359 << _format_size(
360 deviceStats
361 .active_bytes[static_cast<std::size_t>(StatType::LARGE_POOL)]
362 .allocated)
363 << " | " << std::setw(10) << std::right
364 << _format_size(
365 deviceStats
366 .active_bytes[static_cast<std::size_t>(StatType::LARGE_POOL)]
367 .freed)
368 << " |\n"
369 << "| from small pool | " << std::setw(10) << std::right
370 << _format_size(
371 deviceStats
372 .active_bytes[static_cast<std::size_t>(StatType::SMALL_POOL)]
373 .current)
374 << " | " << std::setw(10) << std::right
375 << _format_size(
376 deviceStats
377 .active_bytes[static_cast<std::size_t>(StatType::SMALL_POOL)]
378 .peak)
379 << " | " << std::setw(10) << std::right
380 << _format_size(
381 deviceStats
382 .active_bytes[static_cast<std::size_t>(StatType::SMALL_POOL)]
383 .allocated)
384 << " | " << std::setw(10) << std::right
385 << _format_size(
386 deviceStats
387 .active_bytes[static_cast<std::size_t>(StatType::SMALL_POOL)]
388 .freed)
389 << " |\n"
390 << "|---------------------------------------------------------------------"
391 "------|\n"
392 << "| Requested memory | " << std::setw(10) << std::right
393 << _format_size(
394 deviceStats
395 .requested_bytes[static_cast<std::size_t>(StatType::AGGREGATE)]
396 .current)
397 << " | " << std::setw(10) << std::right
398 << _format_size(
399 deviceStats
400 .requested_bytes[static_cast<std::size_t>(StatType::AGGREGATE)]
401 .peak)
402 << " | " << std::setw(10) << std::right
403 << _format_size(
404 deviceStats
405 .requested_bytes[static_cast<std::size_t>(StatType::AGGREGATE)]
406 .allocated)
407 << " | " << std::setw(10) << std::right
408 << _format_size(
409 deviceStats
410 .requested_bytes[static_cast<std::size_t>(StatType::AGGREGATE)]
411 .freed)
412 << " |\n"
413 << "| from large pool | " << std::setw(10) << std::right
414 << _format_size(
415 deviceStats
416 .requested_bytes[static_cast<std::size_t>(StatType::LARGE_POOL)]
417 .current)
418 << " | " << std::setw(10) << std::right
419 << _format_size(
420 deviceStats
421 .requested_bytes[static_cast<std::size_t>(StatType::LARGE_POOL)]
422 .peak)
423 << " | " << std::setw(10) << std::right
424 << _format_size(
425 deviceStats
426 .requested_bytes[static_cast<std::size_t>(StatType::LARGE_POOL)]
427 .allocated)
428 << " | " << std::setw(10) << std::right
429 << _format_size(
430 deviceStats
431 .requested_bytes[static_cast<std::size_t>(StatType::LARGE_POOL)]
432 .freed)
433 << " |\n"
434 << "| from small pool | " << std::setw(10) << std::right
435 << _format_size(
436 deviceStats
437 .requested_bytes[static_cast<std::size_t>(StatType::SMALL_POOL)]
438 .current)
439 << " | " << std::setw(10) << std::right
440 << _format_size(
441 deviceStats
442 .requested_bytes[static_cast<std::size_t>(StatType::SMALL_POOL)]
443 .peak)
444 << " | " << std::setw(10) << std::right
445 << _format_size(
446 deviceStats
447 .requested_bytes[static_cast<std::size_t>(StatType::SMALL_POOL)]
448 .allocated)
449 << " | " << std::setw(10) << std::right
450 << _format_size(
451 deviceStats
452 .requested_bytes[static_cast<std::size_t>(StatType::SMALL_POOL)]
453 .freed)
454 << " |\n"
455 << "|---------------------------------------------------------------------"
456 "------|\n"
457 << "| GPU reserved memory | " << std::setw(10) << std::right
458 << _format_size(
459 deviceStats
460 .reserved_bytes[static_cast<std::size_t>(StatType::AGGREGATE)]
461 .current)
462 << " | " << std::setw(10) << std::right
463 << _format_size(
464 deviceStats
465 .reserved_bytes[static_cast<std::size_t>(StatType::AGGREGATE)]
466 .peak)
467 << " | " << std::setw(10) << std::right
468 << _format_size(
469 deviceStats
470 .reserved_bytes[static_cast<std::size_t>(StatType::AGGREGATE)]
471 .allocated)
472 << " | " << std::setw(10) << std::right
473 << _format_size(
474 deviceStats
475 .reserved_bytes[static_cast<std::size_t>(StatType::AGGREGATE)]
476 .freed)
477 << " |\n"
478 << "| from large pool | " << std::setw(10) << std::right
479 << _format_size(
480 deviceStats
481 .reserved_bytes[static_cast<std::size_t>(StatType::LARGE_POOL)]
482 .current)
483 << " | " << std::setw(10) << std::right
484 << _format_size(
485 deviceStats
486 .reserved_bytes[static_cast<std::size_t>(StatType::LARGE_POOL)]
487 .peak)
488 << " | " << std::setw(10) << std::right
489 << _format_size(
490 deviceStats
491 .reserved_bytes[static_cast<std::size_t>(StatType::LARGE_POOL)]
492 .allocated)
493 << " | " << std::setw(10) << std::right
494 << _format_size(
495 deviceStats
496 .reserved_bytes[static_cast<std::size_t>(StatType::LARGE_POOL)]
497 .freed)
498 << " |\n"
499 << "| from small pool | " << std::setw(10) << std::right
500 << _format_size(
501 deviceStats
502 .reserved_bytes[static_cast<std::size_t>(StatType::SMALL_POOL)]
503 .current)
504 << " | " << std::setw(10) << std::right
505 << _format_size(
506 deviceStats
507 .reserved_bytes[static_cast<std::size_t>(StatType::SMALL_POOL)]
508 .peak)
509 << " | " << std::setw(10) << std::right
510 << _format_size(
511 deviceStats
512 .reserved_bytes[static_cast<std::size_t>(StatType::SMALL_POOL)]
513 .allocated)
514 << " | " << std::setw(10) << std::right
515 << _format_size(
516 deviceStats
517 .reserved_bytes[static_cast<std::size_t>(StatType::SMALL_POOL)]
518 .freed)
519 << " |\n"
520 << "|---------------------------------------------------------------------"
521 "------|\n"
522 << "| Non-releasable memory | " << std::setw(10) << std::right
523 << _format_size(deviceStats
524 .inactive_split_bytes[static_cast<std::size_t>(
525 StatType::AGGREGATE)]
526 .current)
527 << " | " << std::setw(10) << std::right
528 << _format_size(deviceStats
529 .inactive_split_bytes[static_cast<std::size_t>(
530 StatType::AGGREGATE)]
531 .peak)
532 << " | " << std::setw(10) << std::right
533 << _format_size(deviceStats
534 .inactive_split_bytes[static_cast<std::size_t>(
535 StatType::AGGREGATE)]
536 .allocated)
537 << " | " << std::setw(10) << std::right
538 << _format_size(deviceStats
539 .inactive_split_bytes[static_cast<std::size_t>(
540 StatType::AGGREGATE)]
541 .freed)
542 << " |\n"
543 << "| from large pool | " << std::setw(10) << std::right
544 << _format_size(deviceStats
545 .inactive_split_bytes[static_cast<std::size_t>(
546 StatType::LARGE_POOL)]
547 .current)
548 << " | " << std::setw(10) << std::right
549 << _format_size(deviceStats
550 .inactive_split_bytes[static_cast<std::size_t>(
551 StatType::LARGE_POOL)]
552 .peak)
553 << " | " << std::setw(10) << std::right
554 << _format_size(deviceStats
555 .inactive_split_bytes[static_cast<std::size_t>(
556 StatType::LARGE_POOL)]
557 .allocated)
558 << " | " << std::setw(10) << std::right
559 << _format_size(deviceStats
560 .inactive_split_bytes[static_cast<std::size_t>(
561 StatType::LARGE_POOL)]
562 .freed)
563 << " |\n"
564 << "| from small pool | " << std::setw(10) << std::right
565 << _format_size(deviceStats
566 .inactive_split_bytes[static_cast<std::size_t>(
567 StatType::SMALL_POOL)]
568 .current)
569 << " | " << std::setw(10) << std::right
570 << _format_size(deviceStats
571 .inactive_split_bytes[static_cast<std::size_t>(
572 StatType::SMALL_POOL)]
573 .peak)
574 << " | " << std::setw(10) << std::right
575 << _format_size(deviceStats
576 .inactive_split_bytes[static_cast<std::size_t>(
577 StatType::SMALL_POOL)]
578 .allocated)
579 << " | " << std::setw(10) << std::right
580 << _format_size(deviceStats
581 .inactive_split_bytes[static_cast<std::size_t>(
582 StatType::SMALL_POOL)]
583 .freed)
584 << " |\n"
585 << "|---------------------------------------------------------------------"
586 "------|\n"
587 << "| Allocations | " << std::setw(10) << std::right
588 << deviceStats.allocation[static_cast<std::size_t>(StatType::AGGREGATE)]
589 .current
590 << " | " << std::setw(10) << std::right
591 << deviceStats.allocation[static_cast<std::size_t>(StatType::AGGREGATE)]
592 .peak
593 << " | " << std::setw(10) << std::right
594 << deviceStats.allocation[static_cast<std::size_t>(StatType::AGGREGATE)]
595 .allocated
596 << " | " << std::setw(10) << std::right
597 << deviceStats.allocation[static_cast<std::size_t>(StatType::AGGREGATE)]
598 .freed
599 << " |\n"
600 << "|---------------------------------------------------------------------"
601 "------|\n"
602 << "| from large pool | " << std::setw(10) << std::right
603 << deviceStats.allocation[static_cast<std::size_t>(StatType::LARGE_POOL)]
604 .current
605 << " | " << std::setw(10) << std::right
606 << deviceStats.allocation[static_cast<std::size_t>(StatType::LARGE_POOL)]
607 .peak
608 << " | " << std::setw(10) << std::right
609 << deviceStats.allocation[static_cast<std::size_t>(StatType::LARGE_POOL)]
610 .allocated
611 << " | " << std::setw(10) << std::right
612 << deviceStats.allocation[static_cast<std::size_t>(StatType::LARGE_POOL)]
613 .freed
614 << " |\n"
615 << "|---------------------------------------------------------------------"
616 "------|\n"
617 << "| from small pool | " << std::setw(10) << std::right
618 << deviceStats.allocation[static_cast<std::size_t>(StatType::SMALL_POOL)]
619 .current
620 << " | " << std::setw(10) << std::right
621 << deviceStats.allocation[static_cast<std::size_t>(StatType::SMALL_POOL)]
622 .peak
623 << " | " << std::setw(10) << std::right
624 << deviceStats.allocation[static_cast<std::size_t>(StatType::SMALL_POOL)]
625 .allocated
626 << " | " << std::setw(10) << std::right
627 << deviceStats.allocation[static_cast<std::size_t>(StatType::SMALL_POOL)]
628 .freed
629 << " |\n"
630 << "|---------------------------------------------------------------------"
631 "------|\n"
632 << "| Active allocs | " << std::setw(10) << std::right
633 << deviceStats.active[static_cast<std::size_t>(StatType::AGGREGATE)]
634 .current
635 << " | " << std::setw(10) << std::right
636 << deviceStats.active[static_cast<std::size_t>(StatType::AGGREGATE)].peak
637 << " | " << std::setw(10) << std::right
638 << deviceStats.active[static_cast<std::size_t>(StatType::AGGREGATE)]
639 .allocated
640 << " | " << std::setw(10) << std::right
641 << deviceStats.active[static_cast<std::size_t>(StatType::AGGREGATE)].freed
642 << " |\n"
643 << "|---------------------------------------------------------------------"
644 "------|\n"
645 << "| from large pool | " << std::setw(10) << std::right
646 << deviceStats.active[static_cast<std::size_t>(StatType::LARGE_POOL)]
647 .current
648 << " | " << std::setw(10) << std::right
649 << deviceStats.active[static_cast<std::size_t>(StatType::LARGE_POOL)].peak
650 << " | " << std::setw(10) << std::right
651 << deviceStats.active[static_cast<std::size_t>(StatType::LARGE_POOL)]
652 .allocated
653 << " | " << std::setw(10) << std::right
654 << deviceStats.active[static_cast<std::size_t>(StatType::LARGE_POOL)].freed
655 << " |\n"
656 << "|---------------------------------------------------------------------"
657 "------|\n"
658 << "| from small pool | " << std::setw(10) << std::right
659 << deviceStats.active[static_cast<std::size_t>(StatType::SMALL_POOL)]
660 .current
661 << " | " << std::setw(10) << std::right
662 << deviceStats.active[static_cast<std::size_t>(StatType::SMALL_POOL)].peak
663 << " | " << std::setw(10) << std::right
664 << deviceStats.active[static_cast<std::size_t>(StatType::SMALL_POOL)]
665 .allocated
666 << " | " << std::setw(10) << std::right
667 << deviceStats.active[static_cast<std::size_t>(StatType::SMALL_POOL)].freed
668 << " |\n"
669 << "|---------------------------------------------------------------------"
670 "------|\n"
671 << "| GPU reserved segments | " << std::setw(10) << std::right
672 << deviceStats.segment[static_cast<std::size_t>(StatType::AGGREGATE)]
673 .current
674 << " | " << std::setw(10) << std::right
675 << deviceStats.segment[static_cast<std::size_t>(StatType::AGGREGATE)].peak
676 << " | " << std::setw(10) << std::right
677 << deviceStats.segment[static_cast<std::size_t>(StatType::AGGREGATE)]
678 .allocated
679 << " | " << std::setw(10) << std::right
680 << deviceStats.segment[static_cast<std::size_t>(StatType::AGGREGATE)].freed
681 << " |\n"
682 << "|---------------------------------------------------------------------"
683 "------|\n"
684 << "| from large pool | " << std::setw(10) << std::right
685 << deviceStats.segment[static_cast<std::size_t>(StatType::LARGE_POOL)]
686 .current
687 << " | " << std::setw(10) << std::right
688 << deviceStats.segment[static_cast<std::size_t>(StatType::LARGE_POOL)].peak
689 << " | " << std::setw(10) << std::right
690 << deviceStats.segment[static_cast<std::size_t>(StatType::LARGE_POOL)]
691 .allocated
692 << " | " << std::setw(10) << std::right
693 << deviceStats.segment[static_cast<std::size_t>(StatType::LARGE_POOL)]
694 .freed
695 << " |\n"
696 << "|---------------------------------------------------------------------"
697 "------|\n"
698 << "| from small pool | " << std::setw(10) << std::right
699 << deviceStats.segment[static_cast<std::size_t>(StatType::SMALL_POOL)]
700 .current
701 << " | " << std::setw(10) << std::right
702 << deviceStats.segment[static_cast<std::size_t>(StatType::SMALL_POOL)].peak
703 << " | " << std::setw(10) << std::right
704 << deviceStats.segment[static_cast<std::size_t>(StatType::SMALL_POOL)]
705 .allocated
706 << " | " << std::setw(10) << std::right
707 << deviceStats.segment[static_cast<std::size_t>(StatType::SMALL_POOL)]
708 .freed
709 << " |\n"
710 << "|---------------------------------------------------------------------"
711 "------|\n"
712 << "| Non-releasable allocs | " << std::setw(10) << std::right
713 << deviceStats
714 .inactive_split[static_cast<std::size_t>(StatType::AGGREGATE)]
715 .current
716 << " | " << std::setw(10) << std::right
717 << deviceStats
718 .inactive_split[static_cast<std::size_t>(StatType::AGGREGATE)]
719 .peak
720 << " | " << std::setw(10) << std::right
721 << deviceStats
722 .inactive_split[static_cast<std::size_t>(StatType::AGGREGATE)]
723 .allocated
724 << " | " << std::setw(10) << std::right
725 << deviceStats
726 .inactive_split[static_cast<std::size_t>(StatType::AGGREGATE)]
727 .freed
728 << " |\n"
729 << "|---------------------------------------------------------------------"
730 "------|\n"
731 << "| from large pool | " << std::setw(10) << std::right
732 << deviceStats
733 .inactive_split[static_cast<std::size_t>(StatType::LARGE_POOL)]
734 .current
735 << " | " << std::setw(10) << std::right
736 << deviceStats
737 .inactive_split[static_cast<std::size_t>(StatType::LARGE_POOL)]
738 .peak
739 << " | " << std::setw(10) << std::right
740 << deviceStats
741 .inactive_split[static_cast<std::size_t>(StatType::LARGE_POOL)]
742 .allocated
743 << " | " << std::setw(10) << std::right
744 << deviceStats
745 .inactive_split[static_cast<std::size_t>(StatType::LARGE_POOL)]
746 .freed
747 << " |\n"
748 << "|---------------------------------------------------------------------"
749 "------|\n"
750 << "| from small pool | " << std::setw(10) << std::right
751 << deviceStats
752 .inactive_split[static_cast<std::size_t>(StatType::SMALL_POOL)]
753 .current
754 << " | " << std::setw(10) << std::right
755 << deviceStats
756 .inactive_split[static_cast<std::size_t>(StatType::SMALL_POOL)]
757 .peak
758 << " | " << std::setw(10) << std::right
759 << deviceStats
760 .inactive_split[static_cast<std::size_t>(StatType::SMALL_POOL)]
761 .allocated
762 << " | " << std::setw(10) << std::right
763 << deviceStats
764 .inactive_split[static_cast<std::size_t>(StatType::SMALL_POOL)]
765 .freed
766 << " |\n"
767 << "|---------------------------------------------------------------------"
768 "------|\n"
769 << "| Oversize allocations | " << std::setw(10) << std::right
770 << deviceStats.oversize_allocations.current << " | " << std::setw(10)
771 << std::right << deviceStats.oversize_allocations.peak << " | "
772 << std::setw(10) << std::right
773 << deviceStats.oversize_allocations.allocated << " | " << std::setw(10)
774 << std::right << deviceStats.oversize_allocations.freed << " |\n"
775 << "|---------------------------------------------------------------------"
776 "------|\n"
777 << "| Oversize GPU segments | " << std::setw(10) << std::right
778 << deviceStats.oversize_segments.current << " | " << std::setw(10)
779 << std::right << deviceStats.oversize_segments.peak << " | "
780 << std::setw(10) << std::right << deviceStats.oversize_segments.allocated
781 << " | " << std::setw(10) << std::right
782 << deviceStats.oversize_segments.freed << " |\n"
783 << "|====================================================================="
784 "======|";
785#else
786 os << "Memory summary is only available for CUDA/HIP devices";
787#endif
788
789 return os.str();
790}
791
796inline void init(std::ostream &os = Log(log::info)) {
797 torch::manual_seed(1);
798
799 // Set number of intraop thread pool threads
800#ifdef IGANET_WITH_OPENMP
801 at::set_num_threads(
802 utils::getenv("IGANET_INTRAOP_NUM_THREADS", omp_get_max_threads()));
803#else
804 at::set_num_threads(utils::getenv("IGANET_INTRAOP_NUM_THREADS", 1));
805#endif
806
807 // Set number of interop thread pool threads
808 at::set_num_interop_threads(utils::getenv("IGANET_INTEROP_NUM_THREADS", 1));
809
810#ifdef IGANET_WITH_MPI
811 int flag;
812 MPI_Initialized(&flag);
813
814 if (flag == 0)
815 if (MPI_Init(NULL, NULL) != MPI_SUCCESS)
816 throw std::runtime_error("An error occurred during MPI initialization");
817
818 int rank;
819 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
820 if (rank == 0)
821#endif
822 // Output version information
823 os << getVersion();
824}
825
830inline void finalize(std::ostream &os = Log(log::info)) {
831
832#if defined(CUDA_VERSION) || defined(HIP_VERSION)
833 std::cout << "\n" << memory_summary() << std::endl;
834#endif
835
836#ifdef IGANET_WITH_MPI
837 if (MPI_Finalize() != MPI_SUCCESS)
838 throw std::runtime_error("An error occurred during MPI finalization");
839#endif
840
841 os << "Succeeded\n";
842}
843
848inline int get_iomanip() {
849 static int i = std::ios_base::xalloc();
850 return i;
851}
852
856inline std::ostream &verbose(std::ostream &os) {
857 os.iword(get_iomanip()) = 1;
858 return os;
859}
863inline std::ostream &regular(std::ostream &os) {
864 os.iword(get_iomanip()) = 0;
865 return os;
866}
867
871inline bool is_verbose(std::ostream &os) {
872 return os.iword(get_iomanip()) != 0;
873}
875
876} // namespace iganet
877
878namespace std {
879
886template <typename T, std::size_t N>
887inline std::ostream &operator<<(std::ostream &os, const std::array<T, N> &obj) {
888 at::optional<std::string> name_ = c10::demangle(typeid(obj).name());
889
890#if defined(_WIN32)
891 // Windows adds "struct" or "class" as a prefix.
892 if (name_->find("struct ") == 0) {
893 name_->erase(name_->begin(), name_->begin() + 7);
894 } else if (name_->find("class ") == 0) {
895 name_->erase(name_->begin(), name_->begin() + 6);
896 }
897#endif // defined(_WIN32)
898
899 os << *name_ << "(";
900 for (const auto &i : obj)
901 os << i << (&i == &(*obj.rbegin()) ? "" : ",");
902 os << ")";
903
904 return os;
905}
906
907namespace detail {
914template <typename... Ts, std::size_t... Is>
915inline std::ostream &output_tuple(std::ostream &os,
916 const std::tuple<Ts...> &obj,
917 std::index_sequence<Is...>) {
918 (..., (os << std::get<Is>(obj) << "\n"));
919 return os;
920}
921
922} // namespace detail
923
929template <typename... Ts>
930inline std::ostream &operator<<(std::ostream &os,
931 const std::tuple<Ts...> &obj) {
932 at::optional<std::string> name_ = c10::demangle(typeid(obj).name());
933
934#if defined(_WIN32)
935 // Windows adds "struct" or "class" as a prefix.
936 if (name_->find("struct ") == 0) {
937 name_->erase(name_->begin(), name_->begin() + 7);
938 } else if (name_->find("class ") == 0) {
939 name_->erase(name_->begin(), name_->begin() + 6);
940 }
941#endif // defined(_WIN32)
942
943 os << *name_ << "(\n";
944 detail::output_tuple(os, obj, std::make_index_sequence<sizeof...(Ts)>());
945 os << "\n)";
946
947 return os;
948}
949
950} // namespace std
Dummy output stream.
Definition core.hpp:124
NullOStream()
Constructor.
Definition core.hpp:127
NullStreamBuffer nullStreamBuffer
Definition core.hpp:130
Dummy stream buffer.
Definition core.hpp:115
int overflow(int c) override
Dummy output.
Definition core.hpp:120
Environment utility function.
T getenv(std::string variable, const T &default_value)
Returns the value from an environment variable.
Definition getenv.hpp:28
Definition core.hpp:73
bool is_verbose(std::ostream &os)
Tests whether verbose output is enabled on a stream.
Definition core.hpp:871
void finalize(std::ostream &os=Log(log::info))
Finalizes the library.
Definition core.hpp:830
struct iganet::@0 Log
Logger.
init
Enumerator for specifying the initialization of B-spline coefficients.
Definition bspline.hpp:58
log
Enumerator for specifying the logging level.
Definition core.hpp:102
@ none
Definition boundary.hpp:38
std::ostream & regular(std::ostream &os)
Disables verbose output on a stream.
Definition core.hpp:863
short int short_t
Signed short integer type used by IgANet's compact enumerations.
Definition core.hpp:76
std::string memory_summary(c10::DeviceIndex device=0)
Return a human-readable printout of the current memory allocator statistics for a given device.
Definition core.hpp:193
int get_iomanip()
Stream manipulators.
Definition core.hpp:848
std::string getVersion()
Returns version information.
Definition sysinfo.hpp:685
std::ostream & output_tuple(std::ostream &os, const std::tuple< Ts... > &obj, std::index_sequence< Is... >)
Writes each element of a tuple to a separate line.
Definition core.hpp:915
STL namespace.
std::ostream & operator<<(std::ostream &os, const std::array< T, N > &obj)
Prints a std::array of generic objects.
Definition core.hpp:887
System information.