VTK
dox/Rendering/ParallelLIC/vtkPPixelTransfer.h
Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Program:   Visualization Toolkit
00004   Module:    vtkPPixelTransfer.h
00005 
00006   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
00007   All rights reserved.
00008   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
00009 
00010      This software is distributed WITHOUT ANY WARRANTY; without even
00011      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
00012      PURPOSE.  See the above copyright notice for more information.
00013 
00014 =========================================================================*/
00028 #ifndef __vtkPPixelTransfer_h
00029 #define __vtkPPixelTransfer_h
00030 
00031 #include "vtkPixelTransfer.h"
00032 #include "vtkRenderingParallelLICModule.h" // for export
00033 #include "vtkSetGet.h" // for macros
00034 #include "vtkPixelExtent.h" // for pixel extent
00035 #include "vtkMPI.h" // for mpi
00036 #include "vtkMPIPixelTT.h" // for type traits
00037 #include "vtkMPIPixelView.h" // for mpi subarrays
00038 
00039 // included vtkSystemIncludes.h in the base class.
00040 #include <iostream> // for ostream
00041 #include <vector> // for vector
00042 #include <cstring> // for memcpy
00043 
00044 // #define vtkPPixelTransferDEBUG
00045 
00046 class VTKRENDERINGPARALLELLIC_EXPORT vtkPPixelTransfer : public vtkPixelTransfer
00047 {
00048 public:
00049   vtkPPixelTransfer()
00050       :
00051     SrcRank(0),
00052     DestRank(0),
00053     UseBlockingSend(0),
00054     UseBlockingRecv(0)
00055     {}
00056 
00058 
00060   vtkPPixelTransfer(
00061         int srcRank,
00062         const vtkPixelExtent &srcWholeExt,
00063         const vtkPixelExtent &srcExt,
00064         int destRank,
00065         const vtkPixelExtent &destWholeExt,
00066         const vtkPixelExtent &destExt,
00067         int id=0)
00068         :
00069     Id(id),
00070     SrcRank(srcRank),
00071     SrcWholeExt(srcWholeExt),
00072     SrcExt(srcExt),
00073     DestRank(destRank),
00074     DestWholeExt(destWholeExt),
00075     DestExt(destExt),
00076     UseBlockingSend(0),
00077     UseBlockingRecv(0)
00078     {}
00080 
00082 
00084   vtkPPixelTransfer(
00085         int srcRank,
00086         const vtkPixelExtent &srcWholeExt,
00087         const vtkPixelExtent &targetExt,
00088         int destRank,
00089         const vtkPixelExtent &destWholeExt,
00090         int id)
00091         :
00092     Id(id),
00093     SrcRank(srcRank),
00094     SrcWholeExt(srcWholeExt),
00095     SrcExt(targetExt),
00096     DestRank(destRank),
00097     DestWholeExt(destWholeExt),
00098     DestExt(targetExt),
00099     UseBlockingSend(0),
00100     UseBlockingRecv(0)
00101     {}
00103 
00105 
00107   vtkPPixelTransfer(
00108         int srcRank,
00109         int destRank,
00110         const vtkPixelExtent &wholeExt,
00111         const vtkPixelExtent &targetExt,
00112         int id=0)
00113         :
00114     Id(id),
00115     SrcRank(srcRank),
00116     SrcWholeExt(wholeExt),
00117     SrcExt(targetExt),
00118     DestRank(destRank),
00119     DestWholeExt(wholeExt),
00120     DestExt(targetExt),
00121     UseBlockingSend(0),
00122     UseBlockingRecv(0)
00123     {}
00125 
00127 
00129   vtkPPixelTransfer(
00130         int srcRank,
00131         int destRank,
00132         const vtkPixelExtent &ext,
00133         int id=0)
00134         :
00135     Id(id),
00136     SrcRank(srcRank),
00137     SrcWholeExt(ext),
00138     SrcExt(ext),
00139     DestRank(destRank),
00140     DestWholeExt(ext),
00141     DestExt(ext),
00142     UseBlockingSend(0),
00143     UseBlockingRecv(0)
00144     {}
00146 
00148 
00150   vtkPPixelTransfer(
00151         int srcRank,
00152         const vtkPixelExtent &srcWholeExt,
00153         int destRank,
00154         const vtkPixelExtent &destWholeExt,
00155         int id=0)
00156         :
00157     Id(id),
00158     SrcRank(srcRank),
00159     SrcWholeExt(srcWholeExt),
00160     SrcExt(srcWholeExt),
00161     DestRank(destRank),
00162     DestWholeExt(destWholeExt),
00163     DestExt(destWholeExt),
00164     UseBlockingSend(0),
00165     UseBlockingRecv(0)
00166     {}
00168 
00170 
00173   vtkPPixelTransfer(
00174         const vtkPixelExtent &srcWholeExt,
00175         const vtkPixelExtent &srcExt,
00176         const vtkPixelExtent &destWholeExt,
00177         const vtkPixelExtent &destExt)
00178         :
00179     Id(0),
00180     SrcRank(0),
00181     SrcWholeExt(srcWholeExt),
00182     SrcExt(srcExt),
00183     DestRank(0),
00184     DestWholeExt(destWholeExt),
00185     DestExt(destExt),
00186     UseBlockingSend(0),
00187     UseBlockingRecv(0)
00188     {}
00190 
00191   ~vtkPPixelTransfer(){}
00192 
00194 
00195   void SetSourceRank(int rank)
00196   { this->SrcRank=rank; }
00198 
00199   int GetSourceRank() const
00200   { return this->SrcRank; }
00201 
00202   void SetDestinationRank(int rank)
00203   { this->DestRank=rank; }
00204 
00205   int GetDestinationRank() const
00206   { return this->DestRank; }
00207 
00209 
00212   bool Sender(int rank) const { return (this->SrcRank == rank); }
00213   bool Receiver(int rank) const { return (this->DestRank == rank); }
00214   bool Local(int rank) const
00215   { return (this->Sender(rank) && this->Receiver(rank)); }
00217 
00219 
00221   void SetSourceWholeExtent(vtkPixelExtent &srcExt)
00222   { this->SrcWholeExt=srcExt; }
00224 
00225   vtkPixelExtent &GetSourceWholeExtent()
00226   { return this->SrcWholeExt; }
00227 
00228   const vtkPixelExtent &GetSourceWholeExtent() const
00229   { return this->SrcWholeExt; }
00230 
00232 
00234   void SetSourceExtent(vtkPixelExtent &srcExt)
00235   { this->SrcExt=srcExt; }
00237 
00238   vtkPixelExtent &GetSourceExtent()
00239   { return this->SrcExt; }
00240 
00241   const vtkPixelExtent &GetSourceExtent() const
00242   { return this->SrcExt; }
00243 
00245 
00247   void SetDestinationWholeExtent(vtkPixelExtent &destExt)
00248   { this->DestWholeExt=destExt; }
00250 
00251   vtkPixelExtent &GetDestinationWholeExtent()
00252   { return this->DestWholeExt; }
00253 
00254   const vtkPixelExtent &GetDestinationWholeExtent() const
00255   { return this->DestWholeExt; }
00256 
00258 
00260   void SetDestinationExtent(vtkPixelExtent &destExt)
00261   { this->DestExt=destExt; }
00263 
00264   vtkPixelExtent &GetDestinationExtent()
00265   { return this->DestExt; }
00266 
00267   const vtkPixelExtent &GetDestinationExtent() const
00268   { return this->DestExt; }
00269 
00271 
00272   void SetTransactionId(int id)
00273   { this->Id=id; }
00275 
00276   int GetTransactionId() const
00277   { return this->Id; }
00278 
00280 
00281   void SetUseBlockingSend(int val)
00282   { this->UseBlockingSend=val; }
00284 
00285   int GetUseBlockingSend() const
00286   { return this->UseBlockingSend; }
00287 
00288   void SetUseBlockingRecv(int val)
00289   { this->UseBlockingRecv=val; }
00290 
00291   int GetUseBlockingRecv() const
00292   { return this->UseBlockingRecv; }
00293 
00295 
00296   template<typename SOURCE_TYPE, typename DEST_TYPE>
00297   int Execute(
00298         MPI_Comm comm,
00299         int rank,
00300         int nComps,
00301         SOURCE_TYPE *srcData,
00302         DEST_TYPE *destData,
00303         std::vector<MPI_Request> &reqs,
00304         std::deque<MPI_Datatype> &types,
00305         int tag);
00307 
00309 
00311   int Execute(
00312         MPI_Comm comm,
00313         int rank,
00314         int nComps,
00315         int srcType,
00316         void *srcData,
00317         int destType,
00318         void *destData,
00319         std::vector<MPI_Request> &reqs,
00320         std::deque<MPI_Datatype> &types,
00321         int tag);
00323 
00325 
00327   int Blit(
00328          int nComps,
00329          int srcType,
00330          void *srcData,
00331          int destType,
00332          void *destData);
00334 
00335 private:
00336   // distpatch helper for vtk data type enum
00337   template<typename SOURCE_TYPE>
00338   int Execute(
00339         MPI_Comm comm,
00340         int rank,
00341         int nComps,
00342         SOURCE_TYPE *srcData,
00343         int destType,
00344         void *destData,
00345         std::vector<MPI_Request> &reqs,
00346         std::deque<MPI_Datatype> &types,
00347         int tag);
00348 
00349 private:
00350   int Id;                      // transaction id
00351   int SrcRank;                 // rank who owns source memory
00352   vtkPixelExtent SrcWholeExt;  // source extent
00353   vtkPixelExtent SrcExt;       // source subset to transfer
00354   int DestRank;                // rank who owns destination memory
00355   vtkPixelExtent DestWholeExt; // destination extent
00356   vtkPixelExtent DestExt;      // destination subset
00357   int UseBlockingSend;         // controls for non-blocking comm
00358   int UseBlockingRecv;
00359 };
00360 
00361 //-----------------------------------------------------------------------------
00362 template<typename SOURCE_TYPE>
00363 int vtkPPixelTransfer::Execute(
00364        MPI_Comm comm,
00365        int rank,
00366        int nComps,
00367        SOURCE_TYPE *srcData,
00368        int destType,
00369        void *destData,
00370        std::vector<MPI_Request> &reqs,
00371        std::deque<MPI_Datatype> &types,
00372        int tag)
00373 {
00374   // second layer of dispatch
00375   switch(destType)
00376     {
00377     vtkTemplateMacro(
00378         return this->Execute(
00379             comm,
00380             rank,
00381             nComps,
00382             srcData,
00383             (VTK_TT*)destData,
00384             reqs,
00385             types,
00386             tag));
00387     }
00388   return 0;
00389 }
00390 
00391 //-----------------------------------------------------------------------------
00392 template<typename SOURCE_TYPE, typename DEST_TYPE>
00393 int vtkPPixelTransfer::Execute(
00394        MPI_Comm comm,
00395        int rank,
00396        int nComps,
00397        SOURCE_TYPE *srcData,
00398        DEST_TYPE *destData,
00399        std::vector<MPI_Request> &reqs,
00400        std::deque<MPI_Datatype> &types,
00401        int tag)
00402 {
00403   int iErr = 0;
00404   if ((comm == MPI_COMM_NULL) || (this->Local(rank)))
00405     {
00406     // transaction is local, bypass mpi in favor of memcpy
00407     return vtkPixelTransfer::Blit(
00408             this->SrcWholeExt,
00409             this->SrcExt,
00410             this->DestWholeExt,
00411             this->DestExt,
00412             nComps,
00413             srcData,
00414             nComps,
00415             destData);
00416     }
00417 
00418   if (rank == this->DestRank)
00419     {
00420     // use mpi to receive the data
00421     if (destData == NULL)
00422       {
00423       return -1;
00424       }
00425 
00426     MPI_Datatype subarray;
00427     iErr = vtkMPIPixelViewNew<DEST_TYPE>(
00428           this->DestWholeExt,
00429           this->DestExt,
00430           nComps,
00431           subarray);
00432     if (iErr)
00433       {
00434       return -4;
00435       }
00436 
00437     if (this->UseBlockingRecv)
00438       {
00439       MPI_Status stat;
00440       iErr = MPI_Recv(
00441             destData,
00442             1,
00443             subarray,
00444             this->SrcRank,
00445             tag,
00446             comm,
00447             &stat);
00448       }
00449     else
00450       {
00451       reqs.push_back(MPI_REQUEST_NULL);
00452       iErr = MPI_Irecv(
00453             destData,
00454             1,
00455             subarray,
00456             this->SrcRank,
00457             tag,
00458             comm,
00459             &reqs.back());
00460       }
00461 
00462     #define HOLD_RECV_TYPES
00463     #ifdef HOLD_RECV_YPES
00464     types.push_back(subarray);
00465     #else
00466     MPI_Type_free(&subarray);
00467     #endif
00468 
00469     if (iErr)
00470       {
00471       return -5;
00472       }
00473     }
00474 
00475   if (rank == this->SrcRank)
00476     {
00477     // use mpi to send the data
00478     if (srcData == NULL)
00479       {
00480       return -1;
00481       }
00482 
00483     MPI_Datatype subarray;
00484     iErr = vtkMPIPixelViewNew<SOURCE_TYPE>(
00485           this->SrcWholeExt,
00486           this->SrcExt,
00487           nComps,
00488           subarray);
00489     if (iErr)
00490       {
00491       return -2;
00492       }
00493 
00494     if (this->UseBlockingSend)
00495       {
00496       iErr = MPI_Ssend(
00497             srcData,
00498             1,
00499             subarray,
00500             this->DestRank,
00501             tag,
00502             comm);
00503       }
00504     else
00505       {
00506       MPI_Request req;
00507       iErr = MPI_Isend(
00508             srcData,
00509             1,
00510             subarray,
00511             this->DestRank,
00512             tag,
00513             comm,
00514             &req);
00515       #define SAVE_SEND_REQS
00516       #ifdef SAVE_SEND_REQS
00517       reqs.push_back(req);
00518       #else
00519       MPI_Request_free(&req);
00520       #endif
00521       }
00522 
00523     #define HOLD_SEND_TYPES
00524     #ifdef HOLD_SEND_TYPES
00525     types.push_back(subarray);
00526     #else
00527     MPI_Type_free(&subarray);
00528     #endif
00529 
00530     if (iErr)
00531       {
00532       return -3;
00533       }
00534     }
00535 
00536   return iErr;
00537 }
00538 
00539 ostream &operator<<(std::ostream &os, const vtkPPixelTransfer &gt);
00540 
00541 #endif
00542 // VTK-HeaderTest-Exclude: vtkPPixelTransfer.h