Evita  0.16
evMultiProcessController.h
Go to the documentation of this file.
1 /*
2  *
3  * EVITA: Efficient Visualization of Terascale Datasets
4  * Copyright (C) 2000-2016 Team Evita
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  *
20  */
21 
22 /*
23  * This code was derived from vtk's vtkMultiProcessController class.
24  * The original copyright notice for the code is shown below.
25  *
26  * Modifications from the original source are:
27  * 09-may-2001: Added Send()/Receive() for pointer data
28  * 09-may-2001: Added Blocking field
29  *
30  */
31 
32 /*=========================================================================
33 
34  Program: Visualization Toolkit
35  Module: $RCSfile: evMultiProcessController.h,v $
36  Language: C++
37  Date: $Date: 2016/05/15 20:48:50 $
38  Version: $Revision: 1.7 $
39 
40 Copyright (c) 1993-2001 Ken Martin, Will Schroeder, Bill Lorensen
41 All rights reserved.
42 
43 Redistribution and use in source and binary forms, with or without
44 modification, are permitted provided that the following conditions are met:
45 
46  * Redistributions of source code must retain the above copyright notice,
47  this list of conditions and the following disclaimer.
48 
49  * Redistributions in binary form must reproduce the above copyright notice,
50  this list of conditions and the following disclaimer in the documentation
51  and/or other materials provided with the distribution.
52 
53  * Neither name of Ken Martin, Will Schroeder, or Bill Lorensen nor the names
54  of any contributors may be used to endorse or promote products derived
55  from this software without specific prior written permission.
56 
57  * Modified source versions must be plainly marked as such, and must not be
58  misrepresented as being the original software.
59 
60 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
61 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
62 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
63 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
64 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
65 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
66 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
67 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
68 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
69 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
70 
71 =========================================================================*/
72 // .NAME evMultiProcessController - Multiprocessing communication superclass
73 // .SECTION Description
74 // evMultiProcessController supplies an API for sending and receiving
75 // message between processes. The controller also defines calls for
76 // sending and receiving vtkDataObjects, and remote method invocations.
77 
78 // .SECTION see also
79 // vtkMPIController vtkThreadedController
80 
81 #ifndef __evMultiProcessController_h
82 #define __evMultiProcessController_h
83 
84 #include "vtkObject.h"
85 #include "vtkDataObject.h"
86 class vtkDataSet;
87 class vtkImageData;
88 class vtkCollection;
89 
90 
91 #define VTK_MP_CONTROLLER_MAX_PROCESSES 1024
92 #define VTK_MP_CONTROLLER_ANY_SOURCE -1
93 #define VTK_MP_CONTROLLER_INVALID_SOURCE -2
94 
95 // The special tag used for RMI communication.
96 #define VTK_MP_CONTROLLER_RMI_TAG 315167
97 #define VTK_MP_CONTROLLER_RMI_ARG_TAG 315168
98 
99 
100 // Internally implemented RMI to break the process loop.
101 #define VTK_BREAK_RMI_TAG 239954
102 
103 
105 
106 #define EVBLOCKING 0
107 #define EVNONBLOCKING 1
108 
109 
110 //BTX
111 // The type of function that gets called when new processes are initiated.
112 typedef void (*evProcessFunctionType)(evMultiProcessController *controller,
113  void *userData);
114 
115 // The type of function that gets called when an RMI is triggered.
116 typedef void (*evRMIFunctionType)(void *localArg,
117  void *remoteArg, int remoteArgLength,
118  int remoteProcessId);
119 //ETX
120 
121 
122 class VTK_EXPORT evMultiProcessController : public vtkObject
123 {
124 public:
125  static evMultiProcessController *New();
126  vtkTypeMacro(evMultiProcessController,vtkObject);
127  void PrintSelf(ostream& os, vtkIndent indent);
128 
129  // Description:
130  // This method is for setting up the processes.
131  // If a subclass needs to initialize process communication (i.e. MPI)
132  // it would over ride this method.
133  virtual void Initialize(int vtkNotUsed(argc), char *arcv[]) {arcv=arcv;}
134 
135  // Description:
136  // Set the number of processes you will be using. This defaults
137  // to the maximum number available. If you set this to a value
138  // higher than the default, you will get an error.
139  virtual void SetNumberOfProcesses(int num);
140  vtkGetMacro( NumberOfProcesses, int );
141 
142  //BTX
143  // Description:
144  // Set the SingleMethod to f() and the UserData of the
145  // for the method to be executed by all of the processes
146  // when SingleMethodExecute is called. All the processes will
147  // start by calling this function.
148  void SetSingleMethod(evProcessFunctionType, void *data);
149  //ETX
150 
151  // Description:
152  // Execute the SingleMethod (as define by SetSingleMethod) using
153  // this->NumberOfProcesses processes. This will only return when
154  // all the processes finish executing their methods.
155  virtual void SingleMethodExecute() = 0;
156 
157  //BTX
158  // Description:
159  // Set the MultipleMethod to f() and the UserData of the
160  // for the method to be executed by the process index
161  // when MultipleMethodExecute is called. This is for having each
162  // process start with a different function and data argument.
163  void SetMultipleMethod(int index, evProcessFunctionType, void *data);
164  //ETX
165 
166  // Description:
167  // Execute the MultipleMethods (as define by calling SetMultipleMethod
168  // for each of the required this->NumberOfProcesses methods) using
169  // this->NumberOfProcesses processes.
170  virtual void MultipleMethodExecute() = 0;
171 
172  // Description:
173  // Tells you which process [0, NumProcess) you are in.
174  virtual int GetLocalProcessId() { return this->LocalProcessId; }
175 
176  // Description:
177  // This convenience method returns the controller associated with the
178  // local process. It returns NULL until the processes are spawned.
179  // It is better if you hang on to the controller passed as an argument to the
180  // SingleMethod or MultipleMethod functions.
181  static evMultiProcessController *GetGlobalController();
182 
183  //------------------ Communication --------------------
184 
185  // Description:
186  // This method sends an object to another process. Tag eliminates ambiguity
187  // and is used to match sends to receives.
188  virtual int Send(vtkDataObject *data, int remoteProcessId, int tag);
189 
190  // Description:
191  // Subclass have to supply these methods to send various arrays of data.
192  virtual int Send(int *data, int length, int remoteProcessId, int tag) = 0;
193  virtual int Send(unsigned long *data, int length,
194  int remoteProcessId, int tag) = 0;
195  virtual int Send(char *data, int length,
196  int remoteProcessId, int tag) = 0;
197  virtual int Send(double *data, int length,
198  int remoteProcessId, int tag) = 0;
199 
200  virtual void Clear(int remoteProcessId) = 0;
201 
202  // Description:
203  // This method receives a data object from a corresponding send. It blocks
204  // until the receive is finished.
205  virtual int Receive(vtkDataObject *data, int remoteProcessId, int tag);
206 
207  // Description:
208  // Subclass have to supply these methods to receive various arrays of data.
209  // The methods also have to support a remoteProcessId of
210  // VTK_MP_CONTROLLER_ANY_SOURCE
211  virtual int Receive(int *data, int length, int remoteProcessId, int tag) = 0;
212  virtual int Receive(unsigned long *data, int length,
213  int remoteProcessId, int tag) = 0;
214  virtual int Receive(char *data, int length,
215  int remoteProcessId, int tag) = 0;
216  virtual int Receive(double *data, int length,
217  int remoteProcessId, int tag) = 0;
218 
219  // Description:
220  // By default, sending objects use shallow copy whenever possible.
221  // This flag forces the controller to use deep copies instead.
222  // This is necessary when asynchronous processing occurs
223  // (i.e. pipeline parallelism). This is only important when using
224  // vtkThreadedController.
225  vtkSetMacro(ForceDeepCopy, int);
226  vtkGetMacro(ForceDeepCopy, int);
227  vtkBooleanMacro(ForceDeepCopy, int);
228 
229  vtkSetMacro(Blocking, int);
230  vtkGetMacro(Blocking, int);
231 
232  //------------------ RMIs --------------------
233  //BTX
234  // Description:
235  // Register remote method invocation in the receiving process
236  // which makes the call. It must have a unique tag as an RMI id.
237  // The evRMIFunctionType has several arguments: localArg (same as passed in),
238  // remoteArg, remoteArgLength (memory passed by process triggering the RMI),
239  // remoteProcessId.
240  void AddRMI(evRMIFunctionType, void *localArg, int tag);
241 
242  // Description:
243  // Take an RMI away.
244  void RemoveRMI(evRMIFunctionType f, void *arg, int tag)
245  {f = f; arg = arg; tag = tag; vtkErrorMacro("RemoveRMI Not Implemented Yet");};
246  //ETX
247 
248  // Description:
249  // A method to trigger a method invocation in another process.
250  void TriggerRMI(int remoteProcessId, void *arg, int argLength, int tag);
251 
252  // Description:
253  // Convenience method when the arg is a string.
254  void TriggerRMI(int remoteProcessId, char *arg, int tag)
255  { this->TriggerRMI(remoteProcessId, (void*)arg, strlen(arg)+1, tag); }
256 
257  // Description:
258  // Convenience method when there is no argument.
259  void TriggerRMI(int remoteProcessId, int tag)
260  { this->TriggerRMI(remoteProcessId, NULL, 0, tag); }
261 
262  // Description:
263  // Calling this method gives control to the controller to start
264  // processing RMIs.
265  void ProcessRMIs();
266 
267  // Description:
268  // Setting this flag to 1 will cause the ProcessRMIs loop to return.
269  // This also causes vtkUpStreamPorts to return from
270  // their WaitForUpdate loops.
271  vtkSetMacro(BreakFlag, int);
272  vtkGetMacro(BreakFlag, int);
273 
274  //------------------ Timing --------------------
275  // Description:
276  // For performance monitoring, reading and writing polydata to strings
277  // are timed. Access to these times is provided by these methods.
278  vtkGetMacro(WriteTime, float);
279  vtkGetMacro(ReadTime, float);
280  vtkGetMacro(SendWaitTime, float);
281  vtkGetMacro(SendTime, float);
282  vtkGetMacro(ReceiveWaitTime, float);
283  vtkGetMacro(ReceiveTime, float);
284 
285 protected:
290 
291  int MaximumNumberOfProcesses;
293  // Since we cannot use this ivar in vtkThreadController subclass,
294  // maybe we should eliminated it from this superclass.
296 
298  void *SingleData;
300  void *MultipleData[VTK_MP_CONTROLLER_MAX_PROCESSES];
301 
302  vtkCollection *RMIs;
303 
306  // The data may not take up all of the string.
308 
309  // This is a flag that can be used by the ports to break
310  // their update loop. (same as ProcessRMIs)
312 
313  // convenience method
314  void DeleteAndSetMarshalString(char *str, int strLength);
315 
316  // Write and read from marshal string
317  // return 1 success, 0 fail
318  int WriteObject(vtkDataObject *object);
319  int ReadObject(vtkDataObject *object);
320 
321  int WriteDataSet(vtkDataSet *object);
322  int ReadDataSet(vtkDataSet *object);
323 
324  int WriteImageData(vtkImageData *object);
325  int ReadImageData(vtkImageData *object);
326 
327  void ProcessRMI(int remoteProcessId, void *arg, int argLength, int rmiTag);
328 
329  // This method implements "GetGlobalController".
330  // It needs to be virtual and static.
331  virtual evMultiProcessController *GetLocalController();
332  // It has to be set by the subclass (SingleMethodExecute ...),
333  // but I do not want to make the global variable visible in the header file.
334  virtual void SetGlobalController(evMultiProcessController *controller);
335 
336  float ReadTime;
337  float WriteTime;
338 
340  float SendTime;
342  float ReceiveTime;
343 
344  // This flag can force deep copies during send.
346 
347  int Blocking;
348 };
349 
350 
351 #endif
int ForceDeepCopy
Definition: evMultiProcessController.h:345
void(* evRMIFunctionType)(void *localArg, void *remoteArg, int remoteArgLength, int remoteProcessId)
Definition: evMultiProcessController.h:116
evProcessFunctionType SingleMethod
Definition: evMultiProcessController.h:297
int MarshalStringLength
Definition: evMultiProcessController.h:305
float ReceiveWaitTime
Definition: evMultiProcessController.h:341
int Blocking
Definition: evMultiProcessController.h:347
void TriggerRMI(int remoteProcessId, int tag)
Definition: evMultiProcessController.h:259
evMultiProcessController(const evMultiProcessController &)
Definition: evMultiProcessController.h:288
float ReceiveTime
Definition: evMultiProcessController.h:342
void * SingleData
Definition: evMultiProcessController.h:298
virtual int GetLocalProcessId()
Definition: evMultiProcessController.h:174
void operator=(const evMultiProcessController &)
Definition: evMultiProcessController.h:289
int LocalProcessId
Definition: evMultiProcessController.h:295
virtual void Initialize(int vtkNotUsed(argc), char *arcv[])
Definition: evMultiProcessController.h:133
void(* evProcessFunctionType)(evMultiProcessController *controller, void *userData)
Definition: evMultiProcessController.h:112
int BreakFlag
Definition: evMultiProcessController.h:311
#define VTK_MP_CONTROLLER_MAX_PROCESSES
Definition: evMultiProcessController.h:91
vtkCollection * RMIs
Definition: evMultiProcessController.h:302
Definition: evMultiProcessController.h:122
float SendWaitTime
Definition: evMultiProcessController.h:339
void TriggerRMI(int remoteProcessId, char *arg, int tag)
Definition: evMultiProcessController.h:254
float SendTime
Definition: evMultiProcessController.h:340
int NumberOfProcesses
Definition: evMultiProcessController.h:292
char * MarshalString
Definition: evMultiProcessController.h:304
float WriteTime
Definition: evMultiProcessController.h:337
void RemoveRMI(evRMIFunctionType f, void *arg, int tag)
Definition: evMultiProcessController.h:244
float ReadTime
Definition: evMultiProcessController.h:336
int MarshalDataLength
Definition: evMultiProcessController.h:307