Commit 10c6913a authored by Berk Geveci's avatar Berk Geveci Committed by George Zagaris
Browse files

Fixed legacy parallel reader and writer.

To work with the new pipeline changes.

Change-Id: Ic5c8ac86026999f79924d8e61b10fbcb18286bb8
parent dbbef3f2
......@@ -19,9 +19,13 @@ if (catch.catch(globals(),"""channel = open("test.tmp", "w")""") == 0):
reader.SetXYZFileName("" + str(VTK_DATA_ROOT) + "/Data/combxyz.bin")
reader.SetQFileName("" + str(VTK_DATA_ROOT) + "/Data/combq.bin")
reader.Update()
contr = vtk.vtkDummyController()
extract = vtk.vtkTransmitStructuredDataPiece()
extract.SetController(contr)
extract.SetInputData(reader.GetOutput().GetBlock(0))
writer = vtk.vtkPDataSetWriter()
writer.SetFileName("comb.pvtk")
writer.SetInputData(reader.GetOutput().GetBlock(0))
writer.SetInputConnection(extract.GetOutputPort())
writer.SetNumberOfPieces(4)
writer.Write()
pReader = vtk.vtkPDataSetReader()
......@@ -51,9 +55,12 @@ if (catch.catch(globals(),"""channel = open("test.tmp", "w")""") == 0):
fractal.SetWholeExtent(0,9,0,9,0,9)
fractal.SetSampleCX(0.1,0.1,0.1,0.1)
fractal.SetMaximumNumberOfIterations(10)
extract2 = vtk.vtkTransmitStructuredDataPiece()
extract2.SetController(contr)
extract2.SetInputConnection(fractal.GetOutputPort())
writer2 = vtk.vtkPDataSetWriter()
writer.SetFileName("fractal.pvtk")
writer.SetInputConnection(fractal.GetOutputPort())
writer.SetInputConnection(extract2.GetOutputPort())
writer.SetNumberOfPieces(4)
writer.Write()
pReader2 = vtk.vtkPDataSetReader()
......@@ -67,6 +74,8 @@ if (catch.catch(globals(),"""channel = open("test.tmp", "w")""") == 0):
mapper2.SetPiece(0)
mapper2.SetGhostLevel(0)
mapper2.Update()
# Strip the ghost cells requested by the contour filter
mapper2.GetInput().RemoveGhostCells(1)
file.delete("-force", "fractal.pvtk")
file.delete("-force", "fractal.0.vtk")
file.delete("-force", "fractal.1.vtk")
......
......@@ -32,6 +32,7 @@
#include "vtkStructuredPointsReader.h"
#include "vtkUnstructuredGrid.h"
#include "vtkExtentTranslator.h"
#include "vtkNew.h"
vtkStandardNewMacro(vtkPDataSetReader);
......@@ -888,6 +889,17 @@ ifstream *vtkPDataSetReader::OpenFile(const char* filename)
return file;
}
//----------------------------------------------------------------------------
int vtkPDataSetReader::RequestInformation(vtkInformation*,
vtkInformationVector**,
vtkInformationVector* outputVector)
{
vtkInformation* outInfo = outputVector->GetInformationObject(0);
outInfo->Set(vtkStreamingDemandDrivenPipeline::CAN_HANDLE_PIECE_REQUEST(), 1);
return 1;
}
//----------------------------------------------------------------------------
int vtkPDataSetReader::RequestData(vtkInformation* request,
vtkInformationVector** inputVector ,
......@@ -1114,7 +1126,19 @@ int vtkPDataSetReader::ImageDataExecute(
int i, j;
// Allocate the data object.
vtkStreamingDemandDrivenPipeline::GetUpdateExtent(info, uExt);
int wUExt[6];
vtkStreamingDemandDrivenPipeline::GetUpdateExtent(info, wUExt);
vtkNew<vtkExtentTranslator> et;
et->SetWholeExtent(wUExt);
et->SetPiece(info->Get(
vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()));
et->SetNumberOfPieces(info->Get(
vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES()));
int ghostLevels = info->Get(
vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS());
et->SetGhostLevel(ghostLevels);
et->PieceToExtent();
et->GetExtent(uExt);
output->SetExtent(uExt);
output->AllocateScalars(info);
......@@ -1179,6 +1203,15 @@ int vtkPDataSetReader::ImageDataExecute(
delete [] pieceMask;
reader->Delete();
if (ghostLevels > 0)
{
et->SetGhostLevel(0);
et->PieceToExtent();
int zeroExt[6];
et->GetExtent(zeroExt);
output->GenerateGhostLevelArray(zeroExt);
}
return 1;
}
......@@ -1215,7 +1248,19 @@ int vtkPDataSetReader::StructuredGridExecute(
{
pieceMask[i] = 0;
}
vtkStreamingDemandDrivenPipeline::GetUpdateExtent(info, uExt);
int wUExt[6];
vtkStreamingDemandDrivenPipeline::GetUpdateExtent(info, wUExt);
vtkNew<vtkExtentTranslator> et;
et->SetWholeExtent(wUExt);
et->SetPiece(info->Get(
vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()));
et->SetNumberOfPieces(info->Get(
vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES()));
int ghostLevels = info->Get(
vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS());
et->SetGhostLevel(ghostLevels);
et->PieceToExtent();
et->GetExtent(uExt);
this->CoverExtent(uExt, pieceMask);
// Now read the pieces.
......@@ -1351,6 +1396,16 @@ int vtkPDataSetReader::StructuredGridExecute(
delete [] pieceMask;
reader->Delete();
if (ghostLevels > 0)
{
et->SetGhostLevel(0);
et->PieceToExtent();
int zeroExt[6];
et->GetExtent(zeroExt);
output->GenerateGhostLevelArray(zeroExt);
}
return 1;
}
......
......@@ -63,6 +63,10 @@ protected:
vtkInformationVector** inputVector,
vtkInformationVector* outputVector);
virtual int RequestInformation(vtkInformation*,
vtkInformationVector**,
vtkInformationVector*);
virtual int RequestData(vtkInformation*,
vtkInformationVector**,
vtkInformationVector*);
......
......@@ -18,6 +18,7 @@
#include "vtkObjectFactory.h"
#include "vtkImageData.h"
#include "vtkInformation.h"
#include "vtkMultiProcessController.h"
#include "vtkStructuredGrid.h"
#include "vtkRectilinearGrid.h"
#include "vtkStreamingDemandDrivenPipeline.h"
......@@ -25,6 +26,10 @@
vtkStandardNewMacro(vtkPDataSetWriter);
vtkCxxSetObjectMacro(vtkPDataSetWriter,
Controller,
vtkMultiProcessController);
//----------------------------------------------------------------------------
vtkPDataSetWriter::vtkPDataSetWriter()
{
......@@ -36,12 +41,16 @@ vtkPDataSetWriter::vtkPDataSetWriter()
this->FilePattern = NULL;
this->SetFilePattern("%s.%d.vtk");
this->UseRelativeFileNames = 1;
this->Controller = 0;
this->SetController(vtkMultiProcessController::GetGlobalController());
}
//----------------------------------------------------------------------------
vtkPDataSetWriter::~vtkPDataSetWriter()
{
this->SetFilePattern(NULL);
this->SetController(0);
}
......@@ -139,8 +148,71 @@ int vtkPDataSetWriter::Write()
}
}
// Lets write the toplevel file.
if (this->StartPiece == 0)
// Restore the fileRoot to the full path.
strncpy(fileRoot, this->FileName, length);
fileRoot[length] = '\0';
// Trim off the pvtk extension.
if (strncmp(fileRoot+length-5, ".pvtk", 5) == 0)
{
fileRoot[length-5] = '\0';
}
if (strncmp(fileRoot+length-4, ".vtk", 4) == 0)
{
fileRoot[length-4] = '\0';
}
this->UpdateInformation();
// Now write the pieces assigned to this writer.
vtkDataSetWriter *writer = vtkDataSetWriter::New();
writer->SetFileTypeToBinary();
vtkDataObject *copy;
for (i = this->StartPiece; i <= this->EndPiece; ++i)
{
sprintf(fileName, this->FilePattern, fileRoot, i);
writer->SetFileName(fileName);
inputAlg->SetUpdateExtent(inputAlgPort,
i, this->NumberOfPieces, this->GhostLevel);
inputAlg->Update();
// Store the extent of this piece in Extents. This is later used
// to write the extents in the pvtk file.
vtkInformation* info = input->GetInformation();
int* ext = 0;
if (info->Has(vtkDataObject::DATA_EXTENT()))
{
ext = input->GetInformation()->Get(vtkDataObject::DATA_EXTENT());
}
if (ext)
{
this->Extents[i] = std::vector<int>(ext, ext+6);
}
copy = input->NewInstance();
copy->ShallowCopy(input);
// I am putting this in here because shallow copy does not copy the
// UpdateExtentInitializedFlag, and I do not want to touch ShallowCopy
// in ParaViews release.
// copy->Crop(vtkStreamingDemandDrivenPipeline::GetUpdateExtent(
// this->GetInputInformation()));
writer->SetInputData(vtkDataSet::SafeDownCast(copy));
writer->Write();
copy->Delete();
copy = NULL;
if (writer->GetErrorCode() == vtkErrorCode::OutOfDiskSpaceError)
{
this->DeleteFiles();
this->SetErrorCode(vtkErrorCode::OutOfDiskSpaceError);
break;
}
}
writer->Delete();
writer = NULL;
// Lets write the toplevel file.
if (this->StartPiece == 0 &&
(!this->Controller || this->Controller->GetLocalProcessId() == 0))
{
fptr = this->OpenFile();
if (fptr == NULL)
......@@ -164,7 +236,6 @@ int vtkPDataSetWriter::Write()
return 0;
}
inputAlg->UpdateInformation();
switch (input->GetDataObjectType())
{
case VTK_POLY_DATA:
......@@ -226,50 +297,6 @@ int vtkPDataSetWriter::Write()
delete fptr;
}
// Restore the fileRoot to the full path.
strncpy(fileRoot, this->FileName, length);
fileRoot[length] = '\0';
// Trim off the pvtk extension.
if (strncmp(fileRoot+length-5, ".pvtk", 5) == 0)
{
fileRoot[length-5] = '\0';
}
if (strncmp(fileRoot+length-4, ".vtk", 4) == 0)
{
fileRoot[length-4] = '\0';
}
// Now write the pieces assigned to this writer.
vtkDataSetWriter *writer = vtkDataSetWriter::New();
writer->SetFileTypeToBinary();
vtkDataObject *copy;
for (i = this->StartPiece; i <= this->EndPiece; ++i)
{
sprintf(fileName, this->FilePattern, fileRoot, i);
writer->SetFileName(fileName);
inputAlg->SetUpdateExtent(inputAlgPort,
i, this->NumberOfPieces, this->GhostLevel);
inputAlg->Update();
copy = input->NewInstance();
copy->ShallowCopy(input);
// I am putting this in here because shallow copy does not copy the
// UpdateExtentInitializedFlag, and I do not want to touch ShallowCopy
// in ParaViews release.
copy->Crop(vtkStreamingDemandDrivenPipeline::GetUpdateExtent(
this->GetInputInformation()));
writer->SetInputData(vtkDataSet::SafeDownCast(copy));
writer->Write();
copy->Delete();
copy = NULL;
if (writer->GetErrorCode() == vtkErrorCode::OutOfDiskSpaceError)
{
this->DeleteFiles();
this->SetErrorCode(vtkErrorCode::OutOfDiskSpaceError);
break;
}
}
writer->Delete();
writer = NULL;
delete [] fileName;
delete [] fileRoot;
......@@ -310,8 +337,6 @@ int vtkPDataSetWriter::WriteImageMetaData(vtkImageData * input,
int *pi;
double *pf;
vtkInformation* inInfo = this->GetInputInformation();
int inputAlgPort;
vtkAlgorithm* inputAlg = this->GetInputAlgorithm(0, 0, inputAlgPort);
// We should indicate the type of data that is being saved.
*fptr << " dataType=\"" << input->GetClassName() << "\"" << endl;
......@@ -332,11 +357,85 @@ int vtkPDataSetWriter::WriteImageMetaData(vtkImageData * input,
// some processes.
*fptr << " numberOfPieces=\"" << this->NumberOfPieces << "\" >" << endl;
// The code below gathers extens from all processes to write in the
// meta-file. Note that the extent of each piece was already stored by
// each writer. This is gathering it all to root node.
if (this->Controller)
{
// Even though the logic is pretty straightforward, we need to
// do a fair amount of work to use GatherV. Each rank simply
// serializes its extents to 7 int blocks - piece number and 6
// extent values. Then we gather this all to root.
int rank = this->Controller->GetLocalProcessId();
int nRanks = this->Controller->GetNumberOfProcesses();
int nPiecesTotal = 0;
vtkIdType nPieces = this->Extents.size();
vtkIdType* offsets = 0;
vtkIdType* nPiecesAll = 0;
vtkIdType* recvLengths = 0;
if (rank == 0)
{
nPiecesAll = new vtkIdType[nRanks];
recvLengths = new vtkIdType[nRanks];
offsets = new vtkIdType[nRanks];
}
this->Controller->Gather(&nPieces, nPiecesAll, 1, 0);
if (rank == 0)
{
for (int i=0; i<nRanks; i++)
{
offsets[i] = nPiecesTotal*7;
nPiecesTotal += nPiecesAll[i];
recvLengths[i] = nPiecesAll[i]*7;
}
}
int* sendBuffer = 0;
int sendSize = nPieces*7;
if (nPieces > 0)
{
sendBuffer = new int[sendSize];
ExtentsType::iterator iter = this->Extents.begin();
for (int count = 0; iter != this->Extents.end(); iter++, count++)
{
sendBuffer[count*7] = iter->first;
memcpy(&sendBuffer[count*7+1], &iter->second[0], 6*sizeof(int));
}
}
int* recvBuffer = 0;
if (rank == 0)
{
recvBuffer = new int[nPiecesTotal*7];
}
this->Controller->GatherV(sendBuffer, recvBuffer, sendSize,
recvLengths, offsets, 0);
if (rank == 0)
{
// Add all received values to Extents.
// These are later written in WritePPieceAttributes()
for (int i=1; i<nRanks; i++)
{
for (int j=0; j<nPiecesAll[i]; j++)
{
int* buffer = recvBuffer + offsets[i] + j*7;
this->Extents[*buffer] =
std::vector<int>(buffer+1, buffer+7);
}
}
}
delete[] nPiecesAll;
delete[] recvBuffer;
delete[] offsets;
delete[] recvLengths;
delete[] sendBuffer;
}
for (i = 0; i < this->NumberOfPieces; ++i)
{
inputAlg->SetUpdateExtent(inputAlgPort,
i, this->NumberOfPieces, this->GhostLevel);
pi = vtkStreamingDemandDrivenPipeline::GetUpdateExtent(inInfo);
pi = &this->Extents[i][0];
sprintf(str, this->FilePattern, root, i);
*fptr << " <Piece fileName=\"" << str << "\"" << endl
<< " extent=\"" << pi[0] << " " << pi[1] << " " << pi[2] << " "
......@@ -357,8 +456,6 @@ int vtkPDataSetWriter::WriteRectilinearGridMetaData(vtkRectilinearGrid *input,
{
int i;
int *pi;
int inputAlgPort;
vtkAlgorithm* inputAlg = this->GetInputAlgorithm(0, 0, inputAlgPort);
// We should indicate the type of data that is being saved.
*fptr << " dataType=\"" << input->GetClassName() << "\"" << endl;
......@@ -374,10 +471,7 @@ int vtkPDataSetWriter::WriteRectilinearGridMetaData(vtkRectilinearGrid *input,
*fptr << " numberOfPieces=\"" << this->NumberOfPieces << "\" >" << endl;
for (i = 0; i < this->NumberOfPieces; ++i)
{
inputAlg->SetUpdateExtent(inputAlgPort,
i, this->NumberOfPieces, this->GhostLevel);
pi = vtkStreamingDemandDrivenPipeline::GetUpdateExtent(
this->GetInputInformation());
pi = &this->Extents[i][0];
sprintf(str, this->FilePattern, root, i);
*fptr << " <Piece fileName=\"" << str << "\"" << endl
<< " extent=\"" << pi[0] << " " << pi[1] << " " << pi[2] << " "
......@@ -399,8 +493,6 @@ int vtkPDataSetWriter::WriteStructuredGridMetaData(vtkStructuredGrid *input,
{
int i;
int *pi;
int inputAlgPort;
vtkAlgorithm* inputAlg = this->GetInputAlgorithm(0, 0, inputAlgPort);
// We should indicate the type of data that is being saved.
*fptr << " dataType=\"" << input->GetClassName() << "\"" << endl;
......@@ -416,10 +508,7 @@ int vtkPDataSetWriter::WriteStructuredGridMetaData(vtkStructuredGrid *input,
*fptr << " numberOfPieces=\"" << this->NumberOfPieces << "\" >" << endl;
for (i = 0; i < this->NumberOfPieces; ++i)
{
inputAlg->SetUpdateExtent(inputAlgPort,
i, this->NumberOfPieces, this->GhostLevel);
pi = vtkStreamingDemandDrivenPipeline::GetUpdateExtent(
this->GetInputInformation());
pi = &this->Extents[i][0];
sprintf(str, this->FilePattern, root, i);
*fptr << " <Piece fileName=\"" << str << "\"" << endl
<< " extent=\"" << pi[0] << " " << pi[1] << " " << pi[2] << " "
......
......@@ -24,9 +24,13 @@
#include "vtkIOParallelModule.h" // For export macro
#include "vtkDataSetWriter.h"
#include <map> // for keeping track of extents
#include <vector> // for keeping track of extents
class vtkImageData;
class vtkRectilinearGrid;
class vtkStructuredGrid;
class vtkMultiProcessController;
class VTKIOPARALLEL_EXPORT vtkPDataSetWriter : public vtkDataSetWriter
{
......@@ -75,6 +79,13 @@ public:
vtkGetMacro(UseRelativeFileNames, int);
vtkBooleanMacro(UseRelativeFileNames, int);
// Description:
// Controller used to communicate data type of blocks.
// By default, the global controller is used. If you want another
// controller to be used, set it with this.
virtual void SetController(vtkMultiProcessController*);
vtkGetObjectMacro(Controller, vtkMultiProcessController);
protected:
vtkPDataSetWriter();
~vtkPDataSetWriter();
......@@ -102,6 +113,11 @@ protected:
void DeleteFiles();
typedef std::map<int, std::vector<int> > ExtentsType;
ExtentsType Extents;
vtkMultiProcessController* Controller;
private:
vtkPDataSetWriter(const vtkPDataSetWriter&); // Not implemented
void operator=(const vtkPDataSetWriter&); // Not implemented
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment