Skip to content

Commit 0d6dbec

Browse files
committed
---
yaml --- r: 13119 b: refs/heads/master c: f0c3458 h: refs/heads/master i: 13117: 5dc3721 13115: e9feb6b 13111: 8871df5 13103: 9ea7817 13087: 9d4ce9a 13055: bb1c77a v: v3
1 parent 93e643c commit 0d6dbec

File tree

3 files changed

+70
-43
lines changed

3 files changed

+70
-43
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: f05040f17af1f4fcd6cda2b9cfe3ee43dc9c18e4
2+
refs/heads/master: f0c345841ce14f6ce618d1ed09c1d728bd253c87
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 4a81779abd786ff22d71434c6d9a5917ea4cdfff
55
refs/heads/try: 2898dcc5d97da9427ac367542382b6239d9c0bbf

trunk/src/libstd/par.rs

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import comm::send;
44
import comm::recv;
55
import future::future;
66

7-
export map, mapi, alli, any;
7+
export map, mapi, alli, any, mapi_factory;
88

99
#[doc="The maximum number of tasks this module will spawn for a single
1010
operationg."]
@@ -18,15 +18,16 @@ return the intermediate results.
1818
1919
This is used to build most of the other parallel vector functions,
2020
like map or alli."]
21-
fn map_slices<A: copy send, B: copy send>(xs: [A],
22-
f: fn~(uint, [const A]/&) -> B)
21+
fn map_slices<A: copy send, B: copy send>(
22+
xs: [A],
23+
f: fn() -> fn~(uint, [const A]/&) -> B)
2324
-> [B] {
2425

2526
let len = xs.len();
2627
if len < min_granularity {
2728
log(info, "small slice");
2829
// This is a small vector, fall back on the normal map.
29-
[f(0u, xs)]
30+
[f()(0u, xs)]
3031
}
3132
else {
3233
let num_tasks = uint::min(max_tasks, len / min_granularity);
@@ -40,7 +41,7 @@ fn map_slices<A: copy send, B: copy send>(xs: [A],
4041
let end = uint::min(len, base + items_per_task);
4142
// FIXME: why is the ::<A, ()> annotation required here?
4243
vec::unpack_slice::<A, ()>(xs) {|p, _len|
43-
let f = ptr::addr_of(f);
44+
let f = f();
4445
futures += [future::spawn() {|copy base|
4546
unsafe {
4647
let len = end - base;
@@ -52,7 +53,7 @@ fn map_slices<A: copy send, B: copy send>(xs: [A],
5253
log(info, #fmt("slice: %?",
5354
(base, vec::len(slice), end - base)));
5455
assert(vec::len(slice) == end - base);
55-
(*f)(base, slice)
56+
f(base, slice)
5657
}
5758
}];
5859
};
@@ -73,16 +74,40 @@ fn map_slices<A: copy send, B: copy send>(xs: [A],
7374

7475
#[doc="A parallel version of map."]
7576
fn map<A: copy send, B: copy send>(xs: [A], f: fn~(A) -> B) -> [B] {
76-
vec::concat(map_slices(xs) {|_base, slice|
77-
vec::map(slice, f)
77+
vec::concat(map_slices(xs) {||
78+
fn~(_base: uint, slice : [const A]/&) -> [B] {
79+
vec::map(slice, f)
80+
}
7881
})
7982
}
8083

8184
#[doc="A parallel version of mapi."]
8285
fn mapi<A: copy send, B: copy send>(xs: [A], f: fn~(uint, A) -> B) -> [B] {
83-
let slices = map_slices(xs) {|base, slice|
84-
vec::mapi(slice) {|i, x|
85-
f(i + base, x)
86+
let slices = map_slices(xs) {||
87+
fn~(base: uint, slice : [const A]/&) -> [B] {
88+
vec::mapi(slice) {|i, x|
89+
f(i + base, x)
90+
}
91+
}
92+
};
93+
let r = vec::concat(slices);
94+
log(info, (r.len(), xs.len()));
95+
assert(r.len() == xs.len());
96+
r
97+
}
98+
99+
#[doc="A parallel version of mapi.
100+
101+
In this case, f is a function that creates functions to run over the
102+
inner elements. This is to skirt the need for copy constructors."]
103+
fn mapi_factory<A: copy send, B: copy send>(
104+
xs: [A], f: fn() -> fn~(uint, A) -> B) -> [B] {
105+
let slices = map_slices(xs) {||
106+
let f = f();
107+
fn~(base: uint, slice : [const A]/&) -> [B] {
108+
vec::mapi(slice) {|i, x|
109+
f(i + base, x)
110+
}
86111
}
87112
};
88113
let r = vec::concat(slices);
@@ -93,16 +118,16 @@ fn mapi<A: copy send, B: copy send>(xs: [A], f: fn~(uint, A) -> B) -> [B] {
93118

94119
#[doc="Returns true if the function holds for all elements in the vector."]
95120
fn alli<A: copy send>(xs: [A], f: fn~(uint, A) -> bool) -> bool {
96-
vec::all(map_slices(xs) {|base, slice|
121+
vec::all(map_slices(xs) {|| fn~(base: uint, slice : [const A]/&) -> bool {
97122
vec::alli(slice) {|i, x|
98123
f(i + base, x)
99124
}
100-
}) {|x| x }
125+
}}) {|x| x }
101126
}
102127

103128
#[doc="Returns true if the function holds for any elements in the vector."]
104129
fn any<A: copy send>(xs: [A], f: fn~(A) -> bool) -> bool {
105-
vec::any(map_slices(xs) {|_base, slice|
130+
vec::any(map_slices(xs) {|| fn~(_base : uint, slice: [const A]/&) -> bool {
106131
vec::any(slice, f)
107-
}) {|x| x }
132+
}}) {|x| x }
108133
}

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

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ fn pbfs(graph: graph, key: node_id) -> bfs_result {
227227
}
228228
}
229229

230-
let (_res, graph) = arc::shared_arc(copy graph);
230+
let graph = arc::arc(copy graph);
231231

232232
let mut i = 0u;
233233
while par::any(colors, is_gray) {
@@ -236,33 +236,35 @@ fn pbfs(graph: graph, key: node_id) -> bfs_result {
236236
i += 1u;
237237
let old_len = colors.len();
238238

239-
let (_res, color) = arc::shared_arc(copy colors);
240-
241-
colors = par::mapi(colors) {|i, c|
242-
let c : color = c;
243-
let colors = &arc::get_arc(color);
244-
let colors = arc::get(colors);
245-
let graph = &arc::get_arc(graph);
246-
let graph = arc::get(graph);
247-
alt c {
248-
white {
249-
let i = i as node_id;
250-
251-
let neighbors = (*graph)[i];
252-
253-
let mut color = white;
254-
255-
neighbors.each() {|k|
256-
if is_gray((*colors)[k]) {
257-
color = gray(k);
258-
false
259-
}
260-
else { true }
239+
let color = arc::arc(colors);
240+
241+
colors = par::mapi_factory(*arc::get(&color)) {||
242+
let colors = arc::clone(&color);
243+
let graph = arc::clone(&graph);
244+
fn~(i: uint, c: color) -> color {
245+
let c : color = c;
246+
let colors = arc::get(&colors);
247+
let graph = arc::get(&graph);
248+
alt c {
249+
white {
250+
let i = i as node_id;
251+
252+
let neighbors = (*graph)[i];
253+
254+
let mut color = white;
255+
256+
neighbors.each() {|k|
257+
if is_gray((*colors)[k]) {
258+
color = gray(k);
259+
false
260+
}
261+
else { true }
261262
};
262-
color
263-
}
264-
gray(parent) { black(parent) }
265-
black(parent) { black(parent) }
263+
color
264+
}
265+
gray(parent) { black(parent) }
266+
black(parent) { black(parent) }
267+
}
266268
}
267269
};
268270
assert(colors.len() == old_len);

0 commit comments

Comments
 (0)