diff --git a/Filters/Core/Testing/Cxx/CMakeLists.txt b/Filters/Core/Testing/Cxx/CMakeLists.txt index 0196a260ac74589c9993db32f0b1916850ad8a61..ddc1f71acad95f9d8b0faaf40159aadd9c84c5e4 100644 --- a/Filters/Core/Testing/Cxx/CMakeLists.txt +++ b/Filters/Core/Testing/Cxx/CMakeLists.txt @@ -109,4 +109,13 @@ set(all_tests ${no_vtkm_tests} ) +if (TARGET VTK::ParallelMPI) + set(vtkFiltersCoreCxxTests-MPI_NUMPROCS 2) + vtk_add_test_mpi(vtkFiltersCoreCxxTests-MPI mpi_test + TestAppendFilterDistributed.cxx,NO_VALID + ) + + vtk_test_cxx_executable(vtkFiltersCoreCxxTests-MPI mpi_test) +endif() + vtk_test_cxx_executable(vtkFiltersCoreCxxTests all_tests) diff --git a/Filters/Core/Testing/Cxx/TestAppendFilterDistributed.cxx b/Filters/Core/Testing/Cxx/TestAppendFilterDistributed.cxx new file mode 100644 index 0000000000000000000000000000000000000000..572c441e4453895088a66ac73919a038a97f12dc --- /dev/null +++ b/Filters/Core/Testing/Cxx/TestAppendFilterDistributed.cxx @@ -0,0 +1,61 @@ +// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen +// SPDX-License-Identifier: BSD-3-Clause + +#include "vtkImageData.h" +#include "vtkMPIController.h" +#include "vtkUnstructuredGrid.h" + +#include <vtkAppendFilter.h> +#include <vtkGenerateGlobalIds.h> +#include <vtkGeometryFilter.h> +#include <vtkLogger.h> +#include <vtkRedistributeDataSetFilter.h> +#include <vtkSpatioTemporalHarmonicsSource.h> + +int TestAppendFilterDistributed(int argc, char* argv[]) +{ + // Initialize MPI Controller + vtkNew<vtkMPIController> controller; + controller->Initialize(&argc, &argv); + vtkMultiProcessController::SetGlobalController(controller); + + vtkNew<vtkSpatioTemporalHarmonicsSource> source; + source->Update(); + + vtkNew<vtkGenerateGlobalIds> globalIds; + globalIds->SetInputData(source->GetOutput()); + globalIds->SetTolerance(0); + globalIds->Update(); + + vtkNew<vtkRedistributeDataSetFilter> redistribute; + redistribute->SetInputData(globalIds->GetOutput()); + redistribute->Update(); + + // This filter is only here to test cell's faces and points validity, it will crash if invalid. + vtkNew<vtkGeometryFilter> geometry; + geometry->SetInputData(redistribute->GetOutput()); + geometry->Update(); + + vtkSmartPointer<vtkUnstructuredGrid> grid = + vtkUnstructuredGrid::SafeDownCast(redistribute->GetOutput()); + + if (grid->GetNumberOfCells() != 8000) + { + std::cerr << "Incorrect number of cells. Expected 8000 got " << grid->GetNumberOfCells() + << std::endl; + controller->Finalize(); + return EXIT_FAILURE; + } + + if (grid->GetNumberOfPoints() != 4851) + { + std::cerr << "Incorrect number of points. Expected 4851 got " << grid->GetNumberOfPoints() + << std::endl; + controller->Finalize(); + return EXIT_FAILURE; + } + + controller->Finalize(); + + return EXIT_SUCCESS; +} diff --git a/Filters/Core/vtk.module b/Filters/Core/vtk.module index a9bd1e45cab98969037ed1c884a12b26aa0eb93e..f370846d70ad4a0dae8f57a7fc0bd1b4c884fe9b 100644 --- a/Filters/Core/vtk.module +++ b/Filters/Core/vtk.module @@ -54,3 +54,5 @@ TEST_DEPENDS VTK::TestingDataModel TEST_OPTIONAL_DEPENDS VTK::AcceleratorsVTKmFilters + VTK::mpi + VTK::ParallelMPI diff --git a/Filters/Core/vtkAppendFilter.cxx b/Filters/Core/vtkAppendFilter.cxx index 1087d921ca9170ee93e927482a341756316f64ea..f7a6c23c23939a55bc66bd865a091605e9d95699 100644 --- a/Filters/Core/vtkAppendFilter.cxx +++ b/Filters/Core/vtkAppendFilter.cxx @@ -302,34 +302,30 @@ int vtkAppendFilter::RequestData(vtkInformation* vtkNotUsed(request), { if (reallyMergePoints) { - if (!dataSet->HasAnyGhostPoints() || - dataSet->GetGhostArray(vtkDataObject::POINT)->GetValue(ptId) == 0) + if (dataSetGlobalIdsArray) { - if (dataSetGlobalIdsArray) + vtkIdType globalId = dataSetGlobalIdsArray->GetValue(ptId); + auto it = addedPointsMap.find(globalId); + if (it == addedPointsMap.end()) { - vtkIdType globalId = dataSetGlobalIdsArray->GetValue(ptId); - auto it = addedPointsMap.find(globalId); - if (it == addedPointsMap.end()) - { - globalIndices[ptId + ptOffset] = newPts->GetNumberOfPoints(); - dataSet->GetPoint(ptId, p); - vtkIdType newPtId = newPts->InsertNextPoint(p); - addedPointsMap.emplace(globalId, newPtId); - } - else - { - globalIndices[ptId + ptOffset] = it->second; - } + globalIndices[ptId + ptOffset] = newPts->GetNumberOfPoints(); + dataSet->GetPoint(ptId, p); + vtkIdType newPtId = newPts->InsertNextPoint(p); + addedPointsMap.emplace(globalId, newPtId); } else { - vtkIdType globalPtId = 0; - dataSet->GetPoint(ptId, p); - ptInserter->InsertUniquePoint(p, globalPtId); - globalIndices[ptId + ptOffset] = globalPtId; - // The point inserter puts the point into newPts, so we don't have to do that here. + globalIndices[ptId + ptOffset] = it->second; } } + else + { + vtkIdType globalPtId = 0; + dataSet->GetPoint(ptId, p); + ptInserter->InsertUniquePoint(p, globalPtId); + globalIndices[ptId + ptOffset] = globalPtId; + // The point inserter puts the point into newPts, so we don't have to do that here. + } } else { @@ -481,7 +477,8 @@ void vtkAppendFilter::AppendArrays(int attributesType, vtkInformationVector** in const auto numberOfInputTuples = inputData->GetNumberOfTuples(); for (vtkIdType id = 0; id < numberOfInputTuples; ++id) { - if (!reallyMergePoints || !dataSet->HasAnyGhostPoints() || + if (attributesType != vtkDataObject::POINT || !reallyMergePoints || + !dataSet->HasAnyGhostPoints() || dataSet->GetGhostArray(vtkDataObject::POINT)->GetValue(id) == 0) { if (globalIds != nullptr)