1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkPConvertToMultiBlockDataSet.cxx
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 =========================================================================*/
15 #include "vtkPConvertToMultiBlockDataSet.h"
16 
17 #include "vtkCommunicator.h"
18 #include "vtkMultiBlockDataSet.h"
19 #include "vtkMultiProcessController.h"
20 #include "vtkObjectFactory.h"
21 #include "vtkPartitionedDataSet.h"
22 #include "vtkPartitionedDataSetCollection.h"
23 #include "vtkSmartPointer.h"
24 
25 vtkObjectFactoryNewMacro(vtkPConvertToMultiBlockDataSet);
vtkCxxSetObjectMacro(vtkPConvertToMultiBlockDataSet,Controller,vtkMultiProcessController)26 vtkCxxSetObjectMacro(vtkPConvertToMultiBlockDataSet, Controller, vtkMultiProcessController)
27   //----------------------------------------------------------------------------
28   vtkPConvertToMultiBlockDataSet::vtkPConvertToMultiBlockDataSet()
29   : Controller(nullptr)
30 {
31   this->SetController(vtkMultiProcessController::GetGlobalController());
32 }
33 
34 //----------------------------------------------------------------------------
~vtkPConvertToMultiBlockDataSet()35 vtkPConvertToMultiBlockDataSet::~vtkPConvertToMultiBlockDataSet()
36 {
37   this->SetController(nullptr);
38 }
39 
40 //----------------------------------------------------------------------------
RequestData(vtkInformation * request,vtkInformationVector ** inputVector,vtkInformationVector * outputVector)41 int vtkPConvertToMultiBlockDataSet::RequestData(
42   vtkInformation* request, vtkInformationVector** inputVector, vtkInformationVector* outputVector)
43 {
44   vtkSmartPointer<vtkPartitionedDataSetCollection> input;
45   if (auto pdc = vtkPartitionedDataSetCollection::GetData(inputVector[0], 0))
46   {
47     input = pdc;
48   }
49   else if (auto pd = vtkPartitionedDataSet::GetData(inputVector[0], 0))
50   {
51     input = vtkSmartPointer<vtkPartitionedDataSetCollection>::New();
52     input->SetPartitionedDataSet(0, pd);
53   }
54 
55   const int numRanks = this->Controller ? this->Controller->GetNumberOfProcesses() : 1;
56   if (numRanks == 1 || input == nullptr || input->GetNumberOfPartitionedDataSets() == 0)
57   {
58     // nothing to do.
59     return this->Superclass::RequestData(request, inputVector, outputVector);
60   }
61 
62   auto output = vtkMultiBlockDataSet::GetData(outputVector, 0);
63 
64   // ensure that we have exactly the same number of partitions on all ranks.
65   vtkNew<vtkPartitionedDataSetCollection> clone;
66   clone->ShallowCopy(input);
67 
68   const auto count = input->GetNumberOfPartitionedDataSets();
69   std::vector<unsigned int> piece_counts(count);
70   for (unsigned int cc = 0; cc < count; ++cc)
71   {
72     piece_counts[cc] = clone->GetPartitionedDataSet(cc)
73       ? clone->GetPartitionedDataSet(cc)->GetNumberOfPartitions()
74       : 0;
75   }
76 
77   std::vector<unsigned int> result(piece_counts.size());
78   this->Controller->AllReduce(
79     &piece_counts[0], &result[0], static_cast<vtkIdType>(count), vtkCommunicator::MAX_OP);
80 
81   for (unsigned int cc = 0; cc < count; ++cc)
82   {
83     if (result[cc] > 0)
84     {
85       if (clone->GetPartitionedDataSet(cc) == nullptr)
86       {
87         clone->SetPartitionedDataSet(cc, vtkNew<vtkPartitionedDataSet>{});
88       }
89       clone->GetPartitionedDataSet(cc)->SetNumberOfPartitions(result[cc]);
90     }
91   }
92   return this->Execute(clone, output) ? 1 : 0;
93 }
94 
95 //----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)96 void vtkPConvertToMultiBlockDataSet::PrintSelf(ostream& os, vtkIndent indent)
97 {
98   this->Superclass::PrintSelf(os, indent);
99 }
100