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 */ 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