module Data.Repa.Vector.Generic
(
unstreamToVector2
, unstreamToMVector2
, chainOfVector
, unchainToVector
, unchainToMVector)
where
import Data.Repa.Chain as C
import qualified Data.Vector.Generic as GV
import qualified Data.Vector.Generic.Mutable as GM
import qualified Data.Vector.Fusion.Stream.Monadic as S
import qualified Data.Vector.Fusion.Stream.Size as S
import Control.Monad.Primitive
#include "repa-stream.h"
unstreamToVector2
:: (PrimMonad m, GV.Vector v a, GV.Vector v b)
=> S.Stream m (Maybe a, Maybe b)
-> m (v a, v b)
unstreamToVector2 s
= do (mvec1, mvec2) <- unstreamToMVector2 s
vec1 <- GV.unsafeFreeze mvec1
vec2 <- GV.unsafeFreeze mvec2
return (vec1, vec2)
unstreamToMVector2
:: (PrimMonad m, GM.MVector v a, GM.MVector v b)
=> S.Stream m (Maybe a, Maybe b)
-> m (v (PrimState m) a, v (PrimState m) b)
unstreamToMVector2 (S.Stream step s0 sz)
= case sz of
S.Exact i -> unstreamToMVector2_max i s0 step
S.Max i -> unstreamToMVector2_max i s0 step
S.Unknown -> error "repa-stream: finish unstreamToMVector2"
unstreamToMVector2_max nMax s0 step
= GM.unsafeNew nMax >>= \vecL
-> GM.unsafeNew nMax >>= \vecR
-> let
go !sPEC !iL !iR !s
= step s >>= \m
-> case m of
S.Yield (mL, mR) s'
-> do !iL' <- case mL of
Nothing -> return iL
Just xL -> do GM.unsafeWrite vecL iL xL
return (iL + 1)
!iR' <- case mR of
Nothing -> return iR
Just xR -> do GM.unsafeWrite vecR iR xR
return (iR + 1)
go sPEC iL' iR' s'
S.Skip s'
-> go sPEC iL iR s'
S.Done
-> return ( GM.unsafeSlice 0 iL vecL
, GM.unsafeSlice 0 iR vecR)
in go S.SPEC 0 0 s0
chainOfVector
:: (Monad m, GV.Vector v a)
=> v a -> Chain m Int a
chainOfVector vec
= Chain (S.Exact len) 0 step
where
!len = GV.length vec
step !i
| i >= len
= return $ Done i
| otherwise
= return $ Yield (GV.unsafeIndex vec i) (i + 1)
unchainToVector
:: (PrimMonad m, GV.Vector v a)
=> C.Chain m s a -> m (v a, s)
unchainToVector chain
= do (mvec, c') <- unchainToMVector chain
vec <- GV.unsafeFreeze mvec
return (vec, c')
unchainToMVector
:: (PrimMonad m, GM.MVector v a)
=> Chain m s a
-> m (v (PrimState m) a, s)
unchainToMVector (Chain sz s0 step)
= case sz of
S.Exact i -> unchainToMVector_max i s0 step
S.Max i -> unchainToMVector_max i s0 step
S.Unknown -> unchainToMVector_unknown 32 s0 step
unchainToMVector_max nMax s0 step
= GM.unsafeNew nMax >>= \vec
-> let
go !sPEC !i !s
= step s >>= \m
-> case m of
Yield e s'
-> do GM.unsafeWrite vec i e
go sPEC (i + 1) s'
Skip s' -> go sPEC i s'
Done s' -> return (GM.unsafeSlice 0 i vec, s')
in go S.SPEC 0 s0
unchainToMVector_unknown nStart s0 step
= GM.unsafeNew nStart >>= \vec0
-> let
go !sPEC !vec !i !n !s
= step s >>= \m
-> case m of
Yield e s'
| i >= n
-> do vec' <- GM.unsafeGrow vec n
GM.unsafeWrite vec' i e
go sPEC vec' (i + 1) (n + n) s'
| otherwise
-> do GM.unsafeWrite vec i e
go sPEC vec (i + 1) n s'
Skip s' -> go sPEC vec i n s'
Done s' -> return (GM.unsafeSlice 0 i vec, s')
in go S.SPEC vec0 0 nStart s0