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/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
00042
00043 #include "vtkPBGLDistributedGraphHelper.h"
00044 #include "vtkVariantBoostSerialization.h"
00045
00046 namespace boost {
00047
00048
00049
00050
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
00069 struct vtkVertexOwnerMap
00070 {
00071
00072 vtkVertexOwnerMap() : helper(0) { }
00073
00074
00075 explicit vtkVertexOwnerMap(vtkGraph* graph)
00076 : helper(graph? graph->GetDistributedGraphHelper() : 0) { }
00077
00078
00079
00080 vtkDistributedGraphHelper *helper;
00081 };
00082
00083
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
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
00103
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
00114 inline vtkVertexOwnerMap
00115 get(vertex_owner_t, vtkGraph* graph)
00116 {
00117 return vtkVertexOwnerMap(graph);
00118 }
00119
00120
00121
00122 struct vtkVertexLocalMap
00123 {
00124
00125 vtkVertexLocalMap() : helper(0) { }
00126
00127
00128 explicit vtkVertexLocalMap(vtkGraph* graph)
00129 : helper(graph? graph->GetDistributedGraphHelper() : 0) { }
00130
00131
00132
00133 vtkDistributedGraphHelper *helper;
00134 };
00135
00136
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
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
00156
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
00167 inline vtkVertexLocalMap
00168 get(vertex_local_t, vtkGraph* graph)
00169 {
00170 return vtkVertexLocalMap(graph);
00171 }
00172
00173
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 vtkstd::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 vtkstd::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
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 vtkstd::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 vtkstd::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
00267 template<>
00268 struct hash<vtkEdgeType>
00269 {
00270 vtkstd::size_t operator()(const vtkEdgeType& edge) const
00271 {
00272 return hash_value(edge.Id);
00273 }
00274 };
00275
00276 }
00277
00278
00279
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 } } }
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
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
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