MOOSE - Multiscale Object Oriented Simulation Environment
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
testBuiltins.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-2010 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 #include "DiagonalMsg.h"
12 #include "OneToAllMsg.h"
13 #include "../scheduling/Clock.h"
14 #include "Arith.h"
15 #include "TableBase.h"
16 #include "Table.h"
17 #include <queue>
18 
19 #include "../shell/Shell.h"
20 
21 extern void testNSDF();
22 
23 void testArith()
24 {
25  Id a1id = Id::nextId();
26  unsigned int size = 10;
27  Element* a1 = new GlobalDataElement(
28  a1id, Arith::initCinfo(), "a1", size );
29 
30  Eref a1_0( a1, 0 );
31  Eref a1_1( a1, 1 );
32 
33  Arith* data1_0 = reinterpret_cast< Arith* >( a1->data( 0 ) );
34 
35  data1_0->arg1( 1 );
36  data1_0->arg2( 0 );
37 
38  ProcInfo p;
39  data1_0->process( a1_0, &p );
40 
41  assert( data1_0->getOutput() == 1 );
42 
43  data1_0->arg1( 1 );
44  data1_0->arg2( 2 );
45 
46  data1_0->process( a1_0, &p );
47 
48  assert( data1_0->getOutput() == 3 );
49 
50  a1id.destroy();
51 
52  cout << "." << flush;
53 }
54 
60 {
61  if ( Shell::numNodes() > 1 )
62  return;
63  unsigned int numFib = 20;
64  Id a1id = Id::nextId();
65  Element* a1 = new LocalDataElement(
66  a1id, Arith::initCinfo(), "a1", numFib );
67 
68  Arith* data = reinterpret_cast< Arith* >( a1->data( 0 ) );
69  if ( data ) {
70  data->arg1( 0 );
71  data->arg2( 1 );
72  }
73 
74  const Finfo* outFinfo = Arith::initCinfo()->findFinfo( "output" );
75  const Finfo* arg1Finfo = Arith::initCinfo()->findFinfo( "arg1" );
76  const Finfo* arg2Finfo = Arith::initCinfo()->findFinfo( "arg2" );
77  const Finfo* procFinfo = Arith::initCinfo()->findFinfo( "process" );
78  DiagonalMsg* dm1 = new DiagonalMsg( a1, a1, 0 );
79  bool ret = outFinfo->addMsg( arg1Finfo, dm1->mid(), a1 );
80  assert( ret );
81  dm1->setStride( 1 );
82 
83  DiagonalMsg* dm2 = new DiagonalMsg( a1, a1, 0 );
84  ret = outFinfo->addMsg( arg2Finfo, dm2->mid(), a1 );
85  assert( ret );
86  dm1->setStride( 2 );
87 
88  /*
89  bool ret = DiagonalMsg::add( a1, "output", a1, "arg1", 1 );
90  assert( ret );
91  ret = DiagonalMsg::add( a1, "output", a1, "arg2", 2 );
92  assert( ret );
93  */
94 
95  Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() );
96  shell->doSetClock( 0, 1.0 );
97  Eref clocker = Id( 1 ).eref();
98 
99  const Finfo* proc0Finfo = Clock::initCinfo()->findFinfo( "process0" );
100  OneToAllMsg* otam = new OneToAllMsg( clocker, a1, 0 );
101  ret = proc0Finfo->addMsg( procFinfo, otam->mid(), clocker.element() );
102 
103  assert( ret );
104 
105  shell->doStart( numFib );
106  unsigned int f1 = 1;
107  unsigned int f2 = 0;
108  for ( unsigned int i = 0; i < numFib; ++i ) {
109  // if ( a1->dataHandler()->isDataHere( i ) ) {
110  Arith* data = reinterpret_cast< Arith* >( a1->data( i ) );
111  // cout << Shell::myNode() << ": i = " << i << ", " << data->getOutput() << ", " << f1 << endl;
112  assert( data->getOutput() == f1 );
113  // }
114  unsigned int temp = f1;
115  f1 = temp + f2;
116  f2 = temp;
117  }
118 
119  a1id.destroy();
120  cout << "." << flush;
121 }
122 
128 {
129  unsigned int numFib = 20;
130 
131  // Id a1id = Id::nextId();
132  Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() );
133 
134  Id a1id = shell->doCreate( "Arith", ObjId(), "a1", numFib );
135  SetGet1< double >::set( a1id, "arg1", 0 );
136  SetGet1< double >::set( a1id, "arg2", 1 );
137 
138  /*
139  Arith* data = reinterpret_cast< Arith* >( a1->dataHandler()->data( 0 ) );
140 
141  if ( data ) {
142  data->arg1( 0 );
143  data->arg2( 1 );
144  }
145  */
146 
147  ObjId mid1 = shell->doAddMsg( "Diagonal",
148  ObjId( a1id, 0 ), "output", ObjId( a1id, 0 ), "arg1" );
149  bool ret = Field< int >::set( mid1, "stride", 1 );
150  assert( ret );
151 
152  ObjId mid2 = shell->doAddMsg( "Diagonal",
153  ObjId( a1id, 0 ), "output", ObjId( a1id, 0 ), "arg2" );
154  ret = Field< int >::set( mid2, "stride", 2 );
155  assert( ret );
156 
157  /*
158  bool ret = DiagonalMsg::add( a1, "output", a1, "arg1", 1 );
159  assert( ret );
160  ret = DiagonalMsg::add( a1, "output", a1, "arg2", 2 );
161  assert( ret );
162  */
163 
164  shell->doSetClock( 0, 1.0 );
165  shell->doUseClock( "/a1", "process", 0 );
166 
167  shell->doStart( numFib );
168 
169  vector< double > retVec;
170  Field< double >::getVec( a1id, "outputValue", retVec );
171  assert( retVec.size() == numFib );
172 
173  unsigned int f1 = 1;
174  unsigned int f2 = 0;
175  for ( unsigned int i = 0; i < numFib; ++i ) {
176  /*
177  if ( a1->dataHandler()->isDataHere( i ) ) {
178  Arith* data = reinterpret_cast< Arith* >( a1->dataHandler()->data( i ) );
179  // cout << Shell::myNode() << ": i = " << i << ", " << data->getOutput() << ", " << f1 << endl;
180  assert( data->getOutput() == f1 );
181  }
182  */
183  assert( doubleEq( retVec[i], f1 ) );
184  unsigned int temp = f1;
185  f1 = temp + f2;
186  f2 = temp;
187  }
188 
189  a1id.destroy();
190  cout << "." << flush;
191 }
192 
194 {
195  bool isNamedPlot( const string& line, const string& plotname );
196  double getYcolumn( const string& line );
197 
198  assert( isNamedPlot( "/plotname foo", "foo" ) );
199  assert( !isNamedPlot( "/plotname foo", "bar" ) );
200  assert( !isNamedPlot( "/newplot", "bar" ) );
201  assert( !isNamedPlot( "", "bar" ) );
202  assert( !isNamedPlot( "1234.56", "bar" ) );
203 
204  assert( doubleEq( getYcolumn( "123.456" ), 123.456 ) );
205  assert( doubleEq( getYcolumn( "987 123.456" ), 123.456 ) );
206  assert( doubleEq( getYcolumn( "987 23.456" ), 23.456 ) );
207  assert( doubleEq( getYcolumn( "987 3.456" ), 3.456 ) );
208  assert( doubleEq( getYcolumn( "987 0.456" ), 0.456 ) );
209  assert( doubleEq( getYcolumn( "987.6 0.456 1111.1" ), 987.6 ) );
210  cout << "." << flush;
211 }
212 
214 {
215  double getRMSDiff( const vector< double >& v1, const vector< double >& v2 );
216  double getRMS( const vector< double >& v );
217 
218  double getRMSRatio( const vector< double >& v1, const vector< double >& v2 );
219 
220  vector< double > v1;
221  vector< double > v2;
222  v1.push_back( 0 );
223  v1.push_back( 1 );
224  v1.push_back( 2 );
225 
226  v2.push_back( 0 );
227  v2.push_back( 1 );
228  v2.push_back( 2 );
229 
230  double r1 = sqrt( 5.0 / 3.0 );
231  double r2 = sqrt( 1.0 / 3.0 );
232 
233  assert( doubleEq( getRMS( v1 ), r1 ) );
234  assert( doubleEq( getRMS( v2 ), r1 ) );
235  assert( doubleEq( getRMSDiff( v1, v2 ), 0 ) );
236  assert( doubleEq( getRMSRatio( v1, v2 ), 0 ) );
237 
238  v2[2] = 3;
239  assert( doubleEq( getRMS( v2 ), sqrt( 10.0/3.0 ) ) );
240  assert( doubleEq( getRMSDiff( v1, v2 ), r2 ) );
241  assert( doubleEq( getRMSRatio( v1, v2 ), r2 / ( sqrt( 10.0/3.0 ) + r1 ) ) );
242  cout << "." << flush;
243 }
244 
245 void testTable()
246 {
249  Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() );
250  vector< Id > ret;
251  Neutral::children( Id().eref(), ret );
252  ObjId tabid = shell->doCreate( "Table", ObjId(), "tab", 1 );
253  assert( tabid != ObjId() );
254  Table* t = reinterpret_cast< Table* >( tabid.eref().data() );
255  for ( unsigned int i = 0; i < 100; ++i ) {
256  t->input( sqrt((double) i ) );
257  }
258  vector< double > values = Field< vector< double > >::get( tabid, "vector");
259  assert( values.size() == 100 );
260  for ( unsigned int i = 0; i < 100; ++i ) {
261  double ret = LookupField< unsigned int, double >::get( tabid, "y", i );
262  assert( doubleEq( values[i] , sqrt((double) i ) ) );
263  assert( doubleEq( ret , sqrt((double) i ) ) );
264  }
265  shell->doDelete( tabid );
266  cout << "." << flush;
267 }
268 
273 {
274  Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() );
275  ObjId tabid = shell->doCreate( "Table", ObjId(), "tab", 1 );
276  assert( tabid != ObjId() );
277  ObjId arithid = shell->doCreate( "Arith", ObjId(), "arith", 1 );
278  assert( arithid != ObjId() );
279  // Table* t = reinterpret_cast< Table* >( tabid.eref().data() );
280  ObjId ret = shell->doAddMsg( "Single",
281  tabid.eref().objId(), "requestOut",
282  arithid.eref().objId(), "getOutputValue" );
283  assert( ret != ObjId() );
284  ret = shell->doAddMsg( "Single", arithid.eref().objId(), "output",
285  arithid.eref().objId(), "arg1" );
286  assert( ret != ObjId() );
287  shell->doSetClock( 0, 1 );
288  shell->doSetClock( 1, 1 );
289  shell->doUseClock( "/arith", "process", 0 );
290  shell->doUseClock( "/tab", "process", 1 );
291  unsigned int numEntries = Field< unsigned int >::get( tabid, "size" );
292  assert( numEntries == 0 );
293  Id clockId( 1 );
294  // clockId.element()->digestMessages();
295  // tabid.element()->digestMessages();
296  // arithid.element()->digestMessages();
297  shell->doReinit();
298  numEntries = Field< unsigned int >::get( tabid, "size" );
299  assert( numEntries == 1 ); // One for reinit call.
300  SetGet1< double >::set( arithid, "arg1", 0.0 );
301  SetGet1< double >::set( arithid, "arg2", 2.0 );
302  shell->doStart( 100 );
303 
304  numEntries = Field< unsigned int >::get( tabid, "size" );
305  assert( numEntries == 101 ); // One for reinit call, 100 for process.
306  vector< double > temp = Field< vector< double > >::get( tabid, "vector" );
307 
308  for ( unsigned int i = 0; i < 100; ++i ) {
309  double ret = LookupField< unsigned int, double >::get( tabid, "y", i );
310  assert( doubleEq( ret, 2 * i ) );
311  assert( doubleEq( temp[i], 2 * i ) );
312  }
313 
315  // Here we check using the 'get' message with multiple targets
317  Id arith2 = shell->doCopy( arithid, ObjId(), "arith2", 1, false, false);
318  shell->doUseClock( "/arith2", "process", 0 );
319  ret = shell->doAddMsg( "Single",
320  tabid.eref().objId(), "requestOut",
321  arith2.eref().objId(), "getOutputValue" );
322  shell->doReinit();
323  SetGet1< double >::set( arithid, "arg1", 0.0 );
324  SetGet1< double >::set( arithid, "arg2", 2.0 );
325  SetGet1< double >::set( arith2, "arg1", 10.0 );
326  SetGet1< double >::set( arith2, "arg2", 12.0 );
327  shell->doStart( 100 );
328 
329  numEntries = Field< unsigned int >::get( tabid, "size" );
330  // One for reinit call, 100 for process, and there are two targets.
331  assert( numEntries == 202 );
332  temp = Field< vector< double > >::get( tabid, "vector" );
333 
334  for ( unsigned int i = 1; i < 100; ++i ) {
335  assert( doubleEq( temp[2 * i], 2 * i ) );
336  assert( doubleEq( temp[2 * i + 1], 10 + 12 * i ) );
337  }
338 
339 
340  // Perhaps I should do another test without reinit.
341  /*
342  SetGet2< string, string >::set(
343  tabid.eref(), "xplot", "testfile", "testplot" );
344  tabentry.destroy();
345  */
346  shell->doDelete( arithid );
347  shell->doDelete( arith2 );
348  shell->doDelete( tabid );
349  cout << "." << flush;
350 
351 }
352 
353 void testStats()
354 {
355  Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() );
356  unsigned int size = 1000;
357  vector< double > sinewave( size, 0 );
358  for ( unsigned int i = 0; i < size; ++i ) {
359  sinewave[i] = sin( 2 * i * PI / static_cast< double >( size ) );
360  }
361  ObjId tabid = shell->doCreate( "StimulusTable", ObjId(), "tab", 1 );
362  assert( tabid != ObjId() );
363  Field< vector< double > >::set( tabid, "vector", sinewave );
364  Field< double >::set( tabid, "startTime", 0 );
365  Field< double >::set( tabid, "stopTime", size );
366  Field< double >::set( tabid, "loopTime", size );
367  Field< double >::set( tabid, "stepSize", 0 );
368  Field< double >::set( tabid, "stepPosition", 0 );
369  Field< bool >::set( tabid, "doLoop", true );
370 
371  ObjId stat1 = shell->doCreate( "Stats", ObjId(), "stat1", 1 );
372  Field< unsigned int >::set( stat1, "windowLength", size );
373 
374  ObjId mid = shell->doAddMsg( "Single", tabid, "output",
375  stat1, "input" );
376 
377  shell->doUseClock( "/tab", "process", 0 );
378  shell->doUseClock( "/stat1", "process", 1 );
379  shell->doSetClock( 0, 1 );
380  shell->doSetClock( 1, 1 );
381 
382  shell->doReinit();
383  shell->doStart( size/2 );
384  double mean = Field< double >::get( stat1, "mean" );
385  double sdev = Field< double >::get( stat1, "sdev" );
386  double sum = Field< double >::get( stat1, "sum" );
387  unsigned int num = Field< unsigned int >::get( stat1, "num" );
388  double wmean = Field< double >::get( stat1, "wmean" );
389  double wsdev = Field< double >::get( stat1, "wsdev" );
390  double wsum = Field< double >::get( stat1, "wsum" );
391  unsigned int wnum = Field< unsigned int >::get( stat1, "wnum" );
392  assert( doubleApprox( mean, 2.0 / PI ) );
393  assert( doubleApprox( sdev, 0.3077627 ) );
394  assert( doubleApprox( sum, size / PI ) );
395  assert( doubleApprox( num, size/2 ) );
396  assert( doubleApprox( wmean, 2.0 / PI ) );
397  // assert( doubleApprox( wsdev, 1.0/sqrt( 2.0 ) ) );
398  assert( doubleApprox( wsum, size / PI ) );
399  assert( wnum == size/2 );
400 
401  shell->doStart( size );
402  mean = Field< double >::get( stat1, "mean" );
403  sdev = Field< double >::get( stat1, "sdev" );
404  sum = Field< double >::get( stat1, "sum" );
405  num = Field< unsigned int >::get( stat1, "num" );
406  wmean = Field< double >::get( stat1, "wmean" );
407  wsdev = Field< double >::get( stat1, "wsdev" );
408  wsum = Field< double >::get( stat1, "wsum" );
409  wnum = Field< unsigned int >::get( stat1, "wnum" );
410  assert( doubleApprox( mean, 2.0 / (PI * 3.0) ) );
411  assert( doubleApprox( sdev, 0.6745136 ) );
412  assert( doubleApprox( sum, size / PI ) );
413  assert( doubleApprox( num, 3 * size/2 ) );
414  assert( doubleApprox( wmean, 0 ) );
415  assert( doubleApprox( wsdev, 1.0/sqrt( 2.0 ) ) );
416  assert( doubleApprox( wsum, 0 ) );
417  assert( wnum == size );
418 
419  shell->doDelete( tabid );
420  shell->doDelete( stat1 );
421  cout << "." << flush;
422 }
423 
425 {
426  testArith();
427  testTable();
428  testNSDF();
429 }
430 
432 {
433 // testFibonacci(); Nov 2013: Waiting till we have the MsgObjects fixed.
434  testGetMsg();
435  testStats();
436 }
437 
439 {
440  // testMpiFibonacci();
441  cout << "." << flush;
442 }
double getRMSDiff(const vector< double > &v1, const vector< double > &v2)
Definition: TableBase.cpp:326
void doStart(double runtime, bool notify=false)
Definition: Shell.cpp:332
ObjId mid() const
Definition: Msg.h:106
char * data() const
Definition: Eref.cpp:41
void testArith()
bool isNamedPlot(const string &line, const string &plotname)
Definition: TableBase.cpp:192
static A get(const ObjId &dest, const string &field, L index)
Definition: SetGet.h:532
void testStats()
Definition: Arith.h:12
void doSetClock(unsigned int tickNum, double dt)
Definition: Shell.cpp:377
void testMpiFibonacci()
static const Cinfo * initCinfo()
Definition: Clock.cpp:133
Definition: SetGet.h:236
Id doCopy(Id orig, ObjId newParent, string newName, unsigned int n, bool toGlobal, bool copyExtMsgs)
Returns the Id of the root of the copied tree upon success.
Definition: ShellCopy.cpp:16
Definition: ObjId.h:20
double getRMSRatio(const vector< double > &v1, const vector< double > &v2)
Definition: TableBase.cpp:352
const int numEntries
Definition: proc.cpp:60
Eref eref() const
Definition: Id.cpp:125
static void children(const Eref &e, vector< Id > &ret)
Definition: Neutral.cpp:342
Element * element() const
Definition: Eref.h:42
static bool set(const ObjId &dest, const string &field, A arg)
Definition: SetGet.h:245
void testBuiltinsProcess()
Id doCreate(string type, ObjId parent, string name, unsigned int numData, NodePolicy nodePolicy=MooseBlockBalance, unsigned int preferredNode=1)
Definition: Shell.cpp:181
void destroy() const
Definition: Id.cpp:176
void testUtilsForCompareXplot()
bool doubleApprox(double x, double y)
Definition: doubleEq.cpp:24
double getOutput() const
Definition: Arith.cpp:185
void process(const Eref &e, ProcPtr p)
Definition: Arith.cpp:125
void setStride(int stride)
Definition: DiagonalMsg.cpp:81
void testMpiBuiltins()
bool doubleEq(double x, double y)
Definition: doubleEq.cpp:16
void testNSDF()
Definition: testNSDF.cpp:97
double getYcolumn(const string &line)
Definition: TableBase.cpp:231
static Id nextId()
Definition: Id.cpp:132
void testUtilsForLoadXplot()
virtual bool addMsg(const Finfo *target, ObjId mid, Element *src) const
Definition: Finfo.h:92
void testFibonacci()
ObjId objId() const
Definition: Eref.cpp:57
Definition: Eref.h:26
void arg2(double v)
Definition: Arith.cpp:152
void doReinit()
Definition: Shell.cpp:362
double getRMS(const vector< double > &v)
Definition: TableBase.cpp:340
Eref eref() const
Definition: ObjId.cpp:66
virtual char * data(unsigned int rawIndex, unsigned int fieldIndex=0) const =0
ObjId doAddMsg(const string &msgType, ObjId src, const string &srcField, ObjId dest, const string &destField)
Definition: Shell.cpp:269
static bool set(const ObjId &dest, const string &field, A arg)
Definition: SetGet.h:153
const double PI
Definition: consts.cpp:12
bool doDelete(ObjId oid)
Definition: Shell.cpp:259
Definition: Id.h:17
void testBuiltins()
void doUseClock(string path, string field, unsigned int tick)
Definition: Shell.cpp:382
void testGetMsg()
static const Cinfo * initCinfo()
Definition: Arith.cpp:22
static A get(const ObjId &dest, const string &field)
Definition: SetGet.h:284
Definition: Table.h:18
void arg1(double v)
Definition: Arith.cpp:147
static unsigned int numNodes()
static void getVec(ObjId dest, const string &field, vector< A > &vec)
Definition: SetGet.h:317
void input(double v)
Definition: Table.cpp:338
Definition: Shell.h:43
const Finfo * findFinfo(const string &name) const
Definition: Cinfo.cpp:224
Definition: Finfo.h:12
void testTable()