Skip to content
Snippets Groups Projects
Commit 5b502262 authored by Cory Quammen's avatar Cory Quammen
Browse files

vtkXMLMultiBlockDataReader: fix when reading nested multipiece datasets

When a vtkMultiBlockDataSet contains a vtkMultiPieceDataSet,
vtkXMLPMultiBlockDataWriter will split each piece into another
vtkMultiPieceDataSet. As a result, the written XML data file will
contain nested "Piece" elements. Since vtkMultiPieceDataSets are not
hierarchical, this dataset cannot be recreated as described.

To fix, have the reader replace the top-level vtkMultiPieceDataSet
with a vtkMultiBlockDataSet instead when nested Piece elements are
found.

Modified test to exercise writing out a vtkMultiPieceDataSet block and
read it back in.
parent d2310987
No related branches found
No related tags found
No related merge requests found
...@@ -43,6 +43,13 @@ else: ...@@ -43,6 +43,13 @@ else:
# | |-- [0,1,..nranks](0,1,...nranks) # | |-- [0,1,..nranks](0,1,...nranks)
# | |-- [0,1,..nranks](0,1,...nranks) # | |-- [0,1,..nranks](0,1,...nranks)
# | ... (up to total number of ranks) # | ... (up to total number of ranks)
# |
# |-- <MP> # level where a multipiece dataset is present on all ranks
# | |
# | |-- [0,1,..nranks](0,1,...nranks)
# | |-- [0,1,..nranks](0,1,...nranks)
# | |-- [0,1,..nranks](0,1,...nranks)
# | ... (up to total number of ranks)
def createDataSet(empty): def createDataSet(empty):
...@@ -62,12 +69,20 @@ def createData(non_null_ranks, non_empty_ranks, num_ranks): ...@@ -62,12 +69,20 @@ def createData(non_null_ranks, non_empty_ranks, num_ranks):
mb.SetBlock(i, createDataSet(i not in non_empty_ranks)) mb.SetBlock(i, createDataSet(i not in non_empty_ranks))
return mb return mb
def createMP(num_pieces):
mp = vtk.vtkMultiPieceDataSet()
mp.SetNumberOfPieces(num_pieces)
for i in range(num_pieces):
mp.SetPiece(i, createDataSet(False))
return mp
def createMB(piece, num_pieces): def createMB(piece, num_pieces):
output = vtk.vtkMultiBlockDataSet() output = vtk.vtkMultiBlockDataSet()
output.SetNumberOfBlocks(3) output.SetNumberOfBlocks(4)
output.SetBlock(0, createData([piece], [piece], num_pieces)) output.SetBlock(0, createData([piece], [piece], num_pieces))
output.SetBlock(1, createData(range(num_pieces), [piece], num_pieces)) output.SetBlock(1, createData(range(num_pieces), [piece], num_pieces))
output.SetBlock(2, createData(range(num_pieces), range(num_pieces), num_pieces)) output.SetBlock(2, createData(range(num_pieces), range(num_pieces), num_pieces))
output.SetBlock(3, createMP(num_pieces))
return output return output
writer = vtk.vtkXMLPMultiBlockDataWriter() writer = vtk.vtkXMLPMultiBlockDataWriter()
...@@ -104,6 +119,6 @@ if rank == 0: ...@@ -104,6 +119,6 @@ if rank == 0:
# set of files, let's just look at the files we wrote out. # set of files, let's just look at the files we wrote out.
files = os.listdir(prefix) files = os.listdir(prefix)
expected_file_count = nranks + nranks + (nranks*nranks) expected_file_count = nranks + nranks + 2*(nranks*nranks)
print ("Expecting %d files for the leaf nodes" % expected_file_count) print ("Expecting %d files for the leaf nodes" % expected_file_count)
assert (len(files) == expected_file_count) assert (len(files) == expected_file_count)
...@@ -172,7 +172,20 @@ void vtkXMLMultiBlockDataReader::ReadComposite(vtkXMLDataElement* element, ...@@ -172,7 +172,20 @@ void vtkXMLMultiBlockDataReader::ReadComposite(vtkXMLDataElement* element,
// Child is a multipiece dataset. Create it. // Child is a multipiece dataset. Create it.
else if (mblock != nullptr && strcmp(tagName, "Piece") == 0) else if (mblock != nullptr && strcmp(tagName, "Piece") == 0)
{ {
vtkMultiPieceDataSet* childDS = vtkMultiPieceDataSet::New(); // Look ahead to see if there is a nested Piece structure, which can happen when
// the dataset pieces in a vtkMultiPieceDataSet are themselves split into
// vtkMultiPieceDataSets when saved in parallel.
vtkCompositeDataSet* childDS;
if (childXML->FindNestedElementWithName("Piece"))
{
// Create a multiblock to handle a multipiece child
childDS = vtkMultiBlockDataSet::New();
}
else
{
// Child is not multipiece, so it is safe to create a vtkMultiPieceDataSet
childDS = vtkMultiPieceDataSet::New();
}
this->ReadComposite(childXML, childDS, filePath, dataSetIndex); this->ReadComposite(childXML, childDS, filePath, dataSetIndex);
const char* name = childXML->GetAttribute("name"); const char* name = childXML->GetAttribute("name");
mblock->SetBlock(index, childDS); mblock->SetBlock(index, childDS);
...@@ -284,7 +297,21 @@ int vtkXMLMultiBlockDataReader::FillMetaData(vtkCompositeDataSet* metadata, ...@@ -284,7 +297,21 @@ int vtkXMLMultiBlockDataReader::FillMetaData(vtkCompositeDataSet* metadata,
// Child is a multipiece dataset. Create it. // Child is a multipiece dataset. Create it.
else if (mblock != nullptr && strcmp(tagName, "Piece") == 0) else if (mblock != nullptr && strcmp(tagName, "Piece") == 0)
{ {
vtkMultiPieceDataSet* childDS = vtkMultiPieceDataSet::New(); // Look ahead to see if there is a nested Piece structure, which can happen when
// the dataset pieces in a vtkMultiPieceDataSet are themselves split into
// vtkMultiPieceDataSets when saved in parallel.
vtkCompositeDataSet* childDS;
if (childXML->FindNestedElementWithName("Piece"))
{
// Create a multiblock to handle a multipiece child
childDS = vtkMultiBlockDataSet::New();
}
else
{
// Child is not multipiece, so it is safe to create a vtkMultiPieceDataSet
childDS = vtkMultiPieceDataSet::New();
}
this->FillMetaData(childDS, childXML, filePath, dataSetIndex); this->FillMetaData(childDS, childXML, filePath, dataSetIndex);
mblock->SetBlock(index, childDS); mblock->SetBlock(index, childDS);
childDS->Delete(); childDS->Delete();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment