ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
vtkMultiProcessControllerHelper.cxx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: ParaView
4  Module: vtkMultiProcessControllerHelper.cxx
5 
6  Copyright (c) Kitware, Inc.
7  All rights reserved.
8  See Copyright.txt or http://www.paraview.org/HTML/Copyright.html 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 =========================================================================*/
16 
17 #include "vtkAppendCompositeDataLeaves.h"
18 #include "vtkAppendFilter.h"
19 #include "vtkAppendPolyData.h"
20 #include "vtkCompositeDataSet.h"
21 #include "vtkGraph.h"
22 #include "vtkImageAppend.h"
23 #include "vtkImageData.h"
24 #include "vtkMolecule.h"
25 //#include "vtkMoleculeAppend.h"
26 #include "vtkMultiProcessController.h"
27 #include "vtkMultiProcessStream.h"
28 #include "vtkNew.h"
29 #include "vtkObjectFactory.h"
30 #include "vtkStreamingDemandDrivenPipeline.h"
31 #include "vtkStructuredGridAppend.h"
32 #include "vtkTrivialProducer.h"
33 #include "vtkUnstructuredGrid.h"
34 
35 #include <vector>
36 
38 //----------------------------------------------------------------------------
40 {
41 }
42 
43 //----------------------------------------------------------------------------
45 {
46 }
47 
48 //----------------------------------------------------------------------------
49 int vtkMultiProcessControllerHelper::ReduceToAll(vtkMultiProcessController* controller,
50  vtkMultiProcessStream& data,
51  void (*operation)(vtkMultiProcessStream& A, vtkMultiProcessStream& B), int vtkNotUsed(tag))
52 {
53  int numProcs = controller->GetNumberOfProcesses();
54  if (numProcs <= 1)
55  {
56  return 1;
57  }
58 
59  std::vector<unsigned char> raw_data;
60  data.GetRawData(raw_data);
61  data.Reset();
62 
63  std::vector<vtkIdType> counts(numProcs);
64  const auto my_count = static_cast<vtkIdType>(raw_data.size());
65  controller->AllGather(&my_count, &counts[0], 1);
66 
67  std::vector<vtkIdType> offsets(numProcs, 0);
68  for (int cc = 1; cc < numProcs; ++cc)
69  {
70  offsets[cc] = offsets[cc - 1] + counts[cc - 1];
71  }
72 
73  std::vector<unsigned char> buffer(offsets.back() + counts.back());
74 
75  controller->AllGatherV(&raw_data[0], &buffer[0], my_count, &counts[0], &offsets[0]);
76 
77  // now perform pair-wise reduction operation locally.
78  data.SetRawData(&buffer[0], static_cast<unsigned int>(counts[0]));
79  for (int cc = 1; cc < numProcs; ++cc)
80  {
81  vtkMultiProcessStream other;
82  other.SetRawData(&buffer[offsets[cc]], static_cast<unsigned int>(counts[cc]));
83  // operation produces result in the second argument.
84  (*operation)(other, data);
85  }
86  return 1;
87 }
88 
89 //-----------------------------------------------------------------------------
91  vtkDataObject** pieces, unsigned int num_pieces)
92 {
93  if (num_pieces == 0)
94  {
95  return NULL;
96  }
97 
98  vtkDataObject* result = pieces[0]->NewInstance();
99 
100  std::vector<vtkSmartPointer<vtkDataObject> > piece_vector;
101  piece_vector.resize(num_pieces);
102  for (unsigned int cc = 0; cc < num_pieces; cc++)
103  {
104  piece_vector[cc] = pieces[cc];
105  }
106 
108  {
109  return result;
110  }
111  result->Delete();
112  return NULL;
113 }
114 
115 //-----------------------------------------------------------------------------
117  std::vector<vtkSmartPointer<vtkDataObject> >& pieces, vtkDataObject* result)
118 {
119  if (pieces.size() == 0)
120  {
121  return false;
122  }
123 
124  if (pieces.size() == 1)
125  {
126  result->ShallowCopy(pieces[0]);
127  vtkImageData* id = vtkImageData::SafeDownCast(pieces[0]);
128  if (id)
129  {
130  vtkStreamingDemandDrivenPipeline::SetWholeExtent(
131  result->GetInformation(), static_cast<vtkImageData*>(pieces[0].GetPointer())->GetExtent());
132  }
133  return true;
134  }
135 
136  // PolyData and Unstructured grid need different append filters.
137  vtkAlgorithm* appender = NULL;
138  if (vtkPolyData::SafeDownCast(result))
139  {
140  appender = vtkAppendPolyData::New();
141  }
142  else if (vtkUnstructuredGrid::SafeDownCast(result))
143  {
144  appender = vtkAppendFilter::New();
145  }
146  else if (vtkImageData::SafeDownCast(result))
147  {
148  vtkImageAppend* ia = vtkImageAppend::New();
149  ia->PreserveExtentsOn();
150  appender = ia;
151  }
152  else if (vtkStructuredGrid::SafeDownCast(result))
153  {
154  appender = vtkStructuredGridAppend::New();
155  ;
156  }
157  else if (vtkMolecule::SafeDownCast(result))
158  {
159  //appender = vtkMoleculeAppend::New();
160  }
161  else if (vtkGraph::SafeDownCast(result))
162  {
163  vtkGenericWarningMacro("Support for vtkGraph has been depreciated.");
164  return false;
165  }
166  else if (vtkCompositeDataSet::SafeDownCast(result))
167  {
168  // this only supports composite datasets of polydata and unstructured
169  // grids.
170  vtkAppendCompositeDataLeaves* cdl = vtkAppendCompositeDataLeaves::New();
171  cdl->AppendFieldDataOn();
172  appender = cdl;
173  }
174  else
175  {
176  vtkGenericWarningMacro(<< result->GetClassName() << " cannot be merged");
177  result->ShallowCopy(pieces[0]);
178  return false;
179  }
180  std::vector<vtkSmartPointer<vtkDataObject> >::iterator iter;
181  for (iter = pieces.begin(); iter != pieces.end(); ++iter)
182  {
183  vtkDataSet* ds = vtkDataSet::SafeDownCast(iter->GetPointer());
184  if (ds && ds->GetNumberOfPoints() == 0)
185  {
186  // skip empty pieces.
187  continue;
188  }
189  vtkMolecule* mol = vtkMolecule::SafeDownCast(iter->GetPointer());
190  if (mol && mol->GetNumberOfAtoms() == 0)
191  {
192  continue;
193  }
194 
195  vtkNew<vtkTrivialProducer> tp;
196  tp->SetOutput(iter->GetPointer());
197  appender->AddInputConnection(0, tp->GetOutputPort());
198  }
199  // input connections may be 0, since we skip empty inputs in the loop above.
200  if (appender->GetNumberOfInputConnections(0) > 0)
201  {
202  appender->Update();
203  result->ShallowCopy(appender->GetOutputDataObject(0));
204  }
205  appender->Delete();
206  return true;
207 }
208 
209 //----------------------------------------------------------------------------
210 void vtkMultiProcessControllerHelper::PrintSelf(ostream& os, vtkIndent indent)
211 {
212  this->Superclass::PrintSelf(os, indent);
213 }
#define NULL
core::Tensor result
Definition: VtkUtils.cpp:76
void PrintSelf(ostream &os, vtkIndent indent) override
static vtkDataObject * MergePieces(vtkDataObject **pieces, unsigned int num_pieces)
static int ReduceToAll(vtkMultiProcessController *controller, vtkMultiProcessStream &data, void(*operation)(vtkMultiProcessStream &A, vtkMultiProcessStream &B), int tag)
GraphType data
Definition: graph_cut.cc:138
vtkStandardNewMacro(vtkMultiProcessControllerHelper)