module Data.Array.Repa.Stencil.Partition ( Offset (..) , Size (..) , Region (..) , partitionForStencil) where -- | An offset in the 2d plane. data Offset = Offset !Int !Int -- | Size of a region in the 2d plane. data Size = Size !Int !Int -- | A region in the 2d plane. data Region = Region { regionX :: !Int , regionY :: !Int , regionWidth :: !Int , regionHeight :: !Int } deriving Show -- | Create a new region of the given size. regionOfSize :: Size -> Region regionOfSize (Size w h) = Region 0 0 w h {-# INLINE regionOfSize #-} -- | Offset a region. offsetRegion :: Offset -> Region -> Region offsetRegion (Offset x y) (Region x0 y0 w h) = Region (x0 + x) (y0 + y) w h {-# INLINE offsetRegion #-} -- | Partition a region into inner and border regions for the given stencil. partitionForStencil :: Size -- ^ Size of array -> Size -- ^ Size of stencil -> Offset -- ^ Focus of stencil -> [Region] partitionForStencil (Size arrW arrH) (Size krnW krnH) (Offset focX focY) = let gapNorth = focY gapSouth = krnH - focY - 1 gapWest = focX gapEast = krnW - focX - 1 innerW = arrW - gapWest - gapEast innerH = arrH - gapNorth - gapSouth regionInner = offsetRegion (Offset gapWest gapNorth) $ regionOfSize (Size innerW innerH) regionNorth = regionOfSize (Size arrW gapNorth) regionSouth = offsetRegion (Offset 0 (gapNorth + innerH)) $ regionOfSize (Size arrW gapSouth) regionWest = offsetRegion (Offset 0 gapNorth) $ regionOfSize (Size gapWest innerH) regionEast = offsetRegion (Offset (gapWest + innerW) gapNorth) $ regionOfSize (Size gapEast innerH) in [regionInner, regionNorth, regionSouth, regionWest, regionEast] {-# INLINE partitionForStencil #-}