{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE StandaloneDeriving #-}
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 707
{-# LANGUAGE AutoDeriveTypeable #-}
#endif
module Numerical.Array.Layout.Dense(
DenseLayout(..)
,Locality(..)
,Format(..)
,Row
,Column
,Direct
,module Numerical.Array.Layout.Base
) where
import Numerical.Nat
import Control.Applicative
import Numerical.Array.Locality
import Numerical.Array.Layout.Base
import Numerical.Array.Shape as S
import Data.Data(Data,Typeable)
import Control.NumericalMonad.State.Strict
import qualified Data.Foldable as F
import Data.Traversable
import Prelude hiding (foldr,foldl,map,scanl,scanr,scanl1,scanr1)
data Direct
data Row
data Column
type instance LayoutLogicalFormat (Format Direct cont ('S 'Z ) rep )
= Format Direct 'Contiguous ('S 'Z) rep
data instance Format Direct 'Contiguous ('S 'Z) rep =
FormatDirectContiguous {
logicalShapeDirectContiguous :: {-#UNPACK#-} !Int }
deriving (Show,Eq,Data)
data instance Format Direct 'Strided ('S 'Z) rep =
FormatDirectStrided {
logicalShapeDirectStrided :: {-#UNPACK#-}!Int
,logicalStrideDirectStrided:: {-#UNPACK#-}!Int}
type instance LayoutLogicalFormat (Format Row cont n rep )
= Format Row 'Contiguous n rep
data instance Format Row 'Contiguous n rep =
FormatRowContiguous {
boundsFormRow :: !(Shape n Int)}
data instance Format Row 'Strided n rep =
FormatRowStrided
{boundsFormRowStrided:: !(Shape n Int)
,strideFormRowStrided:: !(Shape n Int)}
data instance Format Row 'InnerContiguous n rep =
FormatRowInnerContiguous {
boundsFormRowInnerContig :: !(Shape n Int)
,strideFormRowInnerContig:: !(Shape n Int)}
type instance LayoutLogicalFormat (Format Column cont n rep )
= Format Column 'Contiguous n rep
data instance Format Column 'Contiguous n rep =
FormatColumnContiguous {
boundsColumnContig :: !(Shape n Int)}
data instance Format Column 'InnerContiguous n rep =
FormatColumnInnerContiguous {
boundsColumnInnerContig :: !(Shape n Int)
,strideFormColumnInnerContig:: !(Shape n Int)
}
deriving instance Show (Shape n Int) => Show (Format Column 'InnerContiguous n rep)
deriving instance (Data (Shape n Int),Typeable n,Typeable rep) =>Data (Format Column 'InnerContiguous n rep)
data instance Format Column 'Strided n rep =
FormatColumnStrided {
boundsColumnStrided :: !(Shape n Int)
,strideFormColumnStrided:: !(Shape n Int)}
deriving instance Show (Shape n Int) => Show (Format Column 'Strided n rep)
deriving instance (Data (Shape n Int),Typeable n,Typeable rep) => Data (Format Column 'Strided n rep)
type instance Transposed (Format Direct 'Contiguous ('S 'Z) rep) =
Format Direct 'Contiguous ('S 'Z) rep
type instance Transposed (Format Direct 'Strided ('S 'Z) rep ) =
Format Direct 'Strided ('S 'Z) rep
type instance Transposed (Format Row 'Contiguous rank rep) =
Format Column 'Contiguous rank rep
type instance Transposed (Format Row 'InnerContiguous rank rep) =
Format Column 'InnerContiguous rank rep
type instance Transposed (Format Row 'Strided rank rep) =
Format Column 'Strided rank rep
type instance Transposed (Format Column 'Contiguous rank rep)=
Format Row 'Contiguous rank rep
type instance Transposed (Format Column 'InnerContiguous rank rep)=
Format Row 'InnerContiguous rank rep
type instance Transposed (Format Column 'Strided rank rep)=
Format Row 'Strided rank rep
{-# INLINE basicAddressRangeGeneric #-}
basicAddressRangeGeneric ::
(Functor (Shape rank),Applicative (Shape rank),F.Foldable (Shape rank),
DenseLayout form rank, Address~LayoutAddress form)=> form -> Maybe (Range Address)
basicAddressRangeGeneric = \ form ->
if (fmap (flip (-) 1)$ basicLogicalShape form) `strictlyDominates` pure 0
then Just $!
Range (basicToDenseAddress form $! pure 0)
(basicToDenseAddress form $!
fmap (flip (-) 1) $! basicLogicalShape form)
else Nothing
{-# INLINE basicToAddressDenseGeneric #-}
basicToAddressDenseGeneric :: (Functor (Shape rank),Applicative (Shape rank),F.Foldable (Shape rank),
DenseLayout form rank,Address~LayoutAddress form) => form -> Shape rank Int -> Maybe Address
basicToAddressDenseGeneric = \ form ix ->
if (fmap (flip (-) 1)$ basicLogicalShape form) `weaklyDominates` ix
&& ix `weaklyDominates` pure 0
then Just $ basicToDenseAddress form ix
else Nothing
{-# INLINE basicToIndexDenseGeneric #-}
basicToIndexDenseGeneric ::
(Functor (Shape rank),F.Foldable (Shape rank),
DenseLayout form rank,Address~LayoutAddress form) => form -> Address -> Shape rank Int
basicToIndexDenseGeneric = \form addr ->
basicToDenseIndex form addr
{-# INLINE basicNextAddressDenseGeneric #-}
basicNextAddressDenseGeneric ::
(Functor (Shape rank),F.Foldable (Shape rank),
DenseLayout form rank,Address~LayoutAddress form) => form -> Address-> Maybe Address
basicNextAddressDenseGeneric = \ form addy ->
case basicAddressRange form of
Just (Range lo hi ) -> if addy >= lo && addy < hi
then Just $! basicNextDenseAddress form addy
else Nothing
Nothing -> Nothing
{-# INLINE basicNextIndexDenseGeneric #-}
basicNextIndexDenseGeneric :: (Functor (Shape rank),F.Foldable (Shape rank),Applicative (Shape rank),
DenseLayout form rank,Address~LayoutAddress form) =>
form -> Shape rank Int -> Maybe Address ->Maybe (Shape rank Int,Address)
basicNextIndexDenseGeneric = \form ix _ ->
if (fmap (flip (-) 1)$ basicLogicalShape form) `strictlyDominates` ix
&& ix `weaklyDominates` pure 0
then
Just $! basicNextDenseIndex form ix
else
Nothing
{-# INLINE basicAffineAddressShiftDenseGeneric #-}
basicAffineAddressShiftDenseGeneric :: (DenseLayout form rank
,DenseLayout (LayoutLogicalFormat form) rank
,Address~ LayoutAddress (LayoutLogicalFormat form))
=> form -> Address -> Int -> Maybe Address
basicAffineAddressShiftDenseGeneric form = \ addy shift ->
let newForm = basicLogicalForm form in
do
nativeIndex <- return $ basicToDenseIndex form addy
popBaseAddress <- return $ basicToDenseAddress newForm nativeIndex
rng <- basicAddressRange newForm
candidateAddress <- return $ popBaseAddress + Address shift
if (getConst $ rangeMin ( Const) rng) <= candidateAddress
&& candidateAddress <= (getConst $ rangeMax ( Const) rng)
then return $ basicToDenseAddress form $ basicToDenseIndex newForm candidateAddress
else Nothing
type instance LayoutAddress (Format Direct 'Contiguous ('S 'Z) rep) = Address
type instance LayoutLogicalFormat (Format Direct 'Contiguous ('S 'Z) rep) = Format Direct 'Contiguous ('S 'Z) rep
instance Layout (Format Direct 'Contiguous ('S 'Z) rep) ('S 'Z) where
{-# INLINE basicLogicalShape #-}
basicLogicalShape = \ x -> (logicalShapeDirectContiguous x) :* Nil
basicLogicalForm = id
transposedLayout = id
{-# INLINE basicCompareIndex #-}
basicCompareIndex = \ _ (l:* _) (r:* _) -> compare l r
basicAddressRange = basicAddressRangeGeneric
basicToAddress = basicToAddressDenseGeneric
basicToIndex = basicToIndexDenseGeneric
basicNextAddress = basicNextAddressDenseGeneric
basicNextIndex = basicNextIndexDenseGeneric
basicAddressPopCount = \ _ (Range (Address lo) (Address hi )) ->
if hi >= lo then hi - lo
else error $ "for basicAddressPopCount requires address obey hi >= lo, given: "
++ show hi ++ " " ++ show lo
basicAddressAsInt = \ _ (Address a) -> a
basicAffineAddressShift = basicAffineAddressShiftDenseGeneric
{-# INLINE basicAffineAddressShift #-}
{-# INLINE basicAddressRange #-}
{-# INLINE basicToAddress #-}
{-# INLINE basicToIndex #-}
{-# INLINE basicNextAddress #-}
{-# INLINE basicNextIndex #-}
{-# INLINE basicAddressPopCount #-}
type instance LayoutAddress (Format Direct 'Strided ('S 'Z) rep) = Address
instance Layout (Format Direct 'Strided ('S 'Z) rep) ('S 'Z) where
{-# INLINE basicLogicalShape #-}
basicLogicalShape = \x -> (logicalShapeDirectStrided x) :* Nil
transposedLayout = id
basicLogicalForm = (\ (n :* Nil ) -> FormatDirectContiguous n) . basicLogicalShape
{-# INLINE basicCompareIndex #-}
basicCompareIndex = \ _ (l:* _) (r:* _) -> compare l r
basicAddressRange = basicAddressRangeGeneric
basicToAddress = basicToAddressDenseGeneric
basicToIndex = basicToIndexDenseGeneric
basicNextAddress = basicNextAddressDenseGeneric
basicNextIndex = basicNextIndexDenseGeneric
basicAddressPopCount = \form@(FormatDirectStrided size _ ) (Range loA hiA)->
let newForm = (FormatDirectContiguous size)
in
basicAddressPopCount newForm
(Range (basicToDenseAddress newForm $ basicToDenseIndex form loA)
(basicToDenseAddress newForm $ basicToDenseIndex form hiA) )
basicAddressAsInt = \ _ (Address a) -> a
basicAffineAddressShift = basicAffineAddressShiftDenseGeneric
{-# INLINE basicAffineAddressShift #-}
{-# INLINE basicAddressRange #-}
{-# INLINE basicToAddress #-}
{-# INLINE basicToIndex #-}
{-# INLINE basicNextAddress #-}
{-# INLINE basicNextIndex #-}
{-# INLINE basicAddressPopCount #-}
type instance LayoutAddress (Format Row locality rank rep) = Address
instance (Applicative (Shape rank), Traversable (Shape rank))
=> Layout (Format Row 'Contiguous rank rep) rank where
transposedLayout = \(FormatRowContiguous shp) -> FormatColumnContiguous $ reverseShape shp
{-# INLINE basicLogicalShape #-}
basicLogicalShape = boundsFormRow
basicLogicalForm = id
{-# INLINE basicCompareIndex #-}
basicCompareIndex = \ _ ls rs -> foldl majorCompareLeftToRight EQ $ S.map2 compare ls rs
basicAddressPopCount = \ _ (Range (Address lo) (Address hi )) -> hi - lo
basicAddressRange = basicAddressRangeGeneric
basicToAddress = basicToAddressDenseGeneric
basicToIndex = basicToIndexDenseGeneric
basicNextAddress = basicNextAddressDenseGeneric
basicNextIndex = basicNextIndexDenseGeneric
basicAddressAsInt = \ _ (Address a) -> a
basicAffineAddressShift = basicAffineAddressShiftDenseGeneric
{-# INLINE basicAffineAddressShift #-}
{-# INLINE basicAddressRange #-}
{-# INLINE basicToAddress #-}
{-# INLINE basicToIndex #-}
{-# INLINE basicNextAddress #-}
{-# INLINE basicNextIndex #-}
{-# INLINE basicAddressPopCount #-}
instance (Applicative (Shape rank), Traversable (Shape rank))
=> Layout (Format Row 'InnerContiguous rank rep) rank where
{-# INLINE basicLogicalShape #-}
basicLogicalShape = boundsFormRowInnerContig
basicLogicalForm form = FormatRowContiguous $ basicLogicalShape form
transposedLayout = \(FormatRowInnerContiguous shp stride) ->
FormatColumnInnerContiguous (reverseShape shp) (reverseShape stride)
{-# INLINE basicCompareIndex #-}
basicCompareIndex = \ _ ls rs ->
foldl majorCompareLeftToRight EQ $ S.map2 compare ls rs
basicAddressRange = basicAddressRangeGeneric
basicToAddress = basicToAddressDenseGeneric
basicToIndex = basicToIndexDenseGeneric
basicNextAddress = basicNextAddressDenseGeneric
basicNextIndex = basicNextIndexDenseGeneric
basicAddressPopCount = \form@(FormatRowInnerContiguous size _) (Range loA hiA)->
let newForm = (FormatRowContiguous size)
in
basicAddressPopCount newForm
(Range (basicToDenseAddress newForm $ basicToDenseIndex form loA)
(basicToDenseAddress newForm $ basicToDenseIndex form hiA) )
basicAddressAsInt = \ _ (Address a) -> a
basicAffineAddressShift = basicAffineAddressShiftDenseGeneric
{-# INLINE basicAffineAddressShift #-}
{-# INLINE basicAddressRange #-}
{-# INLINE basicToAddress #-}
{-# INLINE basicToIndex #-}
{-# INLINE basicNextAddress #-}
{-# INLINE basicNextIndex #-}
{-# INLINE basicAddressPopCount #-}
instance (Applicative (Shape rank),Traversable (Shape rank))
=> Layout (Format Row 'Strided rank rep) rank where
{-# INLINE basicLogicalShape #-}
basicLogicalShape = boundsFormRowStrided
basicLogicalForm form = FormatRowContiguous $ basicLogicalShape form
transposedLayout = \(FormatRowStrided shp stride) ->
FormatColumnStrided (reverseShape shp) (reverseShape stride)
{-# INLINE basicCompareIndex #-}
basicCompareIndex = \ _ ls rs ->
foldl majorCompareLeftToRight EQ $ S.map2 compare ls rs
basicAddressRange = basicAddressRangeGeneric
basicToAddress = basicToAddressDenseGeneric
basicToIndex = basicToIndexDenseGeneric
basicNextAddress = basicNextAddressDenseGeneric
basicNextIndex = basicNextIndexDenseGeneric
basicAddressPopCount = \form@(FormatRowStrided size _) (Range loA hiA)->
let newForm = (FormatRowContiguous size)
in
basicAddressPopCount newForm
(Range (basicToDenseAddress newForm $ basicToDenseIndex form loA)
(basicToDenseAddress newForm $ basicToDenseIndex form hiA) )
basicAddressAsInt = \ _ (Address a) -> a
basicAffineAddressShift = basicAffineAddressShiftDenseGeneric
{-# INLINE basicAffineAddressShift #-}
{-# INLINE basicAddressRange #-}
{-# INLINE basicToAddress #-}
{-# INLINE basicToIndex #-}
{-# INLINE basicNextAddress #-}
{-# INLINE basicNextIndex #-}
{-# INLINE basicAddressPopCount #-}
type instance LayoutAddress (Format Column locality rank rep) = Address
instance (Applicative (Shape rank), Traversable (Shape rank))
=> Layout (Format Column 'Contiguous rank rep) rank where
{-# INLINE basicLogicalShape #-}
basicLogicalShape = boundsColumnContig
basicLogicalForm = id
transposedLayout = \(FormatColumnContiguous shp)-> FormatRowContiguous $ reverseShape shp
{-# INLINE basicCompareIndex #-}
basicCompareIndex = \ _ ls rs -> foldr majorCompareRightToLeft EQ $ S.map2 compare ls rs
basicAddressPopCount = \ _ (Range (Address lo) (Address hi )) ->
if hi >= lo then hi - lo
else error $ "for basicAddressPopCount, require address hi >= lo, given: "
++ show hi ++ " " ++ show lo
basicAddressRange = basicAddressRangeGeneric
basicToAddress = basicToAddressDenseGeneric
basicToIndex = basicToIndexDenseGeneric
basicNextAddress = basicNextAddressDenseGeneric
basicNextIndex = basicNextIndexDenseGeneric
basicAddressAsInt = \ _ (Address a) -> a
basicAffineAddressShift = basicAffineAddressShiftDenseGeneric
{-# INLINE basicAffineAddressShift #-}
{-# INLINE basicAddressRange #-}
{-# INLINE basicToAddress #-}
{-# INLINE basicToIndex #-}
{-# INLINE basicNextAddress #-}
{-# INLINE basicNextIndex #-}
{-# INLINE basicAddressPopCount #-}
instance (Applicative (Shape rank), Traversable (Shape rank))
=> Layout (Format Column 'InnerContiguous rank rep) rank where
{-# INLINE basicLogicalShape #-}
basicLogicalShape = boundsColumnInnerContig
basicLogicalForm form = FormatColumnContiguous $ basicLogicalShape form
transposedLayout = \(FormatColumnInnerContiguous shp stride)->
FormatRowInnerContiguous (reverseShape shp) (reverseShape stride)
{-# INLINE basicCompareIndex #-}
basicCompareIndex = \ _ ls rs -> foldr majorCompareRightToLeft EQ $ S.map2 compare ls rs
basicAddressRange = basicAddressRangeGeneric
basicToAddress = basicToAddressDenseGeneric
basicToIndex = basicToIndexDenseGeneric
basicNextAddress= basicNextAddressDenseGeneric
basicNextIndex= basicNextIndexDenseGeneric
basicAddressPopCount = \form@(FormatColumnInnerContiguous size _) (Range loA hiA)->
let newForm = (FormatColumnContiguous size)
in
basicAddressPopCount newForm
(Range (basicToDenseAddress newForm $ basicToDenseIndex form loA)
(basicToDenseAddress newForm $ basicToDenseIndex form hiA) )
basicAddressAsInt = \ _ (Address a) -> a
basicAffineAddressShift = basicAffineAddressShiftDenseGeneric
{-# INLINE basicAffineAddressShift #-}
{-# INLINE basicAddressRange #-}
{-# INLINE basicToAddress #-}
{-# INLINE basicToIndex #-}
{-# INLINE basicNextAddress #-}
{-# INLINE basicNextIndex #-}
{-# INLINE basicAddressPopCount #-}
instance (Applicative (Shape rank), Traversable (Shape rank))
=> Layout (Format Column 'Strided rank rep) rank where
{-# INLINE basicLogicalShape #-}
basicLogicalShape = boundsColumnStrided
basicLogicalForm form = FormatColumnContiguous $ basicLogicalShape form
transposedLayout = \(FormatColumnStrided shp stride)->
FormatRowStrided (reverseShape shp) (reverseShape stride)
{-# INLINE basicCompareIndex #-}
basicCompareIndex = \ _ ls rs -> foldr majorCompareRightToLeft EQ $ S.map2 compare ls rs
basicAddressRange = basicAddressRangeGeneric
basicToAddress = basicToAddressDenseGeneric
basicToIndex = basicToIndexDenseGeneric
basicNextAddress = basicNextAddressDenseGeneric
basicNextIndex = basicNextIndexDenseGeneric
basicAddressPopCount = \form@(FormatColumnStrided size _) (Range loA hiA)->
let newForm = (FormatColumnContiguous size)
in
basicAddressPopCount newForm
(Range (basicToDenseAddress newForm $ basicToDenseIndex form loA)
(basicToDenseAddress newForm $ basicToDenseIndex form hiA) )
basicAddressAsInt = \ _ (Address a) -> a
basicAffineAddressShift = basicAffineAddressShiftDenseGeneric
{-# INLINE basicAffineAddressShift #-}
{-# INLINE basicAddressRange #-}
{-# INLINE basicToAddress #-}
{-# INLINE basicToIndex #-}
{-# INLINE basicNextAddress #-}
{-# INLINE basicNextIndex #-}
{-# INLINE basicAddressPopCount #-}
{-# INLINE computeStrideShape #-}
computeStrideShape ::
((Int -> State Int Int) -> Shape n Int -> State Int (Shape n Int )) -> Shape n Int -> Shape n Int
computeStrideShape = \trvse shp ->
flip evalState 1 $
flip trvse shp $
\ val ->
do accum <- get ;
put $! (val * accum) ;
return accum;
instance DenseLayout (Format Direct 'Contiguous ('S 'Z) rep) ('S 'Z) where
{-#INLINE basicToDenseAddress #-}
basicToDenseAddress = \ (FormatDirectContiguous _) (j :* _ ) -> Address j
{-# INLINE basicToDenseIndex #-}
basicToDenseIndex = \ (FormatDirectContiguous _) (Address ix) -> (ix ) :* Nil
{-# INLINE basicNextDenseAddress #-}
basicNextDenseAddress = \ _ addr -> addr + 1
instance DenseLayout (Format Direct 'Strided ('S 'Z) rep) ('S 'Z) where
{-#INLINE basicToDenseAddress #-}
basicToDenseAddress = \ (FormatDirectStrided _ strid) (j :* Nil )-> Address (strid * j)
{-# INLINE basicNextDenseAddress #-}
basicNextDenseAddress = \ (FormatDirectStrided _ strid) addr -> addr + Address strid
{-# INLINE basicNextDenseIndex #-}
basicNextDenseIndex = \ form (i:* Nil ) -> (\ix -> (ix,basicToDenseAddress form ix)) $! (i + 1 :* Nil )
{-# INLINE basicToDenseIndex #-}
basicToDenseIndex = \ (FormatDirectStrided _ stride) (Address ix) -> (ix `div` stride ) :* Nil
instance (Applicative (Shape rank),F.Foldable (Shape rank), Traversable (Shape rank)) =>
DenseLayout (Format Row 'Contiguous rank rep) rank where
{-# INLINE basicToDenseAddress #-}
basicToDenseAddress = \rs tup ->
let !strider = computeStrideShape traverse (boundsFormRow rs)
in Address $! S.foldl' (+) 0 $! map2 (*) strider tup
{-# INLINE basicNextDenseAddress #-}
basicNextDenseAddress = \_ addr -> addr + 1
{-# INLINE basicToDenseIndex #-}
basicToDenseIndex = \ rs (Address ix) ->
let !striderShape = computeStrideShape traverse (boundsFormRow rs)
in
flip evalState ix $
flip (S.backwards traverse) striderShape $
\ currentStride ->
do remainderIx <- get ;
let (!qt,!rm)= quotRem remainderIx currentStride
put $! rm
return qt;
instance (Applicative (Shape rank),F.Foldable (Shape rank), Traversable (Shape rank))
=> DenseLayout (Format Row 'InnerContiguous rank rep) rank where
{-# INLINE basicToDenseAddress #-}
basicToDenseAddress = \rs tup ->
Address $! S.foldl' (+) 0 $!
map2 (*) (strideFormRowInnerContig rs ) tup
{-# INLINE basicNextDenseIndex #-}
basicNextDenseIndex = \ form@(FormatRowInnerContiguous shape _) ix ->
(\index -> (index,basicToDenseAddress form index)) $!
flip evalState 1 $
for ((,) <$> ix <*> shape) $
\(ixv ,shpv )->
do carry <-get
let (newCarry,modVal)=divMod (carry + ixv) shpv
put $! newCarry
return modVal
{-# INLINE basicToDenseIndex #-}
basicToDenseIndex = \ rs (Address ix) -> flip evalState ix $
flip ( S.backwards traverse) (strideFormRowInnerContig rs ) $
\ currentStride ->
do remainderIx <- get ;
let (!qt,!rm)= quotRem remainderIx currentStride
put $! rm
return qt;
instance (Applicative (Shape rank),F.Foldable (Shape rank), Traversable (Shape rank))
=> DenseLayout (Format Row 'Strided rank rep) rank where
{-# INLINE basicToDenseAddress #-}
basicToDenseAddress = \rs tup -> Address $!
S.foldl' (+) 0 $! map2 (*) (strideFormRowStrided rs ) tup
{-# INLINE basicNextDenseIndex #-}
basicNextDenseIndex = \ form@(FormatRowStrided shape _) ix ->
(\index -> (index,basicToDenseAddress form index)) $!
flip evalState 1 $
for ((,) <$> ix <*> shape) $
\(ixv ,shpv )->
do carry <-get
let (newCarry,modVal)=divMod (carry + ixv) shpv
put $! newCarry
return modVal
{-# INLINE basicToDenseIndex #-}
basicToDenseIndex = \ rs (Address ix) -> flip evalState ix $
flip (S.backwards traverse ) (strideFormRowStrided rs ) $
\ currentStride ->
do remainderIx <- get ;
let (!qt,!rm)= quotRem remainderIx currentStride
put $! rm
return qt;
instance (Applicative (Shape rank),F.Foldable (Shape rank), Traversable (Shape rank))
=> DenseLayout (Format Column 'Contiguous rank rep) rank where
{-# INLINE basicToDenseAddress #-}
basicToDenseAddress = \rs tup ->
let !strider = computeStrideShape (S.backwards traverse) (boundsColumnContig rs)
in Address $! S.foldl' (+) 0 $! map2 (*) strider tup
{-# INLINE basicNextDenseAddress #-}
basicNextDenseAddress = \_ addr -> addr + 1
{-# INLINE basicToDenseIndex #-}
basicToDenseIndex = \ rs (Address ix) ->
let !striderShape = computeStrideShape (S.backwards traverse) (boundsColumnContig rs)
in
flip evalState ix $
for striderShape $
\ currentStride ->
do remainderIx <- get ;
let (!qt,!rm)= quotRem remainderIx currentStride
put $! rm
return qt;
instance (Applicative (Shape rank),F.Foldable (Shape rank), Traversable (Shape rank))
=> DenseLayout (Format Column 'InnerContiguous rank rep) rank where
{-# INLINE basicToDenseAddress #-}
basicToDenseAddress = \ form tup -> let !strider = strideFormColumnInnerContig form
in Address $! foldl' (+) 0 $! map2 (*) strider tup
{-# INLINE basicNextDenseIndex #-}
basicNextDenseIndex = \ form@(FormatColumnInnerContiguous shape _) ix ->
(\index -> (index,basicToDenseAddress form index)) $!
flip evalState 1 $
flip (S.backwards traverse) ((,) <$> ix <*> shape) $
\(ixv ,shpv )->
do carry <-get
let (newCarry,modVal)=divMod (carry + ixv) shpv
put $! newCarry
return modVal
{-# INLINE basicToDenseIndex #-}
basicToDenseIndex = \ rs (Address ix) -> flip evalState ix $
flip S.traverse (strideFormColumnInnerContig rs ) $
\ currentStride ->
do remainderIx <- get ;
let (!qt,!rm)= quotRem remainderIx currentStride
put $! rm
return qt;
instance (Applicative (Shape rank),F.Foldable (Shape rank), Traversable (Shape rank))
=> DenseLayout (Format Column 'Strided rank rep) rank where
{-# INLINE basicToDenseAddress #-}
basicToDenseAddress = \ form tup -> let !strider = strideFormColumnStrided form
in Address $! foldl' (+) 0 $! map2 (*) strider tup
{-# INLINE basicNextDenseIndex #-}
basicNextDenseIndex = \ form@(FormatColumnStrided shape _) ix ->
(\index -> (index,basicToDenseAddress form index)) $!
flip evalState 1 $
flip (S.backwards traverse) ((,) <$> ix <*> shape) $
\(ixv ,shpv )->
do carry <-get
let (newCarry,modVal)=divMod (carry + ixv) shpv
put $! newCarry
return modVal
{-# INLINE basicToDenseIndex #-}
basicToDenseIndex = \ rs (Address ix) -> flip evalState ix $
flip S.traverse (strideFormColumnStrided rs ) $
\ currentStride ->
do remainderIx <- get ;
let (!qt,!rm)= quotRem remainderIx currentStride
put $! rm
return qt;