23fad25fd70a868f6ce2a4d318f50b40520a857b
[charm.git] / tests / converse / megacon / megacon.c
1  /**************************************************************************
2  * DESCRIPTION:
3  *
4  * To add a test to megacon, you have to:
5  *
6  *   1. write a testname_moduleinit function that initializes the module.
7  *   2. write a testname_init function that starts the test.
8  *   3. declare the testname_init function inside this module.
9  *   4. extend the tests[] table in this module to include the new test.
10  *
11  **************************************************************************/
12
13 #include <stdio.h>
14 #include <converse.h>
15 #include "megacon.cpm.h"
16
17 /******************************************************************************
18  *
19  * Test Configuration Section
20  *
21  *****************************************************************************/
22
23 void blkinhand_init(void);
24 void posixth_init(void);
25 void future_init(void);
26 void bigmsg_init(void);
27 void vecsend_init(void);
28 void nodenum_init(void);
29 void specmsg_init(void);
30 void vars_init(void);
31 void priotest_init(void);
32 void ringsimple_init(void);
33 void ring_init(void);
34 void fibobj_init(void);
35 void fibthr_init(void);
36 void broadc_init(void);
37 void multicast_init(void);
38 void deadlock_init(void);
39 void multisend_init(void);
40 void handler_init(void);
41 void reduction_init(void);
42
43 void blkinhand_moduleinit(void);
44 void posixth_moduleinit(void);
45 void future_moduleinit(void);
46 void bigmsg_moduleinit(void);
47 void vecsend_moduleinit(void);
48 void nodenum_moduleinit(void);
49 void specmsg_moduleinit(void);
50 void vars_moduleinit(void);
51 void priotest_moduleinit(void);
52 void ringsimple_moduleinit(void);
53 void ring_moduleinit(void);
54 void fibobj_moduleinit(void);
55 void fibthr_moduleinit(void);
56 void broadc_moduleinit(void);
57 void multicast_moduleinit(void);
58 void deadlock_moduleinit(void);
59 void multisend_moduleinit(void);
60 void handler_moduleinit(void);
61 void reduction_moduleinit(void);
62
63 struct testinfo
64 {
65   char *name;
66   void (*initiator)(void);
67   void (*initializer)(void);
68   int  reentrant;
69   int  numacks;
70 }
71 tests[] = {
72   //{ "blkinhand", blkinhand_init, blkinhand_moduleinit,  1,  1 },
73   //{ "posixth",   posixth_init,   posixth_moduleinit,    0,  1 },
74   //{ "future",    future_init,    future_moduleinit,     1,  1 },
75   //{ "bigmsg",    bigmsg_init,    bigmsg_moduleinit,     1,  1 },
76   //{ "vecsend",   vecsend_init,   vecsend_moduleinit,    0,  1 },
77   //{ "nodenum",   nodenum_init,   nodenum_moduleinit,    0,  1 },
78   //{ "specmsg",   specmsg_init,   specmsg_moduleinit,    0,  0 },
79   //{ "vars",      vars_init,      vars_moduleinit,       0,  1 },
80   //{ "priotest",  priotest_init,  priotest_moduleinit,   1,  0 },
81   { "ringsimple",ringsimple_init,ringsimple_moduleinit, 0, 10 },
82   //{ "ring",      ring_init,      ring_moduleinit,       1,  1 },
83   //{ "fibobj",    fibobj_init,    fibobj_moduleinit,     1,  1 },
84   //{ "fibthr",    fibthr_init,    fibthr_moduleinit,     1,  1 },
85   //{ "broadc",    broadc_init,    broadc_moduleinit,     1,  1 },
86   //    { "multicast", multicast_init, multicast_moduleinit,  1,  1 },
87   //    { "deadlock",  deadlock_init,  deadlock_moduleinit,   0,  2 },
88   //    { "handler",  handler_init,  handler_moduleinit,   1,  1 },
89   //    { "multisend", multisend_init, multisend_moduleinit,  0,  1 },
90   //    { "reduction", reduction_init, reduction_moduleinit, 0, 1 },
91       { 0,0,0,0 },
92 };
93
94 /******************************************************************************
95  *
96  * Central Control Section
97  *
98  *****************************************************************************/
99
100 CpvDeclare(int, test_bank_size);
101 CpvDeclare(int, test_negate_skip);
102 CpvDeclare(char **, tests_to_skip);
103 CpvDeclare(int, num_tests_to_skip);
104 CpvDeclare(double, test_start_time);
105 CpvDeclare(int, next_test_index);
106 CpvDeclare(int, next_test_number);
107 CpvDeclare(int, acks_expected);
108 CpvDeclare(int, acks_received);
109
110 /* The megacon shutdown sequence is to idle for a while, then exit.  */
111 /* the idling period makes it possible to detect extra runaway msgs. */
112
113 CpmInvokable megacon_stop()
114 {
115   CsdExitScheduler();
116 }
117
118 CpmInvokable megacon_shutdown(int n)
119 {
120   if (n==0) {
121     CmiPrintf("exiting.\n");
122     Cpm_megacon_stop(CpmSend(CpmALL));
123   } else {
124     Cpm_megacon_shutdown(CpmEnqueueIFIFO(0, 1), n-1);
125   }
126 }
127
128 int megacon_skip(char *test)
129 {
130   int i;
131   int num_skip = CpvAccess(num_tests_to_skip);
132   char **skip;
133   skip = CpvAccess(tests_to_skip);
134   for (i=0; i<num_skip; i++) {
135     if ((skip[i][0]=='-')&&(strcmp(skip[i]+1, test)==0))
136       {
137         /*      CmiPrintf("skipping test %s\n",skip[i]);*/
138         return 1 - CpvAccess(test_negate_skip);
139       }
140   }
141   return CpvAccess(test_negate_skip);
142 }
143
144 void megacon_next()
145 {
146   int i, pos, idx, num, bank, numacks;
147
148   bank = CpvAccess(test_bank_size);
149   num = CpvAccess(next_test_number);
150 nextidx:
151   idx = CpvAccess(next_test_index);
152   if (idx < bank) {
153     numacks = tests[idx].numacks;
154     if (megacon_skip(tests[idx].name)) {
155       /*      CmiPrintf("skipping test %s\n",tests[idx].name);*/
156       CpvAccess(next_test_index)++;
157       goto nextidx;
158     }
159     CpvAccess(acks_expected) = numacks ? numacks : CmiNumPes();
160     CpvAccess(acks_received) = 0;
161     CpvAccess(test_start_time) = CmiWallTimer();
162     CmiPrintf("test %d: initiated [%s]\n", num, tests[idx].name);
163     (tests[idx].initiator)();
164     return; 
165   }
166   if (idx < (2*bank)) {
167     pos = idx - bank;
168     numacks = tests[pos].numacks;
169     if ((tests[pos].reentrant == 0)||(megacon_skip(tests[pos].name))||
170         CpvAccess(test_negate_skip)) {
171       CpvAccess(next_test_index)++;
172       goto nextidx;
173     }
174     CpvAccess(acks_expected) = 5 * (numacks ? numacks : CmiNumPes());
175     CpvAccess(acks_received) = 0;
176     CpvAccess(test_start_time) = CmiWallTimer();
177     CmiPrintf("test %d: initiated [multi %s]\n", num, tests[pos].name);
178     for (i=0; i<5; i++) (tests[pos].initiator)();
179     return;
180   }
181   if (idx== (2*bank)) {
182     CpvAccess(acks_expected) = 0;
183     CpvAccess(acks_received) = 0;
184     CpvAccess(test_start_time) = CmiWallTimer();
185     CmiPrintf("test %d: initiated [all-at-once]\n", num);
186     for (i=0; i<bank; i++) {
187       numacks = tests[i].numacks;
188       if (!megacon_skip(tests[i].name)) {
189         CpvAccess(acks_expected) += (numacks ? numacks : CmiNumPes());
190         (tests[i].initiator)();
191       }
192     }
193     return;
194   }
195   if (idx== ((2*bank)+1)) {
196     CmiPrintf("All tests completed, verifying quiescence...\n");
197     Cpm_megacon_shutdown(CpmSend(0), 50000);
198     return;
199   }
200   CmiPrintf("System should have been quiescent, but it wasnt.\n");
201   exit(1);
202 }
203
204 CpmInvokable megacon_ack()
205 {
206   CpvAccess(acks_received)++;
207   if (CpvAccess(acks_received) == CpvAccess(acks_expected)) {
208     CmiPrintf("test %d: completed (%1.2f sec)\n",
209               CpvAccess(next_test_number),
210               CmiWallTimer() - CpvAccess(test_start_time));
211     CpvAccess(next_test_number)++;
212     CpvAccess(next_test_index)++;
213     megacon_next();
214   }
215 }
216
217 void megacon_init(int argc, char **argv)
218 {
219   int numtests, i;
220   CpmModuleInit();
221   CfutureModuleInit();
222   CpthreadModuleInit();
223   CpmInitializeThisModule();
224   for (i=0; (tests[i].initializer); i++)
225     (tests[i].initializer)();
226   CpvInitialize(int, test_bank_size);
227   CpvInitialize(int, test_negate_skip);
228   CpvInitialize(double, test_start_time);
229   CpvInitialize(int, num_tests_to_skip);
230   CpvInitialize(char **, tests_to_skip);
231   CpvInitialize(int, next_test_index);
232   CpvInitialize(int, next_test_number);
233   CpvInitialize(int, acks_expected);
234   CpvInitialize(int, acks_received);
235   for (numtests=0; tests[numtests].name; numtests++);
236   CpvAccess(test_bank_size) = numtests;
237   CpvAccess(next_test_index) = 0;
238   CpvAccess(next_test_number) = 0;
239   CpvAccess(test_negate_skip)=0;
240   for (i=1; i<argc; i++)
241     if (strcmp(argv[i],"-only")==0)
242       CpvAccess(test_negate_skip)=1;
243   CpvAccess(num_tests_to_skip) = argc;
244   /*    if(CpvAccess(test_negate_skip)) {
245     CpvAccess(num_tests_to_skip)--;
246   }
247   */
248   CpvAccess(tests_to_skip) = argv;
249   if (CmiMyPe()==0)
250     megacon_next();
251 }
252
253 int main(int argc, char **argv)
254 {
255   ConverseInit(argc,argv,megacon_init,0,0);
256 }