VTK  9.1.0
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 =========================================================================*/
29 #ifndef vtkPPixelTransfer_h
30 #define vtkPPixelTransfer_h
31 
32 #include "vtkMPI.h" // for mpi
33 #include "vtkMPIPixelTT.h" // for type traits
34 #include "vtkMPIPixelView.h" // for mpi subarrays
35 #include "vtkPixelExtent.h" // for pixel extent
36 #include "vtkPixelTransfer.h"
37 #include "vtkRenderingParallelLICModule.h" // for export
38 #include "vtkSetGet.h" // for macros
39 
40 // included vtkSystemIncludes.h in the base class.
41 #include <cstring> // for memcpy
42 #include <iostream> // for ostream
43 #include <vector> // for vector
44 
45 // #define vtkPPixelTransferDEBUG
46 
47 class VTKRENDERINGPARALLELLIC_EXPORT vtkPPixelTransfer : public vtkPixelTransfer
48 {
49 public:
51  : SrcRank(0)
52  , DestRank(0)
53  , UseBlockingSend(0)
54  , UseBlockingRecv(0)
55  {
56  }
57 
62  vtkPPixelTransfer(int srcRank, const vtkPixelExtent& srcWholeExt, const vtkPixelExtent& srcExt,
63  int destRank, const vtkPixelExtent& destWholeExt, const vtkPixelExtent& destExt, int id = 0)
64  : Id(id)
65  , SrcRank(srcRank)
66  , SrcWholeExt(srcWholeExt)
67  , SrcExt(srcExt)
68  , DestRank(destRank)
69  , DestWholeExt(destWholeExt)
70  , DestExt(destExt)
71  , UseBlockingSend(0)
72  , UseBlockingRecv(0)
73  {
74  }
75 
80  vtkPPixelTransfer(int srcRank, const vtkPixelExtent& srcWholeExt, const vtkPixelExtent& targetExt,
81  int destRank, const vtkPixelExtent& destWholeExt, int id)
82  : Id(id)
83  , SrcRank(srcRank)
84  , SrcWholeExt(srcWholeExt)
85  , SrcExt(targetExt)
86  , DestRank(destRank)
87  , DestWholeExt(destWholeExt)
88  , DestExt(targetExt)
89  , UseBlockingSend(0)
90  , UseBlockingRecv(0)
91  {
92  }
93 
98  vtkPPixelTransfer(int srcRank, int destRank, const vtkPixelExtent& wholeExt,
99  const vtkPixelExtent& targetExt, int id = 0)
100  : Id(id)
101  , SrcRank(srcRank)
102  , SrcWholeExt(wholeExt)
103  , SrcExt(targetExt)
104  , DestRank(destRank)
105  , DestWholeExt(wholeExt)
106  , DestExt(targetExt)
107  , UseBlockingSend(0)
108  , UseBlockingRecv(0)
109  {
110  }
111 
116  vtkPPixelTransfer(int srcRank, int destRank, const vtkPixelExtent& ext, int id = 0)
117  : Id(id)
118  , SrcRank(srcRank)
119  , SrcWholeExt(ext)
120  , SrcExt(ext)
121  , DestRank(destRank)
122  , DestWholeExt(ext)
123  , DestExt(ext)
124  , UseBlockingSend(0)
125  , UseBlockingRecv(0)
126  {
127  }
128 
133  vtkPPixelTransfer(int srcRank, const vtkPixelExtent& srcWholeExt, int destRank,
134  const vtkPixelExtent& destWholeExt, int id = 0)
135  : Id(id)
136  , SrcRank(srcRank)
137  , SrcWholeExt(srcWholeExt)
138  , SrcExt(srcWholeExt)
139  , DestRank(destRank)
140  , DestWholeExt(destWholeExt)
141  , DestExt(destWholeExt)
142  , UseBlockingSend(0)
143  , UseBlockingRecv(0)
144  {
145  }
146 
152  vtkPPixelTransfer(const vtkPixelExtent& srcWholeExt, const vtkPixelExtent& srcExt,
153  const vtkPixelExtent& destWholeExt, const vtkPixelExtent& destExt)
154  : Id(0)
155  , SrcRank(0)
156  , SrcWholeExt(srcWholeExt)
157  , SrcExt(srcExt)
158  , DestRank(0)
159  , DestWholeExt(destWholeExt)
160  , DestExt(destExt)
161  , UseBlockingSend(0)
162  , UseBlockingRecv(0)
163  {
164  }
165 
167 
172  void SetSourceRank(int rank) { this->SrcRank = rank; }
173 
174  int GetSourceRank() const { return this->SrcRank; }
175 
176  void SetDestinationRank(int rank) { this->DestRank = rank; }
177 
178  int GetDestinationRank() const { return this->DestRank; }
179 
185  bool Sender(int rank) const { return (this->SrcRank == rank); }
186  bool Receiver(int rank) const { return (this->DestRank == rank); }
187  bool Local(int rank) const { return (this->Sender(rank) && this->Receiver(rank)); }
188 
193  void SetSourceWholeExtent(vtkPixelExtent& srcExt) { this->SrcWholeExt = srcExt; }
194 
195  vtkPixelExtent& GetSourceWholeExtent() { return this->SrcWholeExt; }
196 
197  const vtkPixelExtent& GetSourceWholeExtent() const { return this->SrcWholeExt; }
198 
203  void SetSourceExtent(vtkPixelExtent& srcExt) { this->SrcExt = srcExt; }
204 
205  vtkPixelExtent& GetSourceExtent() { return this->SrcExt; }
206 
207  const vtkPixelExtent& GetSourceExtent() const { return this->SrcExt; }
208 
213  void SetDestinationWholeExtent(vtkPixelExtent& destExt) { this->DestWholeExt = destExt; }
214 
215  vtkPixelExtent& GetDestinationWholeExtent() { return this->DestWholeExt; }
216 
217  const vtkPixelExtent& GetDestinationWholeExtent() const { return this->DestWholeExt; }
218 
223  void SetDestinationExtent(vtkPixelExtent& destExt) { this->DestExt = destExt; }
224 
225  vtkPixelExtent& GetDestinationExtent() { return this->DestExt; }
226 
227  const vtkPixelExtent& GetDestinationExtent() const { return this->DestExt; }
228 
232  void SetTransactionId(int id) { this->Id = id; }
233 
234  int GetTransactionId() const { return this->Id; }
235 
239  void SetUseBlockingSend(int val) { this->UseBlockingSend = val; }
240 
241  int GetUseBlockingSend() const { return this->UseBlockingSend; }
242 
243  void SetUseBlockingRecv(int val) { this->UseBlockingRecv = val; }
244 
245  int GetUseBlockingRecv() const { return this->UseBlockingRecv; }
246 
250  template <typename SOURCE_TYPE, typename DEST_TYPE>
251  int Execute(MPI_Comm comm, int rank, int nComps, SOURCE_TYPE* srcData, DEST_TYPE* destData,
252  std::vector<MPI_Request>& reqs, std::deque<MPI_Datatype>& types, int tag);
253 
258  int Execute(MPI_Comm comm, int rank, int nComps, int srcType, void* srcData, int destType,
259  void* destData, std::vector<MPI_Request>& reqs, std::deque<MPI_Datatype>& types, int tag);
260 
264  int Blit(int nComps, int srcType, void* srcData, int destType, void* destData);
265 
266 private:
267  // distpatch helper for vtk data type enum
268  template <typename SOURCE_TYPE>
269  int Execute(MPI_Comm comm, int rank, int nComps, SOURCE_TYPE* srcData, int destType,
270  void* destData, std::vector<MPI_Request>& reqs, std::deque<MPI_Datatype>& types, int tag);
271 
272 private:
273  int Id; // transaction id
274  int SrcRank; // rank who owns source memory
275  vtkPixelExtent SrcWholeExt; // source extent
276  vtkPixelExtent SrcExt; // source subset to transfer
277  int DestRank; // rank who owns destination memory
278  vtkPixelExtent DestWholeExt; // destination extent
279  vtkPixelExtent DestExt; // destination subset
280  int UseBlockingSend; // controls for non-blocking comm
281  int UseBlockingRecv;
282 };
283 
284 //-----------------------------------------------------------------------------
285 template <typename SOURCE_TYPE>
286 int vtkPPixelTransfer::Execute(MPI_Comm comm, int rank, int nComps, SOURCE_TYPE* srcData,
287  int destType, void* destData, std::vector<MPI_Request>& reqs, std::deque<MPI_Datatype>& types,
288  int tag)
289 {
290  // second layer of dispatch
291  switch (destType)
292  {
293  vtkTemplateMacro(
294  return this->Execute(comm, rank, nComps, srcData, (VTK_TT*)destData, reqs, types, tag));
295  }
296  return 0;
297 }
298 
299 //-----------------------------------------------------------------------------
300 template <typename SOURCE_TYPE, typename DEST_TYPE>
301 int vtkPPixelTransfer::Execute(MPI_Comm comm, int rank, int nComps, SOURCE_TYPE* srcData,
302  DEST_TYPE* destData, std::vector<MPI_Request>& reqs, std::deque<MPI_Datatype>& types, int tag)
303 {
304  int iErr = 0;
305  if ((comm == MPI_COMM_NULL) || (this->Local(rank)))
306  {
307  // transaction is local, bypass mpi in favor of memcpy
308  return vtkPixelTransfer::Blit(this->SrcWholeExt, this->SrcExt, this->DestWholeExt,
309  this->DestExt, nComps, srcData, nComps, destData);
310  }
311 
312  if (rank == this->DestRank)
313  {
314  // use mpi to receive the data
315  if (destData == NULL)
316  {
317  return -1;
318  }
319 
320  MPI_Datatype subarray;
321  iErr = vtkMPIPixelViewNew<DEST_TYPE>(this->DestWholeExt, this->DestExt, nComps, subarray);
322  if (iErr)
323  {
324  return -4;
325  }
326 
327  if (this->UseBlockingRecv)
328  {
329  MPI_Status stat;
330  iErr = MPI_Recv(destData, 1, subarray, this->SrcRank, tag, comm, &stat);
331  }
332  else
333  {
334  reqs.push_back(MPI_REQUEST_NULL);
335  iErr = MPI_Irecv(destData, 1, subarray, this->SrcRank, tag, comm, &reqs.back());
336  }
337 
338 #define HOLD_RECV_TYPES
339 #ifdef HOLD_RECV_YPES
340  types.push_back(subarray);
341 #else
342  MPI_Type_free(&subarray);
343 #endif
344 
345  if (iErr)
346  {
347  return -5;
348  }
349  }
350 
351  if (rank == this->SrcRank)
352  {
353  // use mpi to send the data
354  if (srcData == NULL)
355  {
356  return -1;
357  }
358 
359  MPI_Datatype subarray;
360  iErr = vtkMPIPixelViewNew<SOURCE_TYPE>(this->SrcWholeExt, this->SrcExt, nComps, subarray);
361  if (iErr)
362  {
363  return -2;
364  }
365 
366  if (this->UseBlockingSend)
367  {
368  iErr = MPI_Ssend(srcData, 1, subarray, this->DestRank, tag, comm);
369  }
370  else
371  {
372  MPI_Request req;
373  iErr = MPI_Isend(srcData, 1, subarray, this->DestRank, tag, comm, &req);
374 #define SAVE_SEND_REQS
375 #ifdef SAVE_SEND_REQS
376  reqs.push_back(req);
377 #else
378  MPI_Request_free(&req);
379 #endif
380  }
381 
382 #define HOLD_SEND_TYPES
383 #ifdef HOLD_SEND_TYPES
384  types.push_back(subarray);
385 #else
386  MPI_Type_free(&subarray);
387 #endif
388 
389  if (iErr)
390  {
391  return -3;
392  }
393  }
394 
395  return iErr;
396 }
397 
398 VTKRENDERINGPARALLELLIC_EXPORT
399 ostream& operator<<(std::ostream& os, const vtkPPixelTransfer& gt);
400 
401 #endif
402 // VTK-HeaderTest-Exclude: vtkPPixelTransfer.h
class to handle inter-process communication of pixel data from non-contiguous regions of a shared ind...
void SetSourceWholeExtent(vtkPixelExtent &srcExt)
Set/Get the source extent.
const vtkPixelExtent & GetSourceWholeExtent() const
vtkPPixelTransfer(int srcRank, int destRank, const vtkPixelExtent &wholeExt, const vtkPixelExtent &targetExt, int id=0)
Initialize a transaction from sub extent of source to sub extent of dest, both the whole and the subs...
void SetUseBlockingRecv(int val)
int GetTransactionId() const
int GetUseBlockingRecv() const
vtkPixelExtent & GetDestinationWholeExtent()
bool Receiver(int rank) const
void SetDestinationRank(int rank)
vtkPixelExtent & GetSourceExtent()
int GetSourceRank() const
vtkPPixelTransfer(int srcRank, const vtkPixelExtent &srcWholeExt, int destRank, const vtkPixelExtent &destWholeExt, int id=0)
Initialize a transaction from whole extent of source to whole extent of dest, where source and destin...
void SetDestinationWholeExtent(vtkPixelExtent &destExt)
Set/get the destination extent.
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)
Transfer data from source to destination.
vtkPixelExtent & GetDestinationExtent()
vtkPPixelTransfer(int srcRank, int destRank, const vtkPixelExtent &ext, int id=0)
Initialize a transaction from sub extent of source to sub extent of dest, both the whole and the subs...
bool Local(int rank) const
vtkPixelExtent & GetSourceWholeExtent()
void SetTransactionId(int id)
Set/get the transaction id.
int GetUseBlockingSend() const
vtkPPixelTransfer(const vtkPixelExtent &srcWholeExt, const vtkPixelExtent &srcExt, const vtkPixelExtent &destWholeExt, const vtkPixelExtent &destExt)
Initialize a transaction from sub extent of source to sub extent of dest, where the subsets are diffe...
bool Sender(int rank) const
Tests to determine a given rank's role in this transaction.
int Execute(MPI_Comm comm, int rank, int nComps, int srcType, void *srcData, int destType, void *destData, std::vector< MPI_Request > &reqs, std::deque< MPI_Datatype > &types, int tag)
Transfer data from source to destination.
void SetDestinationExtent(vtkPixelExtent &destExt)
Set/get the destination extent.
vtkPPixelTransfer(int srcRank, const vtkPixelExtent &srcWholeExt, const vtkPixelExtent &srcExt, int destRank, const vtkPixelExtent &destWholeExt, const vtkPixelExtent &destExt, int id=0)
Initialize a transaction from sub extent of source to sub extent of dest, where the subsets are diffe...
const vtkPixelExtent & GetDestinationExtent() const
const vtkPixelExtent & GetSourceExtent() const
vtkPPixelTransfer(int srcRank, const vtkPixelExtent &srcWholeExt, const vtkPixelExtent &targetExt, int destRank, const vtkPixelExtent &destWholeExt, int id)
Initialize a transaction from sub extent of source to sub extent of dest, where the subsets are the s...
void SetUseBlockingSend(int val)
Enable/diasable non-blocking communication.
int GetDestinationRank() const
void SetSourceRank(int rank)
Set/Get the MPI rank of source and destination processes.
const vtkPixelExtent & GetDestinationWholeExtent() const
int Blit(int nComps, int srcType, void *srcData, int destType, void *destData)
Block transfer for local memory to memory transfers, without using mpi.
void SetSourceExtent(vtkPixelExtent &srcExt)
Set/Get the source extent.
Representation of a cartesian pixel plane and common operations on it.
pixel extents
static int Blit(const vtkPixelExtent &ext, int nComps, int srcType, void *srcData, int destType, void *destData)
for memory to memory transfers.
VTKRENDERINGPARALLELLIC_EXPORT ostream & operator<<(std::ostream &os, const vtkPPixelTransfer &gt)