src/Utility/IpplInfo.h

Go to the documentation of this file.
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  ***************************************************************************/

Generated on Mon Jan 16 13:23:59 2006 for IPPL by  doxygen 1.4.6