{-# LANGUAGE FlexibleContexts #-}
module Futhark.Internalise.AccurateSizes
  ( shapeBody
  , argShapes
  , ensureResultShape
  , ensureResultExtShape
  , ensureResultExtShapeNoCtx
  , ensureExtShape
  , ensureShape
  , ensureArgShapes
  )
  where

import Control.Monad
import Data.Loc
import qualified Data.Map.Strict as M
import qualified Data.Set as S

import Futhark.Construct
import Futhark.Representation.AST

shapeBody :: (HasScope lore m, MonadFreshNames m, BinderOps lore, Bindable lore) =>
             [VName] -> [Type] -> Body lore
          -> m (Body lore)
shapeBody :: [VName] -> [Type] -> Body lore -> m (Body lore)
shapeBody [VName]
shapenames [Type]
ts Body lore
body =
  Binder lore (Body lore) -> m (Body lore)
forall lore (m :: * -> *) somelore.
(Bindable lore, MonadFreshNames m, HasScope somelore m,
 SameScope somelore lore) =>
Binder lore (Body lore) -> m (Body lore)
runBodyBinder (Binder lore (Body lore) -> m (Body lore))
-> Binder lore (Body lore) -> m (Body lore)
forall a b. (a -> b) -> a -> b
$ do
    [SubExp]
ses <- Body (Lore (BinderT lore (State VNameSource)))
-> BinderT lore (State VNameSource) [SubExp]
forall (m :: * -> *). MonadBinder m => Body (Lore m) -> m [SubExp]
bodyBind Body lore
Body (Lore (BinderT lore (State VNameSource)))
body
    [Type]
sets <- (SubExp -> BinderT lore (State VNameSource) Type)
-> [SubExp] -> BinderT lore (State VNameSource) [Type]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM SubExp -> BinderT lore (State VNameSource) Type
forall t (m :: * -> *). HasScope t m => SubExp -> m Type
subExpType [SubExp]
ses
    [SubExp]
-> BinderT
     lore
     (State VNameSource)
     (Body (Lore (BinderT lore (State VNameSource))))
forall (m :: * -> *).
MonadBinder m =>
[SubExp] -> m (Body (Lore m))
resultBodyM ([SubExp]
 -> BinderT
      lore
      (State VNameSource)
      (Body (Lore (BinderT lore (State VNameSource)))))
-> [SubExp]
-> BinderT
     lore
     (State VNameSource)
     (Body (Lore (BinderT lore (State VNameSource))))
forall a b. (a -> b) -> a -> b
$ [VName] -> [Type] -> [Type] -> [SubExp]
forall u0 u1.
[VName] -> [TypeBase Shape u0] -> [TypeBase Shape u1] -> [SubExp]
argShapes [VName]
shapenames [Type]
ts [Type]
sets

argShapes :: [VName] -> [TypeBase Shape u0] -> [TypeBase Shape u1] -> [SubExp]
argShapes :: [VName] -> [TypeBase Shape u0] -> [TypeBase Shape u1] -> [SubExp]
argShapes [VName]
shapes [TypeBase Shape u0]
valts [TypeBase Shape u1]
valargts =
  (VName -> SubExp) -> [VName] -> [SubExp]
forall a b. (a -> b) -> [a] -> [b]
map VName -> SubExp
addShape [VName]
shapes
  where mapping :: Map VName (Set SubExp)
mapping = [TypeBase Shape u0]
-> [TypeBase Shape u1] -> Map VName (Set SubExp)
forall u0 u1.
[TypeBase Shape u0]
-> [TypeBase Shape u1] -> Map VName (Set SubExp)
shapeMapping [TypeBase Shape u0]
valts [TypeBase Shape u1]
valargts
        addShape :: VName -> SubExp
addShape VName
name =
          case VName -> Map VName (Set SubExp) -> Maybe (Set SubExp)
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup VName
name Map VName (Set SubExp)
mapping of
            Just Set SubExp
s | SubExp
se:[SubExp]
_ <- Set SubExp -> [SubExp]
forall a. Set a -> [a]
S.toList Set SubExp
s -> SubExp
se
            Maybe (Set SubExp)
_ -> IntType -> Integer -> SubExp
intConst IntType
Int32 Integer
0

ensureResultShape :: MonadBinder m =>
                     (m Certificates -> m Certificates)
                  -> ErrorMsg SubExp -> SrcLoc -> [Type] -> Body (Lore m)
                  -> m (Body (Lore m))
ensureResultShape :: (m Certificates -> m Certificates)
-> ErrorMsg SubExp
-> SrcLoc
-> [Type]
-> Body (Lore m)
-> m (Body (Lore m))
ensureResultShape m Certificates -> m Certificates
asserting ErrorMsg SubExp
msg SrcLoc
loc =
  (m Certificates -> m Certificates)
-> ErrorMsg SubExp
-> SrcLoc
-> [ExtType]
-> Body (Lore m)
-> m (Body (Lore m))
forall (m :: * -> *).
MonadBinder m =>
(m Certificates -> m Certificates)
-> ErrorMsg SubExp
-> SrcLoc
-> [ExtType]
-> Body (Lore m)
-> m (Body (Lore m))
ensureResultExtShape m Certificates -> m Certificates
asserting ErrorMsg SubExp
msg SrcLoc
loc ([ExtType] -> Body (Lore m) -> m (Body (Lore m)))
-> ([Type] -> [ExtType])
-> [Type]
-> Body (Lore m)
-> m (Body (Lore m))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Type] -> [ExtType]
forall u. [TypeBase Shape u] -> [TypeBase ExtShape u]
staticShapes

ensureResultExtShape :: MonadBinder m =>
                        (m Certificates -> m Certificates)
                     -> ErrorMsg SubExp -> SrcLoc -> [ExtType] -> Body (Lore m)
                     -> m (Body (Lore m))
ensureResultExtShape :: (m Certificates -> m Certificates)
-> ErrorMsg SubExp
-> SrcLoc
-> [ExtType]
-> Body (Lore m)
-> m (Body (Lore m))
ensureResultExtShape m Certificates -> m Certificates
asserting ErrorMsg SubExp
msg SrcLoc
loc [ExtType]
rettype Body (Lore m)
body =
  m (Body (Lore m)) -> m (Body (Lore m))
forall (m :: * -> *).
MonadBinder m =>
m (Body (Lore m)) -> m (Body (Lore m))
insertStmsM (m (Body (Lore m)) -> m (Body (Lore m)))
-> m (Body (Lore m)) -> m (Body (Lore m))
forall a b. (a -> b) -> a -> b
$ do
    [SubExp]
reses <- Body (Lore m) -> m [SubExp]
forall (m :: * -> *). MonadBinder m => Body (Lore m) -> m [SubExp]
bodyBind (Body (Lore m) -> m [SubExp]) -> m (Body (Lore m)) -> m [SubExp]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
             (m Certificates -> m Certificates)
-> ErrorMsg SubExp
-> SrcLoc
-> [ExtType]
-> Body (Lore m)
-> m (Body (Lore m))
forall (m :: * -> *).
MonadBinder m =>
(m Certificates -> m Certificates)
-> ErrorMsg SubExp
-> SrcLoc
-> [ExtType]
-> Body (Lore m)
-> m (Body (Lore m))
ensureResultExtShapeNoCtx m Certificates -> m Certificates
asserting ErrorMsg SubExp
msg SrcLoc
loc [ExtType]
rettype Body (Lore m)
body
    [Type]
ts <- (SubExp -> m Type) -> [SubExp] -> m [Type]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM SubExp -> m Type
forall t (m :: * -> *). HasScope t m => SubExp -> m Type
subExpType [SubExp]
reses
    let ctx :: [SubExp]
ctx = [ExtType] -> [[SubExp]] -> [SubExp]
forall u a. [TypeBase ExtShape u] -> [[a]] -> [a]
extractShapeContext [ExtType]
rettype ([[SubExp]] -> [SubExp]) -> [[SubExp]] -> [SubExp]
forall a b. (a -> b) -> a -> b
$ (Type -> [SubExp]) -> [Type] -> [[SubExp]]
forall a b. (a -> b) -> [a] -> [b]
map Type -> [SubExp]
forall u. TypeBase Shape u -> [SubExp]
arrayDims [Type]
ts
    Stms (Lore m) -> [SubExp] -> m (Body (Lore m))
forall (m :: * -> *).
MonadBinder m =>
Stms (Lore m) -> [SubExp] -> m (Body (Lore m))
mkBodyM Stms (Lore m)
forall a. Monoid a => a
mempty ([SubExp] -> m (Body (Lore m))) -> [SubExp] -> m (Body (Lore m))
forall a b. (a -> b) -> a -> b
$ [SubExp]
ctx [SubExp] -> [SubExp] -> [SubExp]
forall a. [a] -> [a] -> [a]
++ [SubExp]
reses

ensureResultExtShapeNoCtx :: MonadBinder m =>
                             (m Certificates -> m Certificates)
                          -> ErrorMsg SubExp -> SrcLoc -> [ExtType] -> Body (Lore m)
                          -> m (Body (Lore m))
ensureResultExtShapeNoCtx :: (m Certificates -> m Certificates)
-> ErrorMsg SubExp
-> SrcLoc
-> [ExtType]
-> Body (Lore m)
-> m (Body (Lore m))
ensureResultExtShapeNoCtx m Certificates -> m Certificates
asserting ErrorMsg SubExp
msg SrcLoc
loc [ExtType]
rettype Body (Lore m)
body =
  m (Body (Lore m)) -> m (Body (Lore m))
forall (m :: * -> *).
MonadBinder m =>
m (Body (Lore m)) -> m (Body (Lore m))
insertStmsM (m (Body (Lore m)) -> m (Body (Lore m)))
-> m (Body (Lore m)) -> m (Body (Lore m))
forall a b. (a -> b) -> a -> b
$ do
    [SubExp]
es <- Body (Lore m) -> m [SubExp]
forall (m :: * -> *). MonadBinder m => Body (Lore m) -> m [SubExp]
bodyBind Body (Lore m)
body
    [Type]
es_ts <- (SubExp -> m Type) -> [SubExp] -> m [Type]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM SubExp -> m Type
forall t (m :: * -> *). HasScope t m => SubExp -> m Type
subExpType [SubExp]
es
    let ext_mapping :: Map Int SubExp
ext_mapping = [ExtType] -> [Type] -> Map Int SubExp
forall u u1.
[TypeBase ExtShape u] -> [TypeBase Shape u1] -> Map Int SubExp
shapeExtMapping [ExtType]
rettype [Type]
es_ts
        rettype' :: [ExtType]
rettype' = ((Int, SubExp) -> [ExtType] -> [ExtType])
-> [ExtType] -> [(Int, SubExp)] -> [ExtType]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ((Int -> SubExp -> [ExtType] -> [ExtType])
-> (Int, SubExp) -> [ExtType] -> [ExtType]
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Int -> SubExp -> [ExtType] -> [ExtType]
forall t. FixExt t => Int -> SubExp -> t -> t
fixExt) [ExtType]
rettype ([(Int, SubExp)] -> [ExtType]) -> [(Int, SubExp)] -> [ExtType]
forall a b. (a -> b) -> a -> b
$ Map Int SubExp -> [(Int, SubExp)]
forall k a. Map k a -> [(k, a)]
M.toList Map Int SubExp
ext_mapping
        assertProperShape :: ExtType -> SubExp -> m SubExp
assertProperShape ExtType
t SubExp
se =
          let name :: [Char]
name = [Char]
"result_proper_shape"
          in (m Certificates -> m Certificates)
-> ErrorMsg SubExp
-> SrcLoc
-> ExtType
-> [Char]
-> SubExp
-> m SubExp
forall (m :: * -> *).
MonadBinder m =>
(m Certificates -> m Certificates)
-> ErrorMsg SubExp
-> SrcLoc
-> ExtType
-> [Char]
-> SubExp
-> m SubExp
ensureExtShape m Certificates -> m Certificates
asserting ErrorMsg SubExp
msg SrcLoc
loc ExtType
t [Char]
name SubExp
se
    [SubExp] -> m (Body (Lore m))
forall (m :: * -> *).
MonadBinder m =>
[SubExp] -> m (Body (Lore m))
resultBodyM ([SubExp] -> m (Body (Lore m))) -> m [SubExp] -> m (Body (Lore m))
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (ExtType -> SubExp -> m SubExp)
-> [ExtType] -> [SubExp] -> m [SubExp]
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m [c]
zipWithM ExtType -> SubExp -> m SubExp
assertProperShape [ExtType]
rettype' [SubExp]
es

ensureExtShape :: MonadBinder m =>
                  (m Certificates -> m Certificates)
               -> ErrorMsg SubExp -> SrcLoc -> ExtType -> String -> SubExp
               -> m SubExp
ensureExtShape :: (m Certificates -> m Certificates)
-> ErrorMsg SubExp
-> SrcLoc
-> ExtType
-> [Char]
-> SubExp
-> m SubExp
ensureExtShape m Certificates -> m Certificates
asserting ErrorMsg SubExp
msg SrcLoc
loc ExtType
t [Char]
name SubExp
orig
  | Array{} <- ExtType
t, Var VName
v <- SubExp
orig =
    VName -> SubExp
Var (VName -> SubExp) -> m VName -> m SubExp
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (m Certificates -> m Certificates)
-> ErrorMsg SubExp
-> SrcLoc
-> ExtType
-> [Char]
-> VName
-> m VName
forall (m :: * -> *).
MonadBinder m =>
(m Certificates -> m Certificates)
-> ErrorMsg SubExp
-> SrcLoc
-> ExtType
-> [Char]
-> VName
-> m VName
ensureShapeVar m Certificates -> m Certificates
asserting ErrorMsg SubExp
msg SrcLoc
loc ExtType
t [Char]
name VName
v
  | Bool
otherwise = SubExp -> m SubExp
forall (m :: * -> *) a. Monad m => a -> m a
return SubExp
orig

ensureShape :: MonadBinder m =>
               (m Certificates -> m Certificates)
            -> ErrorMsg SubExp -> SrcLoc -> Type -> String -> SubExp
            -> m SubExp
ensureShape :: (m Certificates -> m Certificates)
-> ErrorMsg SubExp
-> SrcLoc
-> Type
-> [Char]
-> SubExp
-> m SubExp
ensureShape m Certificates -> m Certificates
asserting ErrorMsg SubExp
msg SrcLoc
loc = (m Certificates -> m Certificates)
-> ErrorMsg SubExp
-> SrcLoc
-> ExtType
-> [Char]
-> SubExp
-> m SubExp
forall (m :: * -> *).
MonadBinder m =>
(m Certificates -> m Certificates)
-> ErrorMsg SubExp
-> SrcLoc
-> ExtType
-> [Char]
-> SubExp
-> m SubExp
ensureExtShape m Certificates -> m Certificates
asserting ErrorMsg SubExp
msg SrcLoc
loc (ExtType -> [Char] -> SubExp -> m SubExp)
-> (Type -> ExtType) -> Type -> [Char] -> SubExp -> m SubExp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Type -> ExtType
forall u. TypeBase Shape u -> TypeBase ExtShape u
staticShapes1

-- | Reshape the arguments to a function so that they fit the expected
-- shape declarations.  Not used to change rank of arguments.  Assumes
-- everything is otherwise type-correct.
ensureArgShapes :: (MonadBinder m, Typed (TypeBase Shape u)) =>
                   (m Certificates -> m Certificates)
                -> ErrorMsg SubExp -> SrcLoc -> [VName] -> [TypeBase Shape u] -> [SubExp]
                -> m [SubExp]
ensureArgShapes :: (m Certificates -> m Certificates)
-> ErrorMsg SubExp
-> SrcLoc
-> [VName]
-> [TypeBase Shape u]
-> [SubExp]
-> m [SubExp]
ensureArgShapes m Certificates -> m Certificates
asserting ErrorMsg SubExp
msg SrcLoc
loc [VName]
shapes [TypeBase Shape u]
paramts [SubExp]
args =
  (Type -> SubExp -> m SubExp) -> [Type] -> [SubExp] -> m [SubExp]
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m [c]
zipWithM Type -> SubExp -> m SubExp
ensureArgShape ([VName] -> [TypeBase Shape u] -> [SubExp] -> [Type]
forall t. Typed t => [VName] -> [t] -> [SubExp] -> [Type]
expectedTypes [VName]
shapes [TypeBase Shape u]
paramts [SubExp]
args) [SubExp]
args
  where ensureArgShape :: Type -> SubExp -> m SubExp
ensureArgShape Type
_ (Constant PrimValue
v) = SubExp -> m SubExp
forall (m :: * -> *) a. Monad m => a -> m a
return (SubExp -> m SubExp) -> SubExp -> m SubExp
forall a b. (a -> b) -> a -> b
$ PrimValue -> SubExp
Constant PrimValue
v
        ensureArgShape Type
t (Var VName
v)
          | Type -> Int
forall shape u. ArrayShape shape => TypeBase shape u -> Int
arrayRank Type
t Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
1 = SubExp -> m SubExp
forall (m :: * -> *) a. Monad m => a -> m a
return (SubExp -> m SubExp) -> SubExp -> m SubExp
forall a b. (a -> b) -> a -> b
$ VName -> SubExp
Var VName
v
          | Bool
otherwise =
              (m Certificates -> m Certificates)
-> ErrorMsg SubExp
-> SrcLoc
-> Type
-> [Char]
-> SubExp
-> m SubExp
forall (m :: * -> *).
MonadBinder m =>
(m Certificates -> m Certificates)
-> ErrorMsg SubExp
-> SrcLoc
-> Type
-> [Char]
-> SubExp
-> m SubExp
ensureShape m Certificates -> m Certificates
asserting ErrorMsg SubExp
msg SrcLoc
loc Type
t (VName -> [Char]
baseString VName
v) (SubExp -> m SubExp) -> SubExp -> m SubExp
forall a b. (a -> b) -> a -> b
$ VName -> SubExp
Var VName
v

ensureShapeVar :: MonadBinder m =>
                  (m Certificates -> m Certificates)
               -> ErrorMsg SubExp -> SrcLoc -> ExtType -> String -> VName
               -> m VName
ensureShapeVar :: (m Certificates -> m Certificates)
-> ErrorMsg SubExp
-> SrcLoc
-> ExtType
-> [Char]
-> VName
-> m VName
ensureShapeVar m Certificates -> m Certificates
asserting ErrorMsg SubExp
msg SrcLoc
loc ExtType
t [Char]
name VName
v
  | Array{} <- ExtType
t = do
    [SubExp]
newdims <- Type -> [SubExp]
forall u. TypeBase Shape u -> [SubExp]
arrayDims (Type -> [SubExp]) -> (Type -> Type) -> Type -> [SubExp]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ExtType -> Type -> Type
removeExistentials ExtType
t (Type -> [SubExp]) -> m Type -> m [SubExp]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> VName -> m Type
forall lore (m :: * -> *). HasScope lore m => VName -> m Type
lookupType VName
v
    [SubExp]
olddims <- Type -> [SubExp]
forall u. TypeBase Shape u -> [SubExp]
arrayDims (Type -> [SubExp]) -> m Type -> m [SubExp]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> VName -> m Type
forall lore (m :: * -> *). HasScope lore m => VName -> m Type
lookupType VName
v
    if [SubExp]
newdims [SubExp] -> [SubExp] -> Bool
forall a. Eq a => a -> a -> Bool
== [SubExp]
olddims
      then VName -> m VName
forall (m :: * -> *) a. Monad m => a -> m a
return VName
v
      else do
        Certificates
certs <- m Certificates -> m Certificates
asserting (m Certificates -> m Certificates)
-> m Certificates -> m Certificates
forall a b. (a -> b) -> a -> b
$ do
          [SubExp]
matches <- (SubExp -> SubExp -> m SubExp)
-> [SubExp] -> [SubExp] -> m [SubExp]
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m [c]
zipWithM SubExp -> SubExp -> m SubExp
forall (m :: * -> *). MonadBinder m => SubExp -> SubExp -> m SubExp
checkDim [SubExp]
newdims [SubExp]
olddims
          SubExp
all_match <- [Char] -> ExpT (Lore m) -> m SubExp
forall (m :: * -> *).
MonadBinder m =>
[Char] -> Exp (Lore m) -> m SubExp
letSubExp [Char]
"match" (ExpT (Lore m) -> m SubExp) -> m (ExpT (Lore m)) -> m SubExp
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< BinOp -> SubExp -> [SubExp] -> m (ExpT (Lore m))
forall (m :: * -> *).
MonadBinder m =>
BinOp -> SubExp -> [SubExp] -> m (Exp (Lore m))
foldBinOp BinOp
LogAnd (Bool -> SubExp
forall v. IsValue v => v -> SubExp
constant Bool
True) [SubExp]
matches
          [VName] -> Certificates
Certificates ([VName] -> Certificates)
-> (VName -> [VName]) -> VName -> Certificates
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VName -> [VName]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (VName -> Certificates) -> m VName -> m Certificates
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Char] -> ExpT (Lore m) -> m VName
forall (m :: * -> *).
MonadBinder m =>
[Char] -> Exp (Lore m) -> m VName
letExp [Char]
"empty_or_match_cert"
            (BasicOp (Lore m) -> ExpT (Lore m)
forall lore. BasicOp lore -> ExpT lore
BasicOp (BasicOp (Lore m) -> ExpT (Lore m))
-> BasicOp (Lore m) -> ExpT (Lore m)
forall a b. (a -> b) -> a -> b
$ SubExp -> ErrorMsg SubExp -> (SrcLoc, [SrcLoc]) -> BasicOp (Lore m)
forall lore.
SubExp -> ErrorMsg SubExp -> (SrcLoc, [SrcLoc]) -> BasicOp lore
Assert SubExp
all_match ErrorMsg SubExp
msg (SrcLoc
loc, []))
        Certificates -> m VName -> m VName
forall (m :: * -> *) a. MonadBinder m => Certificates -> m a -> m a
certifying Certificates
certs (m VName -> m VName) -> m VName -> m VName
forall a b. (a -> b) -> a -> b
$ [Char] -> ExpT (Lore m) -> m VName
forall (m :: * -> *).
MonadBinder m =>
[Char] -> Exp (Lore m) -> m VName
letExp [Char]
name (ExpT (Lore m) -> m VName) -> ExpT (Lore m) -> m VName
forall a b. (a -> b) -> a -> b
$ [SubExp] -> VName -> ExpT (Lore m)
forall lore. [SubExp] -> VName -> Exp lore
shapeCoerce [SubExp]
newdims VName
v
  | Bool
otherwise = VName -> m VName
forall (m :: * -> *) a. Monad m => a -> m a
return VName
v
  where checkDim :: SubExp -> SubExp -> m SubExp
checkDim SubExp
desired SubExp
has =
          [Char] -> Exp (Lore m) -> m SubExp
forall (m :: * -> *).
MonadBinder m =>
[Char] -> Exp (Lore m) -> m SubExp
letSubExp [Char]
"dim_match" (Exp (Lore m) -> m SubExp) -> Exp (Lore m) -> m SubExp
forall a b. (a -> b) -> a -> b
$ BasicOp (Lore m) -> Exp (Lore m)
forall lore. BasicOp lore -> ExpT lore
BasicOp (BasicOp (Lore m) -> Exp (Lore m))
-> BasicOp (Lore m) -> Exp (Lore m)
forall a b. (a -> b) -> a -> b
$ CmpOp -> SubExp -> SubExp -> BasicOp (Lore m)
forall lore. CmpOp -> SubExp -> SubExp -> BasicOp lore
CmpOp (PrimType -> CmpOp
CmpEq PrimType
int32) SubExp
desired SubExp
has