VTK
|
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