MOOSE - Multiscale Object Oriented Simulation Environment
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
main.cpp File Reference
#include "header.h"
#include "SparseMatrix.h"
#include <sys/time.h>
#include <math.h>
#include <queue>
#include <unistd.h>
#include "../scheduling/Clock.h"
#include "../msg/DiagonalMsg.h"
#include "../msg/SparseMsg.h"
#include "../mpi/PostMaster.h"
#include "../shell/Shell.h"
+ Include dependency graph for main.cpp:

Go to the source code of this file.

Functions

void checkChildren (Id parent, const string &info)
 
unsigned int getNumCores ()
 
Id init (int argc, char **argv, bool &doUnitTests, bool &doRegressionTests, unsigned int &benchmark)
 
int main (int argc, char **argv)
 
void mooseBenchmarks (unsigned int option)
 
void mpiTests ()
 
void nonMpiTests (Shell *s)
 
void processTests (Shell *s)
 
void speedTestMultiNodeIntFireNetwork (unsigned int size, unsigned int runsteps)
 

Variables

bool quitFlag = 0
 

Function Documentation

void checkChildren ( Id  parent,
const string &  info 
)

Definition at line 136 of file main.cpp.

References Neutral::children(), Id::element(), Id::eref(), and Element::getName().

137 {
138  vector< Id > ret;
139  Neutral::children( parent.eref(), ret );
140  cout << info << " checkChildren of " <<
141  parent.element()->getName() << ": " <<
142  ret.size() << " children\n";
143  for ( vector< Id >::iterator i = ret.begin(); i != ret.end(); ++i )
144  {
145  cout << i->element()->getName() << endl;
146  }
147 }
Element * element() const
Synonym for Id::operator()()
Definition: Id.cpp:113
Eref eref() const
Definition: Id.cpp:125
static void children(const Eref &e, vector< Id > &ret)
Definition: Neutral.cpp:342
const string & getName() const
Definition: Element.cpp:56

+ Here is the call graph for this function:

unsigned int getNumCores ( )

Definition at line 93 of file main.cpp.

Referenced by init().

94 {
95  unsigned int numCPU = 0;
96 #ifdef WIN_32
97  SYSTEM_INFO sysinfo;
98  GetSystemInfo( &sysinfo );
99 
100  numCPU = sysinfo.dwNumberOfProcessors;
101 #endif
102 
103 #ifdef LINUX
104  numCPU = sysconf( _SC_NPROCESSORS_ONLN );
105 #endif
106 
107 #ifdef MACOSX
108  int mib[4];
109  size_t len = sizeof(numCPU);
110 
111  /* set the mib for hw.ncpu */
112  mib[0] = CTL_HW;
113  mib[1] = HW_AVAILCPU; // alternatively, try HW_NCPU;
114 
115  /* get the number of CPUs from the system */
116  sysctl(mib, 2, &numCPU, &len, NULL, 0);
117 
118  if( numCPU < 1 )
119  {
120  mib[1] = HW_NCPU;
121  sysctl( mib, 2, &numCPU, &len, NULL, 0 );
122  }
123 #endif
124  if ( numCPU < 1 )
125  {
126  cout << "No CPU information available. Assuming single core." << endl;
127  numCPU = 1;
128  }
129  return numCPU;
130 }

+ Here is the caller graph for this function:

Id init ( int  argc,
char **  argv,
bool &  doUnitTests,
bool &  doRegressionTests,
unsigned int &  benchmark 
)

Here we allow the user to override the automatic identification of processor configuration

Sets up the Elements that represent each class of Msg.

Definition at line 150 of file main.cpp.

Referenced by benchmarkMsg(), Ksolve::initCinfo(), Gsolve::initCinfo(), moose::CompartmentBase::initCinfo(), NonlinearSystem::initialize(), main(), SteadyState::settle(), testAssortedMsg(), testCopyMsgOps(), testShellAddMsg(), and testSparseMatrix2().

152 {
153  unsigned int numCores = getNumCores();
154  int numNodes = 1;
155  int myNode = 0;
156  bool isInfinite = 0;
157  int opt;
158  benchmark = 0; // Default, means don't do any benchmarks.
160 #ifdef USE_MPI
161  /*
162  // OpenMPI does not use argc or argv.
163  // unsigned int temp_argc = 1;
164  int provided;
165  MPI_Init_thread( &argc, &argv, MPI_THREAD_SERIALIZED, &provided );
166  */
167  MPI_Init( &argc, &argv );
168 
169  MPI_Comm_size( MPI_COMM_WORLD, &numNodes );
170  MPI_Comm_rank( MPI_COMM_WORLD, &myNode );
171  /*
172  if ( provided < MPI_THREAD_SERIALIZED && myNode == 0 ) {
173  cout << "Warning: This MPI implementation does not like multithreading: " << provided << "\n";
174  }
175  */
176  // myNode = MPI::COMM_WORLD.Get_rank();
177 #endif
178 
182  while ( ( opt = getopt( argc, argv, "hiqurn:b:B:" ) ) != -1 )
183  {
184  switch ( opt )
185  {
186  case 'i' : // infinite loop, used for multinode debugging, to give gdb something to attach to.
187  isInfinite = 1;
188  break;
189  case 'n': // Multiple nodes
190  numNodes = (unsigned int)atoi( optarg );
191  break;
192  case 'b': // Benchmark:
193  {
194  string s(optarg);
195  if ( s == "ee" )
196  benchmark = 1;
197  else if ( s == "gsl" )
198  benchmark = 2;
199  else if ( s == "gssa" )
200  benchmark = 3;
201  else if ( s[0] == 'i' )
202  benchmark = 4;
203  else if ( s[0] == 'h' )
204  benchmark = 5;
205  else if ( s[0] == 'm' )
206  benchmark = 6;
207  else
208  cout << "Unknown benchmark, " << optarg << ", skipping\n";
209  }
210  break;
211  case 'B': // Benchmark plus dump data: handle later.
212  break;
213  case 'u': // Do unit tests, pass back.
214  doUnitTests = 1;
215  break;
216  case 'r': // Do regression tests: pass back
217  doRegressionTests = 1;
218  break;
219  case 'q': // quit immediately after completion.
220  quitFlag = 1;
221  break;
222  case 'h': // help
223  default:
224  cout << "Usage: moose -help -infiniteLoop -unit_tests -regression_tests -quit -n numNodes -benchmark [ee gsl gssa intFire hhNet msg_<msgType>_<size>]\n";
225 
226  exit( 1 );
227  }
228  }
229  if ( myNode == 0 )
230  {
231 #ifndef QUIET_MODE
232  cout << "on node " << myNode << ", numNodes = "
233  << numNodes << ", numCores = " << numCores << endl;
234 #endif
235  }
236 
237  Id shellId;
238  Element* shelle =
239  new GlobalDataElement( shellId, Shell::initCinfo(), "root", 1 );
240 
241  Id clockId = Id::nextId();
242  assert( clockId.value() == 1 );
243  Id classMasterId = Id::nextId();
244  Id postMasterId = Id::nextId();
245 
246  Shell* s = reinterpret_cast< Shell* >( shellId.eref().data() );
247  s->setShellElement( shelle );
248  s->setHardware( numCores, numNodes, myNode );
249  s->loadBalance();
250 
252  unsigned int numMsg = Msg::initMsgManagers();
253 
254  new GlobalDataElement( clockId, Clock::initCinfo(), "clock", 1 );
255  new GlobalDataElement( classMasterId, Neutral::initCinfo(), "classes", 1);
256  new GlobalDataElement( postMasterId, PostMaster::initCinfo(), "postmaster", 1 );
257 
258  assert ( shellId == Id() );
259  assert( clockId == Id( 1 ) );
260  assert( classMasterId == Id( 2 ) );
261  assert( postMasterId == Id( 3 ) );
262 
263 
264 
265  // s->connectMasterMsg();
266 
267  Shell::adopt( shellId, clockId, numMsg++ );
268  Shell::adopt( shellId, classMasterId, numMsg++ );
269  Shell::adopt( shellId, postMasterId, numMsg++ );
270 
271  assert( numMsg == 10 ); // Must be the same on all nodes.
272 
273  Cinfo::makeCinfoElements( classMasterId );
274 
275 
276  // This will be initialized within the Process loop, and better there
277  // as it flags attempts to call the Reduce operations before ProcessLoop
278  // Qinfo::clearReduceQ( numCores ); // Initialize the ReduceQ entry.
279 
280 
281  // SetGet::setShell();
282  // Msg* m = new OneToOneMsg( shelle, shelle );
283  // assert ( m != 0 );
284 
285  while ( isInfinite ) // busy loop for debugging under gdb and MPI.
286  ;
287 
288  return shellId;
289 }
static unsigned int numCores
static void makeCinfoElements(Id parent)
Definition: Cinfo.cpp:164
char * data() const
Definition: Eref.cpp:41
unsigned int value() const
Definition: Id.cpp:197
static const Cinfo * initCinfo()
Definition: Clock.cpp:133
static int isInfinite
static void setHardware(unsigned int numCores, unsigned int numNodes, unsigned int myNode)
Eref eref() const
Definition: Id.cpp:125
static const Cinfo * initCinfo()
Definition: Shell.cpp:46
void setShellElement(Element *shelle)
Definition: Shell.cpp:166
static int doRegressionTests
static Id nextId()
Definition: Id.cpp:132
static unsigned int myNode
static void loadBalance()
static unsigned int numNodes
unsigned int getNumCores()
Definition: main.cpp:93
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
static const Cinfo * initCinfo()
Definition: PostMaster.cpp:82
static const Cinfo * initCinfo()
Definition: Neutral.cpp:16
static int doUnitTests
bool quitFlag
Definition: main.cpp:132
Definition: Shell.h:43

+ Here is the caller graph for this function:

int main ( int  argc,
char **  argv 
)

Definition at line 360 of file main.cpp.

References Id::clearAllElements(), Msg::clearAllMsgs(), PostMaster::clearPending(), ObjId::data(), Element::data(), Shell::doQuit(), doRegressionTests, Shell::doSetClock(), doUnitTests, Shell::doUseClock(), Id::element(), init(), Shell::keepLooping(), Shell::launchParser(), mooseBenchmarks(), mpiTests(), Shell::myNode(), nonMpiTests(), Shell::numNodes(), processTests(), and quitFlag.

361 {
362  bool doUnitTests = 0;
363  bool doRegressionTests = 0;
364  unsigned int benchmark = 0;
365  // This reorders the OpFunc to Fid mapping to ensure it is node and
366  // compiler independent.
367  Id shellId = init( argc, argv, doUnitTests, doRegressionTests, benchmark );
368  // Note that the main loop remains the parser loop, though it may
369  // spawn a lot of other stuff.
370  Element* shelle = shellId.element();
371  Shell* s = reinterpret_cast< Shell* >( shelle->data( 0 ) );
372  if ( doUnitTests )
373  nonMpiTests( s ); // These tests do not need the process loop.
374 
375  if ( Shell::myNode() == 0 )
376  {
377  if ( Shell::numNodes() > 1 )
378  {
379  // Use the last clock for the postmaster, so that it is called
380  // after everything else has been processed and all messages
381  // are ready to send out.
382  s->doUseClock( "/postmaster", "process", 9 );
383  s->doSetClock( 9, 1.0 ); // Use a sensible default.
384  }
385 #ifdef DO_UNIT_TESTS
386  if ( doUnitTests )
387  {
388  mpiTests();
389  processTests( s );
390  }
391  // if ( doRegressionTests ) regressionTests();
392 #endif
393  // These are outside unit tests because they happen in optimized
394  // mode, using a command-line argument. As soon as they are done
395  // the system quits, in order to estimate timing.
396  if ( benchmark != 0 )
397  {
398  mooseBenchmarks( benchmark );
399  s->doQuit();
400  }
401  else
402  {
403  // Here we set off a little event loop to poll user input.
404  // It deals with the doQuit call too.
405  if(! quitFlag)
407  }
408  }
409  else
410  {
411  PostMaster* p = reinterpret_cast< PostMaster* >( ObjId( 3 ).data());
412  while ( Shell::keepLooping() )
413  {
414  p->clearPending();
415  }
416  }
419 #ifdef USE_MPI
420  MPI_Finalize();
421 #endif
422  return 0;
423 }
Id init(int argc, char **argv, bool &doUnitTests, bool &doRegressionTests, unsigned int &benchmark)
Definition: main.cpp:150
static void clearAllElements()
Definition: Id.cpp:202
char * data() const
Definition: ObjId.cpp:113
Element * element() const
Synonym for Id::operator()()
Definition: Id.cpp:113
void doSetClock(unsigned int tickNum, double dt)
Definition: Shell.cpp:377
Definition: ObjId.h:20
static void launchParser()
void processTests(Shell *s)
Definition: main.cpp:333
void mooseBenchmarks(unsigned int option)
static int doRegressionTests
void nonMpiTests(Shell *s)
Definition: main.cpp:297
static bool keepLooping()
Definition: Shell.cpp:996
void doQuit()
Definition: Shell.cpp:327
void clearPending()
All arrived messages and set calls are handled and cleared.
Definition: PostMaster.cpp:215
virtual char * data(unsigned int rawIndex, unsigned int fieldIndex=0) const =0
Definition: Id.h:17
static unsigned int myNode()
void doUseClock(string path, string field, unsigned int tick)
Definition: Shell.cpp:382
static int doUnitTests
static unsigned int numNodes()
bool quitFlag
Definition: main.cpp:132
void mpiTests()
Definition: main.cpp:350
static void clearAllMsgs()
Definition: Msg.cpp:286
Definition: Shell.h:43

+ Here is the call graph for this function:

void mooseBenchmarks ( unsigned int  option)

Referenced by main().

+ Here is the caller graph for this function:

void mpiTests ( )

These are tests that are MPI safe. They should also run properly on single nodes.

Definition at line 350 of file main.cpp.

Referenced by main().

351 {
352 #ifdef DO_UNIT_TESTS
353  MOOSE_TEST( "testMpiMsg", testMpiMsg());
354  MOOSE_TEST( "testMpiShell", testMpiShell());
355  MOOSE_TEST( "testMpiBuiltins", testMpiBuiltins());
356  MOOSE_TEST( "testMpiScheduling", testMpiScheduling());
357 #endif
358 }
void testMpiShell()
Definition: testShell.cpp:1833
void testMpiBuiltins()
void testMpiMsg()
Definition: testMsg.cpp:376
void testMpiScheduling()

+ Here is the caller graph for this function:

void nonMpiTests ( Shell s)

These tests are meant to run on individual nodes, and should not invoke MPI calls. They should not be run when MPI is running. These tests do not use the threaded/MPI event loop and are the most basic of the set.

Definition at line 297 of file main.cpp.

Referenced by main().

298 {
299 #ifdef DO_UNIT_TESTS
300  if ( Shell::myNode() == 0 )
301  {
302  unsigned int numNodes = s->numNodes();
303  unsigned int numCores = s->numCores();
304  if ( numCores > 0 )
305  s->setHardware( 1, 1, 0 );
306  MOOSE_TEST("testAsync", testAsync());
307  MOOSE_TEST("testMsg", testMsg());
308  MOOSE_TEST("testShell", testShell());
309  MOOSE_TEST("testScheduling", testScheduling());
310  MOOSE_TEST("testBuiltints", testBuiltins());
311  //MOOSE_TEST("testKinetics", testKinetics());
312  MOOSE_TEST("testKsolve", testKsolve());
313  //MOOSE_TEST("testKsolveProcess", testKsolveProcess());
314  MOOSE_TEST("testBiophysics", testBiophysics());
315  MOOSE_TEST("testDiffusion", testDiffusion());
316  MOOSE_TEST("testHsolve", testHSolve());
317  //MOOSE_TEST("testGeom", testGeom());
318  MOOSE_TEST("testMesh", testMesh());
319  MOOSE_TEST("testSynapse", testSynapse());
320  MOOSE_TEST( "testSigneur", testSigNeur());
321 #ifdef USE_SMOLDYN
322  //MOOSE_TEST(testSmoldyn());
323 #endif
324  s->setHardware( numCores, numNodes, 0 );
325  }
326 #endif
327 }
static unsigned int numCores
void testAsync()
Definition: testAsync.cpp:1813
static unsigned int numCores()
void testDiffusion()
void testKsolve()
Definition: testKsolve.cpp:329
static void setHardware(unsigned int numCores, unsigned int numNodes, unsigned int myNode)
void testShell()
Definition: testShell.cpp:1818
void testMsg()
Definition: testMsg.cpp:370
void testSigNeur()
void testScheduling()
void testMesh()
Definition: testMesh.cpp:2138
static unsigned int numNodes
void testBiophysics()
void testBuiltins()
static unsigned int myNode()
static unsigned int numNodes()
void testSynapse()
void testHSolve()
Definition: testHSolve.cpp:11

+ Here is the caller graph for this function:

void processTests ( Shell s)

These tests involve the threaded/MPI process loop and are the next level of tests.

Definition at line 333 of file main.cpp.

Referenced by main().

334 {
335 #ifdef DO_UNIT_TESTS
336  MOOSE_TEST( "testSchedulingProcess", testSchedulingProcess());
337  MOOSE_TEST( "testBuiltinsProcess", testBuiltinsProcess());
338  // MOOSE_TEST( "testKineticsProcess", testKineticsProcess());
339  MOOSE_TEST( "testBiophysicsProcess", testBiophysicsProcess());
340  // MOOSE_TEST( "testKineticSolversProcess", testKineticSolversProcess());
341  // MOOSE_TEST( "testSimManager", testSimManager());
342  MOOSE_TEST( "testSigNeurProcess", testSigNeurProcess());
343 #endif
344 }
void testSigNeurProcess()
void testBuiltinsProcess()
void testSchedulingProcess()
void testBiophysicsProcess()

+ Here is the caller graph for this function:

void speedTestMultiNodeIntFireNetwork ( unsigned int  size,
unsigned int  runsteps 
)

Variable Documentation

bool quitFlag = 0

Definition at line 132 of file main.cpp.

Referenced by init(), and main().