{-# LANGUAGE GADTs               #-}
{-# LANGUAGE RebindableSyntax    #-}
{-# LANGUAGE RecordWildCards     #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell     #-}
{-# LANGUAGE TypeApplications    #-}
{-# LANGUAGE TypeOperators       #-}
{-# OPTIONS_HADDOCK hide #-}
-- |
-- Module      : Data.Array.Accelerate.LLVM.CodeGen.Stencil
-- Copyright   : [2016..2020] The Accelerate Team
-- License     : BSD3
--
-- Maintainer  : Trevor L. McDonell <trevor.mcdonell@gmail.com>
-- Stability   : experimental
-- Portability : non-portable (GHC extensions)
--

module Data.Array.Accelerate.LLVM.CodeGen.Stencil
  where

import Data.Array.Accelerate.Error
import Data.Array.Accelerate.Representation.Array
import Data.Array.Accelerate.Representation.Shape
import Data.Array.Accelerate.Representation.Stencil
import Data.Array.Accelerate.Representation.Type
import Data.Array.Accelerate.Type

import Data.Array.Accelerate.LLVM.CodeGen.Arithmetic                ( ifThenElse )
import Data.Array.Accelerate.LLVM.CodeGen.Constant
import Data.Array.Accelerate.LLVM.CodeGen.IR
import Data.Array.Accelerate.LLVM.CodeGen.Monad
import Data.Array.Accelerate.LLVM.CodeGen.Sugar
import qualified Data.Array.Accelerate.LLVM.CodeGen.Arithmetic      as A

import Control.Applicative
import Prelude


-- Stencil boundary conditions
--
data IRBoundary arch aenv t where
  IRClamp     :: IRBoundary arch aenv t
  IRMirror    :: IRBoundary arch aenv t
  IRWrap      :: IRBoundary arch aenv t
  IRConstant  :: Operands e -> IRBoundary arch aenv (Array sh e)
  IRFunction  :: IRFun1 arch aenv (sh -> e) -> IRBoundary arch aenv (Array sh e)


-- Generate the stencil pattern including boundary conditions
--
stencilAccess
    :: HasCallStack
    => StencilR sh e stencil
    -> Maybe (IRBoundary arch aenv (Array sh e))
    ->        IRDelayed  arch aenv (Array sh e)
    -> Operands sh
    -> IRExp arch aenv stencil
stencilAccess :: StencilR sh e stencil
-> Maybe (IRBoundary arch aenv (Array sh e))
-> IRDelayed arch aenv (Array sh e)
-> Operands sh
-> IRExp arch aenv stencil
stencilAccess StencilR sh e stencil
sR Maybe (IRBoundary arch aenv (Array sh e))
mbndy IRDelayed arch aenv (Array sh e)
arr =
  case Maybe (IRBoundary arch aenv (Array sh e))
mbndy of
    Maybe (IRBoundary arch aenv (Array sh e))
Nothing   -> StencilR sh e stencil
-> (Operands sh -> IRExp arch Any e)
-> Operands sh
-> IRExp arch aenv stencil
forall sh e stencil arch aenv.
StencilR sh e stencil
-> (Operands sh -> IRExp arch aenv e)
-> Operands sh
-> IRExp arch aenv stencil
goR StencilR sh e stencil
sR (IRDelayed arch aenv (Array sh e) -> Operands sh -> IRExp arch Any e
forall arch aenv sh e.
IRDelayed arch aenv (Array sh e)
-> Operands sh -> IRExp arch aenv e
inbounds     IRDelayed arch aenv (Array sh e)
arr)
    Just IRBoundary arch aenv (Array sh e)
bndy -> StencilR sh e stencil
-> (Operands sh -> IRExp arch Any e)
-> Operands sh
-> IRExp arch aenv stencil
forall sh e stencil arch aenv.
StencilR sh e stencil
-> (Operands sh -> IRExp arch aenv e)
-> Operands sh
-> IRExp arch aenv stencil
goR StencilR sh e stencil
sR (IRBoundary arch aenv (Array sh e)
-> IRDelayed arch aenv (Array sh e)
-> Operands sh
-> IRExp arch Any e
forall sh e arch aenv.
HasCallStack =>
IRBoundary arch aenv (Array sh e)
-> IRDelayed arch aenv (Array sh e)
-> Operands sh
-> IRExp arch aenv e
bounded IRBoundary arch aenv (Array sh e)
bndy IRDelayed arch aenv (Array sh e)
arr)
  where
    -- Base cases, nothing interesting to do here since we know the lower
    -- dimension is Z.
    --
    goR :: StencilR sh e stencil
        -> (Operands sh -> IRExp arch aenv e)
        -> Operands sh
        -> IRExp arch aenv stencil
    goR :: StencilR sh e stencil
-> (Operands sh -> IRExp arch aenv e)
-> Operands sh
-> IRExp arch aenv stencil
goR (StencilRunit3 TypeR e
_) Operands sh -> IRExp arch aenv e
rf Operands sh
ix
      = let (Operands ()
z, Operands Int
i) = Operands ((), Int) -> (Operands (), Operands Int)
forall sh. Operands (sh, Int) -> (Operands sh, Operands Int)
unindex Operands sh
Operands ((), Int)
ix
            rf' :: Int -> IRExp arch aenv e
rf' Int
d  = do Operands Int
d' <- NumType Int
-> Operands Int -> Operands Int -> CodeGen arch (Operands Int)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
A.add NumType Int
forall a. IsNum a => NumType a
numType Operands Int
i (Int -> Operands Int
int Int
d)
                        Operands sh -> IRExp arch aenv e
rf (Operands () -> Operands Int -> Operands ((), Int)
forall sh. Operands sh -> Operands Int -> Operands (sh, Int)
index Operands ()
z Operands Int
d')
        in
        Operands e -> Operands e -> Operands e -> Operands (Tup3 e e e)
forall a b c.
Operands a -> Operands b -> Operands c -> Operands (Tup3 a b c)
tup3 (Operands e -> Operands e -> Operands e -> Operands (Tup3 e e e))
-> IRExp arch aenv e
-> CodeGen arch (Operands e -> Operands e -> Operands (Tup3 e e e))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> IRExp arch aenv e
rf' (-Int
1)
             CodeGen arch (Operands e -> Operands e -> Operands (Tup3 e e e))
-> IRExp arch aenv e
-> CodeGen arch (Operands e -> Operands (Tup3 e e e))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Operands sh -> IRExp arch aenv e
rf   Operands sh
ix
             CodeGen arch (Operands e -> Operands (Tup3 e e e))
-> IRExp arch aenv e -> CodeGen arch (Operands (Tup3 e e e))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> IRExp arch aenv e
rf'   Int
1

    goR (StencilRunit5 TypeR e
_) Operands sh -> IRExp arch aenv e
rf Operands sh
ix
      = let (Operands ()
z, Operands Int
i) = Operands ((), Int) -> (Operands (), Operands Int)
forall sh. Operands (sh, Int) -> (Operands sh, Operands Int)
unindex Operands sh
Operands ((), Int)
ix
            rf' :: Int -> IRExp arch aenv e
rf' Int
d  = do Operands Int
d' <- NumType Int
-> Operands Int -> Operands Int -> CodeGen arch (Operands Int)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
A.add NumType Int
forall a. IsNum a => NumType a
numType Operands Int
i (Int -> Operands Int
int Int
d)
                        Operands sh -> IRExp arch aenv e
rf (Operands () -> Operands Int -> Operands ((), Int)
forall sh. Operands sh -> Operands Int -> Operands (sh, Int)
index Operands ()
z Operands Int
d')
        in
        Operands e
-> Operands e
-> Operands e
-> Operands e
-> Operands e
-> Operands (Tup5 e e e e e)
forall a b c d e.
Operands a
-> Operands b
-> Operands c
-> Operands d
-> Operands e
-> Operands (Tup5 a b c d e)
tup5 (Operands e
 -> Operands e
 -> Operands e
 -> Operands e
 -> Operands e
 -> Operands (Tup5 e e e e e))
-> IRExp arch aenv e
-> CodeGen
     arch
     (Operands e
      -> Operands e
      -> Operands e
      -> Operands e
      -> Operands (Tup5 e e e e e))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> IRExp arch aenv e
rf' (-Int
2)
             CodeGen
  arch
  (Operands e
   -> Operands e
   -> Operands e
   -> Operands e
   -> Operands (Tup5 e e e e e))
-> IRExp arch aenv e
-> CodeGen
     arch
     (Operands e
      -> Operands e -> Operands e -> Operands (Tup5 e e e e e))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> IRExp arch aenv e
rf' (-Int
1)
             CodeGen
  arch
  (Operands e
   -> Operands e -> Operands e -> Operands (Tup5 e e e e e))
-> IRExp arch aenv e
-> CodeGen
     arch (Operands e -> Operands e -> Operands (Tup5 e e e e e))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Operands sh -> IRExp arch aenv e
rf   Operands sh
ix
             CodeGen
  arch (Operands e -> Operands e -> Operands (Tup5 e e e e e))
-> IRExp arch aenv e
-> CodeGen arch (Operands e -> Operands (Tup5 e e e e e))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> IRExp arch aenv e
rf'   Int
1
             CodeGen arch (Operands e -> Operands (Tup5 e e e e e))
-> IRExp arch aenv e -> CodeGen arch (Operands (Tup5 e e e e e))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> IRExp arch aenv e
rf'   Int
2

    goR (StencilRunit7 TypeR e
_) Operands sh -> IRExp arch aenv e
rf Operands sh
ix
      = let (Operands ()
z, Operands Int
i) = Operands ((), Int) -> (Operands (), Operands Int)
forall sh. Operands (sh, Int) -> (Operands sh, Operands Int)
unindex Operands sh
Operands ((), Int)
ix
            rf' :: Int -> IRExp arch aenv e
rf' Int
d  = do Operands Int
d' <- NumType Int
-> Operands Int -> Operands Int -> CodeGen arch (Operands Int)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
A.add NumType Int
forall a. IsNum a => NumType a
numType Operands Int
i (Int -> Operands Int
int Int
d)
                        Operands sh -> IRExp arch aenv e
rf (Operands () -> Operands Int -> Operands ((), Int)
forall sh. Operands sh -> Operands Int -> Operands (sh, Int)
index Operands ()
z Operands Int
d')
        in
        Operands e
-> Operands e
-> Operands e
-> Operands e
-> Operands e
-> Operands e
-> Operands e
-> Operands (Tup7 e e e e e e e)
forall a b c d e f g.
Operands a
-> Operands b
-> Operands c
-> Operands d
-> Operands e
-> Operands f
-> Operands g
-> Operands (Tup7 a b c d e f g)
tup7 (Operands e
 -> Operands e
 -> Operands e
 -> Operands e
 -> Operands e
 -> Operands e
 -> Operands e
 -> Operands (Tup7 e e e e e e e))
-> IRExp arch aenv e
-> CodeGen
     arch
     (Operands e
      -> Operands e
      -> Operands e
      -> Operands e
      -> Operands e
      -> Operands e
      -> Operands (Tup7 e e e e e e e))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> IRExp arch aenv e
rf' (-Int
3)
             CodeGen
  arch
  (Operands e
   -> Operands e
   -> Operands e
   -> Operands e
   -> Operands e
   -> Operands e
   -> Operands (Tup7 e e e e e e e))
-> IRExp arch aenv e
-> CodeGen
     arch
     (Operands e
      -> Operands e
      -> Operands e
      -> Operands e
      -> Operands e
      -> Operands (Tup7 e e e e e e e))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> IRExp arch aenv e
rf' (-Int
2)
             CodeGen
  arch
  (Operands e
   -> Operands e
   -> Operands e
   -> Operands e
   -> Operands e
   -> Operands (Tup7 e e e e e e e))
-> IRExp arch aenv e
-> CodeGen
     arch
     (Operands e
      -> Operands e
      -> Operands e
      -> Operands e
      -> Operands (Tup7 e e e e e e e))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> IRExp arch aenv e
rf' (-Int
1)
             CodeGen
  arch
  (Operands e
   -> Operands e
   -> Operands e
   -> Operands e
   -> Operands (Tup7 e e e e e e e))
-> IRExp arch aenv e
-> CodeGen
     arch
     (Operands e
      -> Operands e -> Operands e -> Operands (Tup7 e e e e e e e))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Operands sh -> IRExp arch aenv e
rf   Operands sh
ix
             CodeGen
  arch
  (Operands e
   -> Operands e -> Operands e -> Operands (Tup7 e e e e e e e))
-> IRExp arch aenv e
-> CodeGen
     arch (Operands e -> Operands e -> Operands (Tup7 e e e e e e e))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> IRExp arch aenv e
rf'   Int
1
             CodeGen
  arch (Operands e -> Operands e -> Operands (Tup7 e e e e e e e))
-> IRExp arch aenv e
-> CodeGen arch (Operands e -> Operands (Tup7 e e e e e e e))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> IRExp arch aenv e
rf'   Int
2
             CodeGen arch (Operands e -> Operands (Tup7 e e e e e e e))
-> IRExp arch aenv e
-> CodeGen arch (Operands (Tup7 e e e e e e e))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> IRExp arch aenv e
rf'   Int
3

    goR (StencilRunit9 TypeR e
_) Operands sh -> IRExp arch aenv e
rf Operands sh
ix
      = let (Operands ()
z, Operands Int
i) = Operands ((), Int) -> (Operands (), Operands Int)
forall sh. Operands (sh, Int) -> (Operands sh, Operands Int)
unindex Operands sh
Operands ((), Int)
ix
            rf' :: Int -> IRExp arch aenv e
rf' Int
d  = do Operands Int
d' <- NumType Int
-> Operands Int -> Operands Int -> CodeGen arch (Operands Int)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
A.add NumType Int
forall a. IsNum a => NumType a
numType Operands Int
i (Int -> Operands Int
int Int
d)
                        Operands sh -> IRExp arch aenv e
rf (Operands () -> Operands Int -> Operands ((), Int)
forall sh. Operands sh -> Operands Int -> Operands (sh, Int)
index Operands ()
z Operands Int
d')
        in
        Operands e
-> Operands e
-> Operands e
-> Operands e
-> Operands e
-> Operands e
-> Operands e
-> Operands e
-> Operands e
-> Operands (Tup9 e e e e e e e e e)
forall a b c d e f g h i.
Operands a
-> Operands b
-> Operands c
-> Operands d
-> Operands e
-> Operands f
-> Operands g
-> Operands h
-> Operands i
-> Operands (Tup9 a b c d e f g h i)
tup9 (Operands e
 -> Operands e
 -> Operands e
 -> Operands e
 -> Operands e
 -> Operands e
 -> Operands e
 -> Operands e
 -> Operands e
 -> Operands (Tup9 e e e e e e e e e))
-> IRExp arch aenv e
-> CodeGen
     arch
     (Operands e
      -> Operands e
      -> Operands e
      -> Operands e
      -> Operands e
      -> Operands e
      -> Operands e
      -> Operands e
      -> Operands (Tup9 e e e e e e e e e))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> IRExp arch aenv e
rf' (-Int
4)
             CodeGen
  arch
  (Operands e
   -> Operands e
   -> Operands e
   -> Operands e
   -> Operands e
   -> Operands e
   -> Operands e
   -> Operands e
   -> Operands (Tup9 e e e e e e e e e))
-> IRExp arch aenv e
-> CodeGen
     arch
     (Operands e
      -> Operands e
      -> Operands e
      -> Operands e
      -> Operands e
      -> Operands e
      -> Operands e
      -> Operands (Tup9 e e e e e e e e e))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> IRExp arch aenv e
rf' (-Int
3)
             CodeGen
  arch
  (Operands e
   -> Operands e
   -> Operands e
   -> Operands e
   -> Operands e
   -> Operands e
   -> Operands e
   -> Operands (Tup9 e e e e e e e e e))
-> IRExp arch aenv e
-> CodeGen
     arch
     (Operands e
      -> Operands e
      -> Operands e
      -> Operands e
      -> Operands e
      -> Operands e
      -> Operands (Tup9 e e e e e e e e e))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> IRExp arch aenv e
rf' (-Int
2)
             CodeGen
  arch
  (Operands e
   -> Operands e
   -> Operands e
   -> Operands e
   -> Operands e
   -> Operands e
   -> Operands (Tup9 e e e e e e e e e))
-> IRExp arch aenv e
-> CodeGen
     arch
     (Operands e
      -> Operands e
      -> Operands e
      -> Operands e
      -> Operands e
      -> Operands (Tup9 e e e e e e e e e))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> IRExp arch aenv e
rf' (-Int
1)
             CodeGen
  arch
  (Operands e
   -> Operands e
   -> Operands e
   -> Operands e
   -> Operands e
   -> Operands (Tup9 e e e e e e e e e))
-> IRExp arch aenv e
-> CodeGen
     arch
     (Operands e
      -> Operands e
      -> Operands e
      -> Operands e
      -> Operands (Tup9 e e e e e e e e e))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Operands sh -> IRExp arch aenv e
rf   Operands sh
ix
             CodeGen
  arch
  (Operands e
   -> Operands e
   -> Operands e
   -> Operands e
   -> Operands (Tup9 e e e e e e e e e))
-> IRExp arch aenv e
-> CodeGen
     arch
     (Operands e
      -> Operands e -> Operands e -> Operands (Tup9 e e e e e e e e e))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> IRExp arch aenv e
rf'   Int
1
             CodeGen
  arch
  (Operands e
   -> Operands e -> Operands e -> Operands (Tup9 e e e e e e e e e))
-> IRExp arch aenv e
-> CodeGen
     arch
     (Operands e -> Operands e -> Operands (Tup9 e e e e e e e e e))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> IRExp arch aenv e
rf'   Int
2
             CodeGen
  arch
  (Operands e -> Operands e -> Operands (Tup9 e e e e e e e e e))
-> IRExp arch aenv e
-> CodeGen arch (Operands e -> Operands (Tup9 e e e e e e e e e))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> IRExp arch aenv e
rf'   Int
3
             CodeGen arch (Operands e -> Operands (Tup9 e e e e e e e e e))
-> IRExp arch aenv e
-> CodeGen arch (Operands (Tup9 e e e e e e e e e))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> IRExp arch aenv e
rf'   Int
4

    -- Recursive cases. Note that because the stencil pattern is defined with
    -- a cons ordering, whereas shapes (indices) are defined as a snoc list,
    -- when we recurse on the stencil structure we must manipulate the
    -- _left-most_ index component
    --
    goR (StencilRtup3 StencilR sh1 e pat1
s1 StencilR sh1 e pat2
s2 StencilR sh1 e pat3
s3) Operands sh -> IRExp arch aenv e
rf Operands sh
ix =
      let shr :: ShapeR sh1
shr = StencilR sh1 e pat1 -> ShapeR sh1
forall sh e pat. StencilR sh e pat -> ShapeR sh
stencilShapeR StencilR sh1 e pat1
s1
          (Operands Int
i, Operands sh1
ix') = ShapeR sh1 -> Operands (sh1, Int) -> (Operands Int, Operands sh1)
forall sh.
ShapeR sh -> Operands (sh, Int) -> (Operands Int, Operands sh)
uncons ShapeR sh1
shr Operands sh
Operands (sh1, Int)
ix
          rf' :: Int -> Operands sh1 -> IRExp arch aenv e
rf' Int
0 Operands sh1
ds = Operands sh -> IRExp arch aenv e
rf (ShapeR sh1 -> Operands Int -> Operands sh1 -> Operands (sh1, Int)
forall sh.
ShapeR sh -> Operands Int -> Operands sh -> Operands (sh, Int)
cons ShapeR sh1
shr Operands Int
i Operands sh1
ds)
          rf' Int
d Operands sh1
ds = do Operands Int
d' <- NumType Int
-> Operands Int -> Operands Int -> CodeGen arch (Operands Int)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
A.add NumType Int
forall a. IsNum a => NumType a
numType Operands Int
i (Int -> Operands Int
int Int
d)
                        Operands sh -> IRExp arch aenv e
rf (ShapeR sh1 -> Operands Int -> Operands sh1 -> Operands (sh1, Int)
forall sh.
ShapeR sh -> Operands Int -> Operands sh -> Operands (sh, Int)
cons ShapeR sh1
shr Operands Int
d' Operands sh1
ds)
      in
      Operands pat1
-> Operands pat2 -> Operands pat3 -> Operands (Tup3 pat1 pat2 pat3)
forall a b c.
Operands a -> Operands b -> Operands c -> Operands (Tup3 a b c)
tup3 (Operands pat1
 -> Operands pat2
 -> Operands pat3
 -> Operands (Tup3 pat1 pat2 pat3))
-> CodeGen arch (Operands pat1)
-> CodeGen
     arch
     (Operands pat2 -> Operands pat3 -> Operands (Tup3 pat1 pat2 pat3))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StencilR sh1 e pat1
-> (Operands sh1 -> IRExp arch aenv e)
-> Operands sh1
-> CodeGen arch (Operands pat1)
forall sh e stencil arch aenv.
StencilR sh e stencil
-> (Operands sh -> IRExp arch aenv e)
-> Operands sh
-> IRExp arch aenv stencil
goR StencilR sh1 e pat1
s1 (Int -> Operands sh1 -> IRExp arch aenv e
rf' (-Int
1)) Operands sh1
ix'
           CodeGen
  arch
  (Operands pat2 -> Operands pat3 -> Operands (Tup3 pat1 pat2 pat3))
-> CodeGen arch (Operands pat2)
-> CodeGen arch (Operands pat3 -> Operands (Tup3 pat1 pat2 pat3))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> StencilR sh1 e pat2
-> (Operands sh1 -> IRExp arch aenv e)
-> Operands sh1
-> CodeGen arch (Operands pat2)
forall sh e stencil arch aenv.
StencilR sh e stencil
-> (Operands sh -> IRExp arch aenv e)
-> Operands sh
-> IRExp arch aenv stencil
goR StencilR sh1 e pat2
s2 (Int -> Operands sh1 -> IRExp arch aenv e
rf'   Int
0)  Operands sh1
ix'
           CodeGen arch (Operands pat3 -> Operands (Tup3 pat1 pat2 pat3))
-> CodeGen arch (Operands pat3)
-> CodeGen arch (Operands (Tup3 pat1 pat2 pat3))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> StencilR sh1 e pat3
-> (Operands sh1 -> IRExp arch aenv e)
-> Operands sh1
-> CodeGen arch (Operands pat3)
forall sh e stencil arch aenv.
StencilR sh e stencil
-> (Operands sh -> IRExp arch aenv e)
-> Operands sh
-> IRExp arch aenv stencil
goR StencilR sh1 e pat3
s3 (Int -> Operands sh1 -> IRExp arch aenv e
rf'   Int
1)  Operands sh1
ix'

    goR (StencilRtup5 StencilR sh1 e pat1
s1 StencilR sh1 e pat2
s2 StencilR sh1 e pat3
s3 StencilR sh1 e pat4
s4 StencilR sh1 e pat5
s5) Operands sh -> IRExp arch aenv e
rf Operands sh
ix =
      let shr :: ShapeR sh1
shr = StencilR sh1 e pat1 -> ShapeR sh1
forall sh e pat. StencilR sh e pat -> ShapeR sh
stencilShapeR StencilR sh1 e pat1
s1
          (Operands Int
i, Operands sh1
ix') = ShapeR sh1 -> Operands (sh1, Int) -> (Operands Int, Operands sh1)
forall sh.
ShapeR sh -> Operands (sh, Int) -> (Operands Int, Operands sh)
uncons ShapeR sh1
shr Operands sh
Operands (sh1, Int)
ix
          rf' :: Int -> Operands sh1 -> IRExp arch aenv e
rf' Int
0 Operands sh1
ds = Operands sh -> IRExp arch aenv e
rf (ShapeR sh1 -> Operands Int -> Operands sh1 -> Operands (sh1, Int)
forall sh.
ShapeR sh -> Operands Int -> Operands sh -> Operands (sh, Int)
cons ShapeR sh1
shr Operands Int
i Operands sh1
ds)
          rf' Int
d Operands sh1
ds = do Operands Int
d' <- NumType Int
-> Operands Int -> Operands Int -> CodeGen arch (Operands Int)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
A.add NumType Int
forall a. IsNum a => NumType a
numType Operands Int
i (Int -> Operands Int
int Int
d)
                        Operands sh -> IRExp arch aenv e
rf (ShapeR sh1 -> Operands Int -> Operands sh1 -> Operands (sh1, Int)
forall sh.
ShapeR sh -> Operands Int -> Operands sh -> Operands (sh, Int)
cons ShapeR sh1
shr Operands Int
d' Operands sh1
ds)
      in
      Operands pat1
-> Operands pat2
-> Operands pat3
-> Operands pat4
-> Operands pat5
-> Operands (Tup5 pat1 pat2 pat3 pat4 pat5)
forall a b c d e.
Operands a
-> Operands b
-> Operands c
-> Operands d
-> Operands e
-> Operands (Tup5 a b c d e)
tup5 (Operands pat1
 -> Operands pat2
 -> Operands pat3
 -> Operands pat4
 -> Operands pat5
 -> Operands (Tup5 pat1 pat2 pat3 pat4 pat5))
-> CodeGen arch (Operands pat1)
-> CodeGen
     arch
     (Operands pat2
      -> Operands pat3
      -> Operands pat4
      -> Operands pat5
      -> Operands (Tup5 pat1 pat2 pat3 pat4 pat5))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StencilR sh1 e pat1
-> (Operands sh1 -> IRExp arch aenv e)
-> Operands sh1
-> CodeGen arch (Operands pat1)
forall sh e stencil arch aenv.
StencilR sh e stencil
-> (Operands sh -> IRExp arch aenv e)
-> Operands sh
-> IRExp arch aenv stencil
goR StencilR sh1 e pat1
s1 (Int -> Operands sh1 -> IRExp arch aenv e
rf' (-Int
2)) Operands sh1
ix'
           CodeGen
  arch
  (Operands pat2
   -> Operands pat3
   -> Operands pat4
   -> Operands pat5
   -> Operands (Tup5 pat1 pat2 pat3 pat4 pat5))
-> CodeGen arch (Operands pat2)
-> CodeGen
     arch
     (Operands pat3
      -> Operands pat4
      -> Operands pat5
      -> Operands (Tup5 pat1 pat2 pat3 pat4 pat5))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> StencilR sh1 e pat2
-> (Operands sh1 -> IRExp arch aenv e)
-> Operands sh1
-> CodeGen arch (Operands pat2)
forall sh e stencil arch aenv.
StencilR sh e stencil
-> (Operands sh -> IRExp arch aenv e)
-> Operands sh
-> IRExp arch aenv stencil
goR StencilR sh1 e pat2
s2 (Int -> Operands sh1 -> IRExp arch aenv e
rf' (-Int
1)) Operands sh1
ix'
           CodeGen
  arch
  (Operands pat3
   -> Operands pat4
   -> Operands pat5
   -> Operands (Tup5 pat1 pat2 pat3 pat4 pat5))
-> CodeGen arch (Operands pat3)
-> CodeGen
     arch
     (Operands pat4
      -> Operands pat5 -> Operands (Tup5 pat1 pat2 pat3 pat4 pat5))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> StencilR sh1 e pat3
-> (Operands sh1 -> IRExp arch aenv e)
-> Operands sh1
-> CodeGen arch (Operands pat3)
forall sh e stencil arch aenv.
StencilR sh e stencil
-> (Operands sh -> IRExp arch aenv e)
-> Operands sh
-> IRExp arch aenv stencil
goR StencilR sh1 e pat3
s3 (Int -> Operands sh1 -> IRExp arch aenv e
rf'   Int
0)  Operands sh1
ix'
           CodeGen
  arch
  (Operands pat4
   -> Operands pat5 -> Operands (Tup5 pat1 pat2 pat3 pat4 pat5))
-> CodeGen arch (Operands pat4)
-> CodeGen
     arch (Operands pat5 -> Operands (Tup5 pat1 pat2 pat3 pat4 pat5))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> StencilR sh1 e pat4
-> (Operands sh1 -> IRExp arch aenv e)
-> Operands sh1
-> CodeGen arch (Operands pat4)
forall sh e stencil arch aenv.
StencilR sh e stencil
-> (Operands sh -> IRExp arch aenv e)
-> Operands sh
-> IRExp arch aenv stencil
goR StencilR sh1 e pat4
s4 (Int -> Operands sh1 -> IRExp arch aenv e
rf'   Int
1)  Operands sh1
ix'
           CodeGen
  arch (Operands pat5 -> Operands (Tup5 pat1 pat2 pat3 pat4 pat5))
-> CodeGen arch (Operands pat5)
-> CodeGen arch (Operands (Tup5 pat1 pat2 pat3 pat4 pat5))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> StencilR sh1 e pat5
-> (Operands sh1 -> IRExp arch aenv e)
-> Operands sh1
-> CodeGen arch (Operands pat5)
forall sh e stencil arch aenv.
StencilR sh e stencil
-> (Operands sh -> IRExp arch aenv e)
-> Operands sh
-> IRExp arch aenv stencil
goR StencilR sh1 e pat5
s5 (Int -> Operands sh1 -> IRExp arch aenv e
rf'   Int
2)  Operands sh1
ix'

    goR (StencilRtup7 StencilR sh1 e pat1
s1 StencilR sh1 e pat2
s2 StencilR sh1 e pat3
s3 StencilR sh1 e pat4
s4 StencilR sh1 e pat5
s5 StencilR sh1 e pat6
s6 StencilR sh1 e pat7
s7) Operands sh -> IRExp arch aenv e
rf Operands sh
ix =
      let shr :: ShapeR sh1
shr = StencilR sh1 e pat1 -> ShapeR sh1
forall sh e pat. StencilR sh e pat -> ShapeR sh
stencilShapeR StencilR sh1 e pat1
s1
          (Operands Int
i, Operands sh1
ix') = ShapeR sh1 -> Operands (sh1, Int) -> (Operands Int, Operands sh1)
forall sh.
ShapeR sh -> Operands (sh, Int) -> (Operands Int, Operands sh)
uncons ShapeR sh1
shr Operands sh
Operands (sh1, Int)
ix
          rf' :: Int -> Operands sh1 -> IRExp arch aenv e
rf' Int
0 Operands sh1
ds = Operands sh -> IRExp arch aenv e
rf (ShapeR sh1 -> Operands Int -> Operands sh1 -> Operands (sh1, Int)
forall sh.
ShapeR sh -> Operands Int -> Operands sh -> Operands (sh, Int)
cons ShapeR sh1
shr Operands Int
i Operands sh1
ds)
          rf' Int
d Operands sh1
ds = do Operands Int
d' <- NumType Int
-> Operands Int -> Operands Int -> CodeGen arch (Operands Int)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
A.add NumType Int
forall a. IsNum a => NumType a
numType Operands Int
i (Int -> Operands Int
int Int
d)
                        Operands sh -> IRExp arch aenv e
rf (ShapeR sh1 -> Operands Int -> Operands sh1 -> Operands (sh1, Int)
forall sh.
ShapeR sh -> Operands Int -> Operands sh -> Operands (sh, Int)
cons ShapeR sh1
shr Operands Int
d' Operands sh1
ds)
      in
      Operands pat1
-> Operands pat2
-> Operands pat3
-> Operands pat4
-> Operands pat5
-> Operands pat6
-> Operands pat7
-> Operands (Tup7 pat1 pat2 pat3 pat4 pat5 pat6 pat7)
forall a b c d e f g.
Operands a
-> Operands b
-> Operands c
-> Operands d
-> Operands e
-> Operands f
-> Operands g
-> Operands (Tup7 a b c d e f g)
tup7 (Operands pat1
 -> Operands pat2
 -> Operands pat3
 -> Operands pat4
 -> Operands pat5
 -> Operands pat6
 -> Operands pat7
 -> Operands (Tup7 pat1 pat2 pat3 pat4 pat5 pat6 pat7))
-> CodeGen arch (Operands pat1)
-> CodeGen
     arch
     (Operands pat2
      -> Operands pat3
      -> Operands pat4
      -> Operands pat5
      -> Operands pat6
      -> Operands pat7
      -> Operands (Tup7 pat1 pat2 pat3 pat4 pat5 pat6 pat7))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StencilR sh1 e pat1
-> (Operands sh1 -> IRExp arch aenv e)
-> Operands sh1
-> CodeGen arch (Operands pat1)
forall sh e stencil arch aenv.
StencilR sh e stencil
-> (Operands sh -> IRExp arch aenv e)
-> Operands sh
-> IRExp arch aenv stencil
goR StencilR sh1 e pat1
s1 (Int -> Operands sh1 -> IRExp arch aenv e
rf' (-Int
3)) Operands sh1
ix'
           CodeGen
  arch
  (Operands pat2
   -> Operands pat3
   -> Operands pat4
   -> Operands pat5
   -> Operands pat6
   -> Operands pat7
   -> Operands (Tup7 pat1 pat2 pat3 pat4 pat5 pat6 pat7))
-> CodeGen arch (Operands pat2)
-> CodeGen
     arch
     (Operands pat3
      -> Operands pat4
      -> Operands pat5
      -> Operands pat6
      -> Operands pat7
      -> Operands (Tup7 pat1 pat2 pat3 pat4 pat5 pat6 pat7))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> StencilR sh1 e pat2
-> (Operands sh1 -> IRExp arch aenv e)
-> Operands sh1
-> CodeGen arch (Operands pat2)
forall sh e stencil arch aenv.
StencilR sh e stencil
-> (Operands sh -> IRExp arch aenv e)
-> Operands sh
-> IRExp arch aenv stencil
goR StencilR sh1 e pat2
s2 (Int -> Operands sh1 -> IRExp arch aenv e
rf' (-Int
2)) Operands sh1
ix'
           CodeGen
  arch
  (Operands pat3
   -> Operands pat4
   -> Operands pat5
   -> Operands pat6
   -> Operands pat7
   -> Operands (Tup7 pat1 pat2 pat3 pat4 pat5 pat6 pat7))
-> CodeGen arch (Operands pat3)
-> CodeGen
     arch
     (Operands pat4
      -> Operands pat5
      -> Operands pat6
      -> Operands pat7
      -> Operands (Tup7 pat1 pat2 pat3 pat4 pat5 pat6 pat7))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> StencilR sh1 e pat3
-> (Operands sh1 -> IRExp arch aenv e)
-> Operands sh1
-> CodeGen arch (Operands pat3)
forall sh e stencil arch aenv.
StencilR sh e stencil
-> (Operands sh -> IRExp arch aenv e)
-> Operands sh
-> IRExp arch aenv stencil
goR StencilR sh1 e pat3
s3 (Int -> Operands sh1 -> IRExp arch aenv e
rf' (-Int
1)) Operands sh1
ix'
           CodeGen
  arch
  (Operands pat4
   -> Operands pat5
   -> Operands pat6
   -> Operands pat7
   -> Operands (Tup7 pat1 pat2 pat3 pat4 pat5 pat6 pat7))
-> CodeGen arch (Operands pat4)
-> CodeGen
     arch
     (Operands pat5
      -> Operands pat6
      -> Operands pat7
      -> Operands (Tup7 pat1 pat2 pat3 pat4 pat5 pat6 pat7))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> StencilR sh1 e pat4
-> (Operands sh1 -> IRExp arch aenv e)
-> Operands sh1
-> CodeGen arch (Operands pat4)
forall sh e stencil arch aenv.
StencilR sh e stencil
-> (Operands sh -> IRExp arch aenv e)
-> Operands sh
-> IRExp arch aenv stencil
goR StencilR sh1 e pat4
s4 (Int -> Operands sh1 -> IRExp arch aenv e
rf'   Int
0)  Operands sh1
ix'
           CodeGen
  arch
  (Operands pat5
   -> Operands pat6
   -> Operands pat7
   -> Operands (Tup7 pat1 pat2 pat3 pat4 pat5 pat6 pat7))
-> CodeGen arch (Operands pat5)
-> CodeGen
     arch
     (Operands pat6
      -> Operands pat7
      -> Operands (Tup7 pat1 pat2 pat3 pat4 pat5 pat6 pat7))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> StencilR sh1 e pat5
-> (Operands sh1 -> IRExp arch aenv e)
-> Operands sh1
-> CodeGen arch (Operands pat5)
forall sh e stencil arch aenv.
StencilR sh e stencil
-> (Operands sh -> IRExp arch aenv e)
-> Operands sh
-> IRExp arch aenv stencil
goR StencilR sh1 e pat5
s5 (Int -> Operands sh1 -> IRExp arch aenv e
rf'   Int
1)  Operands sh1
ix'
           CodeGen
  arch
  (Operands pat6
   -> Operands pat7
   -> Operands (Tup7 pat1 pat2 pat3 pat4 pat5 pat6 pat7))
-> CodeGen arch (Operands pat6)
-> CodeGen
     arch
     (Operands pat7
      -> Operands (Tup7 pat1 pat2 pat3 pat4 pat5 pat6 pat7))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> StencilR sh1 e pat6
-> (Operands sh1 -> IRExp arch aenv e)
-> Operands sh1
-> CodeGen arch (Operands pat6)
forall sh e stencil arch aenv.
StencilR sh e stencil
-> (Operands sh -> IRExp arch aenv e)
-> Operands sh
-> IRExp arch aenv stencil
goR StencilR sh1 e pat6
s6 (Int -> Operands sh1 -> IRExp arch aenv e
rf'   Int
2)  Operands sh1
ix'
           CodeGen
  arch
  (Operands pat7
   -> Operands (Tup7 pat1 pat2 pat3 pat4 pat5 pat6 pat7))
-> CodeGen arch (Operands pat7)
-> CodeGen
     arch (Operands (Tup7 pat1 pat2 pat3 pat4 pat5 pat6 pat7))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> StencilR sh1 e pat7
-> (Operands sh1 -> IRExp arch aenv e)
-> Operands sh1
-> CodeGen arch (Operands pat7)
forall sh e stencil arch aenv.
StencilR sh e stencil
-> (Operands sh -> IRExp arch aenv e)
-> Operands sh
-> IRExp arch aenv stencil
goR StencilR sh1 e pat7
s7 (Int -> Operands sh1 -> IRExp arch aenv e
rf'   Int
3)  Operands sh1
ix'

    goR (StencilRtup9 StencilR sh1 e pat1
s1 StencilR sh1 e pat2
s2 StencilR sh1 e pat3
s3 StencilR sh1 e pat4
s4 StencilR sh1 e pat5
s5 StencilR sh1 e pat6
s6 StencilR sh1 e pat7
s7 StencilR sh1 e pat8
s8 StencilR sh1 e pat9
s9) Operands sh -> IRExp arch aenv e
rf Operands sh
ix =
      let shr :: ShapeR sh1
shr = StencilR sh1 e pat1 -> ShapeR sh1
forall sh e pat. StencilR sh e pat -> ShapeR sh
stencilShapeR StencilR sh1 e pat1
s1
          (Operands Int
i, Operands sh1
ix') = ShapeR sh1 -> Operands (sh1, Int) -> (Operands Int, Operands sh1)
forall sh.
ShapeR sh -> Operands (sh, Int) -> (Operands Int, Operands sh)
uncons ShapeR sh1
shr Operands sh
Operands (sh1, Int)
ix
          rf' :: Int -> Operands sh1 -> IRExp arch aenv e
rf' Int
0 Operands sh1
ds = Operands sh -> IRExp arch aenv e
rf (ShapeR sh1 -> Operands Int -> Operands sh1 -> Operands (sh1, Int)
forall sh.
ShapeR sh -> Operands Int -> Operands sh -> Operands (sh, Int)
cons ShapeR sh1
shr Operands Int
i Operands sh1
ds)
          rf' Int
d Operands sh1
ds = do Operands Int
d' <- NumType Int
-> Operands Int -> Operands Int -> CodeGen arch (Operands Int)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
A.add NumType Int
forall a. IsNum a => NumType a
numType Operands Int
i (Int -> Operands Int
int Int
d)
                        Operands sh -> IRExp arch aenv e
rf (ShapeR sh1 -> Operands Int -> Operands sh1 -> Operands (sh1, Int)
forall sh.
ShapeR sh -> Operands Int -> Operands sh -> Operands (sh, Int)
cons ShapeR sh1
shr Operands Int
d' Operands sh1
ds)
      in
      Operands pat1
-> Operands pat2
-> Operands pat3
-> Operands pat4
-> Operands pat5
-> Operands pat6
-> Operands pat7
-> Operands pat8
-> Operands pat9
-> Operands (Tup9 pat1 pat2 pat3 pat4 pat5 pat6 pat7 pat8 pat9)
forall a b c d e f g h i.
Operands a
-> Operands b
-> Operands c
-> Operands d
-> Operands e
-> Operands f
-> Operands g
-> Operands h
-> Operands i
-> Operands (Tup9 a b c d e f g h i)
tup9 (Operands pat1
 -> Operands pat2
 -> Operands pat3
 -> Operands pat4
 -> Operands pat5
 -> Operands pat6
 -> Operands pat7
 -> Operands pat8
 -> Operands pat9
 -> Operands (Tup9 pat1 pat2 pat3 pat4 pat5 pat6 pat7 pat8 pat9))
-> CodeGen arch (Operands pat1)
-> CodeGen
     arch
     (Operands pat2
      -> Operands pat3
      -> Operands pat4
      -> Operands pat5
      -> Operands pat6
      -> Operands pat7
      -> Operands pat8
      -> Operands pat9
      -> Operands (Tup9 pat1 pat2 pat3 pat4 pat5 pat6 pat7 pat8 pat9))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StencilR sh1 e pat1
-> (Operands sh1 -> IRExp arch aenv e)
-> Operands sh1
-> CodeGen arch (Operands pat1)
forall sh e stencil arch aenv.
StencilR sh e stencil
-> (Operands sh -> IRExp arch aenv e)
-> Operands sh
-> IRExp arch aenv stencil
goR StencilR sh1 e pat1
s1 (Int -> Operands sh1 -> IRExp arch aenv e
rf' (-Int
4)) Operands sh1
ix'
           CodeGen
  arch
  (Operands pat2
   -> Operands pat3
   -> Operands pat4
   -> Operands pat5
   -> Operands pat6
   -> Operands pat7
   -> Operands pat8
   -> Operands pat9
   -> Operands (Tup9 pat1 pat2 pat3 pat4 pat5 pat6 pat7 pat8 pat9))
-> CodeGen arch (Operands pat2)
-> CodeGen
     arch
     (Operands pat3
      -> Operands pat4
      -> Operands pat5
      -> Operands pat6
      -> Operands pat7
      -> Operands pat8
      -> Operands pat9
      -> Operands (Tup9 pat1 pat2 pat3 pat4 pat5 pat6 pat7 pat8 pat9))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> StencilR sh1 e pat2
-> (Operands sh1 -> IRExp arch aenv e)
-> Operands sh1
-> CodeGen arch (Operands pat2)
forall sh e stencil arch aenv.
StencilR sh e stencil
-> (Operands sh -> IRExp arch aenv e)
-> Operands sh
-> IRExp arch aenv stencil
goR StencilR sh1 e pat2
s2 (Int -> Operands sh1 -> IRExp arch aenv e
rf' (-Int
3)) Operands sh1
ix'
           CodeGen
  arch
  (Operands pat3
   -> Operands pat4
   -> Operands pat5
   -> Operands pat6
   -> Operands pat7
   -> Operands pat8
   -> Operands pat9
   -> Operands (Tup9 pat1 pat2 pat3 pat4 pat5 pat6 pat7 pat8 pat9))
-> CodeGen arch (Operands pat3)
-> CodeGen
     arch
     (Operands pat4
      -> Operands pat5
      -> Operands pat6
      -> Operands pat7
      -> Operands pat8
      -> Operands pat9
      -> Operands (Tup9 pat1 pat2 pat3 pat4 pat5 pat6 pat7 pat8 pat9))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> StencilR sh1 e pat3
-> (Operands sh1 -> IRExp arch aenv e)
-> Operands sh1
-> CodeGen arch (Operands pat3)
forall sh e stencil arch aenv.
StencilR sh e stencil
-> (Operands sh -> IRExp arch aenv e)
-> Operands sh
-> IRExp arch aenv stencil
goR StencilR sh1 e pat3
s3 (Int -> Operands sh1 -> IRExp arch aenv e
rf' (-Int
2)) Operands sh1
ix'
           CodeGen
  arch
  (Operands pat4
   -> Operands pat5
   -> Operands pat6
   -> Operands pat7
   -> Operands pat8
   -> Operands pat9
   -> Operands (Tup9 pat1 pat2 pat3 pat4 pat5 pat6 pat7 pat8 pat9))
-> CodeGen arch (Operands pat4)
-> CodeGen
     arch
     (Operands pat5
      -> Operands pat6
      -> Operands pat7
      -> Operands pat8
      -> Operands pat9
      -> Operands (Tup9 pat1 pat2 pat3 pat4 pat5 pat6 pat7 pat8 pat9))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> StencilR sh1 e pat4
-> (Operands sh1 -> IRExp arch aenv e)
-> Operands sh1
-> CodeGen arch (Operands pat4)
forall sh e stencil arch aenv.
StencilR sh e stencil
-> (Operands sh -> IRExp arch aenv e)
-> Operands sh
-> IRExp arch aenv stencil
goR StencilR sh1 e pat4
s4 (Int -> Operands sh1 -> IRExp arch aenv e
rf' (-Int
1)) Operands sh1
ix'
           CodeGen
  arch
  (Operands pat5
   -> Operands pat6
   -> Operands pat7
   -> Operands pat8
   -> Operands pat9
   -> Operands (Tup9 pat1 pat2 pat3 pat4 pat5 pat6 pat7 pat8 pat9))
-> CodeGen arch (Operands pat5)
-> CodeGen
     arch
     (Operands pat6
      -> Operands pat7
      -> Operands pat8
      -> Operands pat9
      -> Operands (Tup9 pat1 pat2 pat3 pat4 pat5 pat6 pat7 pat8 pat9))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> StencilR sh1 e pat5
-> (Operands sh1 -> IRExp arch aenv e)
-> Operands sh1
-> CodeGen arch (Operands pat5)
forall sh e stencil arch aenv.
StencilR sh e stencil
-> (Operands sh -> IRExp arch aenv e)
-> Operands sh
-> IRExp arch aenv stencil
goR StencilR sh1 e pat5
s5 (Int -> Operands sh1 -> IRExp arch aenv e
rf'   Int
0)  Operands sh1
ix'
           CodeGen
  arch
  (Operands pat6
   -> Operands pat7
   -> Operands pat8
   -> Operands pat9
   -> Operands (Tup9 pat1 pat2 pat3 pat4 pat5 pat6 pat7 pat8 pat9))
-> CodeGen arch (Operands pat6)
-> CodeGen
     arch
     (Operands pat7
      -> Operands pat8
      -> Operands pat9
      -> Operands (Tup9 pat1 pat2 pat3 pat4 pat5 pat6 pat7 pat8 pat9))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> StencilR sh1 e pat6
-> (Operands sh1 -> IRExp arch aenv e)
-> Operands sh1
-> CodeGen arch (Operands pat6)
forall sh e stencil arch aenv.
StencilR sh e stencil
-> (Operands sh -> IRExp arch aenv e)
-> Operands sh
-> IRExp arch aenv stencil
goR StencilR sh1 e pat6
s6 (Int -> Operands sh1 -> IRExp arch aenv e
rf'   Int
1)  Operands sh1
ix'
           CodeGen
  arch
  (Operands pat7
   -> Operands pat8
   -> Operands pat9
   -> Operands (Tup9 pat1 pat2 pat3 pat4 pat5 pat6 pat7 pat8 pat9))
-> CodeGen arch (Operands pat7)
-> CodeGen
     arch
     (Operands pat8
      -> Operands pat9
      -> Operands (Tup9 pat1 pat2 pat3 pat4 pat5 pat6 pat7 pat8 pat9))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> StencilR sh1 e pat7
-> (Operands sh1 -> IRExp arch aenv e)
-> Operands sh1
-> CodeGen arch (Operands pat7)
forall sh e stencil arch aenv.
StencilR sh e stencil
-> (Operands sh -> IRExp arch aenv e)
-> Operands sh
-> IRExp arch aenv stencil
goR StencilR sh1 e pat7
s7 (Int -> Operands sh1 -> IRExp arch aenv e
rf'   Int
2)  Operands sh1
ix'
           CodeGen
  arch
  (Operands pat8
   -> Operands pat9
   -> Operands (Tup9 pat1 pat2 pat3 pat4 pat5 pat6 pat7 pat8 pat9))
-> CodeGen arch (Operands pat8)
-> CodeGen
     arch
     (Operands pat9
      -> Operands (Tup9 pat1 pat2 pat3 pat4 pat5 pat6 pat7 pat8 pat9))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> StencilR sh1 e pat8
-> (Operands sh1 -> IRExp arch aenv e)
-> Operands sh1
-> CodeGen arch (Operands pat8)
forall sh e stencil arch aenv.
StencilR sh e stencil
-> (Operands sh -> IRExp arch aenv e)
-> Operands sh
-> IRExp arch aenv stencil
goR StencilR sh1 e pat8
s8 (Int -> Operands sh1 -> IRExp arch aenv e
rf'   Int
3)  Operands sh1
ix'
           CodeGen
  arch
  (Operands pat9
   -> Operands (Tup9 pat1 pat2 pat3 pat4 pat5 pat6 pat7 pat8 pat9))
-> CodeGen arch (Operands pat9)
-> CodeGen
     arch (Operands (Tup9 pat1 pat2 pat3 pat4 pat5 pat6 pat7 pat8 pat9))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> StencilR sh1 e pat9
-> (Operands sh1 -> IRExp arch aenv e)
-> Operands sh1
-> CodeGen arch (Operands pat9)
forall sh e stencil arch aenv.
StencilR sh e stencil
-> (Operands sh -> IRExp arch aenv e)
-> Operands sh
-> IRExp arch aenv stencil
goR StencilR sh1 e pat9
s9 (Int -> Operands sh1 -> IRExp arch aenv e
rf'   Int
4)  Operands sh1
ix'


-- Do not apply any boundary conditions to the given index
--
inbounds
    :: IRDelayed arch aenv (Array sh e)
    -> Operands sh
    -> IRExp arch aenv e
inbounds :: IRDelayed arch aenv (Array sh e)
-> Operands sh -> IRExp arch aenv e
inbounds IRDelayed{ArrayR (Array sh e)
IRExp arch aenv sh
IRFun1 arch aenv (sh -> e)
IRFun1 arch aenv (Int -> e)
delayedLinearIndex :: forall arch aenv sh e.
IRDelayed arch aenv (Array sh e) -> IRFun1 arch aenv (Int -> e)
delayedIndex :: forall arch aenv sh e.
IRDelayed arch aenv (Array sh e) -> IRFun1 arch aenv (sh -> e)
delayedExtent :: forall arch aenv sh e.
IRDelayed arch aenv (Array sh e) -> IRExp arch aenv sh
delayedRepr :: forall arch aenv sh e.
IRDelayed arch aenv (Array sh e) -> ArrayR (Array sh e)
delayedLinearIndex :: IRFun1 arch aenv (Int -> e)
delayedIndex :: IRFun1 arch aenv (sh -> e)
delayedExtent :: IRExp arch aenv sh
delayedRepr :: ArrayR (Array sh e)
..} Operands sh
ix =
  IRFun1 arch aenv (sh -> e)
-> Operands sh -> IROpenExp arch ((), sh) aenv e
forall arch env aenv a b.
IROpenFun1 arch env aenv (a -> b)
-> Operands a -> IROpenExp arch (env, a) aenv b
app1 IRFun1 arch aenv (sh -> e)
delayedIndex Operands sh
Operands sh
ix


-- Apply boundary conditions to the given index
--
bounded
    :: forall sh e arch aenv. HasCallStack
    => IRBoundary arch aenv (Array sh e)
    -> IRDelayed  arch aenv (Array sh e)
    -> Operands sh
    -> IRExp arch aenv e
bounded :: IRBoundary arch aenv (Array sh e)
-> IRDelayed arch aenv (Array sh e)
-> Operands sh
-> IRExp arch aenv e
bounded IRBoundary arch aenv (Array sh e)
bndy IRDelayed{ArrayR (Array sh e)
IRExp arch aenv sh
IRFun1 arch aenv (sh -> e)
IRFun1 arch aenv (Int -> e)
delayedLinearIndex :: IRFun1 arch aenv (Int -> e)
delayedIndex :: IRFun1 arch aenv (sh -> e)
delayedExtent :: IRExp arch aenv sh
delayedRepr :: ArrayR (Array sh e)
delayedLinearIndex :: forall arch aenv sh e.
IRDelayed arch aenv (Array sh e) -> IRFun1 arch aenv (Int -> e)
delayedIndex :: forall arch aenv sh e.
IRDelayed arch aenv (Array sh e) -> IRFun1 arch aenv (sh -> e)
delayedExtent :: forall arch aenv sh e.
IRDelayed arch aenv (Array sh e) -> IRExp arch aenv sh
delayedRepr :: forall arch aenv sh e.
IRDelayed arch aenv (Array sh e) -> ArrayR (Array sh e)
..} Operands sh
ix = do
  let
    tp :: TypeR e -- GHC 8.4 needs this type annotation
    ArrayR ShapeR sh
shr TypeR e
tp = ArrayR (Array sh e)
delayedRepr
  Operands sh
sh <- IRExp arch aenv sh
delayedExtent
  case IRBoundary arch aenv (Array sh e)
bndy of
    IRConstant Operands e
v ->
      if ( TypeR e
tp, ShapeR sh
-> Operands sh -> Operands sh -> CodeGen arch (Operands Bool)
forall sh'.
ShapeR sh'
-> Operands sh' -> Operands sh' -> CodeGen arch (Operands Bool)
inside ShapeR sh
shr Operands sh
sh Operands sh
Operands sh
ix )
        then IRFun1 arch aenv (sh -> e)
-> Operands sh -> IROpenExp arch ((), sh) aenv e
forall arch env aenv a b.
IROpenFun1 arch env aenv (a -> b)
-> Operands a -> IROpenExp arch (env, a) aenv b
app1 IRFun1 arch aenv (sh -> e)
delayedIndex Operands sh
Operands sh
ix
        else Operands e -> CodeGen arch (Operands e)
forall (m :: * -> *) a. Monad m => a -> m a
return Operands e
v
    IRFunction IRFun1 arch aenv (sh -> e)
f ->
      if ( TypeR e
tp, ShapeR sh
-> Operands sh -> Operands sh -> CodeGen arch (Operands Bool)
forall sh'.
ShapeR sh'
-> Operands sh' -> Operands sh' -> CodeGen arch (Operands Bool)
inside ShapeR sh
shr Operands sh
sh Operands sh
Operands sh
ix )
        then IRFun1 arch aenv (sh -> e)
-> Operands sh -> IROpenExp arch ((), sh) aenv e
forall arch env aenv a b.
IROpenFun1 arch env aenv (a -> b)
-> Operands a -> IROpenExp arch (env, a) aenv b
app1 IRFun1 arch aenv (sh -> e)
delayedIndex Operands sh
Operands sh
ix
        else IRFun1 arch aenv (sh -> e)
-> Operands sh -> IROpenExp arch ((), sh) aenv e
forall arch env aenv a b.
IROpenFun1 arch env aenv (a -> b)
-> Operands a -> IROpenExp arch (env, a) aenv b
app1 IRFun1 arch aenv (sh -> e)
f Operands sh
Operands sh
ix
    IRBoundary arch aenv (Array sh e)
_            -> do
      Operands sh
ix' <- ShapeR sh -> Operands sh -> Operands sh -> IRExp arch aenv sh
forall sh'.
ShapeR sh'
-> Operands sh' -> Operands sh' -> CodeGen arch (Operands sh')
bound ShapeR sh
shr Operands sh
sh Operands sh
Operands sh
ix
      Operands e
v   <- IRFun1 arch aenv (sh -> e)
-> Operands sh -> IROpenExp arch ((), sh) aenv e
forall arch env aenv a b.
IROpenFun1 arch env aenv (a -> b)
-> Operands a -> IROpenExp arch (env, a) aenv b
app1 IRFun1 arch aenv (sh -> e)
delayedIndex Operands sh
ix'
      Operands e -> IROpenExp arch ((), sh) aenv e
forall (m :: * -> *) a. Monad m => a -> m a
return Operands e
v
  --
  where
    -- Return the index, updated to obey the given boundary conditions (clamp,
    -- mirror, or wrap only).
    --
    bound :: ShapeR sh' -> Operands sh' -> Operands sh' -> CodeGen arch (Operands sh')
    bound :: ShapeR sh'
-> Operands sh' -> Operands sh' -> CodeGen arch (Operands sh')
bound ShapeR sh'
ShapeRz Operands sh'
OP_Unit Operands sh'
OP_Unit
      = Operands () -> CodeGen arch (Operands ())
forall (m :: * -> *) a. Monad m => a -> m a
return Operands ()
OP_Unit
    bound (ShapeRsnoc ShapeR sh1
shr') (OP_Pair sh sz) (OP_Pair ih iz)
      = do
            Operands sh1
ix' <- ShapeR sh1
-> Operands sh1 -> Operands sh1 -> CodeGen arch (Operands sh1)
forall sh'.
ShapeR sh'
-> Operands sh' -> Operands sh' -> CodeGen arch (Operands sh')
bound ShapeR sh1
shr' Operands sh1
sh Operands sh1
ih
            Operands Int
i' <- if ( ScalarType Int -> TupR ScalarType Int
forall (s :: * -> *) a. s a -> TupR s a
TupRsingle ScalarType Int
scalarTypeInt
                        , SingleType Int
-> Operands Int -> Operands Int -> CodeGen arch (Operands Bool)
forall a arch.
SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
A.lt (SingleType Int
forall a. IsSingle a => SingleType a
singleType :: SingleType Int) Operands Int
iz (Int -> Operands Int
int Int
0))
                      then
                        case IRBoundary arch aenv (Array sh e)
bndy of
                          IRBoundary arch aenv (Array sh e)
IRClamp  -> Operands Int -> CodeGen arch (Operands Int)
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> Operands Int
int Int
0)
                          IRBoundary arch aenv (Array sh e)
IRMirror -> NumType Int -> Operands Int -> CodeGen arch (Operands Int)
forall a arch. NumType a -> Operands a -> CodeGen arch (Operands a)
A.negate NumType Int
forall a. IsNum a => NumType a
numType Operands Int
iz
                          IRBoundary arch aenv (Array sh e)
IRWrap   -> NumType Int
-> Operands Int -> Operands Int -> CodeGen arch (Operands Int)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
A.add    NumType Int
forall a. IsNum a => NumType a
numType Operands Int
sz Operands Int
iz
                          IRBoundary arch aenv (Array sh e)
_        -> String -> CodeGen arch (Operands Int)
forall a. HasCallStack => String -> a
internalError String
"unexpected boundary condition"
                      else
                        if ( ScalarType Int -> TupR ScalarType Int
forall (s :: * -> *) a. s a -> TupR s a
TupRsingle ScalarType Int
scalarTypeInt
                            , SingleType Int
-> Operands Int -> Operands Int -> CodeGen arch (Operands Bool)
forall a arch.
SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
A.gte (SingleType Int
forall a. IsSingle a => SingleType a
singleType :: SingleType Int) Operands Int
iz Operands Int
sz)
                          then
                            case IRBoundary arch aenv (Array sh e)
bndy of
                              IRBoundary arch aenv (Array sh e)
IRClamp  -> NumType Int
-> Operands Int -> Operands Int -> CodeGen arch (Operands Int)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
A.sub NumType Int
forall a. IsNum a => NumType a
numType Operands Int
sz (Int -> Operands Int
int Int
1)
                              IRBoundary arch aenv (Array sh e)
IRWrap   -> NumType Int
-> Operands Int -> Operands Int -> CodeGen arch (Operands Int)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
A.sub NumType Int
forall a. IsNum a => NumType a
numType Operands Int
iz Operands Int
sz
                              IRBoundary arch aenv (Array sh e)
IRMirror -> do
                                Operands Int
a <- NumType Int
-> Operands Int -> Operands Int -> CodeGen arch (Operands Int)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
A.sub NumType Int
forall a. IsNum a => NumType a
numType Operands Int
iz Operands Int
sz
                                Operands Int
b <- NumType Int
-> Operands Int -> Operands Int -> CodeGen arch (Operands Int)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
A.add NumType Int
forall a. IsNum a => NumType a
numType Operands Int
a (Int -> Operands Int
int Int
2)
                                Operands Int
c <- NumType Int
-> Operands Int -> Operands Int -> CodeGen arch (Operands Int)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
A.sub NumType Int
forall a. IsNum a => NumType a
numType Operands Int
sz Operands Int
b
                                Operands Int -> CodeGen arch (Operands Int)
forall (m :: * -> *) a. Monad m => a -> m a
return Operands Int
c
                              IRBoundary arch aenv (Array sh e)
_        -> String -> CodeGen arch (Operands Int)
forall a. HasCallStack => String -> a
internalError String
"unexpected boundary condition"
                          else
                            Operands Int -> CodeGen arch (Operands Int)
forall (m :: * -> *) a. Monad m => a -> m a
return Operands Int
iz
            Operands (sh1, Int) -> CodeGen arch (Operands (sh1, Int))
forall (m :: * -> *) a. Monad m => a -> m a
return (Operands (sh1, Int) -> CodeGen arch (Operands (sh1, Int)))
-> Operands (sh1, Int) -> CodeGen arch (Operands (sh1, Int))
forall a b. (a -> b) -> a -> b
$ Operands sh1 -> Operands Int -> Operands (sh1, Int)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair Operands sh1
ix' Operands Int
i'

    -- Return whether the index is inside the bounds of the given shape
    --
    inside :: ShapeR sh' -> Operands sh' -> Operands sh' -> CodeGen arch (Operands Bool)
    inside :: ShapeR sh'
-> Operands sh' -> Operands sh' -> CodeGen arch (Operands Bool)
inside ShapeR sh'
ShapeRz Operands sh'
OP_Unit Operands sh'
OP_Unit
      = Operands Bool -> CodeGen arch (Operands Bool)
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> Operands Bool
bool Bool
True)
    inside (ShapeRsnoc ShapeR sh1
shr') (OP_Pair sh sz) (OP_Pair ih iz)
      = do
           Block
ifNext <- String -> CodeGen arch Block
forall arch. HasCallStack => String -> CodeGen arch Block
newBlock String
"inside.next"
           Block
ifExit <- String -> CodeGen arch Block
forall arch. HasCallStack => String -> CodeGen arch Block
newBlock String
"inside.exit"

           Block
_  <- String -> CodeGen arch Block
forall arch. HasCallStack => String -> CodeGen arch Block
beginBlock String
"inside.entry"
           Operands Bool
p  <- SingleType Int
-> Operands Int -> Operands Int -> CodeGen arch (Operands Bool)
forall a arch.
SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
A.lt  (SingleType Int
forall a. IsSingle a => SingleType a
singleType :: SingleType Int) Operands Int
iz (Int -> Operands Int
int Int
0) CodeGen arch (Operands Bool)
-> CodeGen arch (Operands Bool) -> CodeGen arch (Operands Bool)
forall arch.
CodeGen arch (Operands Bool)
-> CodeGen arch (Operands Bool) -> CodeGen arch (Operands Bool)
`A.lor'`
                 SingleType Int
-> Operands Int -> Operands Int -> CodeGen arch (Operands Bool)
forall a arch.
SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
A.gte (SingleType Int
forall a. IsSingle a => SingleType a
singleType :: SingleType Int) Operands Int
iz Operands Int
sz
           Block
eb <- Operands Bool -> Block -> Block -> CodeGen arch Block
forall arch.
HasCallStack =>
Operands Bool -> Block -> Block -> CodeGen arch Block
cbr Operands Bool
p Block
ifExit Block
ifNext

           Block -> CodeGen arch ()
forall arch. Block -> CodeGen arch ()
setBlock Block
ifNext
           Operands Bool
nv <- ShapeR sh1
-> Operands sh1 -> Operands sh1 -> CodeGen arch (Operands Bool)
forall sh'.
ShapeR sh'
-> Operands sh' -> Operands sh' -> CodeGen arch (Operands Bool)
inside ShapeR sh1
shr' Operands sh1
sh Operands sh1
ih
           Block
nb <- Block -> CodeGen arch Block
forall arch. HasCallStack => Block -> CodeGen arch Block
br Block
ifExit

           Block -> CodeGen arch ()
forall arch. Block -> CodeGen arch ()
setBlock Block
ifExit
           Name Bool
crit <- CodeGen arch (Name Bool)
forall arch a. CodeGen arch (Name a)
freshName
           Operand Bool
r    <- Block
-> Name Bool
-> [(Operand Bool, Block)]
-> CodeGen arch (Operand Bool)
forall a arch.
HasCallStack =>
Block -> Name a -> [(Operand a, Block)] -> CodeGen arch (Operand a)
phi1 Block
ifExit Name Bool
crit [(Bool -> Operand Bool
boolean Bool
False, Block
eb), (Operands Bool -> Operand Bool
A.unbool Operands Bool
nv, Block
nb)]

           Operands Bool -> CodeGen arch (Operands Bool)
forall (m :: * -> *) a. Monad m => a -> m a
return (Operand Bool -> Operands Bool
OP_Bool Operand Bool
r)


-- Utilities
-- ---------

int :: Int -> Operands Int
int :: Int -> Operands Int
int Int
x = TupR ScalarType Int -> Int -> Operands Int
forall a. TypeR a -> a -> Operands a
constant (ScalarType Int -> TupR ScalarType Int
forall (s :: * -> *) a. s a -> TupR s a
TupRsingle ScalarType Int
scalarTypeInt) Int
x

bool :: Bool -> Operands Bool
bool :: Bool -> Operands Bool
bool = Operand Bool -> Operands Bool
OP_Bool (Operand Bool -> Operands Bool)
-> (Bool -> Operand Bool) -> Bool -> Operands Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Operand Bool
boolean

unindex :: Operands (sh, Int) -> (Operands sh, Operands Int)
unindex :: Operands (sh, Int) -> (Operands sh, Operands Int)
unindex (OP_Pair sh i) = (Operands sh
sh, Operands Int
i)

index :: Operands sh -> Operands Int -> Operands (sh, Int)
index :: Operands sh -> Operands Int -> Operands (sh, Int)
index Operands sh
sh Operands Int
i = Operands sh -> Operands Int -> Operands (sh, Int)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair Operands sh
sh Operands Int
i

tup3 :: Operands a -> Operands b -> Operands c -> Operands (Tup3 a b c)
tup3 :: Operands a -> Operands b -> Operands c -> Operands (Tup3 a b c)
tup3 Operands a
a Operands b
b Operands c
c = Operands (((), a), b) -> Operands c -> Operands (Tup3 a b c)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair (Operands ((), a) -> Operands b -> Operands (((), a), b)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair (Operands () -> Operands a -> Operands ((), a)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair Operands ()
OP_Unit Operands a
a) Operands b
b) Operands c
c

tup5 :: Operands a -> Operands b -> Operands c -> Operands d -> Operands e -> Operands (Tup5 a b c d e)
tup5 :: Operands a
-> Operands b
-> Operands c
-> Operands d
-> Operands e
-> Operands (Tup5 a b c d e)
tup5 Operands a
a Operands b
b Operands c
c Operands d
d Operands e
e =
  Operands (((((), a), b), c), d)
-> Operands e -> Operands (Tup5 a b c d e)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair (Operands ((((), a), b), c)
-> Operands d -> Operands (((((), a), b), c), d)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair (Operands (((), a), b) -> Operands c -> Operands ((((), a), b), c)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair (Operands ((), a) -> Operands b -> Operands (((), a), b)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair (Operands () -> Operands a -> Operands ((), a)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair Operands ()
OP_Unit Operands a
a) Operands b
b) Operands c
c) Operands d
d) Operands e
e

tup7 :: Operands a -> Operands b -> Operands c -> Operands d -> Operands e -> Operands f -> Operands g -> Operands (Tup7 a b c d e f g)
tup7 :: Operands a
-> Operands b
-> Operands c
-> Operands d
-> Operands e
-> Operands f
-> Operands g
-> Operands (Tup7 a b c d e f g)
tup7 Operands a
a Operands b
b Operands c
c Operands d
d Operands e
e Operands f
f Operands g
g =
  Operands (((((((), a), b), c), d), e), f)
-> Operands g -> Operands (Tup7 a b c d e f g)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair (Operands ((((((), a), b), c), d), e)
-> Operands f -> Operands (((((((), a), b), c), d), e), f)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair (Operands (((((), a), b), c), d)
-> Operands e -> Operands ((((((), a), b), c), d), e)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair (Operands ((((), a), b), c)
-> Operands d -> Operands (((((), a), b), c), d)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair (Operands (((), a), b) -> Operands c -> Operands ((((), a), b), c)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair (Operands ((), a) -> Operands b -> Operands (((), a), b)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair (Operands () -> Operands a -> Operands ((), a)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair Operands ()
OP_Unit Operands a
a) Operands b
b) Operands c
c) Operands d
d) Operands e
e) Operands f
f) Operands g
g

tup9 :: Operands a -> Operands b -> Operands c -> Operands d -> Operands e -> Operands f -> Operands g -> Operands h -> Operands i -> Operands (Tup9 a b c d e f g h i)
tup9 :: Operands a
-> Operands b
-> Operands c
-> Operands d
-> Operands e
-> Operands f
-> Operands g
-> Operands h
-> Operands i
-> Operands (Tup9 a b c d e f g h i)
tup9 Operands a
a Operands b
b Operands c
c Operands d
d Operands e
e Operands f
f Operands g
g Operands h
h Operands i
i =
  Operands (((((((((), a), b), c), d), e), f), g), h)
-> Operands i -> Operands (Tup9 a b c d e f g h i)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair (Operands ((((((((), a), b), c), d), e), f), g)
-> Operands h
-> Operands (((((((((), a), b), c), d), e), f), g), h)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair (Operands (((((((), a), b), c), d), e), f)
-> Operands g -> Operands ((((((((), a), b), c), d), e), f), g)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair (Operands ((((((), a), b), c), d), e)
-> Operands f -> Operands (((((((), a), b), c), d), e), f)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair (Operands (((((), a), b), c), d)
-> Operands e -> Operands ((((((), a), b), c), d), e)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair (Operands ((((), a), b), c)
-> Operands d -> Operands (((((), a), b), c), d)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair (Operands (((), a), b) -> Operands c -> Operands ((((), a), b), c)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair (Operands ((), a) -> Operands b -> Operands (((), a), b)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair (Operands () -> Operands a -> Operands ((), a)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair Operands ()
OP_Unit Operands a
a) Operands b
b) Operands c
c) Operands d
d) Operands e
e) Operands f
f) Operands g
g) Operands h
h) Operands i
i


-- Add a _left-most_ dimension to a shape
--
cons :: ShapeR sh -> Operands Int -> Operands sh -> Operands (sh, Int)
cons :: ShapeR sh -> Operands Int -> Operands sh -> Operands (sh, Int)
cons ShapeR sh
ShapeRz          Operands Int
ix Operands sh
OP_Unit         = Operands () -> Operands Int -> Operands ((), Int)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair Operands ()
OP_Unit Operands Int
ix
cons (ShapeRsnoc ShapeR sh1
shr) Operands Int
ix (OP_Pair sh sz) = Operands (sh1, Int) -> Operands Int -> Operands ((sh1, Int), Int)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair (ShapeR sh1 -> Operands Int -> Operands sh1 -> Operands (sh1, Int)
forall sh.
ShapeR sh -> Operands Int -> Operands sh -> Operands (sh, Int)
cons ShapeR sh1
shr Operands Int
ix Operands sh1
sh) Operands Int
sz


-- Remove the _left-most_ index to a shape, and return the remainder
--
uncons :: ShapeR sh -> Operands (sh, Int) -> (Operands Int, Operands sh)
uncons :: ShapeR sh -> Operands (sh, Int) -> (Operands Int, Operands sh)
uncons ShapeR sh
ShapeRz          (OP_Pair OP_Unit v2) = (Operands Int
v2, Operands sh
Operands ()
OP_Unit)
uncons (ShapeRsnoc ShapeR sh1
shr) (OP_Pair v1 v3)
  = let (Operands Int
i, Operands sh1
v1') = ShapeR sh1 -> Operands (sh1, Int) -> (Operands Int, Operands sh1)
forall sh.
ShapeR sh -> Operands (sh, Int) -> (Operands Int, Operands sh)
uncons ShapeR sh1
shr Operands sh
Operands (sh1, Int)
v1
    in  (Operands Int
i, Operands sh1 -> Operands Int -> Operands (sh1, Int)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair Operands sh1
v1' Operands Int
v3)