#[cfg(feature = "mpi-support")]
pub use crate::partitioning::{
PartitionMap, PartitionerConfig, PartitionerError,
metrics::{edge_cut, replication_factor},
partition,
};
#[cfg(feature = "mpi-support")]
pub use crate::partitioning::graph_traits::PartitionableGraph;
#[cfg(feature = "mpi-support")]
pub fn native_partition<G>(
graph: &G,
cfg: &PartitionerConfig,
) -> Result<PartitionMap<G::VertexId>, PartitionerError>
where
G: PartitionableGraph<VertexId = usize> + Sync,
{
partition(graph, cfg)
}
#[cfg(feature = "mpi-support")]
pub fn partition_edge_cut<G>(graph: &G, pm: &PartitionMap<G::VertexId>) -> usize
where
G: PartitionableGraph,
G::VertexId: PartialOrd + Eq + std::hash::Hash + Copy + 'static,
{
edge_cut(graph, pm)
}
#[cfg(feature = "mpi-support")]
pub fn partition_replication_factor<G>(graph: &G, pm: &PartitionMap<G::VertexId>) -> f64
where
G: PartitionableGraph,
G::VertexId: Eq + std::hash::Hash + Copy + Sync + 'static,
{
replication_factor(graph, pm)
}
#[cfg(feature = "mpi-support")]
pub fn partition_metrics<G>(g: &G, pm: &PartitionMap<G::VertexId>) -> (usize, f64)
where
G: PartitionableGraph,
G::VertexId: PartialOrd + Eq + std::hash::Hash + Copy + Sync + 'static,
{
use std::collections::HashMap;
use std::collections::hash_map::Entry;
let mut cut = 0usize;
let mut mask: HashMap<G::VertexId, u64> = HashMap::new();
use rayon::iter::ParallelIterator;
for (u, v) in g.edges().collect::<Vec<_>>() {
let pu = pm.part_of(u);
let pv = pm.part_of(v);
if pu != pv {
cut += 1;
}
let mu = 1u64 << (pu % 64);
let mv = 1u64 << (pv % 64);
match mask.entry(u) {
Entry::Occupied(mut e) => *e.get_mut() |= mu,
Entry::Vacant(e) => {
e.insert(mu);
}
}
match mask.entry(v) {
Entry::Occupied(mut e) => *e.get_mut() |= mv,
Entry::Vacant(e) => {
e.insert(mv);
}
}
}
let rf = if mask.is_empty() {
0.0
} else {
let total: u64 = mask.values().map(|m| m.count_ones() as u64).sum();
total as f64 / mask.len() as f64
};
(cut, rf)
}
#[cfg(all(
feature = "mpi-support",
any(debug_assertions, feature = "check-graph-edges")
))]
pub fn debug_check_edges_contract<G>(g: &G)
where
G: PartitionableGraph,
G::VertexId: PartialOrd + Eq + std::hash::Hash + Copy + std::fmt::Debug + 'static,
{
use rayon::iter::ParallelIterator;
use std::collections::HashSet;
let mut seen = HashSet::new();
for (u, v) in g.edges().collect::<Vec<_>>() {
debug_assert!(u < v, "edges() must yield u < v; got ({:?},{:?})", u, v);
debug_assert!(u != v, "edges() must not yield self-loops");
let key = (u, v);
debug_assert!(
seen.insert(key),
"duplicate edge from edges(): ({:?},{:?})",
u,
v
);
}
}