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