The example program in this chapter is a parallel determinant computation. It uses the data type SqMatrix a to represent a matrix as a list of list together with its bounds.
For getting a parallel version of the program strategies (see section Using a Class of Strategies) are used. Thus, much of the parallelism comes from applying the parList strategy. In order to demonstrate the use of strategies in a parallel functional program this example contains parallelism down to a very fine granularity.
determinant :: (NFDataIntegral a) => SqMatrix a -> a
determinant (SqMatrixC ((iLo,jLo),(iHi,jHi)) mat)
| jHi-jLo+1 == 1 = let
[[mat_1_1]] = mat
in
mat_1_1
| jHi-jLo+1 == 2 = let
[[mat_1_1,mat_1_2],
[mat_2_1,mat_2_2] ] = mat
a = mat_1_1 * mat_2_2
b = mat_1_2 * mat_2_1
strategy r = a `par` b `par` ()
in
a - b `using` strategy
| otherwise =
sum (l_par `using` parList rnf)
where
newLine _ [] = []
newLine j line = pre ++ post `using` strategyN
where
pre = [ line !! (k-1) | k <- [jLo..j-1] ]
post = [ line !! (k-1) | k <- [j+1..jHi] ]
strategyN r = pre `par` post `par` ()
determine1 j = (if pivot > 0 then
sign*pivot*det' `using` strategyD1
else
0) `using` sPar sign
where
sign = if (even (j-jLo)) then 1 else -1
pivot = (head mat) !! (j-1)
mat' = SqMatrixC ((iLo,jLo),(iHi-1,jHi-1))
(map (newLine j) (tail mat))
det' = determinant mat'
strategyD1 r =
parSqMatrix (parList rwhnf) mat' `seq`
det' `par` ()
l_par = map determine1 [jLo..jHi]
Go to the first, previous, next, last section, table of contents.