From d7a2f8047c362a9569bd11f62e48d28a00185262 Mon Sep 17 00:00:00 2001 From: Allison Vacanti <allison.vacanti@kitware.com> Date: Thu, 26 Oct 2017 16:20:28 -0400 Subject: [PATCH] Add test for piece distribution options in XML MBDS reader. --- IO/XML/Testing/Cxx/CMakeLists.txt | 4 + ...TestXMLCompositeDataReaderDistribution.cxx | 211 ++++++++++++++++++ Testing/Data/distTest.vtm.md5 | 1 + Testing/Data/distTest_0_0.vtp.md5 | 1 + Testing/Data/distTest_1_0.vtp.md5 | 1 + Testing/Data/distTest_2_0.vtp.md5 | 1 + Testing/Data/distTest_3_0.vtp.md5 | 1 + Testing/Data/distTest_4_0.vtp.md5 | 1 + Testing/Data/distTest_5_0.vtp.md5 | 1 + Testing/Data/distTest_6_0.vtp.md5 | 1 + Testing/Data/distTest_7_0.vtp.md5 | 1 + Testing/Data/distTest_8_0.vtp.md5 | 1 + Testing/Data/distTest_9_0.vtp.md5 | 1 + 13 files changed, 226 insertions(+) create mode 100644 IO/XML/Testing/Cxx/TestXMLCompositeDataReaderDistribution.cxx create mode 100644 Testing/Data/distTest.vtm.md5 create mode 100644 Testing/Data/distTest_0_0.vtp.md5 create mode 100644 Testing/Data/distTest_1_0.vtp.md5 create mode 100644 Testing/Data/distTest_2_0.vtp.md5 create mode 100644 Testing/Data/distTest_3_0.vtp.md5 create mode 100644 Testing/Data/distTest_4_0.vtp.md5 create mode 100644 Testing/Data/distTest_5_0.vtp.md5 create mode 100644 Testing/Data/distTest_6_0.vtp.md5 create mode 100644 Testing/Data/distTest_7_0.vtp.md5 create mode 100644 Testing/Data/distTest_8_0.vtp.md5 create mode 100644 Testing/Data/distTest_9_0.vtp.md5 diff --git a/IO/XML/Testing/Cxx/CMakeLists.txt b/IO/XML/Testing/Cxx/CMakeLists.txt index d8c50cd7144..ecb69055774 100644 --- a/IO/XML/Testing/Cxx/CMakeLists.txt +++ b/IO/XML/Testing/Cxx/CMakeLists.txt @@ -13,6 +13,10 @@ vtk_add_test_cxx(${vtk-module}CxxTests tests ) # Each of these most be added in a separate vtk_add_test_cxx +vtk_add_test_cxx(${vtk-module}CxxTests tests + TestXMLCompositeDataReaderDistribution.cxx,NO_VALID,NO_OUTPUT + "DATA{${VTK_TEST_INPUT_DIR}/distTest.vtm,REGEX:distTest_[0-9]_0.vtp}" + ) vtk_add_test_cxx(${vtk-module}CxxTests tests TestXMLReaderBadImageData,TestXMLReaderBadData.cxx,NO_VALID,NO_OUTPUT "DATA{${VTK_TEST_INPUT_DIR}/badImageData.xml}" ) diff --git a/IO/XML/Testing/Cxx/TestXMLCompositeDataReaderDistribution.cxx b/IO/XML/Testing/Cxx/TestXMLCompositeDataReaderDistribution.cxx new file mode 100644 index 00000000000..b611d840bfc --- /dev/null +++ b/IO/XML/Testing/Cxx/TestXMLCompositeDataReaderDistribution.cxx @@ -0,0 +1,211 @@ +/*========================================================================= + + Program: Visualization Toolkit + Module: TestXMLCompositeDataReaderDistribution.cxx + + Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen + All rights reserved. + See Copyright.txt or http://www.kitware.com/Copyright.htm for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notice for more information. + +=========================================================================*/ + +#include "vtkXMLCompositeDataReader.h" + +#include "vtkCompositeDataIterator.h" +#include "vtkCompositeDataPipeline.h" +#include "vtkCompositeDataSet.h" +#include "vtkInformation.h" +#include "vtkXMLMultiBlockDataReader.h" +#include "vtkPolyData.h" + +#include "vtkNew.h" + +#include <iostream> +#include <set> +#include <sstream> + +#define TEST_ASSERT(cond, message) \ + do { \ + if (!(cond)) \ + { \ + std::cerr << "Failure at line " << __LINE__ << ":\n" \ + << "\tCondition: " << #cond << "\n" \ + << "\tError: " << message << "\n"; \ + return EXIT_FAILURE; \ + } \ + } while (0) /* do-while swallows semicolons */ + +namespace +{ +// Returns a multiset containing the number of points in each leaf dataset. +std::multiset<vtkIdType> PointCounts(vtkCompositeDataSet *cds) +{ + std::multiset<vtkIdType> result; + + using SmartIterator = vtkSmartPointer<vtkCompositeDataIterator>; + auto it = SmartIterator::Take(cds->NewIterator()); + it->SkipEmptyNodesOn(); + for (it->InitTraversal(); !it->IsDoneWithTraversal(); it->GoToNextItem()) + { + vtkPolyData *pd = vtkPolyData::SafeDownCast(it->GetCurrentDataObject()); + if (pd) + { + result.insert(pd->GetNumberOfPoints()); + } + } + return result; +} + +bool VerifyCounts(vtkCompositeDataSet *cds, + const std::multiset<vtkIdType> &expected) +{ + return PointCounts(cds) == expected; +} + +std::string DumpCounts(vtkCompositeDataSet *cds) +{ + const std::multiset<vtkIdType> ids = PointCounts(cds); + std::ostringstream out; + out << "{ "; + for (auto id : ids) + { + out << id << " "; + } + out << "}"; + return out.str(); +} +} + +int TestXMLCompositeDataReaderDistribution(int argc, char* argv[]) +{ + + if (argc < 2) + { + std::cerr << "Missing argument.\n"; + return EXIT_FAILURE; + } + + vtkNew<vtkXMLMultiBlockDataReader> in; + in->SetFileName(argv[1]); + + // Verify that the dataset is what we expect: 10 leaves, each with a unique + // number of points spanning 1-10 inclusive. + { + in->Update(); + TEST_ASSERT(VerifyCounts(in->GetOutput(), {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}), + "Incorrect partitioning: " << DumpCounts(in->GetOutput())); + } + + // Simulate a request for a partitioning across 3 processors: + vtkNew<vtkInformation> req; + req->Set(vtkCompositeDataPipeline::UPDATE_NUMBER_OF_PIECES(), 3); + + // Verify that block loading works as expected. + { + in->SetPieceDistribution(vtkXMLMultiBlockDataReader::Block); + + // First processor: + req->Set(vtkCompositeDataPipeline::UPDATE_PIECE_NUMBER(), 0); + in->Update(req); + TEST_ASSERT(VerifyCounts(in->GetOutput(), {1, 2, 3, 4}), + "Incorrect partitioning: " << DumpCounts(in->GetOutput())); + + // Second processor: + req->Set(vtkCompositeDataPipeline::UPDATE_PIECE_NUMBER(), 1); + in->Update(req); + TEST_ASSERT(VerifyCounts(in->GetOutput(), {5, 6, 7}), + "Incorrect partitioning: " << DumpCounts(in->GetOutput())); + + // Third processor: + req->Set(vtkCompositeDataPipeline::UPDATE_PIECE_NUMBER(), 2); + in->Update(req); + TEST_ASSERT(VerifyCounts(in->GetOutput(), {8, 9, 10}), + "Incorrect partitioning: " << DumpCounts(in->GetOutput())); + } + + // Verify that interleaved loading works as expected. + { + in->SetPieceDistribution(vtkXMLMultiBlockDataReader::Interleave); + + // First processor: + req->Set(vtkCompositeDataPipeline::UPDATE_PIECE_NUMBER(), 0); + in->Update(req); + TEST_ASSERT(VerifyCounts(in->GetOutput(), {1, 4, 7, 10}), + "Incorrect partitioning: " << DumpCounts(in->GetOutput())); + + // Second processor: + req->Set(vtkCompositeDataPipeline::UPDATE_PIECE_NUMBER(), 1); + in->Update(req); + TEST_ASSERT(VerifyCounts(in->GetOutput(), {2, 5, 8}), + "Incorrect partitioning: " << DumpCounts(in->GetOutput())); + + // Third processor: + req->Set(vtkCompositeDataPipeline::UPDATE_PIECE_NUMBER(), 2); + in->Update(req); + TEST_ASSERT(VerifyCounts(in->GetOutput(), {3, 6, 9}), + "Incorrect partitioning: " << DumpCounts(in->GetOutput())); + } + + // Add an update restriction to test that loading is balanced when datasets 2 + // and 7 (point counts, not ids) are ignored. + req->Append(vtkCompositeDataPipeline::UPDATE_COMPOSITE_INDICES(), 0); + req->Append(vtkCompositeDataPipeline::UPDATE_COMPOSITE_INDICES(), 2); + req->Append(vtkCompositeDataPipeline::UPDATE_COMPOSITE_INDICES(), 3); + req->Append(vtkCompositeDataPipeline::UPDATE_COMPOSITE_INDICES(), 4); + req->Append(vtkCompositeDataPipeline::UPDATE_COMPOSITE_INDICES(), 5); + req->Append(vtkCompositeDataPipeline::UPDATE_COMPOSITE_INDICES(), 7); + req->Append(vtkCompositeDataPipeline::UPDATE_COMPOSITE_INDICES(), 8); + req->Append(vtkCompositeDataPipeline::UPDATE_COMPOSITE_INDICES(), 9); + + // Verify that block loading works as expected. + { + in->SetPieceDistribution(vtkXMLMultiBlockDataReader::Block); + + // First processor: + req->Set(vtkCompositeDataPipeline::UPDATE_PIECE_NUMBER(), 0); + in->Update(req); + TEST_ASSERT(VerifyCounts(in->GetOutput(), {1, 3, 4}), + "Incorrect partitioning: " << DumpCounts(in->GetOutput())); + + // Second processor: + req->Set(vtkCompositeDataPipeline::UPDATE_PIECE_NUMBER(), 1); + in->Update(req); + TEST_ASSERT(VerifyCounts(in->GetOutput(), {5, 6, 8}), + "Incorrect partitioning: " << DumpCounts(in->GetOutput())); + + // Third processor: + req->Set(vtkCompositeDataPipeline::UPDATE_PIECE_NUMBER(), 2); + in->Update(req); + TEST_ASSERT(VerifyCounts(in->GetOutput(), {9, 10}), + "Incorrect partitioning: " << DumpCounts(in->GetOutput())); + } + + // Verify that interleaved loading works as expected. + { + in->SetPieceDistribution(vtkXMLMultiBlockDataReader::Interleave); + + // First processor: + req->Set(vtkCompositeDataPipeline::UPDATE_PIECE_NUMBER(), 0); + in->Update(req); + TEST_ASSERT(VerifyCounts(in->GetOutput(), {1, 5, 9}), + "Incorrect partitioning: " << DumpCounts(in->GetOutput())); + + // Second processor: + req->Set(vtkCompositeDataPipeline::UPDATE_PIECE_NUMBER(), 1); + in->Update(req); + TEST_ASSERT(VerifyCounts(in->GetOutput(), {3, 6, 10}), + "Incorrect partitioning: " << DumpCounts(in->GetOutput())); + + // Third processor: + req->Set(vtkCompositeDataPipeline::UPDATE_PIECE_NUMBER(), 2); + in->Update(req); + TEST_ASSERT(VerifyCounts(in->GetOutput(), {4, 8}), + "Incorrect partitioning: " << DumpCounts(in->GetOutput())); + } + + return EXIT_SUCCESS; +} diff --git a/Testing/Data/distTest.vtm.md5 b/Testing/Data/distTest.vtm.md5 new file mode 100644 index 00000000000..4acfb8bfa29 --- /dev/null +++ b/Testing/Data/distTest.vtm.md5 @@ -0,0 +1 @@ +c4c7116c6c7b7f0e92c757a2f5ea3070 diff --git a/Testing/Data/distTest_0_0.vtp.md5 b/Testing/Data/distTest_0_0.vtp.md5 new file mode 100644 index 00000000000..76b338e4da8 --- /dev/null +++ b/Testing/Data/distTest_0_0.vtp.md5 @@ -0,0 +1 @@ +93aa53a851147f3483ec6b966207a74e diff --git a/Testing/Data/distTest_1_0.vtp.md5 b/Testing/Data/distTest_1_0.vtp.md5 new file mode 100644 index 00000000000..30c4ec4d53e --- /dev/null +++ b/Testing/Data/distTest_1_0.vtp.md5 @@ -0,0 +1 @@ +096d49773e571eb104210d5b423ea17c diff --git a/Testing/Data/distTest_2_0.vtp.md5 b/Testing/Data/distTest_2_0.vtp.md5 new file mode 100644 index 00000000000..f48150f7815 --- /dev/null +++ b/Testing/Data/distTest_2_0.vtp.md5 @@ -0,0 +1 @@ +6a0ed8e47cfdbb27a2f02996e7b1e25a diff --git a/Testing/Data/distTest_3_0.vtp.md5 b/Testing/Data/distTest_3_0.vtp.md5 new file mode 100644 index 00000000000..51d3cc89be3 --- /dev/null +++ b/Testing/Data/distTest_3_0.vtp.md5 @@ -0,0 +1 @@ +989a57c6faffda69c678bb73bcab4623 diff --git a/Testing/Data/distTest_4_0.vtp.md5 b/Testing/Data/distTest_4_0.vtp.md5 new file mode 100644 index 00000000000..45a879c0f3b --- /dev/null +++ b/Testing/Data/distTest_4_0.vtp.md5 @@ -0,0 +1 @@ +a9e12205f4b109593a3c13323177a74b diff --git a/Testing/Data/distTest_5_0.vtp.md5 b/Testing/Data/distTest_5_0.vtp.md5 new file mode 100644 index 00000000000..267d41ef969 --- /dev/null +++ b/Testing/Data/distTest_5_0.vtp.md5 @@ -0,0 +1 @@ +0d2133ec6756ced6dc086f9383573811 diff --git a/Testing/Data/distTest_6_0.vtp.md5 b/Testing/Data/distTest_6_0.vtp.md5 new file mode 100644 index 00000000000..a31cf8a7b26 --- /dev/null +++ b/Testing/Data/distTest_6_0.vtp.md5 @@ -0,0 +1 @@ +9de3f9de7b83424db047035f4f5492ff diff --git a/Testing/Data/distTest_7_0.vtp.md5 b/Testing/Data/distTest_7_0.vtp.md5 new file mode 100644 index 00000000000..fa7b6dc392f --- /dev/null +++ b/Testing/Data/distTest_7_0.vtp.md5 @@ -0,0 +1 @@ +b6dc5dde0b97d4c531b7b0446bb3e068 diff --git a/Testing/Data/distTest_8_0.vtp.md5 b/Testing/Data/distTest_8_0.vtp.md5 new file mode 100644 index 00000000000..4bf1a7a0bfd --- /dev/null +++ b/Testing/Data/distTest_8_0.vtp.md5 @@ -0,0 +1 @@ +1d7c4098d6d08806d4d04f8a9aaf6d1f diff --git a/Testing/Data/distTest_9_0.vtp.md5 b/Testing/Data/distTest_9_0.vtp.md5 new file mode 100644 index 00000000000..0c9ede95b5f --- /dev/null +++ b/Testing/Data/distTest_9_0.vtp.md5 @@ -0,0 +1 @@ +4cb9650348bfb1577c0e2925417dd3f2 -- GitLab