diff --git a/Data/Array/Repa/Eval.hs b/Data/Array/Repa/Eval.hs
--- a/Data/Array/Repa/Eval.hs
+++ b/Data/Array/Repa/Eval.hs
@@ -17,7 +17,7 @@
         , now
         
         -- * Chunked filling
-        , fillChunkedS
+        , fillLinearS
         , fillChunkedP
         , fillChunkedIOP
 
diff --git a/Data/Array/Repa/Eval/Chunked.hs b/Data/Array/Repa/Eval/Chunked.hs
--- a/Data/Array/Repa/Eval/Chunked.hs
+++ b/Data/Array/Repa/Eval/Chunked.hs
@@ -2,37 +2,87 @@
 -- | Evaluate an array by breaking it up into linear chunks and filling
 --   each chunk in parallel.
 module Data.Array.Repa.Eval.Chunked
-	( fillChunkedP
-	, fillChunkedS
+	( fillLinearS
+        , fillBlock2S
+        , fillChunkedP
 	, fillChunkedIOP)
 where
+import Data.Array.Repa.Index
 import Data.Array.Repa.Eval.Gang
+
 import GHC.Exts
 import Prelude		as P
 
+-------------------------------------------------------------------------------
 -- | Fill something sequentially.
 -- 
 --   * The array is filled linearly from start to finish.  
 -- 
-fillChunkedS
+fillLinearS
 	:: Int                  -- ^ Number of elements.
 	-> (Int -> a -> IO ())	-- ^ Update function to write into result buffer.
 	-> (Int -> a)	        -- ^ Fn to get the value at a given index.
 	-> IO ()
 
-{-# INLINE [0] fillChunkedS #-}
-fillChunkedS !(I# len) write getElem
+fillLinearS !(I# len) write getElem
  = fill 0#
  where	fill !ix
 	 | ix >=# len	= return ()
 	 | otherwise
 	 = do	write (I# ix) (getElem (I# ix))
 		fill (ix +# 1#)
+{-# INLINE [0] fillLinearS #-}
 
 
+-------------------------------------------------------------------------------
+-- | Fill a block in a rank-2 array, sequentially.
+--
+--   * Blockwise filling can be more cache-efficient than linear filling for
+--     rank-2 arrays.
+--
+--   * The block is filled in row major order from top to bottom.
+--
+fillBlock2S
+        :: (Int  -> a -> IO ()) -- ^ Update function to write into result buffer.
+        -> (DIM2 -> a)          -- ^ Fn to get the value at the given index.
+        -> Int#                 -- ^ Width of the whole array.
+        -> Int#                 -- ^ x0 lower left corner of block to fill.
+        -> Int#                 -- ^ y0
+        -> Int#                 -- ^ w0 width of block to fill
+        -> Int#                 -- ^ h0 height of block to fill
+        -> IO ()
+
+fillBlock2S
+        write getElem
+        !imageWidth !x0 !y0 !w0 h0
+
+ = do   fillBlock y0 ix0
+ where  !x1     = x0 +# w0
+        !y1     = y0 +# h0
+        !ix0    = x0 +# (y0 *# imageWidth)
+
+        {-# INLINE fillBlock #-}
+        fillBlock !y !ix
+         | y >=# y1     = return ()
+         | otherwise
+         = do   fillLine1 x0 ix
+                fillBlock (y +# 1#) (ix +# imageWidth)
+
+         where  {-# INLINE fillLine1 #-}
+                fillLine1 !x !ix'
+                 | x >=# x1             = return ()
+                 | otherwise
+                 = do   write (I# ix') (getElem (Z :. (I# y) :. (I# x)))
+                        fillLine1 (x +# 1#) (ix' +# 1#)
+
+{-# INLINE [0] fillBlock2S #-}
+
+
+-------------------------------------------------------------------------------
 -- | Fill something in parallel.
 -- 
---   * The array is split into linear chunks and each thread fills one chunk.
+--   * The array is split into linear chunks,
+--     and each thread linearly fills one chunk.
 -- 
 fillChunkedP
         :: Int                  -- ^ Number of elements.
@@ -40,7 +90,6 @@
 	-> (Int -> a)	        -- ^ Fn to get the value at a given index.
 	-> IO ()
 
-{-# INLINE [0] fillChunkedP #-}
 fillChunkedP !(I# len) write getElem
  = 	gangIO theGang
 	 $  \(I# thread) -> 
@@ -68,18 +117,25 @@
 	 | otherwise
 	 = do	write (I# ix) (getElem (I# ix))
 		fill (ix +# 1#) end
+{-# INLINE [0] fillChunkedP #-}
 
 
+-------------------------------------------------------------------------------
 -- | Fill something in parallel, using a separate IO action for each thread.
+--
+--   * The array is split into linear chunks,
+--     and each thread linearly fills one chunk.
+--
 fillChunkedIOP
-        :: Int                          -- ^ Number of elements.
-        -> (Int -> a -> IO ())          -- ^ Update fn to write into result buffer.
-        -> (Int -> IO (Int -> IO a))    -- ^ Create a fn to get the value at a given index.
-                                        --   The first `Int` is the thread number, so you can do some
-                                        --   per-thread initialisation.
+        :: Int  -- ^ Number of elements.
+        -> (Int -> a -> IO ())          
+                -- ^ Update fn to write into result buffer.
+        -> (Int -> IO (Int -> IO a))    
+                -- ^ Create a fn to get the value at a given index.
+                --   The first `Int` is the thread number, so you can do some
+                --   per-thread initialisation.
         -> IO ()
 
-{-# INLINE [0] fillChunkedIOP #-}
 fillChunkedIOP !(I# len) write mkGetElem
  = 	gangIO theGang
 	 $  \(I# thread) -> 
@@ -100,7 +156,6 @@
 	 | thread <# chunkLeftover = thread *# (chunkLen +# 1#)
 	 | otherwise		   = thread *# chunkLen  +# chunkLeftover
 
-
         -- Given the threadId, starting and ending indices. 
         --      Make a function to get each element for this chunk
         --      and call it for every index.
@@ -120,3 +175,6 @@
 	         = do	x       <- getElem (I# ix)
 	                write (I# ix) x
                         go (ix +# 1#)
+{-# INLINE [0] fillChunkedIOP #-}
+
+
diff --git a/Data/Array/Repa/Eval/Cursored.hs b/Data/Array/Repa/Eval/Cursored.hs
--- a/Data/Array/Repa/Eval/Cursored.hs
+++ b/Data/Array/Repa/Eval/Cursored.hs
@@ -3,7 +3,6 @@
 --   each block in parallel.
 module Data.Array.Repa.Eval.Cursored
 	( fillBlock2P
-	, fillBlock2S
 	, fillCursoredBlock2P
 	, fillCursoredBlock2S )
 where
@@ -43,7 +42,7 @@
         write id addDim getElem 
         imageWidth x0 y0 w0 h0
 
-
+{-
 -- | Fill a block in a rank-2 array sequentially.
 --
 --   * Blockwise filling can be more cache-efficient than linear filling for
@@ -69,7 +68,7 @@
  = fillCursoredBlock2S
         write id addDim getElem 
         imageWidth x0 y0 w0 h0
-
+-}
 
 -- Block filling ----------------------------------------------------------------------------------
 -- | Fill a block in a rank-2 array in parallel.
diff --git a/Data/Array/Repa/Eval/Gang.hs b/Data/Array/Repa/Eval/Gang.hs
--- a/Data/Array/Repa/Eval/Gang.hs
+++ b/Data/Array/Repa/Eval/Gang.hs
@@ -100,7 +100,7 @@
         -- Add finalisers so we can shut the workers down cleanly if they
         -- become unreachable.
         zipWithM_ (\varReq varDone 
-                        -> addMVarFinalizer varReq (finaliseWorker varReq varDone)) 
+                        -> mkWeakMVar varReq (finaliseWorker varReq varDone)) 
                 mvsRequest
                 mvsDone
 
diff --git a/Data/Array/Repa/Operators/Mapping.hs b/Data/Array/Repa/Operators/Mapping.hs
--- a/Data/Array/Repa/Operators/Mapping.hs
+++ b/Data/Array/Repa/Operators/Mapping.hs
@@ -16,6 +16,7 @@
 import Data.Array.Repa.Repr.Delayed
 import Data.Array.Repa.Repr.ForeignPtr
 import Data.Array.Repa.Repr.HintSmall
+import Data.Array.Repa.Repr.HintInterleave
 import Data.Array.Repa.Repr.Partitioned
 import Data.Array.Repa.Repr.Unboxed
 import Data.Array.Repa.Repr.Undefined
@@ -176,6 +177,20 @@
 
  szipWith f arr1 (ASmall arr2)
         = ASmall (szipWith f arr1 arr2)
+ {-# INLINE [3] szipWith #-}
+
+
+-- Interleaved ------------------------
+instance   Structured r1 a b
+        => Structured (I r1) a b where
+ type TR (I r1) = I (TR r1)
+
+ smap f (AInterleave arr1)
+        = AInterleave (smap f arr1)
+ {-# INLINE [3] smap #-}
+
+ szipWith f arr1 (AInterleave arr2)
+        = AInterleave (szipWith f arr1 arr2)
  {-# INLINE [3] szipWith #-}
 
 
diff --git a/Data/Array/Repa/Repr/Delayed.hs b/Data/Array/Repa/Repr/Delayed.hs
--- a/Data/Array/Repa/Repr/Delayed.hs
+++ b/Data/Array/Repa/Repr/Delayed.hs
@@ -57,7 +57,7 @@
  loadS (ADelayed sh getElem) mvec
   = mvec `deepSeqMVec` 
     do  traceEventIO "Repa.loadS[Delayed]: start"
-        fillChunkedS (size sh) (unsafeWriteMVec mvec) (getElem . fromIndex sh)
+        fillLinearS (size sh) (unsafeWriteMVec mvec) (getElem . fromIndex sh)
         touchMVec mvec
         traceEventIO "Repa.loadS[Delayed]: end"
  {-# INLINE [4] loadS #-}
diff --git a/Data/Array/Repa/Stencil/Base.hs b/Data/Array/Repa/Stencil/Base.hs
--- a/Data/Array/Repa/Stencil/Base.hs
+++ b/Data/Array/Repa/Stencil/Base.hs
@@ -10,10 +10,10 @@
 -- | How to handle the case when the stencil lies partly outside the array.
 data Boundary a
         -- | Use a fixed value for border regions.
-        = BoundFixed a
+        = BoundFixed !a
 
 	-- | Treat points outside the array as having a constant value.
-	| BoundConst a
+	| BoundConst !a
 
 	-- | Clamp points outside to the same value as the edge pixel.
 	| BoundClamp
diff --git a/Data/Array/Repa/Stencil/Dim2.hs b/Data/Array/Repa/Stencil/Dim2.hs
--- a/Data/Array/Repa/Stencil/Dim2.hs
+++ b/Data/Array/Repa/Stencil/Dim2.hs
@@ -115,7 +115,6 @@
                 BoundFixed c    -> c
                 BoundConst c    -> unsafeAppStencilCursor2_const addDim stencil c arr ix
                 BoundClamp      -> unsafeAppStencilCursor2_clamp addDim stencil arr ix
-
    in
     --  internal region
         APart sh (Range (Z :.    inY :.    inX) (Z :.    inH :.    inW) inInternal) arrInternal
@@ -191,11 +190,12 @@
                 {-# NOINLINE getData' #-}
                 getData' :: Int# -> Int# -> a
                 getData' !x !y
-                 | x <# 0#       = fixed
-                 | x >=# aWidth  = fixed
-                 | y <# 0#       = fixed
-                 | y >=# aHeight = fixed
-                 | otherwise     = arr `unsafeIndex` (Z :. (I# y) :.  (I# x))
+                 |   x <# 0# || x >=# aWidth
+                  || y <# 0# || y >=# aHeight
+                 = fixed
+
+                 | otherwise
+                 = arr `unsafeIndex` (Z :. (I# y) :.  (I# x))
 
                 -- Build a function to pass data from the array to our stencil.
                 {-# INLINE oload #-}
diff --git a/Data/Array/Repa/Stencil/Template.hs b/Data/Array/Repa/Stencil/Template.hs
--- a/Data/Array/Repa/Stencil/Template.hs
+++ b/Data/Array/Repa/Stencil/Template.hs
@@ -92,7 +92,7 @@
 	 $ AppE (VarE (mkName "makeStencil2") 
                         `AppE` (LitE (IntegerL sizeX)) 
                         `AppE` (LitE (IntegerL sizeY)))
-         $ LetE [ PragmaD (InlineP (mkName "coeffs") (InlineSpec True False Nothing))
+         $ LetE [ PragmaD (InlineP (mkName "coeffs") Inline FunLike (BeforePhase 0))
 		, ValD 	  (VarP    coeffs')          (NormalB fnCoeffs) [] ]
 		(VarE (mkName "coeffs"))
 
diff --git a/repa.cabal b/repa.cabal
--- a/repa.cabal
+++ b/repa.cabal
@@ -1,5 +1,5 @@
 Name:                repa
-Version:             3.2.1.1
+Version:             3.2.2.1
 License:             BSD3
 License-file:        LICENSE
 Author:              The DPH Team
@@ -23,12 +23,12 @@
 
 Library
   Build-Depends: 
-        base                 == 4.*,
-        ghc-prim             == 0.2.*,
+        base                 == 4.6.*,
+        ghc-prim             == 0.3.*,
         vector               == 0.9.*,
-        bytestring           == 0.9.*,
-        QuickCheck           >= 2.3 && < 2.5,
-        template-haskell     >= 2.5 && < 2.8
+        bytestring           == 0.10.*,
+        template-haskell     == 2.8.*,
+        QuickCheck           >= 2.3 && < 2.6
 
   ghc-options:
         -Wall -fno-warn-missing-signatures
