Changes between Version 27 and Version 28 of DataParallel/Regular
 Timestamp:
 Jan 20, 2010 2:50:21 AM (7 years ago)
Legend:
 Unmodified
 Added
 Removed
 Modified

DataParallel/Regular
v27 v28 344 344 DArray (() :*: Int :*: Int) Double > DArray (() :*: Int :*: Int) Double > DArray (() :*: Int :*: Int) Double 345 345 mmMult1 arr1@(DArray (() :*: m1 :*: n1) _) arr2@(DArray (() :*: m2 :*: n2) _) = 346 mapFold (+) 0 arrDP346 fold (+) 0 arrDP 347 347 where 348 348 arrDP = DArray (():*: m1 :*: n2 :*:n1) … … 352 352 sums and rows, and in the second step, we collapse each of the rows to it's sum, to obtain the two dimensional 353 353 result matrix. It is important to note that the elements of `arrDP` are never all in memory (otherwise, the memory 354 consumption would be cubic), but each value is consumed immediately by `map Fold`.354 consumption would be cubic), but each value is consumed immediately by `mapfold`. 355 355 356 356 This implementation suffers from the same problem a corresponding C implementation would  since we access one … … 361 361 DArray (() :*: Int :*: Int) Double > DArray (() :*: Int :*: Int) Double > DArray (() :*: Int :*: Int) Double 362 362 mmMult1 arr1@(DArray (() :*: m1 :*: n1) _) arr2@(DArray (() :*: m2 :*: n2) _) = 363 mapFold (+) 0 arrDP363 fold (+) 0 arrDP 364 364 where 365 365 arr2T = forceDArray $ transpose arr2 366 366 arrDP = DArray (():*: m1 :*: n2 :*:n1) 367 367 (\(() :*: i :*: j :*: k) > (index arr1 (() :*: i :*: k)) * (index arr2T (() :*: j:*: k))) 368 369 transpose:: DArray (() :*: Int :*: Int) Double > DArray (() :*: Int :*: Int) Double 370 transpose (DArray (() :*: m :*: n) f) = 371 DArray (() :*: n :*: m) (\(() :*: i :*: j) > f (() :*: j :*: i)) 368 372 }}} 369 373 However, we do need to force the actual creation of the transposed array, otherwise, the change would have no effect at all. We therefore 370 374 use `forceDArray`, which converts it into an array whose array function is a simple indexing operation (see description of `forceDArray` above). This means that the second version requires more memory, but this is offset by improving the locality for each of the multiplications. 375 376 As it is, `mmMult` can only take twodimensional arrays as arguments, and is not mappable. If we look at the implementation closely, we can see that the restriction to twodimensional arrays is unnecessary. All we have to do to generalise it is to adjust the type signatures and replace `()` with an arbitrary shape variable: 377 {{{ 378 mmMult1:: Shape dim => 379 DArray (dim :*: Int :*: Int) Double > DArray (dim :*: Int :*: Int) Double > DArray (dim :*: Int :*: Int) Double 380 mmMult1 arr1@(DArray (sh :*: m1 :*: n1) _) arr2@(DArray (sh' :*: m2 :*: n2) _) = 381 fold (+) 0 arrDP 382 where 383 arr2T = forceDArray $ transpose arr2 384 arrDP = DArray (sh:*: m1 :*: n2 :*:n1) 385 (\(sh :*: i :*: j :*: k) > (index arr1 (sh :*: i :*: k)) * (index arr2T (sh :*: j:*: k))) 386 387 transpose:: Shape dim => 388 DArray (dim :*: Int :*: Int) Double > DArray (dim :*: Int :*: Int) Double 389 transpose (DArray (sh:*: m :*: n) f) = 390 DArray (sh :*: n :*: m) (\(sh :*: i :*: j) > f (sh :*: j :*: i)) 391 }}} 371 392 372 393