module Data.Array.Repa.Repr.HintInterleave (I, Array (..), hintInterleave) where import Data.Array.Repa.Eval.Load import Data.Array.Repa.Eval.Target import Data.Array.Repa.Eval.Interleaved import Data.Array.Repa.Repr.Delayed import Data.Array.Repa.Shape import Data.Array.Repa.Base import Debug.Trace -- | Hints that computing this array will be an unbalanced workload -- and evaluation should be interleaved between the processors. data I r1 instance Source r1 a => Source (I r1) a where data Array (I r1) sh a = AInterleave !(Array r1 sh a) extent (AInterleave arr) = extent arr {-# INLINE extent #-} index (AInterleave arr) ix = index arr ix {-# INLINE index #-} unsafeIndex (AInterleave arr) ix = unsafeIndex arr ix {-# INLINE unsafeIndex #-} linearIndex (AInterleave arr) ix = linearIndex arr ix {-# INLINE linearIndex #-} unsafeLinearIndex (AInterleave arr) ix = unsafeLinearIndex arr ix {-# INLINE unsafeLinearIndex #-} deepSeqArray (AInterleave arr) x = deepSeqArray arr x {-# INLINE deepSeqArray #-} deriving instance Show (Array r1 sh e) => Show (Array (I r1) sh e) deriving instance Read (Array r1 sh e) => Read (Array (I r1) sh e) -- | Wrap an array with a unbalanced-ness hint. hintInterleave :: Array r1 sh e -> Array (I r1) sh e hintInterleave = AInterleave -- Load ----------------------------------------------------------------------- instance (Shape sh, Load D sh e) => Load (I D) sh e where loadP (AInterleave (ADelayed sh getElem)) marr = marr `deepSeqMVec` do traceEventIO "Repa.loadP[Interleaved]: start" fillInterleavedP (size sh) (unsafeWriteMVec marr) (getElem . fromIndex sh) touchMVec marr traceEventIO "Repa.loadP[Interleaved]: end" {-# INLINE [4] loadP #-} -- The fact that the workload is unbalanced doesn't affect us when the -- program is run sequentially, so just use the filling method of the inner -- representation loadS (AInterleave arr) marr = loadS arr marr {-# INLINE loadS #-}