VTK
dox/Infovis/Parallel/vtkPBGLGraphAdapter.h
Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Program:   Visualization Toolkit
00004   Module:    vtkPBGLGraphAdapter.h
00005 
00006   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
00007   All rights reserved.
00008   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
00009 
00010      This software is distributed WITHOUT ANY WARRANTY; without even
00011      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
00012      PURPOSE.  See the above copyright notice for more information.
00013 
00014 =========================================================================*/
00015 /*
00016  * Copyright (C) 2008 The Trustees of Indiana University.
00017  * Use, modification and distribution is subject to the Boost Software
00018  * License, Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt)
00019  */
00027 #ifndef __vtkPBGLGraphAdapter_h
00028 #define __vtkPBGLGraphAdapter_h
00029 
00030 #include "vtkBoostGraphAdapter.h" // for the sequential BGL adapters
00031 
00032 //BTX
00033 #include <boost/graph/use_mpi.hpp>
00034 #include <boost/graph/distributed/mpi_process_group.hpp>
00035 #include <boost/graph/properties.hpp>
00036 #include <boost/graph/parallel/container_traits.hpp>
00037 #include <boost/property_map/parallel/local_property_map.hpp>
00038 #include <boost/property_map/parallel/distributed_property_map.hpp>
00039 #include <boost/serialization/base_object.hpp>
00040 #include <boost/functional/hash.hpp>
00041 //ETX
00042 
00043 #include "vtkPBGLDistributedGraphHelper.h"
00044 #include "vtkVariantBoostSerialization.h"
00045 
00046 namespace boost {
00047 
00048 // Define specializations of class template property_map for
00049 // vtkDirectedGraph and vtkUndirectedGraph, based on the
00050 // specialization for vtkGraph.
00051 #define SUBCLASS_PROPERTY_MAP_SPECIALIZATIONS(Property)         \
00052   template<>                                                    \
00053   struct property_map<vtkDirectedGraph *, Property>             \
00054     : property_map<vtkGraph *, Property> { };                   \
00055                                                                 \
00056   template<>                                                    \
00057   struct property_map<vtkUndirectedGraph *, Property>           \
00058     : property_map<vtkGraph *, Property> { };                   \
00059                                                                 \
00060   template<>                                                    \
00061   struct property_map<vtkDirectedGraph * const, Property>       \
00062     : property_map<vtkGraph *, Property> { };                   \
00063                                                                 \
00064   template<>                                                    \
00065   struct property_map<vtkUndirectedGraph * const, Property>     \
00066     : property_map<vtkGraph *, Property> { }
00067 
00068   // Property map from a vertex descriptor to the owner of the vertex
00069   struct vtkVertexOwnerMap
00070   {
00071     // Default-construct an empty (useless!) vertex-owner map
00072     vtkVertexOwnerMap() : helper(0) { }
00073 
00074     // Construct a vertex-owner map for a specific vtkGraph
00075     explicit vtkVertexOwnerMap(vtkGraph* graph)
00076       : helper(graph? graph->GetDistributedGraphHelper() : 0) { }
00077 
00078     // The distributed graph helper that will aid in mapping vertices
00079     // to their owners.
00080     vtkDistributedGraphHelper *helper;
00081   };
00082 
00083   // Property map traits for the vertex-owner map
00084   template<>
00085   struct property_traits<vtkVertexOwnerMap>
00086   {
00087     typedef vtkIdType value_type;
00088     typedef vtkIdType reference;
00089     typedef vtkIdType key_type;
00090     typedef readable_property_map_tag category;
00091   };
00092 
00093   // Retrieve the owner of the given vertex (the key)
00094   inline property_traits<vtkVertexOwnerMap>::reference
00095   get(
00096     vtkVertexOwnerMap owner_map,
00097     property_traits<vtkVertexOwnerMap>::key_type key)
00098   {
00099     return owner_map.helper->GetVertexOwner(key);
00100   }
00101 
00102    // State that the vertex owner property map of a vtkGraph is the
00103    // vtkVertexOwnerMap
00104    template<>
00105    struct property_map<vtkGraph*, vertex_owner_t>
00106    {
00107      typedef vtkVertexOwnerMap type;
00108      typedef vtkVertexOwnerMap const_type;
00109    };
00110 
00111   SUBCLASS_PROPERTY_MAP_SPECIALIZATIONS(vertex_owner_t);
00112 
00113     // Retrieve the vertex-owner property map from a vtkGraph
00114    inline vtkVertexOwnerMap
00115    get(vertex_owner_t, vtkGraph* graph)
00116    {
00117      return vtkVertexOwnerMap(graph);
00118    }
00119 
00120   // Property map from a vertex descriptor to the local descriptor of
00121   // the vertex
00122   struct vtkVertexLocalMap
00123   {
00124     // Default-construct an empty (useless!) vertex-local map
00125     vtkVertexLocalMap() : helper(0) { }
00126 
00127     // Construct a vertex-local map for a specific vtkGraph
00128     explicit vtkVertexLocalMap(vtkGraph* graph)
00129       : helper(graph? graph->GetDistributedGraphHelper() : 0) { }
00130 
00131     // The distributed graph helper that will aid in mapping vertices
00132     // to their locals.
00133     vtkDistributedGraphHelper *helper;
00134   };
00135 
00136   // Property map traits for the vertex-local map
00137   template<>
00138   struct property_traits<vtkVertexLocalMap>
00139   {
00140     typedef int value_type;
00141     typedef int reference;
00142     typedef vtkIdType key_type;
00143     typedef readable_property_map_tag category;
00144   };
00145 
00146   // Retrieve the local descriptor of the given vertex (the key)
00147   inline property_traits<vtkVertexLocalMap>::reference
00148   get(
00149     vtkVertexLocalMap local_map,
00150     property_traits<vtkVertexLocalMap>::key_type key)
00151   {
00152     return local_map.helper->GetVertexIndex(key);
00153   }
00154 
00155    // State that the vertex local property map of a vtkGraph is the
00156    // vtkVertexLocalMap
00157    template<>
00158    struct property_map<vtkGraph*, vertex_local_t>
00159    {
00160      typedef vtkVertexLocalMap type;
00161      typedef vtkVertexLocalMap const_type;
00162    };
00163 
00164   SUBCLASS_PROPERTY_MAP_SPECIALIZATIONS(vertex_local_t);
00165 
00166     // Retrieve the vertex-local property map from a vtkGraph
00167    inline vtkVertexLocalMap
00168    get(vertex_local_t, vtkGraph* graph)
00169    {
00170      return vtkVertexLocalMap(graph);
00171    }
00172 
00173    // Map from vertex descriptor to (owner, local descriptor)
00174    struct vtkVertexGlobalMap
00175    {
00176      vtkVertexGlobalMap() : helper(0) { }
00177 
00178      explicit vtkVertexGlobalMap(vtkGraph* graph)
00179        : helper(graph? graph->GetDistributedGraphHelper() : 0) { }
00180 
00181      vtkDistributedGraphHelper *helper;
00182    };
00183 
00184    template<>
00185    struct property_traits<vtkVertexGlobalMap>
00186    {
00187      typedef std::pair<int, vtkIdType> value_type;
00188      typedef value_type reference;
00189      typedef vtkIdType key_type;
00190      typedef readable_property_map_tag category;
00191    };
00192 
00193    inline property_traits<vtkVertexGlobalMap>::reference
00194    get(
00195      vtkVertexGlobalMap global_map,
00196      property_traits<vtkVertexGlobalMap>::key_type key)
00197    {
00198      return std::pair<int,vtkIdType>(global_map.helper->GetVertexOwner(key),
00199                                         global_map.helper->GetVertexIndex(key));
00200    }
00201 
00202     //
00203    template<>
00204    struct property_map<vtkGraph*, vertex_global_t>
00205    {
00206      typedef vtkVertexGlobalMap type;
00207      typedef vtkVertexGlobalMap const_type;
00208    };
00209 
00210   SUBCLASS_PROPERTY_MAP_SPECIALIZATIONS(vertex_global_t);
00211 
00212    inline vtkVertexGlobalMap
00213    get(vertex_global_t, vtkGraph* graph)
00214    {
00215      return vtkVertexGlobalMap(graph);
00216    }
00217 
00218    // Map from edge descriptor to (owner, local descriptor)
00219    struct vtkEdgeGlobalMap
00220    {
00221      vtkEdgeGlobalMap() : helper(0) { }
00222 
00223      explicit vtkEdgeGlobalMap(vtkGraph* graph)
00224        : helper(graph? graph->GetDistributedGraphHelper() : 0) { }
00225 
00226      vtkDistributedGraphHelper *helper;
00227    };
00228 
00229    template<>
00230    struct property_traits<vtkEdgeGlobalMap>
00231    {
00232      typedef std::pair<int, vtkIdType> value_type;
00233      typedef value_type reference;
00234      typedef vtkEdgeType key_type;
00235      typedef readable_property_map_tag category;
00236    };
00237 
00238    inline property_traits<vtkEdgeGlobalMap>::reference
00239    get(
00240      vtkEdgeGlobalMap global_map,
00241      property_traits<vtkEdgeGlobalMap>::key_type key)
00242    {
00243      return std::pair<int, vtkIdType>
00244               (global_map.helper->GetEdgeOwner(key.Id), key.Id);
00245    }
00246 
00247    //
00248    template<>
00249    struct property_map<vtkGraph*, edge_global_t>
00250    {
00251      typedef vtkEdgeGlobalMap type;
00252      typedef vtkEdgeGlobalMap const_type;
00253    };
00254 
00255   SUBCLASS_PROPERTY_MAP_SPECIALIZATIONS(edge_global_t);
00256 
00257    inline vtkEdgeGlobalMap
00258    get(edge_global_t, vtkGraph* graph)
00259    {
00260      return vtkEdgeGlobalMap(graph);
00261    }
00262 
00263 #undef SUBCLASS_PROPERTY_MAP_SPECIALIZATIONS
00264 
00265   //===========================================================================
00266   // Hash functions
00267   template<>
00268   struct hash<vtkEdgeType>
00269   {
00270     std::size_t operator()(const vtkEdgeType& edge) const
00271     {
00272       return hash_value(edge.Id);
00273     }
00274   };
00275 
00276 } // namespace boost
00277 
00278 //----------------------------------------------------------------------------
00279 // Extract the process group from a vtkGraph
00280 //----------------------------------------------------------------------------
00281 
00282 namespace boost { namespace graph { namespace parallel {
00283   template<>
00284   struct process_group_type<vtkGraph *>
00285   {
00286     typedef boost::graph::distributed::mpi_process_group type;
00287   };
00288 
00289   template<>
00290   struct process_group_type<vtkDirectedGraph *>
00291     : process_group_type<vtkGraph *> { };
00292 
00293   template<>
00294   struct process_group_type<vtkUndirectedGraph *>
00295     : process_group_type<vtkGraph *> { };
00296 
00297   template<>
00298   struct process_group_type<vtkDirectedGraph * const>
00299     : process_group_type<vtkDirectedGraph *> { };
00300 
00301   template<>
00302   struct process_group_type<vtkUndirectedGraph * const>
00303     : process_group_type<vtkUndirectedGraph *> { };
00304 } } } // end namespace boost::graph::parallel
00305 
00306 boost::graph::distributed::mpi_process_group process_group(vtkGraph *graph);
00307 
00308 inline boost::graph::distributed::mpi_process_group
00309 process_group(vtkDirectedGraph *graph)
00310 {
00311   return process_group(static_cast<vtkGraph *>(graph));
00312 }
00313 
00314 inline boost::graph::distributed::mpi_process_group
00315 process_group(vtkUndirectedGraph *graph)
00316 {
00317   return process_group(static_cast<vtkGraph *>(graph));
00318 }
00319 
00320 //----------------------------------------------------------------------------
00321 // Serialization support for simple VTK structures
00322 //----------------------------------------------------------------------------
00323 
00324 //----------------------------------------------------------------------------
00325 template<typename Archiver>
00326 void serialize(Archiver& ar, vtkEdgeBase& edge, const unsigned int)
00327 {
00328   ar & edge.Id;
00329 }
00330 
00331 template<typename Archiver>
00332 void serialize(Archiver& ar, vtkOutEdgeType& edge, const unsigned int)
00333 {
00334   ar & boost::serialization::base_object<vtkEdgeBase>(edge)
00335      & edge.Target;
00336 }
00337 
00338 template<typename Archiver>
00339 void serialize(Archiver& ar, vtkInEdgeType& edge, const unsigned int)
00340 {
00341   ar & boost::serialization::base_object<vtkEdgeBase>(edge)
00342      & edge.Source;
00343 }
00344 
00345 template<typename Archiver>
00346 void serialize(Archiver& ar, vtkEdgeType& edge, const unsigned int)
00347 {
00348   ar & boost::serialization::base_object<vtkEdgeBase>(edge)
00349      & edge.Source
00350      & edge.Target;
00351 }
00352 
00353 //----------------------------------------------------------------------------
00354 // Simplified tools to build distributed property maps
00355 //----------------------------------------------------------------------------
00356 
00358 
00363 typedef boost::local_property_map<boost::graph::distributed::mpi_process_group,
00364                                   boost::vtkVertexGlobalMap,
00365                                   boost::vtkGraphIndexMap>
00366   vtkGraphDistributedVertexIndexMap;
00368 
00370 
00371 inline vtkGraphDistributedVertexIndexMap
00372 MakeDistributedVertexIndexMap(vtkGraph* graph)
00373 {
00374   vtkDistributedGraphHelper *helper = graph->GetDistributedGraphHelper();
00375   if (!helper)
00376     {
00377     vtkErrorWithObjectMacro(graph, "A vtkGraph without a distributed graph helper is not a distributed graph");
00378     return vtkGraphDistributedVertexIndexMap();
00379     }
00381 
00382   vtkPBGLDistributedGraphHelper *pbglHelper
00383     = vtkPBGLDistributedGraphHelper::SafeDownCast(helper);
00384   if (!pbglHelper)
00385     {
00386     vtkErrorWithObjectMacro(graph, "A vtkGraph with a non-Parallel BGL distributed graph helper cannot be used with the Parallel BGL");
00387     return vtkGraphDistributedVertexIndexMap();
00388     }
00389 
00390   return vtkGraphDistributedVertexIndexMap(pbglHelper->GetProcessGroup(),
00391                                            boost::vtkVertexGlobalMap(graph),
00392                                            boost::vtkGraphIndexMap());
00393 }
00394 
00396 
00398 template<typename DataArray>
00399 struct vtkDistributedVertexPropertyMapType
00400 {
00401   typedef boost::parallel::distributed_property_map<
00402             boost::graph::distributed::mpi_process_group,
00403             boost::vtkVertexGlobalMap,
00404             DataArray*> type;
00405 };
00407 
00409 
00411 template<typename DataArray>
00412 inline typename vtkDistributedVertexPropertyMapType<DataArray>::type
00413 MakeDistributedVertexPropertyMap(vtkGraph* graph, DataArray* array)
00414 {
00415   typedef typename vtkDistributedVertexPropertyMapType<DataArray>::type MapType;
00417 
00418   vtkDistributedGraphHelper *helper = graph->GetDistributedGraphHelper();
00419   if (!helper)
00420     {
00421     vtkErrorWithObjectMacro(graph, "A vtkGraph without a distributed graph helper is not a distributed graph");
00422     return MapType();
00423     }
00424 
00425   vtkPBGLDistributedGraphHelper *pbglHelper
00426     = vtkPBGLDistributedGraphHelper::SafeDownCast(helper);
00427   if (!pbglHelper)
00428     {
00429     vtkErrorWithObjectMacro(graph, "A vtkGraph with a non-Parallel BGL distributed graph helper cannot be used with the Parallel BGL");
00430     return MapType();
00431     }
00432 
00433   return MapType(pbglHelper->GetProcessGroup(),
00434                  boost::vtkVertexGlobalMap(graph),
00435                  array);
00436 }
00437 
00439 
00441 template<typename DataArray>
00442 struct vtkDistributedEdgePropertyMapType
00443 {
00444   typedef boost::parallel::distributed_property_map<
00445             boost::graph::distributed::mpi_process_group,
00446             boost::vtkEdgeGlobalMap,
00447             DataArray*> type;
00448 };
00450 
00452 
00454 template<typename DataArray>
00455 inline typename vtkDistributedEdgePropertyMapType<DataArray>::type
00456 MakeDistributedEdgePropertyMap(vtkGraph* graph, DataArray* array)
00457 {
00458   typedef typename vtkDistributedEdgePropertyMapType<DataArray>::type MapType;
00460 
00461   vtkDistributedGraphHelper *helper = graph->GetDistributedGraphHelper();
00462   if (!helper)
00463     {
00464     vtkErrorWithObjectMacro(graph, "A vtkGraph without a distributed graph helper is not a distributed graph");
00465     return MapType();
00466     }
00467 
00468   vtkPBGLDistributedGraphHelper *pbglHelper
00469     = vtkPBGLDistributedGraphHelper::SafeDownCast(helper);
00470   if (!pbglHelper)
00471     {
00472     vtkErrorWithObjectMacro(graph, "A vtkGraph with a non-Parallel BGL distributed graph helper cannot be used with the Parallel BGL");
00473     return MapType();
00474     }
00475 
00476   return MapType(pbglHelper->GetProcessGroup(),
00477                  boost::vtkEdgeGlobalMap(graph),
00478                  array);
00479 }
00480 
00481 #endif // __vtkPBGLGraphAdapter_h
00482 // VTK-HeaderTest-Exclude: vtkPBGLGraphAdapter.h