MAIA bb96820c
Multiphysics at AIA
Loading...
Searching...
No Matches
environment.cpp
Go to the documentation of this file.
1// Copyright (C) 2024 The m-AIA AUTHORS
2//
3// This file is part of m-AIA (https://git.rwth-aachen.de/aia/m-AIA/m-AIA)
4//
5// SPDX-License-Identifier: LGPL-3.0-only
6
7#include "environment.h"
8
9#include <array>
10#if defined(MAIA_MS_COMPILER)
11#include <Windows.h>
12#include <Winsock2.h>
13#include <direct.h>
14#else
15#include <dirent.h>
16#ifndef _SX
17#include <getopt.h>
18#endif
19#include <pwd.h>
20#include <unistd.h>
21#endif
22#include <ctime> // Needed for generating time strings
23#include <fcntl.h>
24#include <omp.h>
25#include <sys/stat.h>
26#include <sys/types.h>
27#include "application.h"
28#include "globals.h"
29
30#ifdef _SX
31#include <sys/socket.h>
32#endif
33
34#ifdef _OPENMP
35#include <omp.h>
36#endif
37
38using namespace std;
39
41
44
45Environment::Environment(MInt argc, char** argv) {
46 TRACE();
47
48 NEW_TIMER_GROUP(tg_newenv, "New environment");
49 NEW_TIMER(t_completenewenv, "complete new environment", tg_newenv);
50 RECORD_TIMER_START(t_completenewenv);
51
52 // Copy command line parameters to member variables and process them
53 NEW_SUB_TIMER(t_parseCL, "parse command line", t_completenewenv);
54 RECORD_TIMER_START(t_parseCL);
58 RECORD_TIMER_STOP(t_parseCL);
59
60 // After parsing optional command line arguments, print startup information
61 if(globalDomainId() == 0) {
63 }
64
65 // In order to read the property file via ParallelIo a (small) scratch is necessary
66 // Since the properties which define the actual scratch are not known yet
67 // a size of 1000 should be sufficient to perform all property related IO
68 NEW_SUB_TIMER(t_readProp, "read property file", t_completenewenv);
69 RECORD_TIMER_START(t_readProp);
70 MInt tmpScratchNoCells = 750000;
71 mScratch = new Scratch(1.0, tmpScratchNoCells);
72
73 // Read in property file so that all properties are available from this point on
74 DEBUG("Environment:: Context::readPropertyFile", MAIA_DEBUG_IO);
75 if(m_propertyFileInput.find(".toml") == MString::npos) {
77 } else {
79 }
80 // Delete the temporary scratch
81 delete mScratch;
82
83 RECORD_TIMER_STOP(t_readProp);
84
85 // Read in properties on maximum number of cells to know how much scratch space needs to be allocated
94#ifdef _OPENMP
95 // use value from properties file, if not given, use value from environment, if not set, use omp=1
96 MInt maxNoOMPThreads = 1;
97 if(getenv("OMP_NUM_THREADS")) {
98 maxNoOMPThreads = atoi(getenv("OMP_NUM_THREADS"));
99 }
100 maxNoOMPThreads = Context::getBasicProperty<MInt>("numOMPThreads", AT_, &maxNoOMPThreads);
101 omp_set_num_threads(maxNoOMPThreads);
102#endif
103
104 MInt maxNoCells = Context::getBasicProperty<MInt>("maxNoCells", AT_);
105 if(Context::propertyExists("noDomains")) {
106 const MInt testNoDomains = Context::getBasicProperty<MInt>("noDomains", AT_, 0);
107 if(globalNoDomains() < testNoDomains) {
108 // Here, the number of maxNoCells is scaled. This is useful if a test
109 // case is specified to run with a certain number of ranks
110 // ('noDomains' property in run.toml) but needs to be run on a lower
111 // number of mpiranks, p.e. by running maia on an accelerator.
112 maxNoCells *= testNoDomains / (MFloat)globalNoDomains();
113 cerr0 << "noDomain > number of used mpi ranks! Therefore, increasing maxNoCells: " << maxNoCells << std::endl;
114 }
115 }
116
125 NEW_SUB_TIMER(t_allocScratch, "allocate scratch", t_completenewenv);
126 RECORD_TIMER_START(t_allocScratch);
127 MFloat scratchSize = 2.0;
128 scratchSize = Context::getBasicProperty<MFloat>("scratchSize", AT_, &scratchSize);
129
130 // Allocate new scratch space
131 mScratch = new Scratch(scratchSize, maxNoCells);
133 RECORD_TIMER_STOP(t_allocScratch);
134
135 // Create a new MAIA application, the class that controls the actual grid generator/flow solver
136 DEBUG("Environment:: create Application", MAIA_DEBUG_LEVEL1);
138 RECORD_TIMER_STOP(t_completenewenv);
139}
140
144 delete mScratch;
145 if(mApplication != nullptr) delete mApplication;
146}
147
150 Profile runProfile("Environment::run");
151
154
155 TRACE();
156
157 MBool flowSolver = false;
158 flowSolver = Context::getBasicProperty<MBool>("flowSolver", AT_, &flowSolver);
159
160 // Return here if flow solver is not enabled.
161 if(!flowSolver) {
162 return 0;
163 }
164
165 MInt nDim = read_nDim();
166
167 if(nDim == 2) {
168 mApplication->run<2>();
169 } else if(nDim == 3) {
170 mApplication->run<3>();
171 } else {
172 mTerm(1, AT_, "Invalid value of nDim!");
173 }
174
175 return 0;
176}
177
180 TRACE();
181
182#ifdef MAIA_WRITE_ACCESS_PROPERTIES_FILE
184#endif
185 return 0;
186}
187
188
191 TRACE();
192
193#if defined(MAIA_MS_COMPILER) || defined(_SX)
194#pragma message("WARNING: Not implemented!")
195#else
196 opterr = 0;
197 while(true) {
198 int c = 0;
199 DIR* directory = nullptr;
200 string inputDirectory;
201 string outputDirectory;
202 int option_index = 0;
203 static option long_options[] = {
204 {"debug", 1, 0, 'd'}, {"help", 0, 0, 'h'}, {"input", 1, 0, 'i'}, {"output", 1, 0, 'o'},
205 {"version", 0, 0, 'v'}, {"compiler", 0, 0, 'c'}, {"build-type", 0, 0, 'b'}, {0, 0, 0, 0}};
206
207 c = getopt_long(m_argc, m_argv, "d:hi:o:p:vcb", long_options, &option_index);
208 if(c == -1) {
209 break;
210 }
211
212 switch(c) {
213 case 0:
214 cout << "option " << long_options[option_index].name << endl;
215 if(optarg != nullptr) cout << "with arg " << optarg << endl;
216 cout << endl;
217 break;
218
219 case 'd':
220 if(atoi(optarg) < 2 * MDebug::m_maxLevel && atoi(optarg) >= MDebug::m_minLevel) {
221 SET_DEBUG_LEVEL((MDebugLevel)atoi(optarg));
222 if(globalDomainId() == 0) {
223 cout << "SET DEBUG LEVEL TO: " << atoi(optarg) << endl;
224 }
225 m_log << "SET DEBUG LEVEL TO: " << atoi(optarg) << endl;
226 DEBUG("Environment::parseCommandline: option -d " << atoi(optarg), MAIA_DEBUG_IO);
227 } else {
228 cerr << "Error: debug level out of range!" << endl;
229 cerr << "Specified debug level is " << atoi(optarg) << ", but must be in the range of " << endl;
230 cerr << 2 * MDebug::m_minLevel << " <= debug level <= " << 2 * MDebug::m_maxLevel << endl;
231 cerr << "Debug level is unchanged" << endl;
232 return;
233 }
234 break;
235
236 case 'h':
237 cout << "usage: " << m_argv[0] << " [-h] [-b] [-c] [--debug LEVEL] [--input DIRECTORY] "
238 << "[--output DIRECTORY] [-v] [PROPERTY_FILE]" << endl
239 << endl
240 << "positional arguments:" << endl
241 << " PROPERTY_FILE name of property file to use (default: '" << m_propertyFileInput << "')\n"
242 << endl
243 << "optional arguments:\n"
244 << " -b, --build-type show build type that was used\n"
245 << " -c, --compiler show used compiler\n"
246 << " -d, --debug LEVEL use specified debug level\n"
247 << " -h, --help this help screen\n"
248 << " -i, --input DIRECTORY specified directory is used for all "
249 "input files\n"
250 << " -o, --output DIRECTORY specified directory is used for all "
251 "output files\n"
252 << " -v, --version show MAIA version\n"
253 << endl;
254 m_log.close();
255 maia_res.close();
256 MPI_Finalize();
257 exit(0);
258 break;
259
260 case 'i':
261 directory = opendir(optarg);
262 if(directory != nullptr) {
263 closedir(directory);
264 inputDirectory.append(optarg);
265 DEBUG("Environment::parseCommandline: option -i " << optarg, MAIA_DEBUG_IO);
266 } else {
267 stringstream errorMessage;
268 errorMessage << " error opening inputDirectory \"" << optarg << "\"!" << endl;
269 mTerm(1, AT_, errorMessage.str());
270 }
271 break;
272
273 case 'o':
274 directory = opendir(optarg);
275 if(directory != nullptr) {
276 closedir(directory);
277 outputDirectory.append(optarg);
278 DEBUG("Environment::parseCommandline: option -o " << optarg, MAIA_DEBUG_IO);
279 } else {
280 stringstream errorMessage;
281 errorMessage << "Error opening outputDirectory \"" << optarg << "\"!";
282 mTerm(1, AT_, errorMessage.str());
283 }
284 break;
285
286 case 'v':
287// Show version and quit
288#ifndef MAIA_VERSION_STRING
289#define MAIA_VERSION_STRING unknown
290#endif
291 cout << XSTRINGIFY(MAIA_VERSION_STRING) << endl;
292 m_log.close();
293 maia_res.close();
294 MPI_Finalize();
295 exit(0);
296 break;
297
298 case 'c':
299// Show used compiler and quit
300#ifndef MAIA_COMPILER_STRING
301#define MAIA_COMPILER_STRING unknown
302#endif
303 cout << XSTRINGIFY(MAIA_COMPILER_STRING) << endl;
304 m_log.close();
305 maia_res.close();
306 MPI_Finalize();
307 exit(0);
308 break;
309
310 case 'b':
311// Show used build type and quit
312#ifndef MAIA_BUILD_TYPE_STRING
313#define MAIA_BUILD_TYPE_STRING unknown
314#endif
315 cout << XSTRINGIFY(MAIA_BUILD_TYPE_STRING) << endl;
316 m_log.close();
317 maia_res.close();
318 MPI_Finalize();
319 exit(0);
320 break;
321
322 case '?':
323 break;
324
325 default:
326 cerr << "Environment::parseCommandline: Error getopt returned "
327 "unkown option code \""
328 << c << "\"" << endl;
329 }
330 }
331
332 // Obtain command line argument for property file
333 if(optind < m_argc) {
334 m_propertyFileInput = m_argv[optind];
335 }
336 // On domain 0, check if file is readable
337 if(globalDomainId() == 0 && !ifstream(m_propertyFileInput)) {
338 TERMM(1, "property file '" + m_propertyFileInput + "' not readable");
339 }
340#endif
341}
342
343
353 // Define buffer size
354 const MInt bufferSize = 1024;
355
356 // Get current hostname
357 array<char, bufferSize> host_{};
358 gethostname(&host_[0], bufferSize - 1);
359 host_[bufferSize - 1] = '\0';
360 const MString host(&host_[0]);
361
362 // Get current username
363 MString user = "(unknown user)";
364#if defined(MAIA_MS_COMPILER)
365 constexpr MInt INFO_BUFFER_SIZE = 32767;
366 TCHAR infoBuf[INFO_BUFFER_SIZE];
367 DWORD bufCharCount = INFO_BUFFER_SIZE;
368 if(GetUserName(infoBuf, &bufCharCount)) {
369 user = infoBuf;
370 }
371#else
372 passwd* p;
373 p = getpwuid(getuid());
374 if(p) {
375 user = MString(p->pw_name);
376 }
377#endif
378
379 // Get current directory
380 array<char, bufferSize> dir_{};
381#if defined(MAIA_MS_COMPILER)
382 _getcwd(&dir_[0], bufferSize - 1);
383#else
384 if(getcwd(&dir_[0], bufferSize - 1) == nullptr) {
385 TERM(-1);
386 }
387#endif
388 dir_[bufferSize - 1] = '\0';
389 const MString dir(&dir_[0]);
390
391 // Get current execution command and command line arguments
392 const MString executable(m_argv[0]);
393 stringstream ss;
394 if(m_argc > 1) {
395 ss << MString(m_argv[0]);
396 for(MInt n = 1; n < m_argc; n++) {
397 ss << " " << MString(m_argv[n]);
398 }
399 } else {
400 ss << "(none)";
401 }
402 const MString args(ss.str());
403
404 // Create start timestamp
405 array<char, bufferSize> dateString_{};
406 time_t rawTime = 0;
407
408 // Get the current time and write it to rawTime
409 time(&rawTime);
410
411 // Convert to time struct
412 tm* timeInfo = localtime(&rawTime);
413
414 // Format time to string and save to buffer
415 strftime(&dateString_[0], bufferSize, "%Y-%m-%d %H:%M:%S", timeInfo);
416
417 // Store date as real string
418 const MString dateString(&dateString_[0]);
419
420 // Print startup information
421 cout << " _____ ______ ________ ___ ________ \n"
422 " ____|\\ _ \\ _ \\ |\\ __ \\ |\\ \\ |\\ __ \\ ___ \n"
423 " ___\\ \\ \\\\\\__\\ \\ \\\\ \\ \\|\\ \\\\ \\ \\\\ \\ \\|\\ \\ ___ \n"
424 " ___\\ \\ \\\\|__| \\ \\\\ \\ __ \\\\ \\ \\\\ \\ __ \\ ___ \n"
425 " ___\\ \\ \\ \\ \\ \\\\ \\ \\ \\ \\\\ \\ \\\\ \\ \\ \\ \\ ___ \n"
426 " ___\\ \\__\\ \\ \\__\\\\ \\__\\ \\__\\\\ \\__\\\\ \\__\\ \\__\\ ___ \n"
427 " ___\\|__| \\|__| \\|__|\\|__| \\|__| \\|__|\\|__| ____ \n"
428 "\n";
429 cout << "Start time: " << dateString << "\n"
430 << "Number of ranks: " << globalNoDomains() << "\n"
431#ifdef _OPENMP
432 << "Number of OMP threads: " << omp_get_max_threads() << "\n"
433#endif
434 << "Host (of rank 0): " << host << "\n"
435 << "Working directory: " << dir << "\n"
436 << "User: " << user << "\n"
437 << "Executable: " << executable << "\n"
438 << "Command line args: " << args << "\n"
439 << endl;
440}
Manages the initialisation of the solvers, the methods depending to the solvers and the start of the ...
Definition: application.h:37
static void communicateProperties()
Communicates properties to check if default falues match.
Definition: context.cpp:773
static void initializationProcessFinished()
Sets flag to forbide property access.
Definition: context.cpp:745
static void writePropertiesHumanReadable()
Write the properties into a text file.
Definition: context.cpp:600
static void readPropertyFile(FileType, const MString &fileName)
static MBool propertyExists(const MString &name, MInt solver=m_noSolvers)
This function checks if a property exists in general.
Definition: context.cpp:494
void parseCommandline()
Reads out the options that where used by the program call.
static void printStartupInformation()
Print startup summary of MAIA.
Environment(int, char **)
static MChar ** m_argv
Definition: environment.h:29
Application * mApplication
Definition: environment.h:33
MInt run()
Runs the Environment, makes the Application run.
MInt end()
Ends the Environment.
~Environment()
Destructor.
MString m_propertyFileInput
Definition: environment.h:38
Scratch * mScratch
Definition: environment.h:34
static MInt m_argc
Reads the name of the property-file and creates a new Application.
Definition: environment.h:28
void close(MBool forceClose=false)
Pass the close call to the respective internal buffer.
Definition: infoout.cpp:1011
static const MInt m_minLevel
Definition: debug.h:191
static const MInt m_maxLevel
Definition: debug.h:192
This class collects all function timings and produces a profiling for certain areas of the code.
Definition: timer.h:679
This class holds the complete scratch space.
Definition: scratch.h:91
static MString printSelf()
Returns a string summing up the scratch state information and all scratch space elements information.
Definition: scratch.cpp:106
enum { MAIA_DEBUG_ASSERTION=1, MAIA_DEBUG_IO=2, MAIA_DEBUG_ALLOCATION=4, MAIA_DEBUG_TRACE=8, MAIA_DEBUG_TRACE_IN=16, MAIA_DEBUG_TRACE_OUT=32, MAIA_DEBUG_LEVEL1=64, MAIA_DEBUG_LEVEL2=128, MAIA_DEBUG_LEVEL3=256, MAIA_DEBUG_LEVEL4=512, MAIA_DEBUG_LEVEL5=1024, MAIA_DEBUG_USER1=2048, MAIA_DEBUG_USER2=4096, MAIA_DEBUG_USER3=8192, MAIA_DEBUG_USER4=16384, MAIA_DEBUG_USER5=32768 } MDebugLevel
This enum holds the error levels of the DEBUG class.
Definition: debug.h:131
@ NETCDF
Definition: enums.h:18
@ TOML
Definition: enums.h:18
void mTerm(const MInt errorCode, const MString &location, const MString &message)
Definition: functions.cpp:29
MInt globalNoDomains()
Return global number of domains.
MInt globalDomainId()
Return global domain id.
InfoOutFile maia_res
InfoOutFile m_log
std::ostream cerr0
int32_t MInt
Definition: maiatypes.h:62
std::basic_string< char > MString
Definition: maiatypes.h:55
double MFloat
Definition: maiatypes.h:52
bool MBool
Definition: maiatypes.h:58
char MChar
Definition: maiatypes.h:56
void const MInt const MInt const MInt const MInt maxNoCells
Definition: collector.h:240