diff --git a/crates/app/src/app.rs b/crates/app/src/app.rs index d654fc3..5bac78c 100644 --- a/crates/app/src/app.rs +++ b/crates/app/src/app.rs @@ -9,11 +9,11 @@ use log::info; mod loading; mod runner; mod serialize; -mod sssp; mod triangle_count; -runner!(page_rank, graph::page_rank::page_rank, PageRankConfig); -runner!(wcc, graph::wcc::wcc_afforest_dss, WccConfig); +runner!(unweighted: page_rank, graph::page_rank::page_rank, PageRankConfig); +runner!(unweighted: wcc, graph::wcc::wcc_afforest_dss, WccConfig); +runner!(weighted: sssp, graph::sssp::delta_stepping, DeltaSteppingConfig, f32); fn main() -> Result<()> { let args = setup_clap::().run()?; @@ -23,7 +23,7 @@ fn main() -> Result<()> { match args.algorithm { Algorithm::PageRank { config } => page_rank::run(args.args, config)?, - Algorithm::Sssp { config } => sssp::sssp(args.args, config)?, + Algorithm::Sssp { config } => sssp::run(args.args, config)?, Algorithm::TriangleCount { relabel } => triangle_count::triangle_count(args.args, relabel)?, Algorithm::Wcc { config } => wcc::run(args.args, config)?, Algorithm::Loading { diff --git a/crates/app/src/runner.rs b/crates/app/src/runner.rs index 419b66a..d8fe18d 100644 --- a/crates/app/src/runner.rs +++ b/crates/app/src/runner.rs @@ -1,93 +1,134 @@ macro_rules! runner { - ($algo_name:ident, $algo_func:expr, $algo_config:ty) => { + (unweighted: $algo_name:ident, $algo_func:expr, $algo_config:ty) => { mod $algo_name { use graph::prelude::*; + crate::runner!(__entry: $algo_config); + crate::runner!(__run_file_format_all: $algo_config, ()); + crate::runner!(__run_graph_format: $algo_config, ()); + crate::runner!(__bench: $algo_func, $algo_config, DirectedNeighbors, ()); + } + }; - pub(crate) fn run( - args: $crate::CommonArgs, - config: $algo_config, - ) -> ::kommandozeile::Result<()> { - ::log::info!( - "Reading graph ({} bit) from: {:?}", - if args.use_32_bit { "32" } else { "64" }, - args.path - ); + (weighted: $algo_name:ident, $algo_func:expr, $algo_config:ty, $ev_type:ty) => { + mod $algo_name { + use graph::prelude::*; + crate::runner!(__entry: $algo_config); + crate::runner!(__run_file_format_edge_list: $algo_config, $ev_type); + crate::runner!(__run_graph_format: $algo_config, $ev_type); + crate::runner!(__bench: $algo_func, $algo_config, DirectedNeighborsWithValues, $ev_type); + } + }; + + (__entry: $algo_config:ty) => { + pub(crate) fn run( + args: $crate::CommonArgs, + config: $algo_config, + ) -> ::kommandozeile::Result<()> { + ::log::info!( + "Reading graph ({} bit) from: {:?}", + if args.use_32_bit { "32" } else { "64" }, + args.path + ); + + if args.use_32_bit { + run_::(args, config) + } else { + run_::(args, config) + } + } + }; - if args.use_32_bit { - run_::(args, config) - } else { - run_::(args, config) + (__run_file_format_all: $algo_config:ty, $ev_type:ty) => { + fn run_( + args: $crate::CommonArgs, + config: $algo_config, + ) -> ::kommandozeile::Result<()> + where + NI: Idx + ::std::hash::Hash, + { + match args.format { + $crate::FileFormat::EdgeList => { + run__::>(args, config, EdgeListInput::default()) + } + $crate::FileFormat::Graph500 => { + run__::>(args, config, Graph500Input::default()) } } + } + }; - fn run_( - args: $crate::CommonArgs, - config: $algo_config, - ) -> ::kommandozeile::Result<()> - where - NI: Idx + ::std::hash::Hash, - { - match args.format { - $crate::FileFormat::EdgeList => { - run__::>(args, config, EdgeListInput::default()) - } - $crate::FileFormat::Graph500 => { - run__::>(args, config, Graph500Input::default()) - } + (__run_file_format_edge_list: $algo_config:ty, $ev_type:ty) => { + fn run_( + args: $crate::CommonArgs, + config: $algo_config, + ) -> ::kommandozeile::Result<()> + where + NI: Idx + ::std::hash::Hash, + { + match args.format { + $crate::FileFormat::EdgeList => { + run__::>(args, config, EdgeListInput::default()) + } + $crate::FileFormat::Graph500 => { + std::panic!("Graph500 is not supported for weighted graphs") } } + } + }; - fn run__( - args: $crate::CommonArgs, - config: $algo_config, - file_format: Format, - ) -> ::kommandozeile::Result<()> - where - NI: Idx + ::std::hash::Hash, - Format: InputCapabilities, - Format::GraphInput: TryFrom>, - >::GraphInput: Edges, - Error: - From<>>::Error>, - { - match args.graph { - $crate::GraphFormat::CompressedSparseRow => { - run___::, NI, Format>(args, config, file_format) - } - $crate::GraphFormat::AdjacencyList => { - run___::, NI, Format>(args, config, file_format) - } + (__run_graph_format: $algo_config:ty, $ev_type:ty) => { + fn run__( + args: $crate::CommonArgs, + config: $algo_config, + file_format: Format, + ) -> ::kommandozeile::Result<()> + where + NI: Idx + ::std::hash::Hash, + Format: InputCapabilities, + Format::GraphInput: TryFrom>, + >::GraphInput: Edges, + Error: + From<>>::Error>, + { + match args.graph { + $crate::GraphFormat::CompressedSparseRow => { + run___::, NI, Format>(args, config, file_format) + } + $crate::GraphFormat::AdjacencyList => { + run___::, NI, Format>(args, config, file_format) } } + } + }; - fn run___( - args: $crate::CommonArgs, - config: $algo_config, - file_format: Format, - ) -> ::kommandozeile::Result<()> - where - NI: Idx + ::std::hash::Hash, - Format: InputCapabilities, - Format::GraphInput: TryFrom>, - >::GraphInput: Edges, - Error: - From<>>::Error>, - G: Graph + DirectedDegrees + DirectedNeighbors + Sync, - G: TryFrom<(Format::GraphInput, CsrLayout)>, - Error: From<>::Error>, - { - let graph: G = GraphBuilder::new() - .csr_layout(CsrLayout::Sorted) - .file_format(file_format) - .path(args.path) - .build()?; + (__bench: $algo_func:expr, $algo_config:ty, $neighbors_trait:path, $ev_type:ty) => { + fn run___( + args: $crate::CommonArgs, + config: $algo_config, + file_format: Format, + ) -> ::kommandozeile::Result<()> + where + NI: Idx + ::std::hash::Hash, + Format: InputCapabilities, + Format::GraphInput: TryFrom>, + >::GraphInput: Edges, + Error: + From<>>::Error>, + G: Graph + DirectedDegrees + $neighbors_trait + Sync, + G: TryFrom<(Format::GraphInput, CsrLayout)>, + Error: From<>::Error>, + { + let graph: G = GraphBuilder::new() + .csr_layout(CsrLayout::Sorted) + .file_format(file_format) + .path(args.path) + .build()?; - $crate::time(args.runs, args.warmup_runs, || { - $algo_func(&graph, config); - }); + $crate::time(args.runs, args.warmup_runs, || { + $algo_func(&graph, config); + }); - Ok(()) - } + Ok(()) } }; } diff --git a/crates/app/src/sssp.rs b/crates/app/src/sssp.rs deleted file mode 100644 index 063d1b0..0000000 --- a/crates/app/src/sssp.rs +++ /dev/null @@ -1,116 +0,0 @@ -use graph::prelude::*; - -use log::info; - -use super::*; - -pub(crate) fn sssp(args: CommonArgs, config: DeltaSteppingConfig) -> Result<()> { - let CommonArgs { - path, - format: _, - graph: _, - use_32_bit, - runs, - warmup_runs, - } = args; - - info!( - "Reading graph ({} bit) from: {:?}", - if use_32_bit { "32" } else { "64" }, - path - ); - - if use_32_bit { - run::(path, runs, warmup_runs, config) - } else { - run::(path, runs, warmup_runs, config) - } -} - -fn run( - path: PathBuf, - runs: usize, - warmup_runs: usize, - config: DeltaSteppingConfig, -) -> Result<()> { - let graph: DirectedCsrGraph = GraphBuilder::new() - .csr_layout(CsrLayout::Sorted) - .file_format(EdgeListInput::default()) - .path(path) - .build()?; - - time(runs, warmup_runs, || { - delta_stepping(&graph, config); - }); - - Ok(()) -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::CsrLayout; - use crate::GraphBuilder; - - #[test] - fn test_dijkstra() { - let gdl = "(a:A) - (b:B) - (c:C) - (d:D) - (e:E) - (f:F) - (a)-[{cost: 4.0 }]->(b) - (a)-[{cost: 2.0 }]->(c) - (b)-[{cost: 5.0 }]->(c) - (b)-[{cost: 10.0 }]->(d) - (c)-[{cost: 3.0 }]->(e) - (d)-[{cost: 11.0 }]->(f) - (e)-[{cost: 4.0 }]->(d)"; - - let graph: DirectedCsrGraph = GraphBuilder::new() - .csr_layout(CsrLayout::Deduplicated) - .gdl_str::(gdl) - .build() - .unwrap(); - - let actual: Vec = dijkstra(&graph, 0); - let expected: Vec = vec![0.0, 4.0, 2.0, 9.0, 5.0, 20.0]; - - assert_eq!(actual, expected); - } - - fn dijkstra(graph: &DirectedCsrGraph, start_node: usize) -> Vec { - const INF: f32 = f32::MAX; - use float_ord::FloatOrd; - use std::cmp::Reverse; - - let start = Instant::now(); - - let node_count = graph.node_count().index(); - - let mut distances = Vec::with_capacity(node_count); - distances.resize_with(node_count, || FloatOrd(INF)); - distances[start_node.index()] = FloatOrd(0.0); - - let mut queue = std::collections::BinaryHeap::new(); - queue.push(Reverse((FloatOrd(0.0), NI::new(start_node)))); - - while let Some(Reverse((cost, node))) = queue.pop() { - if cost == distances[node.index()] { - for Target { target, value } in graph.out_neighbors_with_values(node) { - let new_distance = cost.0 + value; - if new_distance < distances[target.index()].0 { - let new_distance = FloatOrd(new_distance); - distances[target.index()] = new_distance; - queue.push(Reverse((new_distance, *target))); - } - } - } - } - - info!("Computed Dijkstra in {:?}", start.elapsed()); - - distances.into_iter().map(|d| d.0).collect() - } -}