TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Process.cpp
1/****************************************************************************
2* Copyright (c) 2026, CEA
3* All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9*
10* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
12* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13*
14*****************************************************************************/
15
16#include <Process.h>
17#include <Comm_Group.h>
18#include <PE_Groups.h>
19#include <communications.h>
20#include <Sortie_Nulle.h>
21#include <Journal.h>
22#include <SFichier.h>
23#include <Synonyme_info.h>
24#include <petsc_for_kernel.h>
25#include <comm_incl.h>
26#include <TRUST_Error.h>
27#include <Comm_Group_MPI.h>
28#include <unistd.h> // sleep() on some machines
29#include <SChaine.h>
30#include <FichierHDFPar.h>
31#include <EChaineJDD.h>
32#include <DeviceMemory.h>
33#include <kokkos++.h>
34#include <fstream>
35
36// Each of Cerr, Cout and Journal(i) can be redirected to one of the following four streams:
37// Null output instance (equivalent of /dev/null)
38static Sortie_Nulle journal_zero_;
39// Output instance pointing to cerr
40static Sortie std_err_(cerr);
41// Output instance pointing to cout
42static Sortie std_out_(cout);
43// Journal file instances
44static SFichier journal_file_;
45
46static int journal_file_open_;
47static Nom journal_file_name_;
48// Maximum level of messages written. The initial value determines
49// whether messages written before journal initialization are written or not.
50static int verbose_level_ = 0;
51static int disable_stop_ = 0;
52
53// Flag indicating whether cerr and cout should be redirected to the journal file
54static int cerr_to_journal_ = 0;
56int Process::multiple_files=5120; // Can be modified via the TRUST_MultipleFiles environment variable
57bool Process::force_single_file(const int ranks, const Nom& filename)
58{
59 char* theValue = getenv("TRUST_MultipleFiles");
60 if (theValue != nullptr) multiple_files=atoi(theValue);
61 if (ranks>multiple_files)
62 {
63 if (Process::je_suis_maitre()) // Necessary: called very early in main.cpp before Cerr is fully defined on all processes
64 {
65 Cerr << "======================================================================================================" << finl;
66 Cerr << "Warning! Single file option is forced for " << filename << " above " << multiple_files << " MPI ranks." << finl;
67 Cerr << "for I/O performance reasons on cluster and inodes number limitation." << finl;
68 Cerr << "If you want to keep multiple files, add at the beginning of your data file to outpass the limitation:" << finl;
69 Cerr << "MultipleFiles " << ranks << finl;
70 Cerr << "=====================================================================================================" << finl;
71 }
72 return true;
73 }
74 else
75 return false;
76}
77
78/*! @brief Returns 1 if on the master processor of the current group (i.e. me() == 0), 0 otherwise.
79 *
80 * @return 1 if master processor, 0 otherwise.
81 */
83{
84 const int r = PE_Groups::current_group().rank();
85 return r == 0;
86}
87
88/*! @brief Returns 1 if on the NUMA node master processor, 0 otherwise.
89 *
90 * @return 1 if node master processor, 0 otherwise.
91 */
93{
94 const int r = PE_Groups::get_node_group().rank();
95 return r == 0;
96}
97
98/*! @brief Returns the number of processors in the current group. See Comm_Group::nproc() and PE_Groups::current_group().
99 *
100 * @return Number of processors in the current group.
101 */
103{
104 const int n = PE_Groups::current_group().nproc();
105 return n;
106}
107
109{
110 return Process::nproc() > 1;
111}
112
114{
115 return Process::nproc() == 1;
116}
117
118/*! @brief Returns the rank of the local processor in the current communication group. See Comm_Group::rank() and PE_Groups::current_group().
119 *
120 * @return Rank in the current group.
121 */
123{
124 const int r = PE_Groups::current_group().rank();
125 return r;
126}
127
128/*! @brief Synchronizes all processors in the current group (waits until all processors have reached the barrier).
129 *
130 * Must be executed on all processors in the group.
131 *
132 */
137
138
139/*! @brief Computes the sum of x over all processors in the current group.
140 *
141 * @param x Value to sum across all processors.
142 * @return Sum of x over all processors in the current group.
143 * @sa mp_max()
144 */
145double Process::mp_sum(double x)
146{
148 double y;
150 return y;
151}
152
153float Process::mp_sum(float x)
154{
156 float y;
158 return y;
159}
160
161/*! @brief Computes the sum of x over all processors in the current group.
162 *
163 * !!! Note that the sum of many int might result in a long !!!
164 *
165 * @param x Value to sum across all processors.
166 * @return Sum of x over all processors in the current group.
167 * @sa mp_max()
168 */
169trustIdType Process::mp_sum(trustIdType x)
170{
172 trustIdType y;
174 return y;
175}
176
177template<typename _TYPE_>
178void mp_collective_op_arr(TRUSTArray<_TYPE_>& x, Comm_Group::Collective_Op op, int n)
179{
180 int sz = n==-1 ? x.size_array() : n;
181 assert_parallel<_TYPE_>(sz);
182 if (sz > 0)
183 {
184 _TYPE_ *data = x.addr();
185 _TYPE_ *tmp = new _TYPE_[sz];
187 grp.mp_collective_op(data, tmp, sz, op);
188 memcpy(data, tmp, sz * sizeof(_TYPE_));
189 delete[] tmp;
190 }
191}
192
193template<typename _TYPE_>
194void Process::mp_sum_for_each_item(TRUSTArray<_TYPE_>& x, int n) { mp_collective_op_arr(x, Comm_Group::COLL_SUM, n); }
195
196template<typename _TYPE_>
197void Process::mp_max_for_each_item(TRUSTArray<_TYPE_>& x, int n) { mp_collective_op_arr(x, Comm_Group::COLL_MAX, n); }
198
199template<typename _TYPE_>
200void Process::mp_min_for_each_item(TRUSTArray<_TYPE_>& x, int n) { mp_collective_op_arr(x, Comm_Group::COLL_MIN, n); }
201
202/*! @brief C++14 compatible mp_sum_for_each: combine multiple mp_sum calls into one collective operation
203 * Usage: mp_sum_for_each(a, b); mp_sum_for_each(a, b, c); mp_sum_for_each(a, b, c, d); mp_sum_for_each(a, b, c, d, e);
204 * All arguments must be of the same type (double or int) and are modified in place.
205 * Supports 2-5 parameters.
206 */
207template<typename T>
208void Process::mp_sum_for_each(T& arg1, T& arg2)
209{
210 T data[2] = {arg1, arg2};
211 T tmp[2];
213 grp.mp_collective_op(data, tmp, 2, Comm_Group::COLL_SUM);
214 arg1 = tmp[0];
215 arg2 = tmp[1];
216}
217
218template<typename T>
219void Process::mp_sum_for_each(T& arg1, T& arg2, T& arg3)
220{
221 T data[3] = {arg1, arg2, arg3};
222 T tmp[3];
224 grp.mp_collective_op(data, tmp, 3, Comm_Group::COLL_SUM);
225 arg1 = tmp[0];
226 arg2 = tmp[1];
227 arg3 = tmp[2];
228}
229
230template<typename T>
231void Process::mp_sum_for_each(T& arg1, T& arg2, T& arg3, T& arg4)
232{
233 T data[4] = {arg1, arg2, arg3, arg4};
234 T tmp[4];
236 grp.mp_collective_op(data, tmp, 4, Comm_Group::COLL_SUM);
237 arg1 = tmp[0];
238 arg2 = tmp[1];
239 arg3 = tmp[2];
240 arg4 = tmp[3];
241}
242
243/*! @brief C++14 compatible mp_max_for_each: combine multiple mp_max calls into one collective operation */
244template<typename T>
245void Process::mp_max_for_each(T& arg1, T& arg2)
246{
247 T data[2] = {arg1, arg2};
248 T tmp[2];
250 grp.mp_collective_op(data, tmp, 2, Comm_Group::COLL_MAX);
251 arg1 = tmp[0];
252 arg2 = tmp[1];
253}
254
255template<typename T>
256void Process::mp_max_for_each(T& arg1, T& arg2, T& arg3)
257{
258 T data[3] = {arg1, arg2, arg3};
259 T tmp[3];
261 grp.mp_collective_op(data, tmp, 3, Comm_Group::COLL_MAX);
262 arg1 = tmp[0];
263 arg2 = tmp[1];
264 arg3 = tmp[2];
265}
266
267template<typename T>
268void Process::mp_max_for_each(T& arg1, T& arg2, T& arg3, T& arg4)
269{
270 T data[4] = {arg1, arg2, arg3, arg4};
271 T tmp[4];
273 grp.mp_collective_op(data, tmp, 4, Comm_Group::COLL_MAX);
274 arg1 = tmp[0];
275 arg2 = tmp[1];
276 arg3 = tmp[2];
277 arg4 = tmp[3];
278}
279
280/*! @brief C++14 compatible mp_min_for_each: combine multiple mp_min calls into one collective operation */
281template<typename T>
282void Process::mp_min_for_each(T& arg1, T& arg2)
283{
284 T data[2] = {arg1, arg2};
285 T tmp[2];
287 grp.mp_collective_op(data, tmp, 2, Comm_Group::COLL_MIN);
288 arg1 = tmp[0];
289 arg2 = tmp[1];
290}
291
292template<typename T>
293void Process::mp_min_for_each(T& arg1, T& arg2, T& arg3)
294{
295 T data[3] = {arg1, arg2, arg3};
296 T tmp[3];
298 grp.mp_collective_op(data, tmp, 3, Comm_Group::COLL_MIN);
299 arg1 = tmp[0];
300 arg2 = tmp[1];
301 arg3 = tmp[2];
302}
303
304template<typename T>
305void Process::mp_min_for_each(T& arg1, T& arg2, T& arg3, T& arg4)
306{
307 T data[4] = {arg1, arg2, arg3, arg4};
308 T tmp[4];
310 grp.mp_collective_op(data, tmp, 4, Comm_Group::COLL_MIN);
311 arg1 = tmp[0];
312 arg2 = tmp[1];
313 arg3 = tmp[2];
314 arg4 = tmp[3];
315}
316
317// 5-parameter versions
318template<typename T>
319void Process::mp_sum_for_each(T& arg1, T& arg2, T& arg3, T& arg4, T& arg5)
320{
321 T data[5] = {arg1, arg2, arg3, arg4, arg5};
322 T tmp[5];
324 grp.mp_collective_op(data, tmp, 5, Comm_Group::COLL_SUM);
325 arg1 = tmp[0];
326 arg2 = tmp[1];
327 arg3 = tmp[2];
328 arg4 = tmp[3];
329 arg5 = tmp[4];
330}
331
332template<typename T>
333void Process::mp_max_for_each(T& arg1, T& arg2, T& arg3, T& arg4, T& arg5)
334{
335 T data[5] = {arg1, arg2, arg3, arg4, arg5};
336 T tmp[5];
338 grp.mp_collective_op(data, tmp, 5, Comm_Group::COLL_MAX);
339 arg1 = tmp[0];
340 arg2 = tmp[1];
341 arg3 = tmp[2];
342 arg4 = tmp[3];
343 arg5 = tmp[4];
344}
345
346template<typename T>
347void Process::mp_min_for_each(T& arg1, T& arg2, T& arg3, T& arg4, T& arg5)
348{
349 T data[5] = {arg1, arg2, arg3, arg4, arg5};
350 T tmp[5];
352 grp.mp_collective_op(data, tmp, 5, Comm_Group::COLL_MIN);
353 arg1 = tmp[0];
354 arg2 = tmp[1];
355 arg3 = tmp[2];
356 arg4 = tmp[3];
357 arg5 = tmp[4];
358}
359
360namespace
361{
362
363template <typename T>
364T mp_operations_commun_(T x, Comm_Group::Collective_Op op)
365{
367 T y;
368 grp.mp_collective_op(&x, &y, 1, op);
369 return y;
370}
371}
372
373/*! @brief Returns the maximum value of x across all processors in the current group.
374 *
375 * @param x Value to reduce with max operation.
376 * @return Maximum value of x across all processors.
377 */
378int Process::mp_max(int x) { return mp_operations_commun_(x,Comm_Group::COLL_MAX); }
379double Process::mp_max(double x) { return mp_operations_commun_(x,Comm_Group::COLL_MAX); }
380#if INT_is_64_ == 2
381trustIdType Process::mp_max(trustIdType x) { return mp_operations_commun_(x,Comm_Group::COLL_MAX); }
382#endif
383
384
385/*! @brief Returns the minimum value of x across all processors in the current group.
386 *
387 * @param x Value to reduce with min operation.
388 * @return Minimum value of x across all processors.
389 */
390int Process::mp_min(int x) { return mp_operations_commun_(x,Comm_Group::COLL_MIN); }
391double Process::mp_min(double x) { return mp_operations_commun_(x,Comm_Group::COLL_MIN); }
392#if INT_is_64_ == 2
393trustIdType Process::mp_min(trustIdType x) { return mp_operations_commun_(x,Comm_Group::COLL_MIN); }
394#endif
395
396/*! @brief Computes the partial sum of x over processors 0 to me()-1 (returns 0 on processor 0).
397 *
398 * @param x Value to include in the partial sum.
399 * @return Partial sum of x over processors 0 to me()-1.
400 * @sa Comm_Group::mppartial_sum()
401 *
402 */
403trustIdType Process::mppartial_sum(trustIdType x)
404{
406 trustIdType xx = x;
407 trustIdType y;
408
410 return y;
411}
412
413/*! @brief Computes the logical AND of b across all processors in the current group.
414 *
415 * @param b Boolean value to reduce with AND operation.
416 * @return True if b is true on all processors, false otherwise.
417 */
418bool Process::mp_and(bool b)
419{
421 int x = b ? 1 : 0;
422 int y;
424 return y == 1;
425}
426
427bool Process::mp_or(bool b)
428{
430 int x = b ? 1 : 0;
431 int y;
433 return y == 1;
434}
435
436
438{
439 if (v >= std::numeric_limits<int>::max())
440 Process::exit("Value too big - above 32b and can not be converted to int!!");
441 return static_cast<int>(v);
442}
443
444/*! @brief Exit routine for TRUST within a Kokkos region.
445 *
446 */
447/*
448KOKKOS_FUNCTION
449void Process::Kokkos_exit(const char* str)
450{
451#ifdef TRUST_USE_GPU
452 // ToDo Kokkos: try to exit more properly on device...
453 Kokkos::abort(str);
454 //Kokkos::finalize();
455#else
456 Process::exit(str);
457#endif
458}*/
459
460/*! @brief Exit routine for TRUST on error.
461 *
462 * Saves memory and hierarchy information to files "memoire.dump" and "hierarchie.dump".
463 *
464 * @param i Exit code (forced to -1 if 0).
465 */
466void Process::exit(int i)
467{
468 Nom message="=========================================\nTRUST has caused an error and will stop.\nUnexpected error during TRUST calculation.";
469 std::string jddLine = "\nError triggered at line " + std::to_string(EChaineJDD::file_cur_line_) + " in " + Objet_U::nom_du_cas().getString() + ".data";
470 message+=jddLine;
471 exit(message,i);
472}
473void Process::exit(const Nom& message ,int i)
474{
475 if (exception_sur_exit == 2)
476 {
477 ::exit(-1); // ND 11/01/23 a second ::exit(-1) is used in TRUST because if write permissions are missing, Process::exit() would be called recursively
478 }
479
480 if(je_suis_maitre())
481 {
482 Cerr << message << finl;
483 Cerr.flush();
484 if (!get_disable_stop() && Process::je_suis_maitre())
485 {
486 Nom nomfic( Objet_U::nom_du_cas() );
487 nomfic += ".stop";
488 {
489 SFichier ficstop( nomfic );
490 ficstop <<message<<finl;
491 }
492 }
493 }
494 Journal() << message << finl;
495
497 {
498 // Throw an exception (used by Execute_parallel)
499 throw TRUST_Error("Error in trust ",Process::me());
500 }
501 else
502 {
503 int abort=0;
504#ifdef MPI_
506 {
507 // user defined groups (if any !)
509 {
511 if (sub_type(Comm_Group_MPI,grp))
512 ref_cast_non_const(Comm_Group_MPI,grp).free_all(); // free comm + group
513 }
514
515 const MPI_Comm& mpi_comm=ref_cast(Comm_Group_MPI,PE_Groups::groupe_TRUST()).get_mpi_comm();
516 int tag = 666;
517 int buffer[1]= {1};
518 MPI_Request request;
519
520 // Non-blocking send to me()+1
521 int to_pe = (me()==nproc()-1?0:me()+1);
522 MPI_Isend(buffer, 1, MPI_ENTIER, to_pe, tag, mpi_comm, &request);
523
524 // Non-blocking receive from me()-1
525 int from_pe = (me()==0?nproc()-1:me()-1);
526 MPI_Irecv(buffer, 1, MPI_ENTIER, from_pe, tag, mpi_comm, &request);
527
528 // Wait
529 sleep(1);
530
531 // Check if me() received from me()-1
532 int ok;
533 MPI_Status status;
534 MPI_Test(&request,&ok,&status);
535 if (!ok)
536 abort=1;
537 }
538#endif
539 if (abort)
540 {
541 if (!je_suis_maitre())
542 {
543 std_err_ << "!!! TRUST process number " << Process::me() << " exited unexpectedly ! See error message at the end of the file " << journal_file_name_ << " -> Aborting calculation..." << finl;
544 }
546 }
547 else
548 {
549#ifdef MPI_
550 // On MPI_Finalize si MPI_Initialized and not MPI_Finalized
551 int flag;
552 MPI_Initialized(&flag);
553 if (flag)
554 {
555 MPI_Finalized(&flag);
556 if (!flag)
557 MPI_Finalize();
558 }
559#endif
561 }
562 }
563 Kokkos::finalize();
564 // Force exit
565 if (i==0) i=-1;
566 ::exit(i); // Only ::exit used in the code until 01/23. A second one was added because Process::exit is called recursively if the study directory write permissions are missing.
567}
568
569/*! @brief Abort routine for TRUST on a fatal error.
570 *
571 * In optimized mode, exits cleanly. In debug mode, aborts abruptly to allow debugger inspection.
572 */
574{
575#ifdef NDEBUG
576 // In optimized mode, exit cleanly.
577 exit();
578#else
579 // In debug mode, abort abruptly to capture debugger info.
580 ::abort(); // Only ::abort() used in the code
581#endif
582}
583
584/*! @brief Returns a static Sortie object used as an event journal.
585 *
586 * If message_level <= verbose_level_, the message is written; otherwise it is discarded to a Sortie_Nulle.
587 * If the journal file is open, messages are written to the file; otherwise to stderr.
588 *
589 * @param message_level Level of the message. Written only if <= verbose_level_.
590 * @return Reference to the appropriate Sortie output stream.
591 */
592Sortie& Process::Journal(int message_level)
593{
594 if (message_level <= verbose_level_ && verbose_level_ > 0)
595 {
596 if (journal_file_open_)
597 return journal_file_;
598 else
599 return std_err_;
600 }
601 return journal_zero_;
602}
603
604// Returns the RAM used by the current processor.
606{
607#ifdef PETSCKSP_H
608 PetscLogDouble memoire;
609 PetscMemoryGetCurrentUsage(&memoire);
610 return memoire;
611#else
612 return 0;
613#endif
614}
615#include <sys/resource.h>
616double ru_maxrss()
617{
618 // Best to track OOM
619 struct rusage usage;
620 getrusage(RUSAGE_SELF, &usage);
621 // ru_maxrss is in kilobytes
622 long rss_kb = usage.ru_maxrss;
623 return static_cast<double>(rss_kb*1024);
624}
625
626#ifndef __APPLE__
627#include <malloc.h>
628
629/*
630struct mallinfo2 {
631 size_t hblkhd; // Space in mmapped regions (bytes)
632 size_t hblks; // Number of mmapped regions
633 size_t usmblks; // Always 0 (obsolete field)
634 size_t fsmblks; // Always 0 (obsolete field)
635 size_t uordblks; // Total allocated space (bytes)
636 size_t fordblks; // Total free space (bytes)
637 size_t keepcost; // Top-most, releasable space (bytes)
638};
639*/
640double heap_allocation()
641{
642 // Best to track memory leak
643#if defined(__GLIBC__) && __GLIBC_PREREQ(2, 33)
644 struct mallinfo2 info = mallinfo2();
645#else
646 struct mallinfo info = mallinfo();
647#endif
648 return (double)info.uordblks;
649}
650
651static double heap_allocated_old=0;
652
653#endif /* ndef __APPLE__ */
654
655void Process::imprimer_ram_totale(int all_process)
656{
657 double memoire;
658 //memoire = ram_processeur();
659 memoire = ru_maxrss();
660
661#ifndef __APPLE__
662 double heap_allocated = heap_allocation();
663#endif
664
665 if (memoire)
666 {
667 //Cout << "RAM preliminary: PETSc " << ram_processeur() << " ru_maxrss " << memoire << " mallinfo " << heap_allocated << finl;
668 int Mo=1024*1024;
669 if (all_process) Journal() << (int)(memoire/Mo) << " MBytes of RAM taken by the processor " << Process::me() << finl;
670 {
671 double max_memoire=Process::mp_max(memoire);
672 double total_memoire=Process::mp_sum(memoire);
673 Cout << (int)(total_memoire/Mo) << " MBytes of RAM taken by the calculation (max on a rank: "<<(int)(max_memoire/Mo)<<" MB)." << finl;
674#ifndef __APPLE__
675 Cout << "[RAM] Allocated heap on master rank: " << (int)(heap_allocated/Mo) << " Mbytes";
676 double delta = heap_allocated - heap_allocated_old;
677 if (delta!=0 && heap_allocated_old>0) Cout << " (" << (delta>0 ? "+" : "") << (long)delta << " bytes)";
678 Cout << finl;
679 heap_allocated_old = heap_allocated;
680#ifdef TRUST_USE_GPU
681 int Go = 1024 * Mo;
682 double allocated = mp_max((double)DeviceMemory::allocatedBytesOnDevice());
683 double total = static_cast<double>(DeviceMemory::deviceMemGetInfo(1));
684 Cout << 0.1*(int)(10*allocated/Go) << " GBytes of maximal RAM allocated on a GPU (" << int(100 * allocated / total) << "%)" << finl;
685#endif
686#endif /* ndef __APPLE__ */
687 }
688#ifdef TRUST_USE_ROCM /* Only on adastra */
689 // SUnreclaim on each process:
690 std::ifstream meminfo("/proc/meminfo");
691 std::string line;
692 size_t sunreclaim_kb = 0;
693 size_t mem_available_kb = 0;
694 size_t mem_total_kb = 0;
695 while (std::getline(meminfo, line))
696 {
697 if (line.substr(0, 9) == "MemTotal:")
698 {
699 size_t pos = line.find_first_of("0123456789");
700 mem_total_kb = std::stoull(line.substr(pos));
701 }
702 if (line.substr(0, 13) == "MemAvailable:")
703 {
704 size_t pos = line.find_first_of("0123456789");
705 mem_available_kb = std::stoull(line.substr(pos));
706 }
707 if (line.substr(0, 11) == "SUnreclaim:")
708 {
709 size_t pos = line.find_first_of("0123456789");
710 sunreclaim_kb = std::stoull(line.substr(pos));
711 break;
712 }
713 }
714 Process::Journal() << "[RAM] SUnreclaim: " << sunreclaim_kb/1024 << " MB MemAvailable: " << mem_available_kb/1024 << " MB MemTotal: " << mem_total_kb/1024 << " MB " << finl;
715#endif
716 }
717}
718
719/*! @brief Initializes the journal file.
720 *
721 * @param verbose_level Messages at level <= verbose_level will be printed; others are discarded.
722 * @param file_name If null pointer, everyone writes to cerr; otherwise the name of the file (must be different on each processor).
723 * @param append Indicates whether the file is opened in append mode or not.
724 */
725void init_journal_file(int verbose_level, const char * file_name, int append)
726{
727 end_journal(verbose_level);
728
729 if (verbose_level > 0)
730 {
731 if (file_name)
732 {
733 IOS_OPEN_MODE mode = ios::out;
734 if (append)
735 mode = ios::app;
736 if (!journal_file_.ouvrir(file_name, mode))
737 {
738 Cerr << "Fatal error in init_journal_file: cannot open journal file" << finl;
740 }
741
742 journal_file_open_ = 1;
743 journal_file_name_ = file_name;
744 }
745 }
746 verbose_level_ = verbose_level;
747}
748
749void end_journal(int verbose_level)
750{
751 // Note: careful handling so that it "fails cleanly" if the destructor
752 // writes to the journal!
753 journal_file_.close();
754 journal_file_open_ = 0;
755}
756
757/*! @brief Returns the Sortie object to which Cerr output is redirected.
758 *
759 * This can be std_err_ or journal_file_.
760 *
761 * @return Reference to the output stream used for Cerr.
762 */
763Sortie& get_Cerr()
764{
765 if (journal_file_open_ && cerr_to_journal_)
766 return journal_file_;
767 else
768 {
769 // If groups have not been initialized yet,
770 // we cannot test whether we are the master.
772 return std_err_;
773 // Only the master processor writes to std_err_; others write to journal_file_
775 return std_err_;
776 else if (verbose_level_)
777 return journal_file_;
778 else
779 return journal_zero_;
780 }
781}
782
783/*! @brief Returns cout or the journal file on the master processor, or journal_zero_ otherwise.
784 *
785 * @return Reference to the output stream used for Cout.
786 * @sa cerr_to_journal_
787 *
788 */
789Sortie& get_Cout()
790{
792 {
793 if (journal_file_open_ && cerr_to_journal_)
794 return journal_file_;
795 else
796 return std_out_;
797 }
798 else
799 {
800 return journal_zero_;
801 }
802}
803
804/*! @brief Changes the destination of Cerr and Cout.
805 *
806 * If flag=0, output goes to stderr and stdout; otherwise, if the journal file is open, output goes to
807 * the journal; otherwise output goes to Sortie_Nulle.
808 *
809 * @param flag If 0, use stderr/stdout; if non-zero, redirect to journal or Sortie_Nulle.
810 */
811void set_Cerr_to_journal(int flag)
812{
813 cerr_to_journal_ = flag;
814}
815
816int get_journal_level()
817{
818 return verbose_level_;
819}
820
821void change_journal_level(int level)
822{
823 verbose_level_ = level;
824}
825
826/*! @brief Returns the disable_stop_ flag (Disable or not the writing of the .
827 *
828 * stop file)
829 *
830 */
831int get_disable_stop()
832{
833 return disable_stop_;
834}
835
836/*! @brief Affects a new value to disable_stop_ flag (Disable or not the writing of the .
837 *
838 * stop file)
839 *
840 */
841void change_disable_stop(int new_stop)
842{
843 disable_stop_ = new_stop;
844}
845
846// Explicit template instantiations for mp_*_for_each_item
854
855// Explicit template instantiations for mp_*_for_each (C++14 overloads)
856// mp_sum_for_each
857template void Process::mp_sum_for_each<double>(double&, double&);
858template void Process::mp_sum_for_each<double>(double&, double&, double&);
859template void Process::mp_sum_for_each<double>(double&, double&, double&, double&);
860template void Process::mp_sum_for_each<double>(double&, double&, double&, double&, double&);
861template void Process::mp_sum_for_each<int>(int&, int&);
862template void Process::mp_sum_for_each<int>(int&, int&, int&);
863template void Process::mp_sum_for_each<int>(int&, int&, int&, int&);
864template void Process::mp_sum_for_each<int>(int&, int&, int&, int&, int&);
865// mp_max_for_each
866template void Process::mp_max_for_each<double>(double&, double&);
867template void Process::mp_max_for_each<double>(double&, double&, double&);
868template void Process::mp_max_for_each<double>(double&, double&, double&, double&);
869template void Process::mp_max_for_each<double>(double&, double&, double&, double&, double&);
870template void Process::mp_max_for_each<int>(int&, int&);
871template void Process::mp_max_for_each<int>(int&, int&, int&);
872template void Process::mp_max_for_each<int>(int&, int&, int&, int&);
873template void Process::mp_max_for_each<int>(int&, int&, int&, int&, int&);
874// mp_min_for_each
875template void Process::mp_min_for_each<double>(double&, double&);
876template void Process::mp_min_for_each<double>(double&, double&, double&);
877template void Process::mp_min_for_each<double>(double&, double&, double&, double&);
878template void Process::mp_min_for_each<double>(double&, double&, double&, double&, double&);
879template void Process::mp_min_for_each<int>(int&, int&);
880template void Process::mp_min_for_each<int>(int&, int&, int&);
881template void Process::mp_min_for_each<int>(int&, int&, int&, int&);
882template void Process::mp_min_for_each<int>(int&, int&, int&, int&, int&);
: Class Comm_Group_MPI, derived from the abstract class Comm_Group.
: This class describes a group of processors on which
Definition Comm_Group.h:37
@ COLL_PARTIAL_SUM
Definition Comm_Group.h:49
int nproc() const
Returns the number of processors in the group *this.
Definition Comm_Group.h:185
int rank() const
Returns the rank of the local processor in the group *this.
Definition Comm_Group.h:177
virtual void abort() const =0
virtual void mp_collective_op(const double *x, double *resu, int n, Collective_Op op) const =0
virtual void barrier(int tag) const =0
static int file_cur_line_
Definition EChaineJDD.h:45
class Nom: a character string for naming TRUST objects.
Definition Nom.h:31
const std::string & getString() const
Definition Nom.h:92
static const Nom & nom_du_cas()
Returns a constant reference to the case name. This method is static.
Definition Objet_U.cpp:145
static const int & get_nb_groups()
static void finalize()
Method to call at the end of execution, once back in groupe_TRUST() and just before destroying the ma...
static const Comm_Group & get_user_defined_group()
Returns a reference to the user-defined group.
static const Comm_Group & get_node_group()
Returns a reference to the node-level communicator group.
static bool has_user_defined_group()
static const Comm_Group & current_group()
Returns a reference to the current active processor group.
Definition PE_Groups.h:64
static const Comm_Group & groupe_TRUST()
Returns a reference to the group containing all TRUST processors.
static void mp_max_for_each_item(TRUSTArray< _TYPE_ > &x, int n=-1)
Definition Process.cpp:197
static double mp_min(double)
Definition Process.cpp:391
static int check_int_overflow(trustIdType)
Definition Process.cpp:437
static void mp_sum_for_each(T &arg1, T &arg2)
C++14 compatible mp_sum_for_each: combine multiple mp_sum calls into one collective operation Usage: ...
Definition Process.cpp:208
static double ram_processeur()
Definition Process.cpp:605
static trustIdType mppartial_sum(trustIdType i)
Computes the partial sum of x over processors 0 to me()-1 (returns 0 on processor 0).
Definition Process.cpp:403
static int multiple_files
Definition Process.h:162
static double mp_max(double)
Definition Process.cpp:379
static void mp_sum_for_each_item(TRUSTArray< _TYPE_ > &x, int n=-1)
Definition Process.cpp:194
static bool mp_or(bool)
Definition Process.cpp:427
static int node_master()
Returns 1 if on the NUMA node master processor, 0 otherwise.
Definition Process.cpp:92
static bool is_parallel()
Definition Process.cpp:108
static Sortie & Journal(int message_level=0)
Returns a static Sortie object used as an event journal.
Definition Process.cpp:592
static void abort()
Abort routine for TRUST on a fatal error.
Definition Process.cpp:573
static int nproc()
Returns the number of processors in the current group. See Comm_Group::nproc() and PE_Groups::current...
Definition Process.cpp:102
static double mp_sum(double)
Computes the sum of x over all processors in the current group.
Definition Process.cpp:145
static void mp_max_for_each(T &arg1, T &arg2)
C++14 compatible mp_max_for_each: combine multiple mp_max calls into one collective operation.
Definition Process.cpp:245
static void imprimer_ram_totale(int all_process=0)
Definition Process.cpp:655
static void barrier()
Synchronizes all processors in the current group (waits until all processors have reached the barrier...
Definition Process.cpp:133
static bool force_single_file(const int ranks, const Nom &filename)
Definition Process.cpp:57
static void mp_min_for_each(T &arg1, T &arg2)
C++14 compatible mp_min_for_each: combine multiple mp_min calls into one collective operation.
Definition Process.cpp:282
static int exception_sur_exit
Definition Process.h:161
static int me()
Returns the rank of the local processor in the current communication group. See Comm_Group::rank() an...
Definition Process.cpp:122
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
static int je_suis_maitre()
Returns 1 if on the master processor of the current group (i.e. me() == 0), 0 otherwise.
Definition Process.cpp:82
static void mp_min_for_each_item(TRUSTArray< _TYPE_ > &x, int n=-1)
Definition Process.cpp:200
static bool is_sequential()
Definition Process.cpp:113
static bool mp_and(bool)
Computes the logical AND of b across all processors in the current group.
Definition Process.cpp:418
SFichier is to the C++ ofstream class what Sortie is to the C++ ostream class.
Definition SFichier.h:29
Derived class of Sortie that sends data nowhere (it is a sink). Used in Journal() when logging is dis...
Base class for output streams.
Definition Sortie.h:52
Represents a an array of int/int64/double/... values.
Definition TRUSTArray.h:81
_SIZE_ size_array() const
_TYPE_ * addr()
TRUST_Error class.
Definition TRUST_Error.h:25
static size_t allocatedBytesOnDevice()
static size_t deviceMemGetInfo(bool)