MOOSE - Multiscale Object Oriented Simulation Environment
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
testMsg.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 "../builtins/Arith.h"
12 
13 #include "../shell/Shell.h"
14 
16 {
17  Eref sheller = Id().eref();
18  Shell* shell = reinterpret_cast< Shell* >( sheller.data() );
19  ObjId pa = shell->doCreate( "Neutral", ObjId(), "pa", 1 );
20  unsigned int numData = 5;
21 
22 
24  // Set up the objects.
26  Id a1 = shell->doCreate( "Arith", pa, "a1", numData );
27  Id a2 = shell->doCreate( "Arith", pa, "a2", numData );
28 
29  Id b1 = shell->doCreate( "Arith", pa, "b1", numData );
30  Id b2 = shell->doCreate( "Arith", pa, "b2", numData );
31 
32  Id c1 = shell->doCreate( "Arith", pa, "c1", numData );
33  Id c2 = shell->doCreate( "Arith", pa, "c2", numData );
34 
35  Id d1 = shell->doCreate( "Arith", pa, "d1", numData );
36  Id d2 = shell->doCreate( "Arith", pa, "d2", numData );
37 
38  Id e1 = shell->doCreate( "Arith", pa, "e1", numData );
39  Id e2 = shell->doCreate( "Arith", pa, "e2", numData );
40 
42  // Set up initial conditions
44  bool ret = 0;
45  vector< double > init; // 12345
46  for ( unsigned int i = 1; i < 6; ++i )
47  init.push_back( i );
48  ret = SetGet1< double >::setVec( a1, "arg1", init ); // 12345
49  assert( ret );
50  ret = SetGet1< double >::setVec( b1, "arg1", init ); // 12345
51  assert( ret );
52  ret = SetGet1< double >::setVec( c1, "arg1", init ); // 12345
53  assert( ret );
54  ret = SetGet1< double >::setVec( d1, "arg1", init ); // 12345
55  assert( ret );
56  ret = SetGet1< double >::setVec( e1, "arg1", init ); // 12345
57  assert( ret );
58 
60  // Set up messaging
62  // Should give 04000
63  ObjId m1 = shell->doAddMsg( "Single",
64  ObjId( a1, 3 ), "output", ObjId( a2, 1 ), "arg1" );
65  assert( !m1.bad() );
66 
67  // Should give 33333
68  ObjId m2 = shell->doAddMsg( "OneToAll",
69  ObjId( b1, 2 ), "output", ObjId( b2, 0 ), "arg1" );
70  assert( !m2.bad() );
71 
72  // Should give 12345
73  ObjId m3 = shell->doAddMsg( "OneToOne",
74  ObjId( c1, 0 ), "output", ObjId( c2, 0 ), "arg1" );
75  assert( !m3.bad() );
76 
77  // Should give 01234
78  ObjId m4 = shell->doAddMsg( "Diagonal",
79  ObjId( d1, 0 ), "output", ObjId( d2, 0 ), "arg1" );
80  assert( !m4.bad() );
81 
82  // Should give 54321
83  ObjId m5 = shell->doAddMsg( "Sparse",
84  ObjId( e1, 0 ), "output", ObjId( e2, 0 ), "arg1" );
85  assert( !m5.bad() );
86 
88  m5, "setEntry", 0, 4, 0 );
89  assert( ret );
91  m5, "setEntry", 1, 3, 0 );
92  assert( ret );
94  m5, "setEntry", 2, 2, 0 );
95  assert( ret );
97  m5, "setEntry", 3, 1, 0 );
98  assert( ret );
100  m5, "setEntry", 4, 0, 0 );
101  assert( ret );
102 
103  assert( ret );
104 
106  // Test traversal
108  // Single
109  ObjId f = Msg::getMsg( m1 )->findOtherEnd( ObjId( a1, 3 ) );
110  assert( f == ObjId( a2, 1 ) );
111 
112  f = Msg::getMsg( m1 )->findOtherEnd( ObjId( a2, 1 ) );
113  assert( f == ObjId( a1, 3 ) );
114 
115  f = Msg::getMsg( m1 )->findOtherEnd( ObjId( a1, 0 ) );
116  assert( f.bad() );
117 
118  f = Msg::getMsg( m1 )->findOtherEnd( ObjId( a2, 0 ) );
119  assert( f.bad() );
120 
121  f = Msg::getMsg( m1 )->findOtherEnd( ObjId( b2, 1 ) );
122  assert( f.bad() );
123 
124  // OneToAll
125  f = Msg::getMsg( m2 )->findOtherEnd( ObjId( b1, 2 ) );
126  assert( f == ObjId( b2, 0 ) );
127 
128  f = Msg::getMsg( m2 )->findOtherEnd( ObjId( b2, 0 ) );
129  assert( f == ObjId( b1, 2 ) );
130  f = Msg::getMsg( m2 )->findOtherEnd( ObjId( b2, 1 ) );
131  assert( f == ObjId( b1, 2 ) );
132  f = Msg::getMsg( m2 )->findOtherEnd( ObjId( b2, 2 ) );
133  assert( f == ObjId( b1, 2 ) );
134  f = Msg::getMsg( m2 )->findOtherEnd( ObjId( b2, 3 ) );
135  assert( f == ObjId( b1, 2 ) );
136  f = Msg::getMsg( m2 )->findOtherEnd( ObjId( b2, 4 ) );
137  assert( f == ObjId( b1, 2 ) );
138 
139  f = Msg::getMsg( m2 )->findOtherEnd( ObjId( b1, 0 ) );
140  assert( f.bad() );
141 
142  f = Msg::getMsg( m2 )->findOtherEnd( ObjId( a2, 1 ) );
143  assert( f.bad() );
144 
145  // OneToOne
146  for ( unsigned int i = 0; i < 5; ++i ) {
147  f = Msg::getMsg( m3 )->findOtherEnd( ObjId( c1, i ) );
148  assert( f == ObjId( c2, i ) );
149  f = Msg::getMsg( m3 )->findOtherEnd( ObjId( c2, i ) );
150  assert( f == ObjId( c1, i ) );
151  }
152  f = Msg::getMsg( m3 )->findOtherEnd( ObjId( a2, 1 ) );
153  assert( f.bad() );
154 
155  // Diagonal
156  for ( unsigned int i = 0; i < 4; ++i ) {
157  f = Msg::getMsg( m4 )->findOtherEnd( ObjId( d1, i ) );
158  assert( f == ObjId( d2, i + 1 ) );
159  f = Msg::getMsg( m4 )->findOtherEnd( ObjId( d2, i + 1 ) );
160  assert( f == ObjId( d1, i ) );
161  }
162  f = Msg::getMsg( m4 )->findOtherEnd( ObjId( d1, 4 ) );
163  assert( f.bad() );
164  f = Msg::getMsg( m4 )->findOtherEnd( ObjId( d2, 0 ) );
165  assert( f.bad() );
166 
167  f = Msg::getMsg( m4 )->findOtherEnd( ObjId( a2, 1 ) );
168  assert( f.bad() );
169 
170  // Sparse
171  for ( unsigned int i = 0; i < 5; ++i ) {
172  f = Msg::getMsg( m5 )->findOtherEnd( ObjId( e1, i ) );
173  assert( f == ObjId( e2, 4 - i ) );
174  f = Msg::getMsg( m5 )->findOtherEnd( ObjId( e2, i ) );
175  assert( f == ObjId( e1, 4 - i ) );
176  }
177 
178  f = Msg::getMsg( m5 )->findOtherEnd( ObjId( a2, 1 ) );
179  assert( f.bad() );
180 
181  cout << "." << flush;
182 
184  // Check lookup by funcId.
186  const Finfo* aFinfo = Arith::initCinfo()->findFinfo( "arg1" );
187  FuncId afid = dynamic_cast< const DestFinfo* >( aFinfo )->getFid();
188 
189  ObjId m = a2.element()->findCaller( afid );
190  assert ( m == m1 );
191  m = b2.element()->findCaller( afid );
192  assert ( m == m2 );
193  m = c2.element()->findCaller( afid );
194  assert ( m == m3 );
195  m = d2.element()->findCaller( afid );
196  assert ( m == m4 );
197  m = e2.element()->findCaller( afid );
198  assert ( m == m5 );
199 
201  // Clean up.
203  shell->doDelete( pa );
204 
205  cout << "." << flush;
206 }
207 
208 // Reported as a bug by Subha 22 Feb 2012.
210 {
211  Eref sheller = Id().eref();
212  Shell* shell = reinterpret_cast< Shell* >( sheller.data() );
213  unsigned int numData = 1;
214  Id pa = shell->doCreate( "Neutral", Id(), "pa", numData );
215  numData = 5;
216 
217 
219  // Set up the objects.
221  Id a1 = shell->doCreate( "Arith", pa, "a1", numData );
222  Id a2 = shell->doCreate( "Arith", pa, "a2", numData );
223 
224  Id b1 = shell->doCreate( "Arith", pa, "b1", numData );
225  Id b2 = shell->doCreate( "Arith", pa, "b2", numData );
226 
227  Id c1 = shell->doCreate( "Arith", pa, "c1", numData );
228  Id c2 = shell->doCreate( "Arith", pa, "c2", numData );
229 
230  Id d1 = shell->doCreate( "Arith", pa, "d1", numData );
231  Id d2 = shell->doCreate( "Arith", pa, "d2", numData );
232 
233  Id e1 = shell->doCreate( "Arith", pa, "e1", numData );
234  Id e2 = shell->doCreate( "Arith", pa, "e2", numData );
235 
237  // Set up messaging
239  ObjId m1 = shell->doAddMsg( "Single",
240  ObjId( a1, 3 ), "output", ObjId( a2, 1 ), "arg1" );
241  assert( !m1.bad() );
242  ObjId m2 = shell->doAddMsg( "OneToAll",
243  ObjId( b1, 2 ), "output", ObjId( b2, 0 ), "arg1" );
244  assert( !m2.bad() );
245  ObjId m3 = shell->doAddMsg( "OneToOne",
246  ObjId( c1, 0 ), "output", ObjId( c2, 0 ), "arg1" );
247  assert( !m3.bad() );
248  ObjId m4 = shell->doAddMsg( "Diagonal",
249  ObjId( d1, 0 ), "output", ObjId( d2, 0 ), "arg1" );
250  assert( !m4.bad() );
251  ObjId m5 = shell->doAddMsg( "Sparse",
252  ObjId( e1, 0 ), "output", ObjId( e2, 0 ), "arg1" );
253  assert( !m5.bad() );
254 
256  // List messages
258  Id manager( "/Msgs" );
259  assert( manager != Id() );
260  vector< Id > children =
261  Field< vector< Id > >::get( manager, "children" );
262  assert( children.size() == 5 );
263  assert( children[0].element()->getName() == "singleMsg" );
264  assert( children[1].element()->getName() == "oneToOneMsg" );
265  assert( children[2].element()->getName() == "oneToAllMsg" );
266  assert( children[3].element()->getName() == "diagonalMsg" );
267  assert( children[4].element()->getName() == "sparseMsg" );
268 
269  /*
270  // A remarkably large number of some message classes, including 645
271  // OneToAll which are used by parent-child messages. I thought they
272  // were cleaned out as the tests proceed.
273  for ( unsigned int i = 0; i < children.size(); ++i ) {
274  cout << "\nlocalEntries[" << i << "] = " <<
275  children[i].element()->dataHandler()->localEntries() << endl;
276  }
277  */
278  /*
279  string path = children[0].path();
280  cout << "\nlocalEntries = " <<
281  children[0].element()->dataHandler()->localEntries() << endl;
282  assert( path == "/Msgs/singleMsg[0]" );
283  */
284  assert( children[0].path() == "/Msgs[0]/singleMsg" );
285  assert( children[1].path() == "/Msgs[0]/oneToOneMsg" );
286  assert( children[2].path() == "/Msgs[0]/oneToAllMsg" );
287  assert( children[3].path() == "/Msgs[0]/diagonalMsg" );
288  assert( children[4].path() == "/Msgs[0]/sparseMsg" );
289 
290 
292  // Next: check that the child messages have the appropriate number
293  // and indices of entries.
295 
296  shell->doDelete( pa );
297  cout << "." << flush;
298 }
299 
305 void benchmarkMsg( unsigned int n, string msgType )
306 {
307  Eref sheller = Id().eref();
308  Shell* shell = reinterpret_cast< Shell* >( sheller.data() );
309  vector< double > init( n );
310  for ( unsigned int i = 0; i < n; ++i )
311  init[i] = (i + 1) * 1e6;
312 
313  Id a1 = shell->doCreate( "Arith", Id(), "a1", n );
314 
315  if ( msgType == "Single" ) {
316  for ( unsigned int i = 0; i < n; ++i ) {
317  for ( unsigned int j = 0; j < n; ++j ) {
318  ObjId m1 = shell->doAddMsg( "Single",
319  ObjId( a1, i ), "output", ObjId( a1, j ), "arg3" );
320  assert( !m1.bad() );
321  }
322  }
323  } else if ( msgType == "OneToAll" ) {
324  for ( unsigned int i = 0; i < n; ++i ) {
325  ObjId m1 = shell->doAddMsg( "OneToAll",
326  ObjId( a1, i ), "output", ObjId( a1, 0 ), "arg3" );
327  assert( !m1.bad() );
328  }
329  } else if ( msgType == "OneToOne" ) {
330  for ( unsigned int i = 0; i < n; ++i ) { // just repeat it n times
331  ObjId m1 = shell->doAddMsg( "OneToOne",
332  ObjId( a1, 0 ), "output", ObjId( a1, 0 ), "arg3" );
333  assert( !m1.bad() );
334  }
335  } else if ( msgType == "Diagonal" ) {
336  for ( unsigned int i = 0; i < 2 * n; ++i ) { // Set up all offsets
337  ObjId m1 = shell->doAddMsg( "Diagonal",
338  ObjId( a1, 0 ), "output", ObjId( a1, 0 ), "arg3" );
339  Field< int >::set( m1, "stride", n - i );
340  }
341  } else if ( msgType == "Sparse" ) {
342  ObjId m1 = shell->doAddMsg( "Sparse",
343  ObjId( a1, 0 ), "output", ObjId( a1, 0 ), "arg3" );
344 
346  "setRandomConnectivity", 1.0, 1234 );
347  }
348 
349  shell->doUseClock( "/a1", "proc", 0 );
350  for ( unsigned int i = 0; i < 10; ++i )
351  shell->doSetClock( i, 0 );
352  shell->doSetClock( 0, 1 );
353  shell->doReinit();
354  SetGet1< double >::setVec( a1, "arg1", init );
355  shell->doStart( 100 );
356  for ( unsigned int i = 0; i < n; ++i )
357  init[i] = 0; // be sure we don't retain old info.
358  init.clear();
359  Field< double >::getVec( a1, "outputValue", init );
360  cout << endl;
361  for ( unsigned int i = 0; i < n; ++i ) {
362  cout << i << " " << init[i] << " ";
363  if ( i % 5 == 4 )
364  cout << endl;
365  }
366 
367  shell->doDelete( a1 );
368 }
369 
370 void testMsg()
371 {
372  testAssortedMsg();
374 }
375 
376 void testMpiMsg( )
377 {
378  cout << "." << flush;
379 }
Id init(int argc, char **argv, bool &doUnitTests, bool &doRegressionTests, unsigned int &benchmark)
Definition: main.cpp:150
virtual ObjId findOtherEnd(ObjId) const =0
void doStart(double runtime, bool notify=false)
Definition: Shell.cpp:332
char * data() const
Definition: Eref.cpp:41
void benchmarkMsg(unsigned int n, string msgType)
Definition: testMsg.cpp:305
Element * element() const
Synonym for Id::operator()()
Definition: Id.cpp:113
void doSetClock(unsigned int tickNum, double dt)
Definition: Shell.cpp:377
bool bad() const
Definition: ObjId.cpp:18
Definition: SetGet.h:236
void testAssortedMsg()
Definition: testMsg.cpp:15
Definition: ObjId.h:20
Eref eref() const
Definition: Id.cpp:125
static bool set(const ObjId &dest, const string &field, A arg)
Definition: SetGet.h:245
Id doCreate(string type, ObjId parent, string name, unsigned int numData, NodePolicy nodePolicy=MooseBlockBalance, unsigned int preferredNode=1)
Definition: Shell.cpp:181
void testMsg()
Definition: testMsg.cpp:370
void testMpiMsg()
Definition: testMsg.cpp:376
ObjId findCaller(FuncId fid) const
Definition: Element.cpp:350
Definition: Eref.h:26
void doReinit()
Definition: Shell.cpp:362
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, A1 arg1, A2 arg2, A3 arg3)
Definition: SetGet.h:626
bool doDelete(ObjId oid)
Definition: Shell.cpp:259
Definition: Id.h:17
void doUseClock(string path, string field, unsigned int tick)
Definition: Shell.cpp:382
static const Msg * getMsg(ObjId m)
Definition: Msg.cpp:59
static const Cinfo * initCinfo()
Definition: Arith.cpp:22
static void getVec(ObjId dest, const string &field, vector< A > &vec)
Definition: SetGet.h:317
void testMsgElementListing()
Definition: testMsg.cpp:209
unsigned int FuncId
Definition: header.h:42
static bool setVec(ObjId destId, const string &field, const vector< A > &arg)
Definition: SetGet.h:188
static char path[]
Definition: mfield.cpp:403
Definition: Shell.h:43
const Finfo * findFinfo(const string &name) const
Definition: Cinfo.cpp:224
Definition: Finfo.h:12
static bool set(const ObjId &dest, const string &field, A1 arg1, A2 arg2)
Definition: SetGet.h:365