|
| 1 | +module T = Domainslib.Task |
| 2 | +let num_domains = try int_of_string Sys.argv.(1) with _ -> 1 |
| 3 | +let mat_size = try int_of_string Sys.argv.(2) with _ -> 1200 |
| 4 | +let chunk_size = try int_of_string Sys.argv.(3) with _ -> 16 |
| 5 | + |
| 6 | +let k : Random.State.t Domain.DLS.key = Domain.DLS.new_key () |
| 7 | +let get_state () = try Option.get @@ Domain.DLS.get k with _ -> |
| 8 | + begin |
| 9 | + Domain.DLS.set k (Random.State.make_self_init ()); |
| 10 | + Option.get @@ Domain.DLS.get k |
| 11 | + end |
| 12 | + |
| 13 | +module SquareMatrix = struct |
| 14 | + |
| 15 | + let create f : float array = |
| 16 | + let fa = Array.create_float (mat_size * mat_size) in |
| 17 | + for i = 0 to mat_size * mat_size - 1 do |
| 18 | + fa.(i) <- f (i / mat_size) (i mod mat_size) |
| 19 | + done; |
| 20 | + fa |
| 21 | + let parallel_create pool f : float array = |
| 22 | + let fa = Array.create_float (mat_size * mat_size) in |
| 23 | + T.parallel_for pool ~chunk_size:(mat_size * mat_size / num_domains) ~start:0 |
| 24 | + ~finish:( mat_size * mat_size - 1) ~body:(fun i -> |
| 25 | + fa.(i) <- f (i / mat_size) (i mod mat_size)); |
| 26 | + fa |
| 27 | + |
| 28 | + let get (m : float array) r c = m.(r * mat_size + c) |
| 29 | + let set (m : float array) r c v = m.(r * mat_size + c) <- v |
| 30 | + let parallel_copy pool a = |
| 31 | + let n = Array.length a in |
| 32 | + let copy_part a b i = |
| 33 | + let s = (i * n / num_domains) in |
| 34 | + let e = (i+1) * n / num_domains - 1 in |
| 35 | + Array.blit a s b s (e - s + 1) in |
| 36 | + let b = Array.create_float n in |
| 37 | + let rec aux acc num_domains i = |
| 38 | + if (i = num_domains) then |
| 39 | + (List.iter (fun e -> T.await pool e) acc) |
| 40 | + else begin |
| 41 | + aux ((T.async pool (fun _ -> copy_part a b i))::acc) num_domains (i+1) |
| 42 | + end |
| 43 | + in |
| 44 | + aux [] num_domains 0; |
| 45 | + b |
| 46 | +end |
| 47 | + |
| 48 | +open SquareMatrix |
| 49 | + |
| 50 | +let lup pool (a0 : float array) = |
| 51 | + let a = parallel_copy pool a0 in |
| 52 | + for k = 0 to (mat_size - 2) do |
| 53 | + T.parallel_for pool ~chunk_size:chunk_size ~start:(k + 1) ~finish:(mat_size -1) |
| 54 | + ~body:(fun row -> |
| 55 | + let factor = get a row k /. get a k k in |
| 56 | + for col = k + 1 to mat_size-1 do |
| 57 | + set a row col (get a row col -. factor *. (get a k col)) |
| 58 | + done; |
| 59 | + set a row k factor ) |
| 60 | + done ; |
| 61 | + a |
| 62 | + |
| 63 | +let () = |
| 64 | + let pool = T.setup_pool ~num_domains:(num_domains - 1) in |
| 65 | + let a = parallel_create pool |
| 66 | + (fun _ _ -> (Random.State.float (get_state ()) 100.0) +. 1.0 ) in |
| 67 | + let lu = lup pool a in |
| 68 | + let _l = parallel_create pool (fun i j -> if i > j then get lu i j else if i = j then 1.0 else 0.0) in |
| 69 | + let _u = parallel_create pool (fun i j -> if i <= j then get lu i j else 0.0) in |
| 70 | + T.teardown_pool pool |
0 commit comments