/*========================================================================= Program: Visualization Toolkit Module: vtkBlockDistribution.h 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. =========================================================================*/ /* * Copyright (C) 2008 The Trustees of Indiana University. * Use, modification and distribution is subject to the Boost Software * License, Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt) */ /** * @class vtkBlockDistribution * @brief A helper class that manages a block distribution of N elements of data. * * * */ #ifndef vtkBlockDistribution_h #define vtkBlockDistribution_h class vtkBlockDistribution { public: /** * Create a block distribution with N elements on P processors. */ vtkBlockDistribution(vtkIdType N, vtkIdType P); /** * Retrieves the number of elements for which this block distribution was * built. */ vtkIdType GetNumElements() { return this->NumElements; } /** * Retrieves the number of processors for which this block * distribution was built. */ vtkIdType GetNumProcessors() { return this->NumProcessors; } /** * Get the block size for the processor with the given rank. This is the * number of elements that the processor will store. */ vtkIdType GetBlockSize(vtkIdType rank); /** * Retrieve the process number in [0, GetNumProcessors()) where the element * with the given global index will be located. */ vtkIdType GetProcessorOfElement(vtkIdType globalIndex); /** * Retrieve the local index (offset) on the processor determined by * GetProcessorOfElement that refers to the given global index. */ vtkIdType GetLocalIndexOfElement(vtkIdType globalIndex); /** * Retrieve the first global index stored on the processor with the given * rank. */ vtkIdType GetFirstGlobalIndexOnProcessor(vtkIdType rank); /** * Retrieve the global index associated with the given local index on the * processor with the given rank. */ vtkIdType GetGlobalIndex(vtkIdType localIndex, vtkIdType rank); private: vtkIdType NumElements; vtkIdType NumProcessors; }; // ---------------------------------------------------------------------- inline vtkBlockDistribution::vtkBlockDistribution(vtkIdType N, vtkIdType P) : NumElements(N) , NumProcessors(P) { } // ---------------------------------------------------------------------- inline vtkIdType vtkBlockDistribution::GetBlockSize(vtkIdType rank) { return (this->NumElements / this->NumProcessors) + (rank < this->NumElements % this->NumProcessors ? 1 : 0); } // ---------------------------------------------------------------------- inline vtkIdType vtkBlockDistribution::GetProcessorOfElement(vtkIdType globalIndex) { vtkIdType smallBlockSize = this->NumElements / this->NumProcessors; vtkIdType cutoffProcessor = this->NumElements % this->NumProcessors; vtkIdType cutoffIndex = cutoffProcessor * (smallBlockSize + 1); if (globalIndex < cutoffIndex) { return globalIndex / (smallBlockSize + 1); } else { return cutoffProcessor + (globalIndex - cutoffIndex) / smallBlockSize; } } // ---------------------------------------------------------------------- inline vtkIdType vtkBlockDistribution::GetLocalIndexOfElement(vtkIdType globalIndex) { vtkIdType rank = this->GetProcessorOfElement(globalIndex); return globalIndex - this->GetFirstGlobalIndexOnProcessor(rank); } // ---------------------------------------------------------------------- inline vtkIdType vtkBlockDistribution::GetFirstGlobalIndexOnProcessor(vtkIdType rank) { vtkIdType estimate = rank * (this->NumElements / this->NumProcessors + 1); vtkIdType cutoffProcessor = this->NumElements % this->NumProcessors; if (rank < cutoffProcessor) { return estimate; } else { return estimate - (rank - cutoffProcessor); } } // ---------------------------------------------------------------------- inline vtkIdType vtkBlockDistribution::GetGlobalIndex(vtkIdType localIndex, vtkIdType rank) { return this->GetFirstGlobalIndexOnProcessor(rank) + localIndex; } #endif // VTK-HeaderTest-Exclude: vtkBlockDistribution.h