00001 // -*- C++ -*- 00002 /*************************************************************************** 00003 * 00004 * The IPPL Framework 00005 * 00006 * 00007 * Visit http://people.web.psi.ch/adelmann/ for more details 00008 * 00009 ***************************************************************************/ 00010 00011 #ifndef IPPL_INFO_H 00012 #define IPPL_INFO_H 00013 00014 /* 00015 * IpplInfo.has the following capabilities: 00016 * 1) It initializes all globally-used Ippl variables, such as the 00017 * Communicate class and other manager classes; 00018 * 2) It parses command-line arguments to determine how to configure the 00019 * global state of the Ippl application; 00020 * 3) It properly selects and configures the Communicate class, generally 00021 * resulting in initialization of the parallel machine; 00022 * 4) It offers to the user a single class with access member functions to 00023 * query for information about the Ippl application (such as what is 00024 * the Communicate class instance to use, how many processors are there 00025 * in the current run, etc.) 00026 * 00027 * The globally-available Ippl objects are (available via IpplInfo::variable) 00028 * Communicate *Comm ....... parallel communication object 00029 * Inform *Info ............ used to print out informative messages 00030 * Inform *Warn ............ used to print out warning messages 00031 * Inform *Error ........... used to print out error messages 00032 * Inform *Debug ........... used to print out debugging messages 00033 * 00034 * Note that you should use the following macros to access the Inform objects, 00035 * so that these messages may be left out at compile time: 00036 * INFOMSG("This is some information " << 34 << endl); 00037 * WARNMSG("This is a warning " << 34 << endl); 00038 * ERRORMSG("This is an error message " << 34 << endl); 00039 * DEBUGMSG("This is some debugging info " << 34 << endl); 00040 * 00041 * There is also a 'typedef IpplInfo Ippl' here, so you can simply use 00042 * the name 'Ippl' instead of the longer 'IpplInfo' to access this class. 00043 * 'Ippl' is in fact preferred, as it is shorter. 00044 */ 00045 00046 // include files 00047 #include "Utility/Inform.h" 00048 #include "Message/Communicate.h" 00049 00050 #ifdef IPPL_USE_STANDARD_HEADERS 00051 #include <iostream> 00052 using namespace std; 00053 #else 00054 #include <iostream.h> 00055 #endif 00056 00057 // forward declarations 00058 class IpplStats; 00059 class IpplInfo; 00060 ostream& operator<<(ostream&, const IpplInfo&); 00061 00062 00063 #ifdef IPPL_RUNTIME_ERRCHECK 00064 // special routine used in runtime debugging error detection 00065 extern "C" { 00066 void __C_runtime_error (int trap_code, char *name, int line_no, ...); 00067 }; 00068 #endif 00069 00070 00071 class IpplInfo { 00072 00073 public: 00074 // an enumeration used to indicate whether to KEEP command-line arguments 00075 // or REMOVE them 00076 enum { KEEP = 0, REMOVE = 1 }; 00077 00078 // 00079 // global static objects, available to all Ippl applications (even if 00080 // no IpplInfo object is instantiated) 00081 // 00082 00083 // Inform object to use to print messages to the console (or even to a 00084 // file if requested) 00085 static Inform *Info; 00086 static Inform *Warn; 00087 static Inform *Error; 00088 static Inform *Debug; 00089 00090 // the parallel communication object 00091 static Communicate *Comm; 00092 00093 // the statistics collection object 00094 static IpplStats *Stats; 00095 00096 public: 00097 // Constructor 1: specify the argc, argv values from the cmd line. 00098 // The second argument controls whether the IPPL-specific command line 00099 // arguments are stripped out (the default) or left in (if the setting 00100 // is IpplInfo::KEEP). 00101 IpplInfo(int&, char** &, int removeargs = REMOVE); 00102 00103 // Constructor 2: default constructor. This will not change anything in 00104 // how the static data members are set up. This is useful for declaring 00105 // automatic IpplInfo instances in functions after IpplInfo.has been 00106 // initially created in the main() routine. 00107 IpplInfo(); 00108 00109 // Constructor 3: copy constructor. This will only copy non-static members 00110 // (obviously), if any exist. 00111 IpplInfo(const IpplInfo&); 00112 00113 // Destructor. 00114 ~IpplInfo(); 00115 00116 // Overload the = operator; does the same thing as the copy constructor. 00117 IpplInfo& operator=(const IpplInfo&); 00118 00119 00120 /* NOTE: The following initialize/finalize methods have not yet been 00121 implemented. Add them to IpplInfo.cpp if they are needed (bfh). 00122 // 00123 // Initialize and finalize routines ... initialize can be used if you 00124 // created IpplInfo with the default constructor, and finalize() can 00125 // be used to shut down IPPL and possibly exit the program 00126 // 00127 00128 // initialize ourselves, if we have not yet done so, by parsing the 00129 // command-line args and creating the Communication object. This should 00130 // be called by all the currently-running nodes. 00131 void initialize(int &, char ** &); 00132 00133 // shut down the communication, and possibly exit. This should be called 00134 // by all the nodes, it will not work if it is called by just one node 00135 // and you are running in parallel (in that case, the Communicate subclass 00136 // destructor will hang). 00137 void finalize(); 00138 00139 // a version of finalize that will also shut down all the machines via 00140 // a call to exit() 00141 void finalize(int exitcode); 00142 */ 00143 00144 00145 // 00146 // Standard IPPL action methods (such as abort, etc) 00147 // 00148 00149 // Kill the communication and exit the program, in an emergency. This 00150 // will exit with an error code. If the given exit code is < 0, the 00151 // program will call the system abort(). If the exit code is >= 0, 00152 // the program will call the system exit() with the given error code. 00153 static void abort(const char * = 0, int exitcode = (-1)); 00154 00155 // Signal to ALL the nodes that we should exit or abort. If we abort, 00156 // a core file will be produced. If we exit, no core file will be made. 00157 // The node which calls abortAllNodes will print out the given message; 00158 // the other nodes will print out that they are aborting due to a message 00159 // from this node. The final boolean argument indicates whether the 00160 // calling node should abort or exit just as the other nodes are being 00161 // asked to do; if this is false, then only the other nodes will be 00162 // instructed to quit, and it will be up to the caller to abort or exit 00163 // the current node. This makes it possible to ask all other nodes to 00164 // exit, but have your own node abort. 00165 static void abortAllNodes(const char * = 0, bool thisnode = true); 00166 static void exitAllNodes(const char * = 0, bool thisnode = true); 00167 00168 // 00169 // Functions which return information about the current Ippl application. 00170 // 00171 00172 // Return the number of the 'current' node. 00173 static int myNode(); 00174 00175 // Return the current number of nodes working in parallel, where 00176 // each node may have more than one processor. A 'Node' is basically 00177 // considered as an entity which has a single IP address. 00178 static int getNodes(); 00179 00180 // Return the number of contexts on a given node N. A 'Context' is 00181 // considered to be a single addressable memory space; for shared memory 00182 // machines, this could be the whole machine or one of many separate sections 00183 // each being treated as distinct from the others. 00184 static int getContexts(int); 00185 00186 // Return the number of processes which are actively working on node N in 00187 // context C. A 'Process' is not necessarily one in the strict Unix sense; it 00188 // could be a lightweight thread or indeed a full process. These numbers 00189 // may dynamically change. 00190 static int getProcesses(int, int); 00191 00192 // getSMPs: return number of SMP's (each of which may be running 00193 // several processes) 00194 static int getSMPs(); 00195 00196 // getSMPNodes: return number of nodes on the SMP with the given index 00197 static int getSMPNodes(unsigned int); 00198 00199 // mySMP: return ID of my SMP (numbered 0 ... getSMPs() - 1) 00200 static int mySMP(); 00201 00202 // mySMPNode: return relative node number within the nodes on our SMP 00203 static int mySMPNode(); 00204 00205 // Return argc or argv as provided in the initialization 00206 static int getArgc() { return MyArgc; } 00207 static char **getArgv() { return MyArgv; } 00208 00209 // return true if we should use checksums on messages 00210 static bool useChecksums() { return UseChecksums; } 00211 00212 // return true if we should try to retransmit messages on error 00213 static bool retransmit() { return (UseChecksums && Retransmit); } 00214 00215 #ifdef IPPL_COMM_ALARMS 00216 // A timeout quantity, in seconds, to allow us to wait a certain number 00217 // of seconds before we signal a timeout when we're trying to receive 00218 // a message. 00219 static unsigned int getCommTimeout() { return CommTimeoutSeconds; } 00220 #endif 00221 00222 // Static data about a limit to the number of nodes that should be used 00223 // in FFT operations. If this is <= 0 or > number of nodes, it is ignored. 00224 static int maxFFTNodes() { return MaxFFTNodes; } 00225 00226 // Return the "read chunk size", the number of bytes that will be 00227 // read in, at max, for most Disc read operations. If the final 00228 // character is 'K', 'M', or 'G', the number will mean the number 00229 // of kilobytes, megabytes, or gigabytes. The default is one MB. If 00230 // this is <= 0, then no limit should be used. 00231 static int chunkSize() { return ChunkSize; } 00232 00233 // Return boolean setting for whether we should attempt to use parallel 00234 // I/O within a single SMP, for example by having multipple processors 00235 // try to read from a single file (vs just having one node do it). 00236 static bool perSMPParallelIO() { return PerSMPParallelIO; } 00237 00238 // 00239 // Functions which return information about the Ippl library 00240 // 00241 00242 // printVersion: print out a version summary. If the argument is true, 00243 // print out a detailed listing, otherwise a summary. 00244 static void printVersion(bool = false); 00245 00246 // version: return the name of this version of Ippl, as a string 00247 // (from IpplVersions.h) 00248 static const char *version(); 00249 00250 // versionList: return one of the summary lines from the source code 00251 // version list 00252 static const char *versionList(unsigned int); 00253 00254 // versionListSize: return the number of source code files listed in 00255 // the versionList array. 00256 static unsigned int versionListSize(); 00257 00258 // compileArch: return the architecture on which this library was built 00259 // (from IpplVersions.h) 00260 static const char *compileArch(); 00261 00262 // compileDate: return the date on which this library was prepared for 00263 // compilation (from IpplVersions.h) 00264 static const char *compileDate(); 00265 00266 // compileLine: return the compiler command used to compile each source file 00267 // (from IpplVersions.h) 00268 static const char *compileLine(); 00269 00270 // compileMachine: return the machine on which this library was 00271 // compiled (from IpplVersions.h) 00272 static const char *compileMachine(); 00273 00274 // compileOptions: return the option list used to compile this library 00275 // (from IpplVersions.h) 00276 static const char *compileOptions(); 00277 00278 // compileUser: return the username of the user who compiled this 00279 // library (from IpplVersions.h) 00280 static const char *compileUser(); 00281 00282 // Static flag telling whether to use optimization for reducing 00283 // communication by deferring guard cell fills. 00284 static bool deferGuardCellFills; 00285 00286 // Static flag telling whether to turn off compression in the Field classes. 00287 static bool noFieldCompression; 00288 00289 // Static flag telling whether to try to (pseudo-)randomly offset the 00290 // LField blocks to try to avoid cache conflicts. 00291 static bool offsetStorage; 00292 00293 // Static flag telling whether to try to do a TryCompress after each 00294 // individual LField has been processed in an expression. 00295 static bool extraCompressChecks; 00296 00297 // Static flag telling whether to try to use direct-io. This is only 00298 // possible if the library is compiled with the IPPL_DIRECTIO option, 00299 // and you are on a system that provides this capablity. 00300 static bool useDirectIO; 00301 00302 // Static routine giving one a place to stop at with #$%$%#1 stupid 00303 // debuggers. 00304 static void here(); 00305 00306 // print out statistics to the given Inform stream 00307 static void printStatistics(Inform&); 00308 00309 private: 00310 // Static counter indicating how many IpplInit objects have been created. 00311 // When this gets back to zero, it's time to delete the Comm and quit. 00312 static int NumCreated; 00313 00314 // Static flag indicating whether this class has been created with 00315 // argc,argv specified ever. This should only be done once. 00316 static bool CommInitialized; 00317 00318 // Static flag indicating whether we should print out stats info at the 00319 // end of the program. 00320 static bool PrintStats; 00321 00322 // Static flag indicating if we need to delete the comm object at the end. 00323 static bool NeedDeleteComm; 00324 00325 // Static flag indicating whether to use checksums on messages 00326 static bool UseChecksums; 00327 00328 // Static flag indicating whether to retransmit messages when errors occur 00329 static bool Retransmit; 00330 00331 // Static data with argc and argv 00332 static int MyArgc; 00333 static char **MyArgv; 00334 00335 // Static data with my node number and total number of nodes. These are 00336 // only changed when a new Communicate object is created. 00337 static int MyNode; 00338 static int TotalNodes; 00339 00340 // Static data with SMP information. These are changed after a new 00341 // Communicate object is created. 00342 static int NumSMPs; 00343 static int *SMPIDList; 00344 static int *SMPNodeList; 00345 00346 // Static data about a limit to the number of nodes that should be used 00347 // in FFT operations. If this is <= 0 or > number of nodes, it is ignored. 00348 static int MaxFFTNodes; 00349 00350 // Maximum read chunk size 00351 static int ChunkSize; 00352 00353 // A boolean setting for whether we should attempt to use parallel 00354 // I/O within a single SMP, for example by having multipple processors 00355 // try to read from a single file (vs just having one node do it). 00356 static bool PerSMPParallelIO; 00357 00358 #ifdef IPPL_COMM_ALARMS 00359 // A timeout quantity, in seconds, to allow us to wait a certain number 00360 // of seconds before we signal a timeout when we're trying to receive 00361 // a message. By default, this will be zero; change it with the 00362 // --msgtimeout <seconds> flag 00363 static unsigned int CommTimeoutSeconds; 00364 #endif 00365 00366 // Indicate an error occurred while trying to parse the given command-line 00367 // option, and quit. Arguments are: parameter, error message, bad value 00368 void param_error(const char *, const char *, const char *); 00369 void param_error(const char *, const char *, const char *, const char *); 00370 00371 // find out how many SMP's there are, and which processor we are on 00372 // our local SMP (e.g., if there are two SMP's with 4 nodes each, 00373 // the process will have a node number from 0 ... 7, and an SMP node 00374 // number from 0 ... 3 00375 void find_smp_nodes(); 00376 }; 00377 00378 // macros used to print out messages to the console or a directed file 00379 #define INFOMSG(msg) { *IpplInfo::Info << msg; } 00380 #define WARNMSG(msg) { *IpplInfo::Warn << msg; } 00381 #define ERRORMSG(msg) { *IpplInfo::Error << msg; } 00382 00383 // special macro to print debugging messages 00384 #ifdef IPPL_PRINTDEBUG 00385 #define DEBUGMSG(msg) { *IpplInfo::Debug << msg; } 00386 #else 00387 #define DEBUGMSG(msg) 00388 #endif 00389 00390 00391 // typedef so that we can have a 'Ippl' class that's easier to manipulate 00392 typedef IpplInfo Ippl; 00393 00394 00395 #endif // IPPL_INFO_H 00396 00397 /*************************************************************************** 00398 * $RCSfile: IpplInfo.h,v $ $Author: adelmann $ 00399 * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:33 $ 00400 * IPPL_VERSION_ID: $Id: IpplInfo.h,v 1.1.1.1 2003/01/23 07:40:33 adelmann Exp $ 00401 ***************************************************************************/