Skip to content

Commit 0b5b9dc

Browse files
committed
---
yaml --- r: 12934 b: refs/heads/master c: a79f517 h: refs/heads/master v: v3
1 parent 4d2dd17 commit 0b5b9dc

File tree

2 files changed

+104
-7
lines changed

2 files changed

+104
-7
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: a785f3fc95752dc2cfced5e7ccef710e189acb9c
2+
refs/heads/master: a79f5174ea1be8a90d7e02957ebbf7837916931b
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 4a81779abd786ff22d71434c6d9a5917ea4cdfff
55
refs/heads/try: 2898dcc5d97da9427ac367542382b6239d9c0bbf

trunk/src/test/bench/graph500-bfs.rs

Lines changed: 103 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import comm::*;
1616
import int::abs;
1717

1818
type node_id = i64;
19-
type graph = [map::set<node_id>];
19+
type graph = [[node_id]];
2020
type bfs_result = [node_id];
2121

2222
iface queue<T: send> {
@@ -114,7 +114,15 @@ fn make_graph(N: uint, edges: [(node_id, node_id)]) -> graph {
114114
true
115115
}
116116

117-
graph
117+
graph.map() {|v|
118+
let mut neighbors = [];
119+
v.each_key() {|u|
120+
neighbors += [u];
121+
true
122+
};
123+
124+
neighbors
125+
}
118126
}
119127

120128
#[doc="Returns a vector of all the parents in the BFS tree rooted at key.
@@ -132,7 +140,7 @@ fn bfs(graph: graph, key: node_id) -> bfs_result {
132140
while Q.size() > 0u {
133141
let t = Q.pop_front();
134142

135-
graph[t].each_key() {|k|
143+
graph[t].each() {|k|
136144
if marks[k] == -1 {
137145
marks[k] = t;
138146
Q.add_back(k);
@@ -144,6 +152,75 @@ fn bfs(graph: graph, key: node_id) -> bfs_result {
144152
vec::from_mut(marks)
145153
}
146154

155+
#[doc="A parallel version of the bfs function."]
156+
fn pbfs(graph: graph, key: node_id) -> bfs_result {
157+
// This works by doing functional updates of a color vector.
158+
159+
enum color {
160+
white,
161+
// node_id marks which node turned this gray/black.
162+
// the node id later becomes the parent.
163+
gray(node_id),
164+
black(node_id)
165+
};
166+
167+
let mut colors = vec::from_fn(graph.len()) {|i|
168+
if i as node_id == key {
169+
gray(key)
170+
}
171+
else {
172+
white
173+
}
174+
};
175+
176+
fn is_gray(c: color) -> bool {
177+
alt c {
178+
gray(_) { true }
179+
_ { false }
180+
}
181+
}
182+
183+
let mut i = 0u;
184+
while par::any(colors, is_gray) {
185+
// Do the BFS.
186+
log(info, #fmt("PBFS iteration %?", i));
187+
i += 1u;
188+
colors = par::mapi(colors) {|i, c, copy colors|
189+
let c : color = c;
190+
alt c {
191+
white {
192+
let i = i as node_id;
193+
194+
let neighbors = graph[i];
195+
196+
let mut color = white;
197+
198+
neighbors.each() {|k|
199+
if is_gray(colors[k]) {
200+
color = gray(k);
201+
false
202+
}
203+
else { true }
204+
};
205+
206+
color
207+
}
208+
gray(parent) { black(parent) }
209+
black(parent) { black(parent) }
210+
}
211+
}
212+
}
213+
214+
// Convert the results.
215+
par::map(colors) {|c|
216+
alt c {
217+
white { -1 }
218+
black(parent) { parent }
219+
_ { fail "Found remaining gray nodes in BFS" }
220+
}
221+
}
222+
}
223+
147224
#[doc="Performs at least some of the validation in the Graph500 spec."]
148225
fn validate(edges: [(node_id, node_id)],
149226
root: node_id, tree: bfs_result) -> bool {
@@ -252,7 +329,7 @@ fn main() {
252329
let stop = time::precise_time_s();
253330

254331
let mut total_edges = 0u;
255-
vec::each(graph) {|edges| total_edges += edges.size(); true };
332+
vec::each(graph) {|edges| total_edges += edges.len(); true };
256333

257334
io::stdout().write_line(#fmt("Generated graph with %? edges in %? seconds.",
258335
total_edges / 2u,
@@ -261,7 +338,7 @@ fn main() {
261338
let root = 0;
262339

263340
let start = time::precise_time_s();
264-
let bfs_tree = bfs(graph, root);
341+
let bfs_tree = pbfs(graph, root);
265342
let stop = time::precise_time_s();
266343

267344
io::stdout().write_line(#fmt("BFS completed in %? seconds.",
@@ -342,6 +419,7 @@ like map or alli."]
342419
fn map_slices<A: send, B: send>(xs: [A], f: fn~(uint, [A]) -> B) -> [B] {
343420
let len = xs.len();
344421
if len < min_granularity {
422+
log(info, "small slice");
345423
// This is a small vector, fall back on the normal map.
346424
[f(0u, xs)]
347425
}
@@ -352,6 +430,7 @@ fn map_slices<A: send, B: send>(xs: [A], f: fn~(uint, [A]) -> B) -> [B] {
352430

353431
let mut futures = [];
354432
let mut base = 0u;
433+
log(info, "spawning tasks");
355434
while base < len {
356435
let slice = vec::slice(xs, base,
357436
uint::min(len, base + items_per_task));
@@ -360,6 +439,7 @@ fn map_slices<A: send, B: send>(xs: [A], f: fn~(uint, [A]) -> B) -> [B] {
360439
}];
361440
base += items_per_task;
362441
}
442+
log(info, "tasks spawned");
363443

364444
futures.map() {|ys|
365445
ys.get()
@@ -370,7 +450,16 @@ fn map_slices<A: send, B: send>(xs: [A], f: fn~(uint, [A]) -> B) -> [B] {
370450
#[doc="A parallel version of map."]
371451
fn map<A: send, B: send>(xs: [A], f: fn~(A) -> B) -> [B] {
372452
vec::concat(map_slices(xs) {|_base, slice|
373-
map(slice, f)
453+
vec::map(slice, f)
454+
})
455+
}
456+
457+
#[doc="A parallel version of mapi."]
458+
fn mapi<A: send, B: send>(xs: [A], f: fn~(uint, A) -> B) -> [B] {
459+
vec::concat(map_slices(xs) {|base, slice|
460+
slice.mapi() {|i, x|
461+
f(i + base, x)
462+
}
374463
})
375464
}
376465

@@ -382,4 +471,12 @@ fn alli<A: send>(xs: [A], f: fn~(uint, A) -> bool) -> bool {
382471
}
383472
}) {|x| x }
384473
}
474+
475+
#[doc="Returns true if the function holds for any elements in the vector."]
476+
fn any<A: send>(xs: [A], f: fn~(A) -> bool) -> bool {
477+
vec::any(map_slices(xs) {|_base, slice|
478+
slice.any(f)
479+
}) {|x| x }
480+
}
481+
385482
}

0 commit comments

Comments
 (0)