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 = 0;
40   this->SetController(vtkMultiProcessController::GetGlobalController());
41 }
42 
~vtkPBivariateLinearTableThreshold()43 vtkPBivariateLinearTableThreshold::~vtkPBivariateLinearTableThreshold()
44 {
45   this->SetController(0);
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(vtkInformation* request ,
55                                               vtkInformationVector** inputVector,
56                                               vtkInformationVector* outputVector)
57 {
58   this->Superclass::RequestData(request,inputVector,outputVector);
59 
60   // single process?
61   if (!this->Controller || this->Controller->GetNumberOfProcesses() <= 1)
62     {
63     return 1;
64     }
65 
66  vtkCommunicator* comm = this->Controller->GetCommunicator();
67   if (!comm)
68     {
69     vtkErrorMacro("Need a communicator.");
70     return 0;
71     }
72 
73   vtkTable* outRowDataTable = vtkTable::GetData( outputVector, OUTPUT_ROW_DATA );
74 
75   int numProcesses = this->Controller->GetNumberOfProcesses();
76 
77  // 2) gather the selected data together
78   // for each column, make a new one and add it to a new table
79   vtkSmartPointer<vtkTable> gatheredTable = vtkSmartPointer<vtkTable>::New();
80   for (int i=0; i<outRowDataTable->GetNumberOfColumns(); i++)
81     {
82     vtkAbstractArray* col = vtkAbstractArray::SafeDownCast(outRowDataTable->GetColumn(i));
83     if (!col)
84       continue;
85 
86     vtkIdType myLength = col->GetNumberOfTuples();
87     vtkIdType totalLength = 0;
88     std::vector<vtkIdType> recvLengths(numProcesses,0);
89     std::vector<vtkIdType> recvOffsets(numProcesses,0);
90 
91     // gathers all of the array lengths together
92     comm->AllGather(&myLength, &recvLengths[0], 1);
93 
94     // compute the displacements
95     vtkIdType typeSize = col->GetDataTypeSize();
96     for (int j=0; j<numProcesses; j++)
97       {
98       recvOffsets[j] = totalLength*typeSize;
99       totalLength += recvLengths[j];
100       recvLengths[j] *= typeSize;
101       }
102 
103     // communicating this as a byte array :/
104     vtkAbstractArray* received = vtkAbstractArray::CreateArray(col->GetDataType());
105     received->SetNumberOfTuples(totalLength);
106 
107     char* sendBuf = (char*) col->GetVoidPointer(0);
108     char* recvBuf = (char*) received->GetVoidPointer(0);
109 
110     comm->AllGatherV(sendBuf, recvBuf, myLength*typeSize, &recvLengths[0], &recvOffsets[0]);
111 
112     gatheredTable->AddColumn(received);
113     received->Delete();
114     }
115 
116   outRowDataTable->ShallowCopy(gatheredTable);
117 
118   return 1;
119 }
120