00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00027 #ifndef __vtkPBGLGraphAdapter_h
00028 #define __vtkPBGLGraphAdapter_h
00029
00030 #include "vtkBoostGraphAdapter.h"
00031
00032
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
00040
00041 #include "vtkPBGLDistributedGraphHelper.h"
00042 #include "vtkVariantBoostSerialization.h"
00043
00044 namespace boost {
00045
00046
00047
00048
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
00067 struct vtkVertexOwnerMap
00068 {
00069
00070 vtkVertexOwnerMap() : helper(0) { }
00071
00072
00073 explicit vtkVertexOwnerMap(vtkGraph* graph)
00074 : helper(graph? graph->GetDistributedGraphHelper() : 0) { }
00075
00076
00077
00078 vtkDistributedGraphHelper *helper;
00079 };
00080
00081
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
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
00101
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
00112 inline vtkVertexOwnerMap
00113 get(vertex_owner_t, vtkGraph* graph)
00114 {
00115 return vtkVertexOwnerMap(graph);
00116 }
00117
00118
00119
00120 struct vtkVertexLocalMap
00121 {
00122
00123 vtkVertexLocalMap() : helper(0) { }
00124
00125
00126 explicit vtkVertexLocalMap(vtkGraph* graph)
00127 : helper(graph? graph->GetDistributedGraphHelper() : 0) { }
00128
00129
00130
00131 vtkDistributedGraphHelper *helper;
00132 };
00133
00134
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
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
00154
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
00165 inline vtkVertexLocalMap
00166 get(vertex_local_t, vtkGraph* graph)
00167 {
00168 return vtkVertexLocalMap(graph);
00169 }
00170
00171
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
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
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 }
00275
00276
00277
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 } } }
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
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
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