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