Added most of the Graph500 validation routine. It's very slow.
This commit is contained in:
parent
f5b9ebffa0
commit
d485f23a1a
1 changed files with 109 additions and 4 deletions
|
@ -11,11 +11,12 @@ import std::map::hashmap;
|
|||
import std::deque;
|
||||
import std::deque::t;
|
||||
import io::writer_util;
|
||||
import vec::extensions;
|
||||
import comm::*;
|
||||
import int::abs;
|
||||
|
||||
type node_id = i64;
|
||||
type graph = [map::set<node_id>];
|
||||
type bfs_result = [node_id];
|
||||
|
||||
iface queue<T: send> {
|
||||
fn add_back(T);
|
||||
|
@ -118,7 +119,7 @@ fn make_graph(N: uint, edges: [(node_id, node_id)]) -> graph {
|
|||
#[doc="Returns a vector of all the parents in the BFS tree rooted at key.
|
||||
|
||||
Nodes that are unreachable have a parent of -1."]
|
||||
fn bfs(graph: graph, key: node_id) -> [node_id] {
|
||||
fn bfs(graph: graph, key: node_id) -> bfs_result {
|
||||
let marks : [mut node_id]
|
||||
= vec::to_mut(vec::from_elem(vec::len(graph), -1));
|
||||
|
||||
|
@ -142,6 +143,101 @@ fn bfs(graph: graph, key: node_id) -> [node_id] {
|
|||
vec::from_mut(marks)
|
||||
}
|
||||
|
||||
#[doc="Performs at least some of the validation in the Graph500 spec."]
|
||||
fn validate(edges: [(node_id, node_id)],
|
||||
root: node_id, tree: bfs_result) -> bool {
|
||||
// There are 5 things to test. Below is code for each of them.
|
||||
|
||||
// 1. The BFS tree is a tree and does not contain cycles.
|
||||
//
|
||||
// We do this by iterating over the tree, and tracing each of the
|
||||
// parent chains back to the root. While we do this, we also
|
||||
// compute the levels for each node.
|
||||
|
||||
log(info, "Verifying tree structure...");
|
||||
|
||||
let mut status = true;
|
||||
let level = tree.map() {|parent|
|
||||
let mut parent = parent;
|
||||
let mut path = [];
|
||||
|
||||
if parent == -1 {
|
||||
// This node was not in the tree.
|
||||
-1
|
||||
}
|
||||
else {
|
||||
while parent != root {
|
||||
if vec::contains(path, parent) {
|
||||
status = false;
|
||||
}
|
||||
|
||||
path += [parent];
|
||||
parent = tree[parent];
|
||||
}
|
||||
|
||||
// The length of the path back to the root is the current
|
||||
// level.
|
||||
path.len() as int
|
||||
}
|
||||
};
|
||||
|
||||
if !status { ret status }
|
||||
|
||||
// 2. Each tree edge connects vertices whose BFS levels differ by
|
||||
// exactly one.
|
||||
|
||||
log(info, "Verifying tree edges...");
|
||||
|
||||
let status = tree.alli() {|k, parent|
|
||||
if parent != root && parent != -1 {
|
||||
level[parent] == level[k] - 1
|
||||
}
|
||||
else {
|
||||
true
|
||||
}
|
||||
};
|
||||
|
||||
if !status { ret status }
|
||||
|
||||
// 3. Every edge in the input list has vertices with levels that
|
||||
// differ by at most one or that both are not in the BFS tree.
|
||||
|
||||
log(info, "Verifying graph edges...");
|
||||
|
||||
let status = edges.all() {|e|
|
||||
let (u, v) = e;
|
||||
|
||||
abs(level[u] - level[v]) <= 1
|
||||
};
|
||||
|
||||
if !status { ret status }
|
||||
|
||||
// 4. The BFS tree spans an entire connected component's vertices.
|
||||
|
||||
// This is harder. We'll skip it for now...
|
||||
|
||||
// 5. A node and its parent are joined by an edge of the original
|
||||
// graph.
|
||||
|
||||
log(info, "Verifying tree and graph edges...");
|
||||
|
||||
let status = tree.alli() {|u, v|
|
||||
if v == -1 || u as int == root {
|
||||
true
|
||||
}
|
||||
else {
|
||||
log(info, #fmt("Checking for %? or %?",
|
||||
(u, v), (v, u)));
|
||||
edges.contains((u as int, v)) || edges.contains((v, u as int))
|
||||
}
|
||||
};
|
||||
|
||||
if !status { ret status }
|
||||
|
||||
// If we get through here, all the tests passed!
|
||||
true
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let scale = 14u;
|
||||
|
||||
|
@ -163,10 +259,19 @@ fn main() {
|
|||
total_edges / 2u,
|
||||
stop - start));
|
||||
|
||||
let root = 0;
|
||||
|
||||
let start = time::precise_time_s();
|
||||
let bfs_tree = bfs(graph, 0);
|
||||
let bfs_tree = bfs(graph, root);
|
||||
let stop = time::precise_time_s();
|
||||
|
||||
io::stdout().write_line(#fmt("BFS completed in %? seconds.",
|
||||
stop - start));
|
||||
|
||||
let start = time::precise_time_s();
|
||||
assert(validate(graph, edges, root, bfs_tree));
|
||||
let stop = time::precise_time_s();
|
||||
|
||||
io::stdout().write_line(#fmt("Validation completed in %? seconds.",
|
||||
stop - start));
|
||||
}
|
Loading…
Reference in a new issue