From 689216456b6250d9c0e479cea3eedbf40e512f8a Mon Sep 17 00:00:00 2001 From: Cory Quammen Date: Wed, 25 Oct 2017 17:13:35 -0400 Subject: [PATCH 1/2] Ensure that all processes in subgroup invoke collectives In a distributed dataset where some processes have datasets with no points or cells, not all processes would invoke the same collective communication operations in vtkPKdTree::CreateGlobalDataArrayBounds(). This would lead to a deadlock in pvserver where processes waited for messages that never came. This is solved by distributing the maximum number of cell and point data arrays to all processes so that they all participate in the collective operations. --- Filters/Parallel/vtkPKdTree.cxx | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/Filters/Parallel/vtkPKdTree.cxx b/Filters/Parallel/vtkPKdTree.cxx index 563dd4d6576..20bafb3946b 100644 --- a/Filters/Parallel/vtkPKdTree.cxx +++ b/Filters/Parallel/vtkPKdTree.cxx @@ -2529,6 +2529,19 @@ int vtkPKdTree::AllocateAndZeroFieldArrayMinMax() this->GetDataSet(set)->GetPointData()->GetNumberOfArrays(); } + // Find maximum number of cell and point arrays. Set this number on all processes. + // This handles the case where some processes have datasets with no cell or point + // arrays, which may happen if a dataset on a process has no points or cells. + if (this->NumProcesses > 1) + { + int tmpNumArrays[2], maxNumArrays[2]; + tmpNumArrays[0] = iNumCellArrays; + tmpNumArrays[1] = iNumPointArrays; + this->Controller->AllReduce(tmpNumArrays, maxNumArrays, 2, vtkCommunicator::MAX_OP); + iNumCellArrays = maxNumArrays[0]; + iNumPointArrays = maxNumArrays[1]; + } + this->FreeFieldArrayMinMax(); if (iNumCellArrays > 0) @@ -2828,11 +2841,11 @@ int vtkPKdTree::CreateGlobalDataArrayBounds() if (this->NumProcesses > 1) { - this->SubGroup->ReduceMin(this->CellDataMin, this->CellDataMin, nc, 0); - this->SubGroup->Broadcast(this->CellDataMin, nc, 0); + this->SubGroup->ReduceMin(this->CellDataMin, this->CellDataMin, this->NumCellArrays, 0); + this->SubGroup->Broadcast(this->CellDataMin, this->NumCellArrays, 0); - this->SubGroup->ReduceMax(this->CellDataMax, this->CellDataMax, nc, 0); - this->SubGroup->Broadcast(this->CellDataMax, nc, 0); + this->SubGroup->ReduceMax(this->CellDataMax, this->CellDataMax, this->NumCellArrays, 0); + this->SubGroup->Broadcast(this->CellDataMax, this->NumCellArrays, 0); } } @@ -2858,11 +2871,11 @@ int vtkPKdTree::CreateGlobalDataArrayBounds() if (this->NumProcesses > 1) { - this->SubGroup->ReduceMin(this->PointDataMin, this->PointDataMin, np, 0); - this->SubGroup->Broadcast(this->PointDataMin, np, 0); + this->SubGroup->ReduceMin(this->PointDataMin, this->PointDataMin, this->NumPointArrays, 0); + this->SubGroup->Broadcast(this->PointDataMin, this->NumPointArrays, 0); - this->SubGroup->ReduceMax(this->PointDataMax, this->PointDataMax, np, 0); - this->SubGroup->Broadcast(this->PointDataMax, np, 0); + this->SubGroup->ReduceMax(this->PointDataMax, this->PointDataMax, this->NumPointArrays, 0); + this->SubGroup->Broadcast(this->PointDataMax, this->NumPointArrays, 0); } } -- GitLab From 2645784e82043afd5f6d24edf7b883d0486db432 Mon Sep 17 00:00:00 2001 From: Cory Quammen Date: Wed, 25 Oct 2017 17:52:10 -0400 Subject: [PATCH 2/2] Remove error message in vtkPKdTree::VolumeBounds() The code executes fine when this condition is encountered, so the error message has been converted to a code comment instead. --- Filters/Parallel/vtkPKdTree.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Filters/Parallel/vtkPKdTree.cxx b/Filters/Parallel/vtkPKdTree.cxx index 20bafb3946b..5431816affb 100644 --- a/Filters/Parallel/vtkPKdTree.cxx +++ b/Filters/Parallel/vtkPKdTree.cxx @@ -292,7 +292,7 @@ bool vtkPKdTree::VolumeBounds(double* volBounds) int number_of_datasets = this->GetNumberOfDataSets(); if (number_of_datasets == 0) { - VTKERROR("NumberOfDatasets = 0, cannot determine volume bounds."); + // Cannot determine volume bounds. return false; } -- GitLab