@@ -16,7 +16,7 @@ import comm::*;
16
16
import int:: abs;
17
17
18
18
type node_id = i64 ;
19
- type graph = [ map :: set < node_id > ] ;
19
+ type graph = [ [ node_id ] ] ;
20
20
type bfs_result = [ node_id ] ;
21
21
22
22
iface queue<T : send> {
@@ -114,7 +114,15 @@ fn make_graph(N: uint, edges: [(node_id, node_id)]) -> graph {
114
114
true
115
115
}
116
116
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
+ }
118
126
}
119
127
120
128
#[ 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 {
132
140
while Q . size ( ) > 0 u {
133
141
let t = Q . pop_front ( ) ;
134
142
135
- graph[ t] . each_key ( ) { |k|
143
+ graph[ t] . each ( ) { |k|
136
144
if marks[ k] == -1 {
137
145
marks[ k] = t;
138
146
Q . add_back ( k) ;
@@ -144,6 +152,75 @@ fn bfs(graph: graph, key: node_id) -> bfs_result {
144
152
vec:: from_mut ( marks)
145
153
}
146
154
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 = 0 u;
184
+ while par:: any ( colors, is_gray) {
185
+ // Do the BFS.
186
+ log ( info, #fmt ( "PBFS iteration %?" , i) ) ;
187
+ i += 1 u;
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
+
147
224
#[ doc="Performs at least some of the validation in the Graph500 spec." ]
148
225
fn validate ( edges : [ ( node_id , node_id ) ] ,
149
226
root : node_id , tree : bfs_result ) -> bool {
@@ -252,7 +329,7 @@ fn main() {
252
329
let stop = time:: precise_time_s ( ) ;
253
330
254
331
let mut total_edges = 0 u;
255
- vec:: each ( graph) { |edges| total_edges += edges. size ( ) ; true } ;
332
+ vec:: each ( graph) { |edges| total_edges += edges. len ( ) ; true } ;
256
333
257
334
io:: stdout ( ) . write_line ( #fmt ( "Generated graph with %? edges in %? seconds." ,
258
335
total_edges / 2 u,
@@ -261,7 +338,7 @@ fn main() {
261
338
let root = 0 ;
262
339
263
340
let start = time:: precise_time_s ( ) ;
264
- let bfs_tree = bfs ( graph, root) ;
341
+ let bfs_tree = pbfs ( graph, root) ;
265
342
let stop = time:: precise_time_s ( ) ;
266
343
267
344
io:: stdout ( ) . write_line ( #fmt ( "BFS completed in %? seconds." ,
@@ -342,6 +419,7 @@ like map or alli."]
342
419
fn map_slices < A : send , B : send > ( xs : [ A ] , f : fn ~( uint , [ A ] ) -> B ) -> [ B ] {
343
420
let len = xs. len ( ) ;
344
421
if len < min_granularity {
422
+ log ( info, "small slice" ) ;
345
423
// This is a small vector, fall back on the normal map.
346
424
[ f ( 0 u, xs) ]
347
425
}
@@ -352,6 +430,7 @@ fn map_slices<A: send, B: send>(xs: [A], f: fn~(uint, [A]) -> B) -> [B] {
352
430
353
431
let mut futures = [ ] ;
354
432
let mut base = 0 u;
433
+ log ( info, "spawning tasks" ) ;
355
434
while base < len {
356
435
let slice = vec:: slice ( xs, base,
357
436
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] {
360
439
} ] ;
361
440
base += items_per_task;
362
441
}
442
+ log ( info, "tasks spawned" ) ;
363
443
364
444
futures. map ( ) { |ys|
365
445
ys. get ( )
@@ -370,7 +450,16 @@ fn map_slices<A: send, B: send>(xs: [A], f: fn~(uint, [A]) -> B) -> [B] {
370
450
#[ doc="A parallel version of map." ]
371
451
fn map < A : send , B : send > ( xs : [ A ] , f : fn ~( A ) -> B ) -> [ B ] {
372
452
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
+ }
374
463
} )
375
464
}
376
465
@@ -382,4 +471,12 @@ fn alli<A: send>(xs: [A], f: fn~(uint, A) -> bool) -> bool {
382
471
}
383
472
} ) { |x| x }
384
473
}
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
+
385
482
}
0 commit comments