1 /*=========================================================================
2 
3 Program:   Visualization Toolkit
4 Module:    vtkPBivariateLinearTableThreshold.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 /*-------------------------------------------------------------------------
16   Copyright 2009 Sandia Corporation.
17   Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
18   the U.S. Government retains certain rights in this software.
19 -------------------------------------------------------------------------*/
20 #include "vtkPBivariateLinearTableThreshold.h"
21 
22 #include "vtkDataArrayCollection.h"
23 #include "vtkDataObject.h"
24 #include "vtkDoubleArray.h"
25 #include "vtkIdTypeArray.h"
26 #include "vtkInformation.h"
27 #include "vtkInformationVector.h"
28 #include "vtkMultiProcessController.h"
29 #include "vtkObjectFactory.h"
30 #include "vtkTable.h"
31 
32 #include <map>
33 
34 vtkStandardNewMacro(vtkPBivariateLinearTableThreshold);
35 vtkCxxSetObjectMacro(vtkPBivariateLinearTableThreshold, Controller, vtkMultiProcessController);
36 
vtkPBivariateLinearTableThreshold()37 vtkPBivariateLinearTableThreshold::vtkPBivariateLinearTableThreshold()
38 {
39   this->Controller = nullptr;
40   this->SetController(vtkMultiProcessController::GetGlobalController());
41 }
42 
~vtkPBivariateLinearTableThreshold()43 vtkPBivariateLinearTableThreshold::~vtkPBivariateLinearTableThreshold()
44 {
45   this->SetController(nullptr);
46 }
47 
PrintSelf(ostream & os,vtkIndent indent)48 void vtkPBivariateLinearTableThreshold::PrintSelf(ostream& os, vtkIndent indent)
49 {
50   this->Superclass::PrintSelf(os, indent);
51   os << indent << "Controller: " << this->Controller << endl;
52 }
53 
RequestData(vtkInformation * request,vtkInformationVector ** inputVector,vtkInformationVector * outputVector)54 int vtkPBivariateLinearTableThreshold::RequestData(
55   vtkInformation* request, vtkInformationVector** inputVector, vtkInformationVector* outputVector)
56 {
57   this->Superclass::RequestData(request, inputVector, outputVector);
58 
59   // single process?
60   if (!this->Controller || this->Controller->GetNumberOfProcesses() <= 1)
61   {
62     return 1;
63   }
64 
65   vtkCommunicator* comm = this->Controller->GetCommunicator();
66   if (!comm)
67   {
68     vtkErrorMacro("Need a communicator.");
69     return 0;
70   }
71 
72   vtkTable* outRowDataTable = vtkTable::GetData(outputVector, OUTPUT_ROW_DATA);
73 
74   int numProcesses = this->Controller->GetNumberOfProcesses();
75 
76   // 2) gather the selected data together
77   // for each column, make a new one and add it to a new table
78   vtkSmartPointer<vtkTable> gatheredTable = vtkSmartPointer<vtkTable>::New();
79   for (int i = 0; i < outRowDataTable->GetNumberOfColumns(); i++)
80   {
81     vtkAbstractArray* col = vtkArrayDownCast<vtkAbstractArray>(outRowDataTable->GetColumn(i));
82     if (!col)
83       continue;
84 
85     vtkIdType myLength = col->GetNumberOfTuples();
86     vtkIdType totalLength = 0;
87     std::vector<vtkIdType> recvLengths(numProcesses, 0);
88     std::vector<vtkIdType> recvOffsets(numProcesses, 0);
89 
90     // gathers all of the array lengths together
91     comm->AllGather(&myLength, &recvLengths[0], 1);
92 
93     // compute the displacements
94     vtkIdType typeSize = col->GetDataTypeSize();
95     for (int j = 0; j < numProcesses; j++)
96     {
97       recvOffsets[j] = totalLength * typeSize;
98       totalLength += recvLengths[j];
99       recvLengths[j] *= typeSize;
100     }
101 
102     // communicating this as a byte array :/
103     vtkAbstractArray* received = vtkAbstractArray::CreateArray(col->GetDataType());
104     received->SetNumberOfTuples(totalLength);
105 
106     char* sendBuf = (char*)col->GetVoidPointer(0);
107     char* recvBuf = (char*)received->GetVoidPointer(0);
108 
109     comm->AllGatherV(sendBuf, recvBuf, myLength * typeSize, &recvLengths[0], &recvOffsets[0]);
110 
111     gatheredTable->AddColumn(received);
112     received->Delete();
113   }
114 
115   outRowDataTable->ShallowCopy(gatheredTable);
116 
117   return 1;
118 }
119