Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

Parallel/vtkMultiProcessController.h

Go to the documentation of this file.
00001 /*=========================================================================
00002   
00003   Program:   Visualization Toolkit
00004   Module:    $RCSfile: vtkMultiProcessController.h,v $
00005   Language:  C++
00006   
00007 Copyright (c) 1993-2001 Ken Martin, Will Schroeder, Bill Lorensen 
00008 All rights reserved.
00009 
00010 Redistribution and use in source and binary forms, with or without
00011 modification, are permitted provided that the following conditions are met:
00012 
00013  * Redistributions of source code must retain the above copyright notice,
00014    this list of conditions and the following disclaimer.
00015 
00016  * Redistributions in binary form must reproduce the above copyright notice,
00017    this list of conditions and the following disclaimer in the documentation
00018    and/or other materials provided with the distribution.
00019 
00020  * Neither name of Ken Martin, Will Schroeder, or Bill Lorensen nor the names
00021    of any contributors may be used to endorse or promote products derived
00022    from this software without specific prior written permission.
00023 
00024  * Modified source versions must be plainly marked as such, and must not be
00025    misrepresented as being the original software.
00026 
00027 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
00028 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
00031 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00032 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00033 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00034 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00035 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00036 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037 
00038 =========================================================================*/
00072 #ifndef __vtkMultiProcessController_h
00073 #define __vtkMultiProcessController_h
00074 
00075 #include "vtkObject.h"
00076 #include "vtkDataObject.h"
00077 #include "vtkCommunicator.h"
00078 
00079 class vtkDataSet;
00080 class vtkImageData;
00081 class vtkCollection;
00082 class vtkOutputWindow;
00083 
00084 class vtkMultiProcessController;
00085 
00086 
00087 //BTX
00088 // The type of function that gets called when new processes are initiated.
00089 typedef void (*vtkProcessFunctionType)(vtkMultiProcessController *controller, 
00090                                        void *userData);
00091 
00092 // The type of function that gets called when an RMI is triggered.
00093 typedef void (*vtkRMIFunctionType)(void *localArg, 
00094                                    void *remoteArg, int remoteArgLength, 
00095                                    int remoteProcessId);
00096 //ETX
00097 
00098 
00099 class VTK_PARALLEL_EXPORT vtkMultiProcessController : public vtkObject
00100 {
00101 public:
00102   static vtkMultiProcessController *New();
00103   vtkTypeMacro(vtkMultiProcessController,vtkObject);
00104   void PrintSelf(ostream& os, vtkIndent indent);
00105 
00109   virtual void Initialize(int* vtkNotUsed(argc), char*** vtkNotUsed(arcv))=0;
00110 
00113   virtual void Finalize()=0;
00114 
00116 
00119   virtual void SetNumberOfProcesses(int num);
00120   vtkGetMacro( NumberOfProcesses, int );
00122 
00123   //BTX
00125   /*! Set the SingleMethod to f() and the UserData of the for the method to
00126       be executed by all of the processes when SingleMethodExecute is
00127       called.  All the processes will start by calling this function. */
00128   void SetSingleMethod(vtkProcessFunctionType, void *data);
00129   //ETX
00131 
00135   virtual void SingleMethodExecute() = 0;
00136   
00137   //BTX
00139   /*! Set the MultipleMethod to f() and the UserData of the for the method
00140       to be executed by the process index when MultipleMethodExecute is
00141       called.  This is for having each process start with a different
00142       function and data argument. */
00143   void SetMultipleMethod(int index, vtkProcessFunctionType, void *data); 
00144   //ETX
00146 
00150   virtual void MultipleMethodExecute() = 0;
00151 
00153   virtual int GetLocalProcessId() { return this->LocalProcessId; }
00154 
00159   static vtkMultiProcessController *GetGlobalController();
00160 
00163   virtual void CreateOutputWindow() = 0;
00164   
00166 
00171   vtkSetMacro(ForceDeepCopy, int);
00172   vtkGetMacro(ForceDeepCopy, int);
00173   vtkBooleanMacro(ForceDeepCopy, int);
00175 
00176   
00177   //------------------ RMIs --------------------
00178   //BTX
00184   void AddRMI(vtkRMIFunctionType, void *localArg, int tag);
00185   
00187 
00188   void RemoveRMI(vtkRMIFunctionType f, void *arg, int tag)
00189     {f = f; arg = arg; tag = tag; vtkErrorMacro("RemoveRMI Not Implemented Yet");};
00190   //ETX
00192   
00194   void TriggerRMI(int remoteProcessId, void *arg, int argLength, int tag);
00195 
00197 
00198   void TriggerRMI(int remoteProcessId, char *arg, int tag) 
00199     { this->TriggerRMI(remoteProcessId, (void*)arg, strlen(arg)+1, tag); }
00201 
00203 
00204   void TriggerRMI(int remoteProcessId, int tag)
00205     { this->TriggerRMI(remoteProcessId, NULL, 0, tag); }
00207 
00210   void ProcessRMIs();
00211 
00213 
00216   vtkSetMacro(BreakFlag, int);
00217   vtkGetMacro(BreakFlag, int);
00219 
00221   vtkGetObjectMacro(Communicator, vtkCommunicator);
00223   
00224 //BTX
00225 
00226   enum Consts {
00227     MAX_PROCESSES=8192,
00228     ANY_SOURCE=-1,
00229     INVALID_SOURCE=-2,
00230     RMI_TAG=315167,
00231     RMI_ARG_TAG=315168,
00232     BREAK_RMI_TAG=239954
00233   };
00234 
00235 //ETX
00236 
00238   virtual void Barrier() = 0;
00239 
00240   static void SetGlobalController(vtkMultiProcessController *controller);
00241 
00242   //------------------ Communication --------------------
00243   
00245 
00247   int Send(int* data, int length, int remoteProcessId, int tag);
00248   int Send(unsigned long* data, int length, int remoteProcessId, 
00249            int tag);
00250   int Send(char* data, int length, int remoteProcessId, int tag);
00251   int Send(unsigned char* data, int length, int remoteProcessId, int tag);
00252   int Send(float* data, int length, int remoteProcessId, int tag);
00253   int Send(double* data, int length, int remoteProcessId, int tag);
00254 #ifdef VTK_USE_64BIT_IDS
00255   int Send(vtkIdType* data, int length, int remoteProcessId, int tag);
00257 #endif
00258   int Send(vtkDataObject *data, int remoteId, int tag);
00259   int Send(vtkDataArray *data, int remoteId, int tag);
00260 
00262 
00265   int Receive(int* data, int length, int remoteProcessId, int tag);
00266   int Receive(unsigned long* data, int length, int remoteProcessId, 
00267               int tag);
00268   int Receive(char* data, int length, int remoteProcessId, int tag);
00269   int Receive(unsigned char* data, int length, int remoteProcessId, int tag);
00270   int Receive(float* data, int length, int remoteProcessId, int tag);
00271   int Receive(double* data, int length, int remoteProcessId, int tag);
00272 #ifdef VTK_USE_64BIT_IDS
00273   int Receive(vtkIdType* data, int length, int remoteProcessId, int tag);
00275 #endif
00276   int Receive(vtkDataObject* data, int remoteId, int tag);
00277   int Receive(vtkDataArray* data, int remoteId, int tag);
00278 
00279 // Internally implemented RMI to break the process loop.
00280 
00281 protected:
00282   vtkMultiProcessController();
00283   ~vtkMultiProcessController();
00284   
00285   int MaximumNumberOfProcesses;
00286   int NumberOfProcesses;
00287 
00288   int LocalProcessId;
00289   
00290   vtkProcessFunctionType      SingleMethod;
00291   void                       *SingleData;
00292   vtkProcessFunctionType      MultipleMethod[MAX_PROCESSES];
00293   void                       *MultipleData[MAX_PROCESSES];  
00294   
00295   vtkCollection *RMIs;
00296   
00297   // This is a flag that can be used by the ports to break
00298   // their update loop. (same as ProcessRMIs)
00299   int BreakFlag;
00300 
00301   void ProcessRMI(int remoteProcessId, void *arg, int argLength, int rmiTag);
00302 
00303   // This method implements "GetGlobalController".  
00304   // It needs to be virtual and static.
00305   virtual vtkMultiProcessController *GetLocalController();
00306 
00307   
00308   // This flag can force deep copies during send.
00309   int ForceDeepCopy;
00310 
00311   vtkOutputWindow* OutputWindow;
00312 
00313   // Note that since the communicators can be created differently
00314   // depending on the type of controller, the subclasses are
00315   // responsible of deleting them.
00316   vtkCommunicator* Communicator;
00317 
00318   // Communicator which is a copy of the current user
00319   // level communicator except the context; i.e. even if the tags 
00320   // are the same, the RMI messages will not interfere with user 
00321   // level messages. (This only works with MPI. When using threads,
00322   // the tags have to be unique.)
00323   // Note that since the communicators can be created differently
00324   // depending on the type of controller, the subclasses are
00325   // responsible of deleting them.
00326   vtkCommunicator* RMICommunicator;
00327 
00328 private:
00329   vtkMultiProcessController(const vtkMultiProcessController&);  // Not implemented.
00330   void operator=(const vtkMultiProcessController&);  // Not implemented.
00331 };
00332 
00333 
00334 inline int vtkMultiProcessController::Send(vtkDataObject *data, 
00335                                            int remoteThreadId, int tag)
00336 {
00337   if (this->Communicator)
00338     {
00339     return this->Communicator->Send(data, remoteThreadId, tag);
00340     }
00341   else
00342     {
00343     return 0;
00344     }
00345 }
00346 
00347 inline int vtkMultiProcessController::Send(vtkDataArray *data, 
00348                                            int remoteThreadId, int tag)
00349 {
00350   if (this->Communicator)
00351     {
00352     return this->Communicator->Send(data, remoteThreadId, tag);
00353     }
00354   else
00355     {
00356     return 0;
00357     }
00358 }
00359 
00360 inline int vtkMultiProcessController::Send(int* data, int length, 
00361                                            int remoteThreadId, int tag)
00362 {
00363   if (this->Communicator)
00364     {
00365     return this->Communicator->Send(data, length, remoteThreadId, tag);
00366     }
00367   else
00368     {
00369     return 0;
00370     }
00371 }
00372 
00373 inline int vtkMultiProcessController::Send(unsigned long* data, 
00374                                            int length, int remoteThreadId, 
00375                                            int tag)
00376 {
00377   if (this->Communicator)
00378     {
00379     return this->Communicator->Send(data, length, remoteThreadId, tag);
00380     }
00381   else
00382     {
00383     return 0;
00384     }
00385 }
00386 
00387 inline int vtkMultiProcessController::Send(char* data, int length, 
00388                                            int remoteThreadId, int tag)
00389 {
00390   if (this->Communicator)
00391     {
00392     return this->Communicator->Send(data, length, remoteThreadId, tag);
00393     }
00394   else
00395     {
00396     return 0;
00397     }
00398 }
00399 
00400 inline int vtkMultiProcessController::Send(unsigned char* data, int length, 
00401                                            int remoteThreadId, int tag)
00402 {
00403   if (this->Communicator)
00404     {
00405     return this->Communicator->Send(data, length, remoteThreadId, tag);
00406     }
00407   else
00408     {
00409     return 0;
00410     }
00411 }
00412 
00413 inline int vtkMultiProcessController::Send(float* data, int length, 
00414                                            int remoteThreadId, int tag)
00415 {
00416   if (this->Communicator)
00417     {
00418     return this->Communicator->Send(data, length, remoteThreadId, tag);
00419     }
00420   else
00421     {
00422     return 0;
00423     }
00424 }
00425 
00426 inline int vtkMultiProcessController::Send(double* data, int length, 
00427                                            int remoteThreadId, int tag)
00428 {
00429   if (this->Communicator)
00430     {
00431     return this->Communicator->Send(data, length, remoteThreadId, tag);
00432     }
00433   else
00434     {
00435     return 0;
00436     }
00437 }
00438 
00439 #ifdef VTK_USE_64BIT_IDS
00440 inline int vtkMultiProcessController::Send(vtkIdType* data, int length, 
00441                                            int remoteThreadId, int tag)
00442 {
00443   if (this->Communicator)
00444     {
00445     return this->Communicator->Send(data, length, remoteThreadId, tag);
00446     }
00447   else
00448     {
00449     return 0;
00450     }
00451 }
00452 #endif
00453 
00454 inline int vtkMultiProcessController::Receive(vtkDataObject* data, 
00455                                               int remoteThreadId, int tag)
00456 {
00457   if (this->Communicator)
00458     {
00459     return this->Communicator->Receive(data, remoteThreadId, tag);
00460     }
00461   else
00462     {
00463     return 0;
00464     }
00465 }
00466 
00467 inline int vtkMultiProcessController::Receive(vtkDataArray* data, 
00468                                               int remoteThreadId, int tag)
00469 {
00470   if (this->Communicator)
00471     {
00472     return this->Communicator->Receive(data, remoteThreadId, tag);
00473     }
00474   else
00475     {
00476     return 0;
00477     }
00478 }
00479 
00480 inline int vtkMultiProcessController::Receive(int* data, int length, 
00481                                               int remoteThreadId, int tag)
00482 {
00483   if (this->Communicator)
00484     {
00485     return this->Communicator->Receive(data, length, remoteThreadId, tag);
00486     }
00487   else
00488     {
00489     return 0;
00490     }
00491 }
00492 
00493 inline int vtkMultiProcessController::Receive(unsigned long* data, 
00494                                               int length,int remoteThreadId, 
00495                                               int tag)
00496 {
00497   if (this->Communicator)
00498     {
00499     return this->Communicator->Receive(data, length, remoteThreadId, tag);
00500     }
00501   else
00502     {
00503     return 0;
00504     }
00505 }
00506 
00507 inline int vtkMultiProcessController::Receive(char* data, int length, 
00508                                               int remoteThreadId, int tag)
00509 {
00510   if (this->Communicator)
00511     {
00512     return this->Communicator->Receive(data, length, remoteThreadId, tag);
00513     }
00514   else
00515     {
00516     return 0;
00517     }
00518 }
00519 
00520 inline int vtkMultiProcessController::Receive(unsigned char* data, int length, 
00521                                               int remoteThreadId, int tag)
00522 {
00523   if (this->Communicator)
00524     {
00525     return this->Communicator->Receive(data, length, remoteThreadId, tag);
00526     }
00527   else
00528     {
00529     return 0;
00530     }
00531 }
00532 
00533 inline int vtkMultiProcessController::Receive(float* data, int length, 
00534                                               int remoteThreadId, int tag)
00535 {
00536   if (this->Communicator)
00537     {
00538     return this->Communicator->Receive(data, length, remoteThreadId, tag);
00539     }
00540   else
00541     {
00542     return 0;
00543     }
00544 }
00545 
00546 inline int vtkMultiProcessController::Receive(double* data, int length, 
00547                                               int remoteThreadId, int tag)
00548 {
00549   if (this->Communicator)
00550     {
00551     return this->Communicator->Receive(data, length, remoteThreadId, tag);
00552     }
00553   else
00554     {
00555     return 0;
00556     }
00557 }
00558 
00559 #ifdef VTK_USE_64BIT_IDS
00560 inline int vtkMultiProcessController::Receive(vtkIdType* data, int length, 
00561                                               int remoteThreadId, int tag)
00562 {
00563   if (this->Communicator)
00564     {
00565     return this->Communicator->Receive(data, length, remoteThreadId, tag);
00566     }
00567   else
00568     {
00569     return 0;
00570     }
00571 }
00572 #endif
00573 
00574 #endif

Generated on Thu Mar 28 14:19:29 2002 for VTK by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001