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