module Bench( -- sets of generators g , g1, g2, g3, g4, g5 , g12, g13, g14, g15, g23, g24, g25, g34, g35, g45 , g123, g124, g125, g134, g135, g145, g234, g235, g245, g345 , g1234, g1235, g1245, g1345, g2345 , g12345 -- sequential benchmarks , seq -- parallel benchmarks , par, par_seq -- distributed benhcmarks , dist, dist_seq ) where import Data.List (lookup) import Data.Maybe (fromMaybe) import Prelude hiding (seq) import MasterWorker (HostInfo(..), MaybeHosts(..), orbit) ----------------------------------------------------------------------------- -- generators -- Fibonacci numbers fib :: Int -> Int fib 0 = 1 fib 1 = 1 fib n = fib (n - 1) + fib (n - 2) -- mixing polynomials (up to degree 3) p2 :: Int -> Int -> Int p2 a0 _ = a0 p3 :: Int -> Int -> Int -> Int p3 a1 a0 n = a1 * n + p2 a0 n p4 :: Int -> Int -> Int -> Int -> Int p4 a2 a1 a0 n = a2 * n * n + p3 a1 a0 n p5 :: Int -> Int -> Int -> Int -> Int -> Int p5 a3 a2 a1 a0 n = a3 * n * n * n + p4 a2 a1 a0 n -- step functions (up to 4 steps) s2 :: Int -> Int -> Int s2 b0 n | n < b0 = 0 | otherwise = 1 s3 :: Int -> Int -> Int -> Int s3 b0 b1 n | n < b0 = 0 | otherwise = 1 + s2 b1 n s4 :: Int -> Int -> Int -> Int -> Int s4 b0 b1 b2 n | n < b0 = 0 | otherwise = 1 + s3 b1 b2 n s5 :: Int -> Int -> Int -> Int -> Int -> Int s5 b0 b1 b2 b3 n | n < b0 = 0 | otherwise = 1 + s4 b1 b2 b3 n -- remainder function (range 0..R - 1) r :: Int -> Int -> Int r r0 n = (abs n) `rem` r0 -- generators based on Fibonacci numbers; -- functions f1(N,_),...,f5(N,_) produce numbers in the range 0 .. N-1; -- computationally f1 = fib(0..15), -- f2 = fib(5..20), -- f3 = fib(10..25), -- f4 = fib(11,19,27), bias 49- to 11, 49- to 19, 2- to 27 -- f5 = fib(10,20,30), bias 90- to 10, 9.9- to 20, 0.1- to 30 f1 n x = r n $ (fib (p3 1 0 (r 16 x))) + p3 1 0 x f2 n x = r n $ (fib (p3 1 5 (r 16 x))) + p4 2 5 (-1) x f3 n x = r n $ (fib (p3 1 10 (r 16 x))) + p5 (-1) 0 8 0 x f4 n x = r n $ (fib (p3 8 3 (s5 0 49 98 100 (r 100 x)))) + p2 (-1) x f5 n x = r n $ (fib (p3 10 0 (s5 0 900 999 1000 (r 1000 x)))) + p2 1 x -- sets (= lists) of generators g _ = [] g1 n = [f1 n] g2 n = [f2 n] g3 n = [f3 n] g4 n = [f4 n] g5 n = [f5 n] g12 n = g1 n ++ g2 n g13 n = g1 n ++ g3 n g14 n = g1 n ++ g4 n g15 n = g1 n ++ g5 n g23 n = g2 n ++ g3 n g24 n = g2 n ++ g4 n g25 n = g2 n ++ g5 n g34 n = g3 n ++ g4 n g35 n = g3 n ++ g5 n g45 n = g4 n ++ g5 n g123 n = g12 n ++ g3 n g124 n = g12 n ++ g4 n g125 n = g12 n ++ g5 n g134 n = g13 n ++ g4 n g135 n = g13 n ++ g5 n g145 n = g14 n ++ g5 n g234 n = g23 n ++ g4 n g235 n = g23 n ++ g5 n g245 n = g24 n ++ g5 n g345 n = g34 n ++ g5 n g1234 n = g123 n ++ g4 n g1235 n = g123 n ++ g5 n g1245 n = g124 n ++ g5 n g1345 n = g134 n ++ g5 n g2345 n = g234 n ++ g5 n g12345 n = g1234 n ++ g5 n ----------------------------------------------------------------------------- -- benchmarks, parametrised by -- * list of Generators -- * size of space N > 0 -- * number of processors P > 0 (per node) -- * list of Workers (in short node name format 'name@host') -- sequential orbit computation seq generators n = sz $ orbit (generators n) [0] (Seq (2 * n)) -- parallel orbit computation (par_seq/3 does not spawn image computation) par generators n p = sz $ orbit (generators n) [0] (Par (JustOne (p, ((2 * n) `div` p) + 1, 0, True))) par_seq generators n p = sz $ orbit (generators n) [0] (Par (JustOne (p, ((2 * n) `div` p) + 1, 0, False))) -- distributed orbit computation (dist_seq/4 does not spawn image computation) dist generators n p workers = sz $ orbit (generators n) [0] (Par (Many [(h, p, (2 * n) `div` (w * p) + 1, 1, True) | h <- workers])) where w = length workers dist_seq generators n p workers = sz $ orbit (generators n) [0] (Par (Many [(h, p, (2 * n) `div` (w * p) + 1, 1, False) | h <- workers])) where w = length workers sz (_, mainStats : _) = case "size" `lookup` mainStats of Nothing -> "false" Just s -> "{size," ++ s ++ "}"