MOOSE - Multiscale Object Oriented Simulation Environment
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
pymooseinit.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 ** This program is part of 'MOOSE', the
3 ** Messaging Object Oriented Simulation Environment.
4 ** Copyright (C) 2003-2009 Upinder S. Bhalla. and NCBS
5 ** It is made available under the terms of the
6 ** GNU Lesser General Public License version 2.1
7 ** See the file COPYING.LIB for the full notice.
8 **********************************************************************/
9 
10 #include "header.h"
11 #ifndef WIN32
12  #include <sys/time.h>
13 #else
14  #include <time.h>
15 #endif
16 #include <math.h>
17 #include <queue>
18 #ifdef WIN32
19 #include "../external/xgetopt/XGetopt.h"
20 #else
21 #include <unistd.h> // for getopt
22 #endif
23 #include "../scheduling/Clock.h"
24 #include "DiagonalMsg.h"
25 #include "SparseMatrix.h"
26 #include "SparseMsg.h"
27 #include "../mpi/PostMaster.h"
28 #ifdef USE_MPI
29 #include <mpi.h>
30 #endif
31 #include "../shell/Shell.h"
32 #ifdef MACOSX
33 #include <sys/sysctl.h>
34 #endif // MACOSX
35 
36 #ifdef DO_UNIT_TESTS
37 extern void testSync();
38 extern void testAsync();
39 extern void testSyncArray( unsigned int size, unsigned int method );
40 extern void testShell();
41 extern void testScheduling();
42 extern void testSchedulingProcess();
43 extern void testBuiltins();
44 extern void testBuiltinsProcess();
45 
46 extern void testMpiScheduling();
47 extern void testMpiBuiltins();
48 extern void testMpiShell();
49 extern void testMsg();
50 extern void testMpiMsg();
51 // extern void testKinetics();
52 // extern void testKineticSolvers();
53 // extern void testKineticSolversProcess();
54 extern void testBiophysics();
55 extern void testBiophysicsProcess();
56 // extern void testHSolve();
57 // extern void testKineticsProcess();
58 // extern void testGeom();
59 // extern void testMesh();
60 // extern void testSimManager();
61 // extern void testSigNeur();
62 // extern void testSigNeurProcess();
63 
64 extern unsigned int initMsgManagers();
65 extern void destroyMsgManagers();
66 // void regressionTests();
67 #endif
69  unsigned int size, unsigned int runsteps );
70 
71 #ifdef USE_SMOLDYN
72  extern void testSmoldyn();
73 #endif
74 // bool benchmarkTests( int argc, char** argv );
75 
76 extern void mooseBenchmarks( unsigned int option );
77 
79 // System-dependent function here
81 
82 unsigned int getNumCores()
83 {
84  unsigned int numCPU = 0;
85 #ifdef WIN_32
86  SYSTEM_INFO sysinfo;
87  GetSystemInfo( &sysinfo );
88 
89  numCPU = sysinfo.dwNumberOfProcessors;
90 #endif
91 
92 #ifdef LINUX
93  numCPU = sysconf( _SC_NPROCESSORS_ONLN );
94 #endif
95 
96 #ifdef MACOSX
97  int mib[4];
98  size_t len = sizeof(numCPU);
99 
100  /* set the mib for hw.ncpu */
101  mib[0] = CTL_HW;
102  mib[1] = HW_AVAILCPU; // alternatively, try HW_NCPU;
103 
104  /* get the number of CPUs from the system */
105  sysctl(mib, 2, &numCPU, &len, NULL, 0);
106 
107  if( numCPU < 1 )
108  {
109  mib[1] = HW_NCPU;
110  sysctl( mib, 2, &numCPU, &len, NULL, 0 );
111  }
112 #endif
113  if ( numCPU < 1 )
114  {
115 #ifndef QUIET_MODE
116  cout << "No CPU information available. Assuming single core." << endl;
117 #else
118 #endif
119  numCPU = 1;
120  }
121  return numCPU;
122 }
123 
124 bool quitFlag = 0;
127 
128 void checkChildren( Id parent, const string& info )
129 {
130  vector< Id > ret;
131  Neutral::children( parent.eref(), ret );
132  cout << info << " checkChildren of " <<
133  parent.element()->getName() << ": " <<
134  ret.size() << " children\n";
135  for ( vector< Id >::iterator i = ret.begin(); i != ret.end(); ++i )
136  {
137  cout << i->element()->getName() << endl;
138  }
139 }
140 
141 Id init( int argc, char** argv, bool& doUnitTests, bool& doRegressionTests,
142  unsigned int& benchmark )
143 {
144  unsigned int numCores = getNumCores();
145  int numNodes = 1;
146  int myNode = 0;
147  bool isInfinite = 0;
148  int opt;
149  benchmark = 0; // Default, means don't do any benchmarks.
151 #ifdef USE_MPI
152  /*
153  // OpenMPI does not use argc or argv.
154  // unsigned int temp_argc = 1;
155  int provided;
156  MPI_Init_thread( &argc, &argv, MPI_THREAD_SERIALIZED, &provided );
157  */
158  MPI_Init( &argc, &argv );
159 
160  MPI_Comm_size( MPI_COMM_WORLD, &numNodes );
161  MPI_Comm_rank( MPI_COMM_WORLD, &myNode );
162  /*
163  if ( provided < MPI_THREAD_SERIALIZED && myNode == 0 ) {
164  cout << "Warning: This MPI implementation does not like multithreading: " << provided << "\n";
165  }
166  */
167  // myNode = MPI::COMM_WORLD.Get_rank();
168 #endif
169 
173  while ( ( opt = getopt( argc, argv, "hiqurn:b:B:" ) ) != -1 ) {
174  switch ( opt ) {
175  case 'i' : // infinite loop, used for multinode debugging, to give gdb something to attach to.
176  isInfinite = 1;
177  break;
178  case 'n': // Multiple nodes
179  numNodes = (unsigned int)atoi( optarg );
180  break;
181  case 'b': // Benchmark:
182  benchmark = atoi( optarg );
183  break;
184  case 'B': // Benchmark plus dump data: handle later.
185  break;
186  case 'u': // Do unit tests, pass back.
187  doUnitTests = 1;
188  break;
189  case 'r': // Do regression tests: pass back
190  doRegressionTests = 1;
191  break;
192  case 'q': // quit immediately after completion.
193  quitFlag = 1;
194  break;
195  case 'h': // help
196  default:
197  cout << "Usage: moose -help -infiniteLoop -unit_tests -regression_tests -quit -n numNodes -benchmark [ksolve intFire hhNet msg_<msgType>_<size>]\n";
198 
199  exit( 1 );
200  }
201  }
202  if ( myNode == 0 )
203  {
204 #ifndef QUIET_MODE
205  cout << "on node " << myNode << ", numNodes = "
206  << numNodes << ", numCores = " << numCores << endl;
207 #endif
208  }
209 
210  Id shellId;
211  Element* shelle =
212  new GlobalDataElement( shellId, Shell::initCinfo(), "root", 1 );
213 
214  Id clockId = Id::nextId();
215  assert( clockId.value() == 1 );
216  Id classMasterId = Id::nextId();
217  Id postMasterId = Id::nextId();
218 
219  Shell* s = reinterpret_cast< Shell* >( shellId.eref().data() );
220  s->setShellElement( shelle );
221  s->setHardware( numCores, numNodes, myNode );
222  s->loadBalance();
223 
225  unsigned int numMsg = Msg::initMsgManagers();
226 
227  new GlobalDataElement( clockId, Clock::initCinfo(), "clock", 1 );
228  new GlobalDataElement( classMasterId, Neutral::initCinfo(), "classes", 1);
229  new GlobalDataElement( postMasterId, PostMaster::initCinfo(), "postmaster", 1 );
230 
231  assert ( shellId == Id() );
232  assert( clockId == Id( 1 ) );
233  assert( classMasterId == Id( 2 ) );
234  assert( postMasterId == Id( 3 ) );
235 
236 
237 
238  // s->connectMasterMsg();
239 
240  Shell::adopt( shellId, clockId, numMsg++ );
241  Shell::adopt( shellId, classMasterId, numMsg++ );
242  Shell::adopt( shellId, postMasterId, numMsg++ );
243 
244  assert( numMsg == 10 ); // Must be the same on all nodes.
245 
246  Cinfo::makeCinfoElements( classMasterId );
247 
248 
249  // This will be initialized within the Process loop, and better there
250  // as it flags attempts to call the Reduce operations before ProcessLoop
251  // Qinfo::clearReduceQ( numCores ); // Initialize the ReduceQ entry.
252 
253 
254  // SetGet::setShell();
255  // Msg* m = new OneToOneMsg( shelle, shelle );
256  // assert ( m != 0 );
257 
258  while ( isInfinite ) // busy loop for debugging under gdb and MPI.
259  ;
260 
261  return shellId;
262 }
263 
270 void nonMpiTests( Shell* s )
271 {
272 #ifdef DO_UNIT_TESTS
273  if ( Shell::myNode() == 0 ) {
274  unsigned int numNodes = s->numNodes();
275  unsigned int numCores = s->numCores();
276  if ( numCores > 0 )
277  s->setHardware( 1, 1, 0 );
278  testAsync();
279  testMsg();
280  testShell();
281  testScheduling();
282  testBuiltins();
283  // testKinetics();
284  // testKineticSolvers();
285  testBiophysics();
286  // testHSolve();
287  // testGeom();
288  // testMesh();
289  // testSigNeur();
290 #ifdef USE_SMOLDYN
291  // testSmoldyn();
292 #endif
293  s->setHardware( numCores, numNodes, 0 );
294  }
295 #endif
296 }
297 
302 void processTests( Shell* s )
303 {
304 #ifdef DO_UNIT_TESTS
307  // testKineticsProcess();
309  // testKineticSolversProcess();
310  // testSimManager();
311  // testSigNeurProcess();
312 #endif
313 }
314 
319 void mpiTests()
320 {
321 #ifdef DO_UNIT_TESTS
322  testMpiMsg();
323  cout << "." << flush;
324  testMpiShell();
325  cout << "." << flush;
326  testMpiBuiltins();
327  cout << "." << flush;
329  cout << "." << flush;
330 #endif
331 }
static unsigned int numCores
static void makeCinfoElements(Id parent)
Definition: Cinfo.cpp:164
char * data() const
Definition: Eref.cpp:41
void testAsync()
Definition: testAsync.cpp:1813
void initMsgManagers()
static unsigned int numCores()
Element * element() const
Synonym for Id::operator()()
Definition: Id.cpp:113
unsigned int value() const
Definition: Id.cpp:197
static const Cinfo * initCinfo()
Definition: Clock.cpp:133
void processTests(Shell *s)
void testMpiShell()
Definition: testShell.cpp:1833
static int isInfinite
static void setHardware(unsigned int numCores, unsigned int numNodes, unsigned int myNode)
Eref eref() const
Definition: Id.cpp:125
static void children(const Eref &e, vector< Id > &ret)
Definition: Neutral.cpp:342
void testBuiltinsProcess()
void testShell()
Definition: testShell.cpp:1818
static const Cinfo * initCinfo()
Definition: Shell.cpp:46
void testMsg()
Definition: testMsg.cpp:370
void mpiTests()
void setShellElement(Element *shelle)
Definition: Shell.cpp:166
void testMpiBuiltins()
static int doRegressionTests
void nonMpiTests(Shell *s)
static Id nextId()
Definition: Id.cpp:132
static unsigned int myNode
void testSchedulingProcess()
void testMpiMsg()
Definition: testMsg.cpp:376
void testMpiScheduling()
bool quitFlag
void speedTestMultiNodeIntFireNetwork(unsigned int size, unsigned int runsteps)
void mooseBenchmarks(unsigned int option)
static void loadBalance()
void testScheduling()
void testBiophysicsProcess()
Id init(int argc, char **argv, bool &doUnitTests, bool &doRegressionTests, unsigned int &benchmark)
static unsigned int numNodes
static unsigned int initMsgManagers()
Definition: Msg.cpp:236
static void rebuildOpIndex()
Definition: Cinfo.cpp:589
static bool adopt(ObjId parent, Id child, unsigned int msgIndex)
Definition: Shell.cpp:654
Definition: Id.h:17
void testBiophysics()
void testBuiltins()
void destroyMsgManagers()
static unsigned int myNode()
unsigned int getNumCores()
Definition: pymooseinit.cpp:82
static const Cinfo * initCinfo()
Definition: PostMaster.cpp:82
static const Cinfo * initCinfo()
Definition: Neutral.cpp:16
void checkChildren(Id parent, const string &info)
static int doUnitTests
static unsigned int numNodes()
const string & getName() const
Definition: Element.cpp:56
Definition: Shell.h:43