1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: ParallelResampling.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
16 // Tests ParallelResampling.
17
18 /*
19 ** This test only builds if MPI is in use
20 */
21 #include "vtkDataArray.h"
22 #include "vtkDataObject.h"
23 #include "vtkPolyDataMapper.h"
24 #include "vtkDebugLeaks.h"
25 #include "vtkFloatArray.h"
26 #include "vtkImageData.h"
27 #include "vtkMPICommunicator.h"
28 #include "vtkMPIController.h"
29 #include "vtkNew.h"
30 #include "vtkObjectFactory.h"
31 #include "vtkPResampleFilter.h"
32 #include "vtkPointData.h"
33 #include "vtkProcess.h"
34 #include "vtkRTAnalyticSource.h"
35 #include "vtkTestUtilities.h"
36 #include "vtkDataSetSurfaceFilter.h"
37 #include <mpi.h>
38
39 namespace
40 {
41
42 class MyProcess : public vtkProcess
43 {
44 public:
45 static MyProcess *New();
46 vtkTypeMacro(MyProcess, vtkProcess);
47
48 virtual void Execute();
49
50 void SetArgs(int anArgc,
51 char *anArgv[]);
52
53 protected:
54 MyProcess();
55
56 int Argc;
57 char **Argv;
58 };
59
60 vtkStandardNewMacro(MyProcess);
61
MyProcess()62 MyProcess::MyProcess()
63 {
64 this->Argc=0;
65 this->Argv=0;
66 }
67
SetArgs(int anArgc,char * anArgv[])68 void MyProcess::SetArgs(int anArgc,
69 char *anArgv[])
70 {
71 this->Argc=anArgc;
72 this->Argv=anArgv;
73 }
74
Execute()75 void MyProcess::Execute()
76 {
77 this->ReturnValue=1;
78 int numProcs=this->Controller->GetNumberOfProcesses();
79 int me=this->Controller->GetLocalProcessId();
80 cout << "Nb process found: " << numProcs << endl;
81
82 // Create and execute pipeline
83 vtkNew<vtkRTAnalyticSource> wavelet;
84 vtkNew<vtkPResampleFilter> sampler;
85 vtkNew<vtkDataSetSurfaceFilter> toPolyData;
86 vtkNew<vtkPolyDataMapper> mapper;
87
88 sampler->SetInputConnection(wavelet->GetOutputPort());
89 sampler->SetSamplingDimension(21,21,21); // 21 for perfect match with wavelet default extent
90 //sampler->SetUseInputBounds(0);
91 //sampler->SetCustomSamplingBounds(-10, 10, -10, 10, -10, 10);
92
93 toPolyData->SetInputConnection(sampler->GetOutputPort());
94
95 mapper->SetInputConnection(toPolyData->GetOutputPort());
96 mapper->SetScalarRange(0, numProcs);
97 mapper->SetPiece(me);
98 mapper->SetNumberOfPieces(numProcs);
99 mapper->Update();
100
101 cout << "Got for Wavelet " << wavelet->GetOutput()->GetNumberOfPoints() << " points on process " << me << endl;
102 cout << "Got for Surface " << toPolyData->GetOutput()->GetNumberOfPoints() << " points on process " << me << endl;
103
104 if (me == 0)
105 {
106 // Only root node compare the standard Wavelet data with the probed one
107 vtkNew<vtkRTAnalyticSource> waveletBase1Piece;
108 waveletBase1Piece->Update();
109 vtkImageData *reference = waveletBase1Piece->GetOutput();
110 vtkImageData *result = sampler->GetOutput();
111
112 // Compare RTData Array
113 vtkFloatArray* rtDataRef = vtkFloatArray::SafeDownCast(reference->GetPointData()->GetArray("RTData"));
114 vtkFloatArray* rtDataTest = vtkFloatArray::SafeDownCast(result->GetPointData()->GetArray("RTData"));
115 vtkIdType sizeRef = rtDataRef->GetNumberOfTuples();
116 if(sizeRef == rtDataTest->GetNumberOfTuples() && rtDataRef->GetNumberOfComponents() == 1)
117 {
118 for(vtkIdType idx = 0; idx < sizeRef; ++idx)
119 {
120 if(rtDataRef->GetValue(idx) != rtDataTest->GetValue(idx))
121 {
122 this->ReturnValue = 0;
123 return;
124 }
125 }
126 return; // OK
127 }
128
129 this->ReturnValue = 0;
130 }
131 else
132 {
133 if(sampler->GetOutput()->GetNumberOfPoints() != 0 || wavelet->GetOutput()->GetNumberOfPoints() == 0)
134 {
135 this->ReturnValue = 0;
136 }
137 }
138 }
139
140 }
141
ParallelResampling(int argc,char * argv[])142 int ParallelResampling(int argc, char *argv[])
143 {
144 // This is here to avoid false leak messages from vtkDebugLeaks when
145 // using mpich. It appears that the root process which spawns all the
146 // main processes waits in MPI_Init() and calls exit() when
147 // the others are done, causing apparent memory leaks for any objects
148 // created before MPI_Init().
149 MPI_Init(&argc, &argv);
150
151 // Note that this will create a vtkMPIController if MPI
152 // is configured, vtkThreadedController otherwise.
153 vtkMPIController *contr = vtkMPIController::New();
154 contr->Initialize(&argc, &argv, 1);
155
156 int retVal = 1;
157
158 vtkMultiProcessController::SetGlobalController(contr);
159
160 int me = contr->GetLocalProcessId();
161
162 if (!contr->IsA("vtkMPIController"))
163 {
164 if (me == 0)
165 {
166 cout << "DistributedData test requires MPI" << endl;
167 }
168 contr->Delete();
169 return retVal; // is this the right error val? TODO
170 }
171
172 MyProcess *p=MyProcess::New();
173 p->SetArgs(argc,argv);
174 contr->SetSingleProcessObject(p);
175 contr->SingleMethodExecute();
176
177 retVal=p->GetReturnValue();
178 p->Delete();
179
180 contr->Finalize();
181 contr->Delete();
182
183 return !retVal;
184 }
185