VTK
vtkPPixelTransfer.h
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Visualization Toolkit
4  Module: vtkPPixelTransfer.h
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 =========================================================================*/
28 #ifndef vtkPPixelTransfer_h
29 #define vtkPPixelTransfer_h
30 
31 #include "vtkPixelTransfer.h"
32 #include "vtkRenderingParallelLICModule.h" // for export
33 #include "vtkSetGet.h" // for macros
34 #include "vtkPixelExtent.h" // for pixel extent
35 #include "vtkMPI.h" // for mpi
36 #include "vtkMPIPixelTT.h" // for type traits
37 #include "vtkMPIPixelView.h" // for mpi subarrays
38 
39 // included vtkSystemIncludes.h in the base class.
40 #include <iostream> // for ostream
41 #include <vector> // for vector
42 #include <cstring> // for memcpy
43 
44 // #define vtkPPixelTransferDEBUG
45 
46 class VTKRENDERINGPARALLELLIC_EXPORT vtkPPixelTransfer : public vtkPixelTransfer
47 {
48 public:
50  :
51  SrcRank(0),
52  DestRank(0),
53  UseBlockingSend(0),
54  UseBlockingRecv(0)
55  {}
56 
58 
61  int srcRank,
62  const vtkPixelExtent &srcWholeExt,
63  const vtkPixelExtent &srcExt,
64  int destRank,
65  const vtkPixelExtent &destWholeExt,
66  const vtkPixelExtent &destExt,
67  int id=0)
68  :
69  Id(id),
70  SrcRank(srcRank),
71  SrcWholeExt(srcWholeExt),
72  SrcExt(srcExt),
73  DestRank(destRank),
74  DestWholeExt(destWholeExt),
75  DestExt(destExt),
76  UseBlockingSend(0),
77  UseBlockingRecv(0)
78  {}
80 
82 
85  int srcRank,
86  const vtkPixelExtent &srcWholeExt,
87  const vtkPixelExtent &targetExt,
88  int destRank,
89  const vtkPixelExtent &destWholeExt,
90  int id)
91  :
92  Id(id),
93  SrcRank(srcRank),
94  SrcWholeExt(srcWholeExt),
95  SrcExt(targetExt),
96  DestRank(destRank),
97  DestWholeExt(destWholeExt),
98  DestExt(targetExt),
99  UseBlockingSend(0),
100  UseBlockingRecv(0)
101  {}
103 
105 
108  int srcRank,
109  int destRank,
110  const vtkPixelExtent &wholeExt,
111  const vtkPixelExtent &targetExt,
112  int id=0)
113  :
114  Id(id),
115  SrcRank(srcRank),
116  SrcWholeExt(wholeExt),
117  SrcExt(targetExt),
118  DestRank(destRank),
119  DestWholeExt(wholeExt),
120  DestExt(targetExt),
121  UseBlockingSend(0),
122  UseBlockingRecv(0)
123  {}
125 
127 
130  int srcRank,
131  int destRank,
132  const vtkPixelExtent &ext,
133  int id=0)
134  :
135  Id(id),
136  SrcRank(srcRank),
137  SrcWholeExt(ext),
138  SrcExt(ext),
139  DestRank(destRank),
140  DestWholeExt(ext),
141  DestExt(ext),
142  UseBlockingSend(0),
143  UseBlockingRecv(0)
144  {}
146 
148 
151  int srcRank,
152  const vtkPixelExtent &srcWholeExt,
153  int destRank,
154  const vtkPixelExtent &destWholeExt,
155  int id=0)
156  :
157  Id(id),
158  SrcRank(srcRank),
159  SrcWholeExt(srcWholeExt),
160  SrcExt(srcWholeExt),
161  DestRank(destRank),
162  DestWholeExt(destWholeExt),
163  DestExt(destWholeExt),
164  UseBlockingSend(0),
165  UseBlockingRecv(0)
166  {}
168 
170 
174  const vtkPixelExtent &srcWholeExt,
175  const vtkPixelExtent &srcExt,
176  const vtkPixelExtent &destWholeExt,
177  const vtkPixelExtent &destExt)
178  :
179  Id(0),
180  SrcRank(0),
181  SrcWholeExt(srcWholeExt),
182  SrcExt(srcExt),
183  DestRank(0),
184  DestWholeExt(destWholeExt),
185  DestExt(destExt),
186  UseBlockingSend(0),
187  UseBlockingRecv(0)
188  {}
190 
192 
194 
195  void SetSourceRank(int rank)
196  { this->SrcRank=rank; }
198 
199  int GetSourceRank() const
200  { return this->SrcRank; }
201 
202  void SetDestinationRank(int rank)
203  { this->DestRank=rank; }
204 
205  int GetDestinationRank() const
206  { return this->DestRank; }
207 
209 
212  bool Sender(int rank) const { return (this->SrcRank == rank); }
213  bool Receiver(int rank) const { return (this->DestRank == rank); }
214  bool Local(int rank) const
215  { return (this->Sender(rank) && this->Receiver(rank)); }
217 
219 
222  { this->SrcWholeExt=srcExt; }
224 
226  { return this->SrcWholeExt; }
227 
229  { return this->SrcWholeExt; }
230 
232 
235  { this->SrcExt=srcExt; }
237 
239  { return this->SrcExt; }
240 
242  { return this->SrcExt; }
243 
245 
248  { this->DestWholeExt=destExt; }
250 
252  { return this->DestWholeExt; }
253 
255  { return this->DestWholeExt; }
256 
258 
261  { this->DestExt=destExt; }
263 
265  { return this->DestExt; }
266 
268  { return this->DestExt; }
269 
271 
272  void SetTransactionId(int id)
273  { this->Id=id; }
275 
276  int GetTransactionId() const
277  { return this->Id; }
278 
280 
281  void SetUseBlockingSend(int val)
282  { this->UseBlockingSend=val; }
284 
285  int GetUseBlockingSend() const
286  { return this->UseBlockingSend; }
287 
288  void SetUseBlockingRecv(int val)
289  { this->UseBlockingRecv=val; }
290 
291  int GetUseBlockingRecv() const
292  { return this->UseBlockingRecv; }
293 
295 
296  template<typename SOURCE_TYPE, typename DEST_TYPE>
297  int Execute(
298  MPI_Comm comm,
299  int rank,
300  int nComps,
301  SOURCE_TYPE *srcData,
302  DEST_TYPE *destData,
303  std::vector<MPI_Request> &reqs,
304  std::deque<MPI_Datatype> &types,
305  int tag);
307 
309 
311  int Execute(
312  MPI_Comm comm,
313  int rank,
314  int nComps,
315  int srcType,
316  void *srcData,
317  int destType,
318  void *destData,
319  std::vector<MPI_Request> &reqs,
320  std::deque<MPI_Datatype> &types,
321  int tag);
323 
325 
327  int Blit(
328  int nComps,
329  int srcType,
330  void *srcData,
331  int destType,
332  void *destData);
334 
335 private:
336  // distpatch helper for vtk data type enum
337  template<typename SOURCE_TYPE>
338  int Execute(
339  MPI_Comm comm,
340  int rank,
341  int nComps,
342  SOURCE_TYPE *srcData,
343  int destType,
344  void *destData,
345  std::vector<MPI_Request> &reqs,
346  std::deque<MPI_Datatype> &types,
347  int tag);
348 
349 private:
350  int Id; // transaction id
351  int SrcRank; // rank who owns source memory
352  vtkPixelExtent SrcWholeExt; // source extent
353  vtkPixelExtent SrcExt; // source subset to transfer
354  int DestRank; // rank who owns destination memory
355  vtkPixelExtent DestWholeExt; // destination extent
356  vtkPixelExtent DestExt; // destination subset
357  int UseBlockingSend; // controls for non-blocking comm
358  int UseBlockingRecv;
359 };
360 
361 //-----------------------------------------------------------------------------
362 template<typename SOURCE_TYPE>
364  MPI_Comm comm,
365  int rank,
366  int nComps,
367  SOURCE_TYPE *srcData,
368  int destType,
369  void *destData,
370  std::vector<MPI_Request> &reqs,
371  std::deque<MPI_Datatype> &types,
372  int tag)
373 {
374  // second layer of dispatch
375  switch(destType)
376  {
377  vtkTemplateMacro(
378  return this->Execute(
379  comm,
380  rank,
381  nComps,
382  srcData,
383  (VTK_TT*)destData,
384  reqs,
385  types,
386  tag));
387  }
388  return 0;
389 }
390 
391 //-----------------------------------------------------------------------------
392 template<typename SOURCE_TYPE, typename DEST_TYPE>
394  MPI_Comm comm,
395  int rank,
396  int nComps,
397  SOURCE_TYPE *srcData,
398  DEST_TYPE *destData,
399  std::vector<MPI_Request> &reqs,
400  std::deque<MPI_Datatype> &types,
401  int tag)
402 {
403  int iErr = 0;
404  if ((comm == MPI_COMM_NULL) || (this->Local(rank)))
405  {
406  // transaction is local, bypass mpi in favor of memcpy
407  return vtkPixelTransfer::Blit(
408  this->SrcWholeExt,
409  this->SrcExt,
410  this->DestWholeExt,
411  this->DestExt,
412  nComps,
413  srcData,
414  nComps,
415  destData);
416  }
417 
418  if (rank == this->DestRank)
419  {
420  // use mpi to receive the data
421  if (destData == NULL)
422  {
423  return -1;
424  }
425 
426  MPI_Datatype subarray;
427  iErr = vtkMPIPixelViewNew<DEST_TYPE>(
428  this->DestWholeExt,
429  this->DestExt,
430  nComps,
431  subarray);
432  if (iErr)
433  {
434  return -4;
435  }
436 
437  if (this->UseBlockingRecv)
438  {
439  MPI_Status stat;
440  iErr = MPI_Recv(
441  destData,
442  1,
443  subarray,
444  this->SrcRank,
445  tag,
446  comm,
447  &stat);
448  }
449  else
450  {
451  reqs.push_back(MPI_REQUEST_NULL);
452  iErr = MPI_Irecv(
453  destData,
454  1,
455  subarray,
456  this->SrcRank,
457  tag,
458  comm,
459  &reqs.back());
460  }
461 
462  #define HOLD_RECV_TYPES
463  #ifdef HOLD_RECV_YPES
464  types.push_back(subarray);
465  #else
466  MPI_Type_free(&subarray);
467  #endif
468 
469  if (iErr)
470  {
471  return -5;
472  }
473  }
474 
475  if (rank == this->SrcRank)
476  {
477  // use mpi to send the data
478  if (srcData == NULL)
479  {
480  return -1;
481  }
482 
483  MPI_Datatype subarray;
484  iErr = vtkMPIPixelViewNew<SOURCE_TYPE>(
485  this->SrcWholeExt,
486  this->SrcExt,
487  nComps,
488  subarray);
489  if (iErr)
490  {
491  return -2;
492  }
493 
494  if (this->UseBlockingSend)
495  {
496  iErr = MPI_Ssend(
497  srcData,
498  1,
499  subarray,
500  this->DestRank,
501  tag,
502  comm);
503  }
504  else
505  {
506  MPI_Request req;
507  iErr = MPI_Isend(
508  srcData,
509  1,
510  subarray,
511  this->DestRank,
512  tag,
513  comm,
514  &req);
515  #define SAVE_SEND_REQS
516  #ifdef SAVE_SEND_REQS
517  reqs.push_back(req);
518  #else
519  MPI_Request_free(&req);
520  #endif
521  }
522 
523  #define HOLD_SEND_TYPES
524  #ifdef HOLD_SEND_TYPES
525  types.push_back(subarray);
526  #else
527  MPI_Type_free(&subarray);
528  #endif
529 
530  if (iErr)
531  {
532  return -3;
533  }
534  }
535 
536  return iErr;
537 }
538 
539 VTKRENDERINGPARALLELLIC_EXPORT
540 ostream &operator<<(std::ostream &os, const vtkPPixelTransfer &gt);
541 
542 #endif
543 // VTK-HeaderTest-Exclude: vtkPPixelTransfer.h
vtkPixelExtent & GetSourceExtent()
void SetUseBlockingSend(int val)
vtkPPixelTransfer(int srcRank, int destRank, const vtkPixelExtent &ext, int id=0)
const vtkPixelExtent & GetDestinationExtent() const
void SetDestinationRank(int rank)
int GetSourceRank() const
void SetSourceWholeExtent(vtkPixelExtent &srcExt)
vtkPixelExtent & GetDestinationWholeExtent()
vtkPPixelTransfer(int srcRank, const vtkPixelExtent &srcWholeExt, const vtkPixelExtent &srcExt, int destRank, const vtkPixelExtent &destWholeExt, const vtkPixelExtent &destExt, int id=0)
int GetDestinationRank() const
int GetUseBlockingRecv() const
vtkPixelExtent & GetSourceWholeExtent()
void SetUseBlockingRecv(int val)
void SetSourceExtent(vtkPixelExtent &srcExt)
vtkPPixelTransfer(int srcRank, int destRank, const vtkPixelExtent &wholeExt, const vtkPixelExtent &targetExt, int id=0)
int GetTransactionId() const
const vtkPixelExtent & GetSourceExtent() const
static int Blit(const vtkPixelExtent &ext, int nComps, int srcType, void *srcData, int destType, void *destData)
const vtkPixelExtent & GetSourceWholeExtent() const
VTKRENDERINGPARALLELLIC_EXPORT ostream & operator<<(std::ostream &os, const vtkPPixelTransfer &gt)
vtkPPixelTransfer(int srcRank, const vtkPixelExtent &srcWholeExt, const vtkPixelExtent &targetExt, int destRank, const vtkPixelExtent &destWholeExt, int id)
vtkPPixelTransfer(int srcRank, const vtkPixelExtent &srcWholeExt, int destRank, const vtkPixelExtent &destWholeExt, int id=0)
bool Sender(int rank) const
int Execute(MPI_Comm comm, int rank, int nComps, SOURCE_TYPE *srcData, DEST_TYPE *destData, std::vector< MPI_Request > &reqs, std::deque< MPI_Datatype > &types, int tag)
void SetDestinationWholeExtent(vtkPixelExtent &destExt)
vtkPPixelTransfer(const vtkPixelExtent &srcWholeExt, const vtkPixelExtent &srcExt, const vtkPixelExtent &destWholeExt, const vtkPixelExtent &destExt)
void SetSourceRank(int rank)
bool Local(int rank) const
int GetUseBlockingSend() const
void SetTransactionId(int id)
bool Receiver(int rank) const
void SetDestinationExtent(vtkPixelExtent &destExt)
const vtkPixelExtent & GetDestinationWholeExtent() const
vtkPixelExtent & GetDestinationExtent()