-
Notifications
You must be signed in to change notification settings - Fork 2
Edge Centric and GAS
GraphBrew keeps the existing GAPBS-derived programs as the canonical vertex/frontier baselines and adds edge-centric schedules as separate CPU implementations. Gather-Apply-Scatter (GAS) is added only where its phases match the algorithm rather than being forced onto every graph problem.
The executable contract is:
bench/contracts/edge_gas_algorithms.json
Validate it with:
make check-edge-contracts
make check-edge-contract-profiles| Algorithm | Edge-centric | GAS | Required structure |
|---|---|---|---|
| BFS | yes | no | sparse push plus dense pull |
| BC | yes | no | forward BFS plus ordered backward gather |
| CC | yes | yes | edge linking; optional active min-label propagation |
| CC-SV | yes | no separate GAS | atomic hooking plus pointer jumping |
| PR | yes | yes | incoming gather and residual convergence |
| PR-SPMV | yes | no separate GAS | deterministic synchronous gather |
| SSSP | yes | yes | Delta-Stepping edge baseline; active-set GAS reference |
| TC | yes | no | oriented edges plus sorted adjacency intersection |
bfs_p and tc_p are specialized consumers, not separate semantic
algorithms. Canonical baselines remain isolated in bench/src/; edge drivers
live in bench/src_edge/, GAS drivers in bench/src_gas/, and simulation
drivers in bench/src_sim/. Existing src_sim files are legacy instrumented
forks and are not the semantic contract authority; some have already drifted
from canonical source/verifier behavior. New cache-simulation binaries must
instantiate shared kernels through access hooks instead of copying algorithm
bodies.
- Existing verifier functions remain authoritative.
- BFS parent identity may vary, but it must be a valid shortest-path tree.
- CC labels are representative-invariant; compare partitions, not label bytes.
- BC backward accumulation preserves stored CSR successor order because the
verifier compares normalized floats at
FLT_EPSILONscale. - SSSP distances and TC counts are exact.
- PR variants pass the existing residual threshold.
- Kernel and verifier
SourcePickerinstances must select the same source.
- CSR/source order serves push and scatter.
- CSC/destination order serves pull and Gather.
- Undirected graphs expose both all directed CSR entries and an oriented one-entry-per-edge stream.
- Edge-stream construction is outside timed trials unless conversion itself is the benchmark.
- Dense gathers use destination ownership and deterministic segmented reduction.
- Sparse traversals use thread-local frontier queues and CAS/min updates.
- Work counters are informational; verifier-defined output is the cross-thread correctness gate.
bench/include/graphbrew/edge/ provides the common CPU schedule layer:
- source-major and destination-major flat views preserve logical
(source, destination)edge identity; - non-owning
EdgeStreamviews reject temporary flat graphs at compile time; - ordinal partitions cover every directed entry exactly once, while oriented
undirected iteration retains only
source < destination; -
Frontiercombines sorted sparse IDs with a dense bit map;FrontierBuilderatomically deduplicates parallel producers into thread-local queues; - integer min/max/CAS helpers report whether an update won;
- edge-map access policies are invoked concurrently and must be thread-safe.
Run the primitive and thread-count checks with:
make check-edge-primitivesView construction is intentionally measured separately from algorithm trials:
make edge_view_benchmark
OMP_NUM_THREADS=4 bench/bin/edge_view_benchmark -g 18The first four edge binaries share algorithm headers under
bench/include/graphbrew/algorithms/:
-
pr_spmv_edgeis synchronous Jacobi PageRank. Each iteration freezes outgoing contributions, then performs destination-owned incoming gathers in stored edge order. -
pr_edgeis an explicitly asynchronous destination-owned PageRank schedule. Cross-owner contributions use atomic floats, so immediate visibility is data-race-free. Iteration counts may differ by thread count; the existing residual verifier is the semantic gate. -
cc_edgepreserves Afforest neighbor sampling, skips proven sampled prefixes, then performs edge-balanced atomic union. Directed edges connect endpoints for weak connectivity; symmetric graphs use one oriented edge. -
cc_sv_edgeperforms CAS-safe monotone root hooking followed by atomic shortcutting.
All flat views are built before BenchmarkKernel, so trial timing excludes
representation conversion. The paired matrix runs every declared profile,
including directed, disconnected, synthetic, and dangling-vertex cases,
against the canonical binary and the edge binary at OMP 1/2/4/8:
make check-edge-denseThe matrix gates verifier-defined output. It does not require equal PageRank iterations or bit-identical asynchronous scores.
-
bfs_edgekeeps one sparse-plus-bitmap frontier. Sparse phases push outgoing edges with CAS parent claims; dense phases own destinations and pull from the incoming flat view, so directed traversal uses true predecessors. The canonical alpha/beta switching and scout/awake work metrics are preserved. -
sssp_edgeretains Delta-Stepping rather than scanning every edge. One persistent OpenMP team processes the shared current bin, relaxes only active vertices' weighted outgoing ranges, fuses small same-bin thread-local work, and selects the globally smallest remaining bin. - weighted outgoing flattening preserves
(source, destination, weight)and is built before timed trials.
Both kernel and verifier use separately constructed, identically seeded
SourcePicker instances. Run all registered graph/thread profiles plus paired
multi-trial source checks with:
make check-edge-frontierThe current matrix passes 36/36 verifier-backed edge trials at OMP 1/2/4/8.
-
bc_edgeruns sampled-source Brandes with level-synchronous outgoing edge push, CAS depth discovery, and atomic double path counts. Backward dependency gathers run deepest-to-source and preserve each vertex's stored outgoing CSR order so the existing float-epsilon verifier remains authoritative. -
tc_edgeoptionally applies the canonical degree-relabel heuristic before timing, then processes one oriented undirected edge and intersects the two sorted adjacency prefixes below its middle vertex. Each triangle is counted exactly once; TC is not represented as scalar GAS.
Run the canonical/edge matrix, paired BC sources, and triangle/no-triangle profiles with:
make check-edge-irregularThe current matrix passes 32/32 verifier-backed edge trials at OMP 1/2/4/8.
bench/include/graphbrew/gas/executor.h defines synchronous supersteps over
destination-major Gather and source-major Scatter views:
- Gather programs provide an identity, associative combine, and per-edge contribution.
- Apply returns the new state, changed flag, and convergence contribution.
- Scatter cannot mutate graph/state; it only requests destination activation.
- Dense mode applies every vertex and swaps a reusable next-state buffer.
- Active mode touches only sorted active vertices and incident edges, scatters before committing updates, and preserves inactive state in place.
- Convergence combines in deterministic node/active order.
- Program methods are const and must be reentrant because Gather/Apply/Scatter execute concurrently.
Frontier builders adapt if the OpenMP team grows between supersteps and retain a safe overflow path. Run synchronous, active-only, mixed-schedule, thread-growth, and validation tests with:
make check-gas-runtime-
pr_gasruns dense synchronous incoming Gather, damp/base Apply, and residual Scatter activation. Dense scheduling remains authoritative, so the Scatter pass is intentionally measured even though its frontier is informational. -
cc_gasperforms active minimum-label propagation over a symmetric weak-neighbor view. Directed graphs include both outgoing and incoming neighbors; changed labels activate adjacent vertices. -
sssp_gasis explicitly an active-set Bellman-Ford-class reference: destinations gatherdist[source] + weight, Apply min, and changed vertices activate outgoing neighbors. Delta-Stepping remains the optimized edge baseline; the accepted-doption is CLI compatibility and is not hidden inside GAS.
Run canonical/GAS verifier profiles and paired SSSP sources with:
make check-gasThe current matrix passes 48/48 GAS trials at OMP 1/2/4/8.
There is no separate GAS binary for BFS (first-parent GAS is artificial), BC
(forward and reverse phases differ), PR-SPMV (already the useful synchronous
Gather/Apply core), TC (requires sorted two-list intersection), or MEMCPY
(not a graph algorithm).
Build every implementation with:
make edge-all gas-allRun the complete contract, primitive, canonical-control, edge, GAS, source-pair, thread-count, topology, and repeatability qualification with:
make check-edge-gasThe gate covers directed asymmetric, undirected isolated, path, star, disconnected, weighted isolated/path/star, synthetic power-law-like, triangle, no-triangle, and dangling-vertex cases. It currently passes:
- 112 dense-edge verifier cells;
- 60 frontier-edge verifier trials;
- 56 irregular-edge verifier trials;
- 84 GAS verifier trials;
- 22 two-trial repeatability checks across all 11 edge/GAS binaries;
- canonical smoke/source controls plus primitive and GAS-runtime tests.
Only verifier-defined semantic output is gated. Iteration counts, active work, and examined-edge counters remain informational because legal schedules differ.
The contract records each algorithm's work class, balance policy, ownership, and GAS work class where applicable. Validate those claims against the source with:
make check-edge-structureThe audit binds direction-optimized BFS, active Delta-Stepping bins and fusion,
sampled Brandes, oriented TC intersection, destination-segment PageRank,
Afforest/SV, and dense/active GAS schedules to their implementations. It also
checks conversion/relabel placement before BenchmarkKernel and rejects
unapproved critical sections; only the guarded FrontierBuilder overflow path is
allowed.
Generate an on-demand verified comparison report with:
make report-edge-gas-performance
# or customize:
python3 scripts/experiments/edge_gas_report.py \
--threads 8 --trials 5 --synthetic-scale 14The JSON reports local average time, nominal input-edge rate, canonical-relative
speedup, per-trial and median time, and the structural work/balance/ownership
contract. Source-driven algorithms use the same deterministic SourcePicker
sequence instead of a potentially degenerate fixed source. It explicitly has
hard_speed_gate=false; nominal input-edge rate is not actual examined-edge
work.
The 2026-07-21 four-thread audit used repeated interleaved median trials. This is a shared host, so unmodified near-parity variants remain inconclusive. The research-aligned optimization pass brought three previously stable regressions to parity:
| Variant | Canonical-relative speed | Assessment |
|---|---|---|
bfs_edge |
1.08x | parity / slight win |
cc_edge |
0.94x | near parity |
tc_edge |
1.01x | parity |
cc_sv_edge |
0.58-0.63x | vertex baseline wins |
bc_edge |
0.61-1.37x | inconclusive |
sssp_edge |
0.48-1.56x | inconclusive |
pr_spmv_edge |
0.80-1.44x | inconclusive |
pr_edge |
0.41-1.91x | inconclusive |
| GAS variants | below 0.27x | reference-only |
The successful changes match the cited research: Beamer/GAPBS queue+bitmap DOBFS, Afforest's whole-row giant-component skip, and dynamic forward triangle intersection scheduling. CC-SV now uses direct CSR rows and has near-parity single-thread cost, but parallel root-hook contention remains; the canonical implementation uses racy plain writes while the edge version preserves atomic root hooking. BC, PR, PR-SPMV, and SSSP still require a quiescent/dedicated-host rerun before any performance verdict or tuning.
- BFS: sparse queue production, bitmap materialization, dynamic incoming pull, and sparse/dense switching are schedule primitives; sorting is not.
- Afforest CC: fixed neighbor sampling and row-level skip of the sampled giant component are the critical flow controls, not a full oriented-edge scan.
-
TC: sorted
SET_OPSintersection is already the right compute primitive; the missing gain is work-aware scheduling across oriented source rows. - CC-SV: atomic root CAS/min plus pointer jumping is the remaining hot path and directly matches the D2 atomic-RMW blocker. This is the strongest edge-centric hardware acceleration candidate.
- PowerGraph/GAS: https://www.usenix.org/conference/osdi12/technical-sessions/presentation/gonzalez
- X-Stream: https://dl.acm.org/doi/10.1145/2517349.2522740
- Ligra: https://jshun.csail.mit.edu/ligra.shtml
- Direction-Optimizing BFS: https://people.eecs.berkeley.edu/~krste/papers/beamer-sc2012.pdf
- GraphIt: https://graphit-lang.org/
- GAPBS: https://arxiv.org/abs/1508.03619