/*========================================================================= Program: Visualization Toolkit Module: vtkDistributedGraphHelper.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 vtkDistributedGraphHelper * @brief helper for the vtkGraph class * that allows the graph to be distributed across multiple memory spaces. * * * A distributed graph helper can be attached to an empty vtkGraph * object to turn the vtkGraph into a distributed graph, whose * vertices and edges are distributed across several different * processors. vtkDistributedGraphHelper is an abstract class. Use a * subclass of vtkDistributedGraphHelper, such as * vtkPBGLDistributedGraphHelper, to build distributed graphs. * * The distributed graph helper provides facilities used by vtkGraph * to communicate with other processors that store other parts of the * same distributed graph. The only user-level functionality provided * by vtkDistributedGraphHelper involves this communication among * processors and the ability to map between "distributed" vertex and * edge IDs and their component parts (processor and local index). For * example, the Synchronize() method provides a barrier that allows * all processors to catch up to the same point in the code before any * processor can leave that Synchronize() call. For example, one would * call Synchronize() after adding many edges to a distributed graph, * so that all processors can handle the addition of inter-processor * edges and continue, after the Synchronize() call, with a consistent * view of the distributed graph. For more information about * manipulating (distributed) graphs, see the vtkGraph documentation. * * @sa * vtkGraph */ #ifndef vtkDistributedGraphHelper_h #define vtkDistributedGraphHelper_h #include "vtkCommonDataModelModule.h" // For export macro #include "vtkObject.h" class vtkDistributedGraphHelperInternals; struct vtkEdgeType; class vtkGraph; class vtkVariant; class vtkVariantArray; class vtkInformationIntegerKey; // .NAME vtkVertexPedigreeIdDistributionFunction - The type of a // function used to determine how to distribute vertex pedigree IDs // across processors in a vtkGraph. The pedigree ID distribution // function takes the pedigree ID of the vertex and a user-supplied // void pointer and returns a hash value V. A vertex with that // pedigree ID will reside on processor V % P, where P is the number // of processors. This type is used in conjunction with the // vtkDistributedGraphHelper class. typedef vtkIdType (*vtkVertexPedigreeIdDistribution)(const vtkVariant& pedigreeId, void* userData); class VTKCOMMONDATAMODEL_EXPORT vtkDistributedGraphHelper : public vtkObject { public: vtkTypeMacro(vtkDistributedGraphHelper, vtkObject); void PrintSelf(ostream& os, vtkIndent indent) override; /** * Returns owner of vertex v, by extracting top ceil(log2 P) bits of v. */ vtkIdType GetVertexOwner(vtkIdType v) const; /** * Returns local index of vertex v, by masking off top ceil(log2 P) bits of v. */ vtkIdType GetVertexIndex(vtkIdType v) const; /** * Returns owner of edge with ID e_id, by extracting top ceil(log2 P) bits of e_id. */ vtkIdType GetEdgeOwner(vtkIdType e_id) const; /** * Returns local index of edge with ID e_id, by masking off top ceil(log2 P) * bits of e_id. */ vtkIdType GetEdgeIndex(vtkIdType e_id) const; /** * Builds a distributed ID consisting of the given owner and the local ID. */ vtkIdType MakeDistributedId(int owner, vtkIdType local); /** * Set the pedigreeId -> processor distribution function that determines * how vertices are distributed when they are associated with * pedigree ID, which must be a unique label such as a URL or IP * address. If a nullptr function pointer is provided, the default * hashed distribution will be used. */ void SetVertexPedigreeIdDistribution(vtkVertexPedigreeIdDistribution Func, void* userData); /** * Determine which processor owns the vertex with the given pedigree ID. */ vtkIdType GetVertexOwnerByPedigreeId(const vtkVariant& pedigreeId); /** * Synchronizes all of the processors involved in this distributed * graph, so that all processors have a consistent view of the * distributed graph for the computation that follows. This routine * should be invoked after adding new edges into the distributed * graph, so that other processors will see those edges (or their * corresponding back-edges). */ virtual void Synchronize() = 0; /** * Clones the distributed graph helper, returning another * distributed graph helper of the same kind that can be used in * another vtkGraph. */ virtual vtkDistributedGraphHelper* Clone() = 0; //@{ /** * Information Keys that distributed graphs can append to attribute arrays * to flag them as containing distributed IDs. These can be used to let * routines that migrate vertices (either repartitioning or collecting graphs * to single nodes) to also modify the ids contained in the attribute arrays * to maintain consistency. */ static vtkInformationIntegerKey* DISTRIBUTEDVERTEXIDS(); static vtkInformationIntegerKey* DISTRIBUTEDEDGEIDS(); //@} protected: vtkDistributedGraphHelper(); ~vtkDistributedGraphHelper() override; /** * Add a vertex, optionally with properties, to the distributed graph. * If vertex is non-nullptr, it will be set * to the newly-added (or found) vertex. Note that if propertyArr is * non-nullptr and the vertex data contains pedigree IDs, a vertex will * only be added if there is no vertex with that pedigree ID. */ virtual void AddVertexInternal(vtkVariantArray* propertyArr, vtkIdType* vertex) = 0; /** * Add a vertex with the given pedigreeId to the distributed graph. If * vertex is non-nullptr, it will receive the newly-created vertex. */ virtual void AddVertexInternal(const vtkVariant& pedigreeId, vtkIdType* vertex) = 0; /** * Add an edge (u, v) to the distributed graph. The edge may be directed * undirected. If edge is non-null, it will receive the newly-created edge. * If propertyArr is non-null, it specifies the properties that will be * attached to the newly-created edge. */ virtual void AddEdgeInternal( vtkIdType u, vtkIdType v, bool directed, vtkVariantArray* propertyArr, vtkEdgeType* edge) = 0; /** * Adds an edge (u, v) and returns the new edge. The graph edge may * or may not be directed, depending on the given flag. If edge is * non-null, it will receive the newly-created edge. uPedigreeId is * the pedigree ID of vertex u, which will be added if no vertex by * that pedigree ID exists. If propertyArr is non-null, it specifies * the properties that will be attached to the newly-created edge. */ virtual void AddEdgeInternal(const vtkVariant& uPedigreeId, vtkIdType v, bool directed, vtkVariantArray* propertyArr, vtkEdgeType* edge) = 0; /** * Adds an edge (u, v) and returns the new edge. The graph edge may * or may not be directed, depending on the given flag. If edge is * non-null, it will receive the newly-created edge. vPedigreeId is * the pedigree ID of vertex u, which will be added if no vertex * with that pedigree ID exists. If propertyArr is non-null, it specifies * the properties that will be attached to the newly-created edge. */ virtual void AddEdgeInternal(vtkIdType u, const vtkVariant& vPedigreeId, bool directed, vtkVariantArray* propertyArr, vtkEdgeType* edge) = 0; /** * Adds an edge (u, v) and returns the new edge. The graph edge may * or may not be directed, depending on the given flag. If edge is * non-null, it will receive the newly-created edge. uPedigreeId is * the pedigree ID of vertex u and vPedigreeId is the pedigree ID of * vertex u, each of which will be added if no vertex by that * pedigree ID exists. If propertyArr is non-null, it specifies * the properties that will be attached to the newly-created edge. */ virtual void AddEdgeInternal(const vtkVariant& uPedigreeId, const vtkVariant& vPedigreeId, bool directed, vtkVariantArray* propertyArr, vtkEdgeType* edge) = 0; /** * Try to find the vertex with the given pedigree ID. Returns the * vertex ID if the vertex is found, or -1 if there is no vertex * with that pedigree ID. */ virtual vtkIdType FindVertex(const vtkVariant& pedigreeId) = 0; /** * Determine the source and target of the edge with the given * ID. Used internally by vtkGraph::GetSourceVertex and * vtkGraph::GetTargetVertex. */ virtual void FindEdgeSourceAndTarget(vtkIdType id, vtkIdType* source, vtkIdType* target) = 0; /** * Attach this distributed graph helper to the given graph. This will * be called as part of vtkGraph::SetDistributedGraphHelper. */ virtual void AttachToGraph(vtkGraph* graph); /** * The graph to which this distributed graph helper is already attached. */ vtkGraph* Graph; /** * The distribution function used to map a pedigree ID to a processor. */ vtkVertexPedigreeIdDistribution VertexDistribution; /** * Extra, user-specified data to be passed into the distribution function. */ void* VertexDistributionUserData; /** * Bit mask to speed up decoding graph info {owner,index} */ vtkIdType signBitMask; /** * Bit mask to speed up decoding graph info {owner,index} */ vtkIdType highBitShiftMask; /** * Number of bits required to represent # of processors (owner) */ int procBits; /** * Number of bits required to represent {vertex,edge} index */ int indexBits; private: vtkDistributedGraphHelper(const vtkDistributedGraphHelper&) = delete; void operator=(const vtkDistributedGraphHelper&) = delete; friend class vtkGraph; }; #endif // vtkDistributedGraphHelper_h