23#ifndef NO_AUTO_FML_SETUP
29 [[maybe_unused]]
MemoryLog * MemoryLog::instance =
nullptr;
47 auto udist = std::uniform_real_distribution<double>(0.0, 1.0);
55 void init_mpi([[maybe_unused]]
int * argc, [[maybe_unused]]
char *** argv) {
59 MPI_Init_thread(argc, argv, MPI_THREAD_FUNNELED, &provided);
73 MPI_Comm_rank(MPI_COMM_WORLD, &
ThisTask);
74 MPI_Comm_size(MPI_COMM_WORLD, &
NTasks);
76 char pname[MPI_MAX_PROCESSOR_NAME];
77 MPI_Get_processor_name(pname, &plen);
89 int id = omp_get_thread_num();
107 std::cout <<
"#=====================================================\n";
108 std::cout <<
"# ________________ .____ \n";
109 std::cout <<
"# \\_ _____/ \\ | | \n";
110 std::cout <<
"# | __)/ \\ / \\| | \n";
111 std::cout <<
"# | \\/ Y \\ |___ \n";
112 std::cout <<
"# \\___ /\\____|__ /_______ \\ \n";
113 std::cout <<
"# \\/ \\/ \\/ \n";
116 std::cout <<
"# Initializing FML, MPI and FFTW\n";
118 std::cout <<
"# MPI is enabled. Running with " <<
NTasks <<
" MPI tasks\n";
120 std::cout <<
"# MPI is *not* enabled\n";
123 std::cout <<
"# OpenMP is enabled. Main task has " <<
NThreads <<
" threads availiable\n";
125 std::cout <<
"# OpenMP is *not* enabled\n";
127#if defined(USE_MPI) && defined(USE_OMP)
128 std::cout <<
"# MPI + Threads is" << (
FML::MPIThreadsOK ?
" " :
" *not* ") <<
"working\n";
131 std::cout <<
"# FFTW is enabled. ";
132 std::cout <<
"Thread support is" << (
FML::FFTWThreadsOK ?
" " :
" *not* ") <<
"enabled\n";
134 std::cout <<
"# FFTW is *not* enabled\n";
137 std::cout <<
"# List of tasks:\n";
140 for (
int i = 0; i <
NTasks; i++) {
142 std::cout <<
"# Task " << std::setw(4) << i <<
" [" <<
processor_name <<
"]\n";
143 std::cout <<
"# x-domain [" << std::setw(8) <<
FML::xmin_domain <<
" , " << std::setw(8)
149 MPI_Barrier(MPI_COMM_WORLD);
150 std::this_thread::sleep_for(std::chrono::milliseconds(1));
155 std::cout << std::flush;
157 std::cout <<
"#=====================================================\n";
162 MPI_Barrier(MPI_COMM_WORLD);
163 std::this_thread::sleep_for(std::chrono::milliseconds(1));
172 MPI_Abort(MPI_COMM_WORLD, exit_code);
197 std::vfprintf(stdout, fmt, argp);
210 int status = mkdir(foldername.c_str(), 0777);
211 ok = not((status < 0) && (errno != EEXIST));
213 throw std::runtime_error(
"Failed to create snapshot folder [" + foldername +
"]");
226 return {currentSize_bytes, peakSize_bytes};
235 double cur_rss = sysmem.first / 1e6;
236 double peak_rss = sysmem.second / 1e6;
237 double min_cur_rss = cur_rss;
238 double max_cur_rss = cur_rss;
239 double min_peak = peak_rss;
240 double max_peak = peak_rss;
246 std::cout <<
"#=====================================================\n";
247 std::cout <<
"# System memory use (resident set size): \n";
248 std::cout <<
"# Current RSS: " << std::setw(15) << min_cur_rss <<
" MB (min over tasks)\n";
249 std::cout <<
"# Current RSS: " << std::setw(15) << max_cur_rss <<
" MB (max over tasks)\n";
250 std::cout <<
"# Peak RSS: " << std::setw(15) << min_peak <<
" MB (min over tasks)\n";
251 std::cout <<
"# Peak RSS: " << std::setw(15) << max_peak <<
" MB (max over tasks)\n";
252 std::cout <<
"#=====================================================\n";
258 template std::vector<TYPE> GatherFromTasks<TYPE>(TYPE *); \
259 template void MinOverTasks<TYPE>(TYPE *); \
260 template void MaxOverTasks<TYPE>(TYPE *); \
261 template void SumOverTasks<TYPE>(TYPE *); \
262 template void SumArrayOverTasks<TYPE>(TYPE *, int);
279 void init_fftw([[maybe_unused]]
int * argc, [[maybe_unused]]
char *** argv) {
280#if defined(USE_FFTW) && defined(USE_FFTW_THREADS)
288#if defined(USE_FFTW) && defined(USE_MPI)
294#if defined(USE_FFTW) && defined(USE_MPI)
301#if defined(USE_FFTW) && defined(USE_FFTW_THREADS)
303 SET_FFTW_NTHREADS(nthreads);
static std::string processor_name
size_t getCurrentRSS()
Returns the current resident set size (physical memory use) measured in bytes, or zero if the value c...
size_t getPeakRSS()
Returns the peak (maximum so far) resident set size (physical memory use) measured in bytes,...
Logs all heap allocations in the code that are larger than min_bytes_to_log.
Class for performing timings of the code using std::chrono.
void init_fftw(int *argc, char ***argv)
void set_fftw_nthreads(int nthreads)
bool create_folder(std::string foldername)
double xmax_domain
The local extent of the domain (global domain goes from 0 to 1)
void MinOverTasks(T *value)
Inplace min over tasks of a single value.
std::pair< double, double > get_system_memory_use()
Fetch the resident set size currently and the peak value so far of it.
int NThreads
Total number of threads availiable.
bool MPIThreadsOK
If MPI and threads can work together with FFTW.
void init_mpi(int *argc, char ***argv)
Initialize MPI.
void MaxOverTasks(T *value)
Inplace max over tasks of a single value.
void abort_mpi(int exit_code)
int ThisTask
The MPI task number.
void printf_mpi(const char *fmt,...)
void print_system_memory_use()
Print the resident set size and the peak value of it so far.
FML::UTILS::Timings global_timer
void info()
Show some info about FML.
double xmin_domain
The local extent of the domain (global domain goes from 0 to 1)
int NTasks
Total number of MPI tasks.
void init_fml()
Initialize the global variables within FML We here assume MPI has been initialized.
Singleton for initializing and cleaning up FML Takes care of automatically initializing MPI and FFTW.
static FMLSetup & init(int *argc=nullptr, char ***argv=nullptr)