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