1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    GenericCommunicator.cxx
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 #include <mpi.h>
16 
17 #include "vtkActor.h"
18 #include "vtkCharArray.h"
19 #include "vtkCallbackCommand.h"
20 #include "vtkContourFilter.h"
21 #include "vtkDebugLeaks.h"
22 #include "vtkDoubleArray.h"
23 #include "vtkFloatArray.h"
24 #include "vtkIdTypeArray.h"
25 #include "vtkIntArray.h"
26 #include "vtkMPIController.h"
27 #include "vtkPolyData.h"
28 #include "vtkPolyDataMapper.h"
29 #include "vtkRTAnalyticSource.h"
30 #include "vtkRenderWindow.h"
31 #include "vtkRenderWindowInteractor.h"
32 #include "vtkRenderer.h"
33 #include "vtkUnsignedLongArray.h"
34 #include "vtkImageData.h"
35 
36 #include "vtkDebugLeaks.h"
37 #include "vtkRegressionTestImage.h"
38 
39 
40 static const int scMsgLength = 10;
41 
42 struct GenericCommunicatorArgs_tmp
43 {
44   int* retVal;
45   int argc;
46   char** argv;
47 };
48 
Process2(vtkMultiProcessController * contr,void * vtkNotUsed (arg))49 void Process2(vtkMultiProcessController *contr, void* vtkNotUsed(arg))
50 {
51   vtkCommunicator* comm = contr->GetCommunicator();
52 
53   int i, retVal=1;
54 
55   // Test receiving all supported types of arrays
56   vtkIntArray* ia = vtkIntArray::New();
57   if (!comm->Receive(ia, 0, 11))
58     {
59     cerr << "Server error: Error receiving data." << endl;
60     retVal = 0;
61     }
62   for (i=0; i<ia->GetNumberOfTuples(); i++)
63     {
64     if (ia->GetValue(i) != i)
65       {
66       cerr << "Server error: Corrupt integer array." << endl;
67       retVal = 0;
68       break;
69       }
70     }
71   ia->Delete();
72 
73   vtkUnsignedLongArray* ula = vtkUnsignedLongArray::New();
74   if (!comm->Receive(ula, 0, 22))
75     {
76     cerr << "Server error: Error receiving data." << endl;
77     retVal = 0;
78     }
79   for (i=0; i<ula->GetNumberOfTuples(); i++)
80     {
81     if (ula->GetValue(i) != static_cast<unsigned long>(i))
82       {
83       cerr << "Server error: Corrupt unsigned long array." << endl;
84       retVal = 0;
85       break;
86       }
87     }
88   ula->Delete();
89 
90   vtkCharArray* ca = vtkCharArray::New();
91   if (!comm->Receive(ca, 0, 33))
92     {
93     cerr << "Server error: Error receiving data." << endl;
94     retVal = 0;
95     }
96   for (i=0; i<ca->GetNumberOfTuples(); i++)
97     {
98     if (ca->GetValue(i) != static_cast<char>(i))
99       {
100       cerr << "Server error: Corrupt char array." << endl;
101       retVal = 0;
102       break;
103       }
104     }
105   ca->Delete();
106 
107   vtkUnsignedCharArray* uca = vtkUnsignedCharArray::New();
108   if (!comm->Receive(uca, 0, 44))
109     {
110     cerr << "Server error: Error receiving data." << endl;
111     retVal = 0;
112     }
113   for (i=0; i<uca->GetNumberOfTuples(); i++)
114     {
115     if (uca->GetValue(i) != static_cast<unsigned char>(i))
116       {
117       cerr << "Server error: Corrupt unsigned char array." << endl;
118       retVal = 0;
119       break;
120       }
121     }
122   uca->Delete();
123 
124   vtkFloatArray* fa = vtkFloatArray::New();
125   if (!comm->Receive(fa, 0, 7))
126     {
127     cerr << "Server error: Error receiving data." << endl;
128     retVal = 0;
129     }
130   for (i=0; i<fa->GetNumberOfTuples(); i++)
131     {
132     if (fa->GetValue(i) != static_cast<float>(i))
133       {
134       cerr << "Server error: Corrupt float array." << endl;
135       retVal = 0;
136       break;
137       }
138     }
139   fa->Delete();
140 
141   vtkDoubleArray* da = vtkDoubleArray::New();
142   if (!comm->Receive(da, 0, 7))
143     {
144     cerr << "Server error: Error receiving data." << endl;
145     retVal = 0;
146     }
147   for (i=0; i<da->GetNumberOfTuples(); i++)
148     {
149     if (da->GetValue(i) != static_cast<double>(i))
150       {
151       cerr << "Server error: Corrupt double array." << endl;
152       retVal = 0;
153       break;
154       }
155     }
156   da->Delete();
157 
158   vtkIdTypeArray* ita = vtkIdTypeArray::New();
159   if (!comm->Receive(ita, 0, 7))
160     {
161     cerr << "Server error: Error receiving data." << endl;
162     retVal = 0;
163     }
164   for (i=0; i<ita->GetNumberOfTuples(); i++)
165     {
166     if (ita->GetValue(i) != static_cast<vtkIdType>(i))
167       {
168       cerr << "Server error: Corrupt vtkIdType array." << endl;
169       retVal = 0;
170       break;
171       }
172     }
173   ita->Delete();
174 
175   comm->Send(&retVal, 1, 0, 11);
176 }
177 
Process1(vtkMultiProcessController * contr,void * arg)178 void Process1(vtkMultiProcessController *contr, void *arg)
179 {
180   GenericCommunicatorArgs_tmp* args =
181     reinterpret_cast<GenericCommunicatorArgs_tmp*>(arg);
182 
183   vtkCommunicator* comm = contr->GetCommunicator();
184 
185   int i;
186 
187   // Test sending all supported types of arrays
188   int datai[scMsgLength];
189   for (i=0; i<scMsgLength; i++)
190     {
191     datai[i] = i;
192     }
193   vtkIntArray* ia = vtkIntArray::New();
194   ia->SetArray(datai, 10, 1);
195   if (!comm->Send(ia, 1, 11))
196     {
197     cerr << "Client error: Error sending data." << endl;
198     *(args->retVal) = 0;
199     }
200   ia->Delete();
201 
202   unsigned long dataul[scMsgLength];
203   for (i=0; i<scMsgLength; i++)
204     {
205     dataul[i] = static_cast<unsigned long>(i);
206     }
207   vtkUnsignedLongArray* ula = vtkUnsignedLongArray::New();
208   ula->SetArray(dataul, 10, 1);
209   if (!comm->Send(ula, 1, 22))
210     {
211     cerr << "Client error: Error sending data." << endl;
212     *(args->retVal) = 0;
213     }
214   ula->Delete();
215 
216   char datac[scMsgLength];
217   for (i=0; i<scMsgLength; i++)
218     {
219     datac[i] = static_cast<char>(i);
220     }
221   vtkCharArray* ca = vtkCharArray::New();
222   ca->SetArray(datac, 10, 1);
223   if (!comm->Send(ca, 1, 33))
224     {
225     cerr << "Client error: Error sending data." << endl;
226     *(args->retVal) = 0;
227     }
228   ca->Delete();
229 
230   unsigned char datauc[scMsgLength];
231   for (i=0; i<scMsgLength; i++)
232     {
233     datauc[i] = static_cast<unsigned char>(i);
234     }
235   vtkUnsignedCharArray* uca = vtkUnsignedCharArray::New();
236   uca->SetArray(datauc, 10, 1);
237   if (!comm->Send(uca, 1, 44))
238     {
239     cerr << "Client error: Error sending data." << endl;
240     *(args->retVal) = 0;
241     }
242   uca->Delete();
243 
244   float dataf[scMsgLength];
245   for (i=0; i<scMsgLength; i++)
246     {
247     dataf[i] = static_cast<float>(i);
248     }
249   vtkFloatArray* fa = vtkFloatArray::New();
250   fa->SetArray(dataf, 10, 1);
251   if (!comm->Send(fa, 1, 7))
252     {
253     cerr << "Client error: Error sending data." << endl;
254     *(args->retVal) = 0;
255     }
256   fa->Delete();
257 
258 
259   double datad[scMsgLength];
260   for (i=0; i<scMsgLength; i++)
261     {
262     datad[i] = static_cast<double>(i);
263     }
264   vtkDoubleArray* da = vtkDoubleArray::New();
265   da->SetArray(datad, 10, 1);
266   if (!comm->Send(da, 1, 7))
267     {
268     cerr << "Client error: Error sending data." << endl;
269     *(args->retVal) = 0;
270     }
271   da->Delete();
272 
273   vtkIdType datait[scMsgLength];
274   for (i=0; i<scMsgLength; i++)
275     {
276     datait[i] = static_cast<vtkIdType>(i);
277     }
278   vtkIdTypeArray* ita = vtkIdTypeArray::New();
279   ita->SetArray(datait, 10, 1);
280   if (!comm->Send(ita, 1, 7))
281     {
282     cerr << "Client error: Error sending data." << endl;
283     *(args->retVal) = 0;
284     }
285   ita->Delete();
286 
287   int remoteRetVal;
288   comm->Receive(&remoteRetVal, 1, 1, 11);
289   if (!remoteRetVal)
290     {
291     *(args->retVal) = 0;
292     }
293 
294 }
295 
GenericCommunicator(int argc,char * argv[])296 int GenericCommunicator(int argc, char* argv[])
297 {
298   // This is here to avoid false leak messages from vtkDebugLeaks when
299   // using mpich. It appears that the root process which spawns all the
300   // main processes waits in MPI_Init() and calls exit() when
301   // the others are done, causing apparent memory leaks for any objects
302   // created before MPI_Init().
303   MPI_Init(&argc, &argv);
304 
305   vtkMPIController* contr = vtkMPIController::New();
306   contr->Initialize(&argc, &argv,1);
307   contr->CreateOutputWindow();
308 
309   // Added for regression test.
310   // ----------------------------------------------
311   int retVal = 1;
312   GenericCommunicatorArgs_tmp args;
313   args.retVal = &retVal;
314   args.argc = argc;
315   args.argv = argv;
316   // ----------------------------------------------
317 
318   contr->SetMultipleMethod(0, Process1, &args);
319   contr->SetMultipleMethod(1, Process2, 0);
320   contr->MultipleMethodExecute();
321 
322   contr->Finalize();
323   contr->Delete();
324 
325   return !retVal;
326 }
327