Skip to content

Commit

Permalink
Add adjacency list backed graph implementation (#113)
Browse files Browse the repository at this point in the history
* Move Target into mod.rs

* Add adjacency list structure

* Add AdjacencyList target methods

* From impl for AdjacencyList

* Impl directed graph traits for DirectedALGraph

* Support DirectedALGraph in GraphBuilder

* Reformat imports in csr module

* Remove unused newtype

* Add from_edge_list benches for adjacency list

* Add benchmark for linear edge traversal

* Implement UndirectedALGraph

* Support Graph500 input for AL graphs

* Add new graphs to the prelude

* Add more logging to adjacency list creation

* Add graph format to graph_app common arguments

* Impl Edges for Graph500 input

* Run PageRank app on both graph formats

* Generate page_rank app using macro

* Generate wcc app using macro

* Generate sssp app using macro

* Rename macro and identifiers

* Fix format
  • Loading branch information
s1ck authored Oct 27, 2023
1 parent 3c9b1d7 commit 1e62bc7
Show file tree
Hide file tree
Showing 19 changed files with 975 additions and 371 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ rayon = "1.7.0"
reqwest = { version = "0.11", features = ["stream"] }
serde_json = "1.0.103"
serde = { version = "1.0.174", features = ["derive"] }
tap = "1.0.1"
tempfile = "3.7.0"
thiserror = "1.0.44"
tokio = { version = "1.29.1", features = ["full"], default-features = true }
Expand Down
24 changes: 18 additions & 6 deletions crates/app/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@ use std::{path::PathBuf, time::Instant};

use graph::prelude::*;

use crate::runner::gen_runner;
use kommandozeile::*;
use log::info;

mod loading;
mod page_rank;
mod runner;
mod serialize;
mod sssp;
mod triangle_count;
mod wcc;

gen_runner!(directed+unweighted: page_rank, graph::page_rank::page_rank, PageRankConfig);
gen_runner!(directed+unweighted: wcc, graph::wcc::wcc_afforest_dss, WccConfig);
gen_runner!(directed+weighted: sssp, graph::sssp::delta_stepping, DeltaSteppingConfig, f32);

fn main() -> Result<()> {
let args = setup_clap::<Args>().run()?;
Expand All @@ -19,10 +22,10 @@ fn main() -> Result<()> {
env_logger::init();

match args.algorithm {
Algorithm::PageRank { config } => page_rank::page_rank(args.args, config)?,
Algorithm::Sssp { config } => sssp::sssp(args.args, config)?,
Algorithm::PageRank { config } => page_rank::run(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::wcc(args.args, config)?,
Algorithm::Wcc { config } => wcc::run(args.args, config)?,
Algorithm::Loading {
undirected,
weighted,
Expand Down Expand Up @@ -56,6 +59,9 @@ struct CommonArgs {
#[clap(short, long, value_enum, default_value_t = FileFormat::EdgeList)]
format: FileFormat,

#[clap(short, long, value_enum, default_value_t = GraphFormat::CompressedSparseRow)]
graph: GraphFormat,

#[clap(long)]
use_32_bit: bool,

Expand All @@ -66,6 +72,12 @@ struct CommonArgs {
warmup_runs: usize,
}

#[derive(clap::ValueEnum, Debug, Clone)]
enum GraphFormat {
CompressedSparseRow,
AdjacencyList,
}

#[derive(clap::ValueEnum, Debug, Clone)]
enum FileFormat {
EdgeList,
Expand Down
67 changes: 0 additions & 67 deletions crates/app/src/page_rank.rs

This file was deleted.

136 changes: 136 additions & 0 deletions crates/app/src/runner.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
macro_rules! gen_runner {
(directed+unweighted: $algo_name:ident, $algo_func:expr, $algo_config:ty) => {
mod $algo_name {
use graph::prelude::*;
crate::gen_runner!(__entry: $algo_config);
crate::gen_runner!(__run_file_format_all: $algo_config, ());
crate::gen_runner!(__run_graph_format: $algo_config, ());
crate::gen_runner!(__bench: $algo_func, $algo_config, DirectedNeighbors<NI>, ());
}
};

(directed+weighted: $algo_name:ident, $algo_func:expr, $algo_config:ty, $ev_type:ty) => {
mod $algo_name {
use graph::prelude::*;
crate::gen_runner!(__entry: $algo_config);
crate::gen_runner!(__run_file_format_edge_list: $algo_config, $ev_type);
crate::gen_runner!(__run_graph_format: $algo_config, $ev_type);
crate::gen_runner!(__bench: $algo_func, $algo_config, DirectedNeighborsWithValues<NI, $ev_type>, $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_::<u32>(args, config)
} else {
run_::<u64>(args, config)
}
}
};

(__run_file_format_all: $algo_config:ty, $ev_type:ty) => {
fn run_<NI: Idx>(
args: $crate::CommonArgs,
config: $algo_config,
) -> ::kommandozeile::Result<()>
where
NI: Idx + ::std::hash::Hash,
{
match args.format {
$crate::FileFormat::EdgeList => {
run__::<NI, EdgeListInput<NI, $ev_type>>(args, config, EdgeListInput::default())
}
$crate::FileFormat::Graph500 => {
run__::<NI, Graph500Input<NI>>(args, config, Graph500Input::default())
}
}
}
};

(__run_file_format_edge_list: $algo_config:ty, $ev_type:ty) => {
fn run_<NI: Idx>(
args: $crate::CommonArgs,
config: $algo_config,
) -> ::kommandozeile::Result<()>
where
NI: Idx + ::std::hash::Hash,
{
match args.format {
$crate::FileFormat::EdgeList => {
run__::<NI, EdgeListInput<NI, $ev_type>>(args, config, EdgeListInput::default())
}
$crate::FileFormat::Graph500 => {
std::panic!("Graph500 is not supported for weighted graphs")
}
}
}
};

(__run_graph_format: $algo_config:ty, $ev_type:ty) => {
fn run__<NI, Format>(
args: $crate::CommonArgs,
config: $algo_config,
file_format: Format,
) -> ::kommandozeile::Result<()>
where
NI: Idx + ::std::hash::Hash,
Format: InputCapabilities<NI>,
Format::GraphInput: TryFrom<InputPath<::std::path::PathBuf>>,
<Format as InputCapabilities<NI>>::GraphInput: Edges<NI = NI, EV = $ev_type>,
Error:
From<<Format::GraphInput as TryFrom<InputPath<::std::path::PathBuf>>>::Error>,
{
match args.graph {
$crate::GraphFormat::CompressedSparseRow => {
run___::<DirectedCsrGraph<NI, (), $ev_type>, NI, Format>(args, config, file_format)
}
$crate::GraphFormat::AdjacencyList => {
run___::<DirectedALGraph<NI, (), $ev_type>, NI, Format>(args, config, file_format)
}
}
}
};

(__bench: $algo_func:expr, $algo_config:ty, $neighbors_trait:path, $ev_type:ty) => {
fn run___<G, NI, Format>(
args: $crate::CommonArgs,
config: $algo_config,
file_format: Format,
) -> ::kommandozeile::Result<()>
where
NI: Idx + ::std::hash::Hash,
Format: InputCapabilities<NI>,
Format::GraphInput: TryFrom<InputPath<::std::path::PathBuf>>,
<Format as InputCapabilities<NI>>::GraphInput: Edges<NI = NI, EV = $ev_type>,
Error:
From<<Format::GraphInput as TryFrom<InputPath<::std::path::PathBuf>>>::Error>,
G: Graph<NI> + DirectedDegrees<NI> + $neighbors_trait + Sync,
G: TryFrom<(Format::GraphInput, CsrLayout)>,
Error: From<<G as TryFrom<(Format::GraphInput, CsrLayout)>>::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);
});

Ok(())
}
};
}

pub(crate) use gen_runner;
1 change: 1 addition & 0 deletions crates/app/src/serialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub(crate) fn serialize(args: CommonArgs, undirected: bool, output: PathBuf) ->
let CommonArgs {
path,
format: _,
graph: _,
runs: _,
warmup_runs: _,
use_32_bit,
Expand Down
115 changes: 0 additions & 115 deletions crates/app/src/sssp.rs

This file was deleted.

Loading

0 comments on commit 1e62bc7

Please sign in to comment.