module Data.Array.Repa.Internals.Forcing
( toVector
, toList
, force, force2)
where
import Data.Array.Repa.Internals.EvalChunked
import Data.Array.Repa.Internals.EvalCursored
import Data.Array.Repa.Internals.Elt
import Data.Array.Repa.Internals.Base
import Data.Array.Repa.Index
import Data.Array.Repa.Shape as S
import qualified Data.Vector.Unboxed as V
import qualified Data.Vector.Unboxed.Mutable as VM
import Data.Vector.Unboxed (Vector)
import System.IO.Unsafe
stage = "Data.Array.Repa.Internals.Forcing"
toVector
:: (Shape sh, Elt a)
=> Array sh a
-> Vector a
toVector arr
= case force arr of
Array _ [Region _ (GenManifest vec)] -> vec
_ -> error $ stage ++ ".toVector: force failed"
toList :: (Shape sh, Elt a)
=> Array sh a
-> [a]
toList arr
= V.toList $ toVector arr
force :: (Shape sh, Elt a)
=> Array sh a -> Array sh a
force arr
= unsafePerformIO
$ do (sh, vec) <- forceIO arr
return $ sh `seq` vec `seq`
Array sh [Region RangeAll (GenManifest vec)]
where forceIO arr'
= case arr' of
Array sh [Region RangeAll (GenManifest vec)]
-> return (sh, vec)
Array sh _
-> do mvec <- VM.unsafeNew (S.size sh)
fillChunkedP mvec (\ix -> arr' `unsafeIndex` fromIndex sh ix)
vec <- V.unsafeFreeze mvec
return (sh, vec)
force2 :: Elt a => Array DIM2 a -> Array DIM2 a
force2 arr
= unsafePerformIO
$ do (sh, vec) <- forceIO2 arr
return $ sh `seq` vec `seq`
Array sh [Region RangeAll (GenManifest vec)]
where forceIO2 arr'
= arr' `deepSeqArray`
case arr' of
Array sh [Region RangeAll (GenManifest vec)]
-> return (sh, vec)
Array sh [r1]
-> do mvec <- VM.new (S.size sh)
fillRegion2P mvec sh r1
vec <- V.unsafeFreeze mvec
return (sh, vec)
Array sh [r1, r2]
-> do mvec <- VM.new (S.size sh)
fillRegion2P mvec sh r1
fillRegion2P mvec sh r2
vec <- V.unsafeFreeze mvec
return (sh, vec)
Array sh regions
-> do mvec <- VM.new (S.size sh)
mapM_ (fillRegion2P mvec sh) regions
vec <- V.unsafeFreeze mvec
return (sh, vec)
fillRegion2P
:: Elt a
=> VM.IOVector a
-> DIM2
-> Region DIM2 a
-> IO ()
fillRegion2P mvec sh@(_ :. height :. width) (Region range gen)
= mvec `seq` height `seq` width `seq`
case range of
RangeAll
-> fillRect2 mvec sh gen
(Rect (Z :. 0 :. 0)
(Z :. height 1 :. width 1))
RangeRects _ [rect]
-> fillRect2 mvec sh gen rect
RangeRects _ [r1, r2, r3, r4]
-> do fillRect2 mvec sh gen r1
fillRect2 mvec sh gen r2
fillRect2 mvec sh gen r3
fillRect2 mvec sh gen r4
RangeRects _ rects
-> mapM_ (fillRect2 mvec sh gen) rects
fillRect2
:: Elt a
=> VM.IOVector a
-> DIM2
-> Generator DIM2 a
-> Rect DIM2
-> IO ()
fillRect2 mvec (_ :. _ :. width) gen (Rect (Z :. y0 :. x0) (Z :. y1 :. x1))
= mvec `seq` width `seq` y0 `seq` x0 `seq` y1 `seq` x1 `seq`
case gen of
GenManifest{}
-> error "fillRegion2P: GenManifest, copy elements."
GenCursor makeCursor shiftCursor loadElem
-> fillCursoredBlock2P mvec
makeCursor shiftCursor loadElem
width x0 y0 x1 y1