packages feed

futhark 0.10.1 → 0.10.2

raw patch · 54 files changed

+1055/−1126 lines, 54 filesdep +terminal-sizedep ~basePVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: terminal-size

Dependency ranges changed: base

API changes (from Hackage documentation)

- Futhark.TypeCheck: type UsageMap = Map VName [Usage]
- Futhark.TypeCheck: usageMap :: Occurences -> UsageMap
- Language.Futhark.Attributes: arrayOfWithAliases :: Monoid as => TypeBase dim as -> as -> ShapeDecl dim -> Uniqueness -> Maybe (TypeBase dim as)
- Language.Futhark.Attributes: concreteType :: TypeBase f vn -> Bool
- Language.Futhark.Attributes: modifyShapeAnnotations :: (oldshape -> newshape) -> TypeBase oldshape as -> TypeBase newshape as
- Language.Futhark.Attributes: patIdentSet :: (Functor f, Ord vn) => PatternBase f vn -> Set (IdentBase f vn)
- Language.Futhark.Attributes: returnType :: TypeBase dim Aliasing -> Diet -> CompType -> TypeBase dim Aliasing
- Language.Futhark.Attributes: setArrayShape :: TypeBase dim as -> ShapeDecl dim -> TypeBase dim as
- Language.Futhark.Attributes: typeToRecordArrayElem :: Monoid as => TypeBase dim as -> Maybe (RecordArrayElemTypeBase dim)
- Language.Futhark.Syntax: Filter :: ExpBase f vn -> ExpBase f vn -> SrcLoc -> ExpBase f vn
- Language.Futhark.Syntax: GenReduce :: ExpBase f vn -> ExpBase f vn -> ExpBase f vn -> ExpBase f vn -> ExpBase f vn -> SrcLoc -> ExpBase f vn
- Language.Futhark.Syntax: Map :: ExpBase f vn -> ExpBase f vn -> f CompType -> SrcLoc -> ExpBase f vn
- Language.Futhark.Syntax: MapLike :: StreamOrd -> StreamForm f vn
- Language.Futhark.Syntax: Partition :: Int -> ExpBase f vn -> ExpBase f vn -> SrcLoc -> ExpBase f vn
- Language.Futhark.Syntax: RedLike :: StreamOrd -> Commutativity -> ExpBase f vn -> StreamForm f vn
- Language.Futhark.Syntax: Reduce :: Commutativity -> ExpBase f vn -> ExpBase f vn -> ExpBase f vn -> SrcLoc -> ExpBase f vn
- Language.Futhark.Syntax: Scan :: ExpBase f vn -> ExpBase f vn -> ExpBase f vn -> SrcLoc -> ExpBase f vn
- Language.Futhark.Syntax: Stream :: StreamForm f vn -> ExpBase f vn -> ExpBase f vn -> SrcLoc -> ExpBase f vn
- Language.Futhark.Syntax: data StreamForm f vn
- Language.Futhark.Syntax: instance (GHC.Classes.Eq vn, GHC.Classes.Ord vn) => Language.Futhark.Syntax.ArrayDim (Language.Futhark.Syntax.DimDecl vn)
- Language.Futhark.Syntax: instance GHC.Classes.Eq vn => GHC.Classes.Eq (Language.Futhark.Syntax.DimDecl vn)
- Language.Futhark.Syntax: instance GHC.Classes.Eq vn => GHC.Classes.Eq (Language.Futhark.Syntax.QualName vn)
- Language.Futhark.Syntax: instance GHC.Classes.Eq vn => GHC.Classes.Eq (Language.Futhark.Syntax.TypeArgExp vn)
- Language.Futhark.Syntax: instance GHC.Classes.Eq vn => GHC.Classes.Eq (Language.Futhark.Syntax.TypeExp vn)
- Language.Futhark.Syntax: instance GHC.Classes.Ord vn => GHC.Classes.Ord (Language.Futhark.Syntax.DimDecl vn)
- Language.Futhark.Syntax: instance GHC.Classes.Ord vn => GHC.Classes.Ord (Language.Futhark.Syntax.QualName vn)
- Language.Futhark.Syntax: instance Language.Futhark.Syntax.Showable f vn => GHC.Show.Show (Language.Futhark.Syntax.StreamForm f vn)
- Language.Futhark.Syntax: type CompType = TypeBase () Aliasing
- Language.Futhark.Traversals: [mapOnCompType] :: ASTMapper m -> CompType -> m CompType
- Language.Futhark.Traversals: [mapOnType] :: ASTMapper m -> TypeBase () () -> m (TypeBase () ())
- Language.Futhark.Traversals: instance Language.Futhark.Traversals.ASTMappable (Language.Futhark.Syntax.TypeBase () ())
- Language.Futhark.Traversals: instance Language.Futhark.Traversals.ASTMappable Language.Futhark.Syntax.CompType
- Language.Futhark.TypeChecker.Types: substituteTypesInBoundV :: TypeSubs -> BoundV -> BoundV
+ Futhark.Optimise.CSE: instance Futhark.Optimise.CSE.CSEInOp op => Futhark.Optimise.CSE.CSEInOp (Futhark.Representation.Kernels.Kernel.HostOp lore op)
+ Futhark.Pass.ExplicitAllocations: instance Futhark.Pass.ExplicitAllocations.SizeSubst op => Futhark.Pass.ExplicitAllocations.SizeSubst (Futhark.Representation.Kernels.Kernel.HostOp lore op)
+ Futhark.Representation.AST.Syntax: ObservePrim :: Diet
+ Futhark.Representation.AST.Syntax.Core: ObservePrim :: Diet
+ Futhark.Representation.Kernels.Kernel: HostOp :: inner -> HostOp lore inner
+ Futhark.Representation.Kernels.Kernel: data HostOp lore inner
+ Futhark.Representation.Kernels.Kernel: instance Futhark.Analysis.Metrics.OpMetrics inner => Futhark.Analysis.Metrics.OpMetrics (Futhark.Representation.Kernels.Kernel.HostOp lore inner)
+ Futhark.Representation.Kernels.Kernel: instance Futhark.Analysis.SymbolTable.IndexOp op => Futhark.Analysis.SymbolTable.IndexOp (Futhark.Representation.Kernels.Kernel.HostOp lore op)
+ Futhark.Representation.Kernels.Kernel: instance Futhark.Analysis.Usage.UsageInOp inner => Futhark.Analysis.Usage.UsageInOp (Futhark.Representation.Kernels.Kernel.HostOp lore inner)
+ Futhark.Representation.Kernels.Kernel: instance Futhark.Optimise.Simplify.Lore.CanBeWise inner => Futhark.Optimise.Simplify.Lore.CanBeWise (Futhark.Representation.Kernels.Kernel.HostOp lore inner)
+ Futhark.Representation.Kernels.Kernel: instance Futhark.Representation.AST.Attributes.Aliases.AliasedOp inner => Futhark.Representation.AST.Attributes.Aliases.AliasedOp (Futhark.Representation.Kernels.Kernel.HostOp lore inner)
+ Futhark.Representation.Kernels.Kernel: instance Futhark.Representation.AST.Attributes.Aliases.CanBeAliased inner => Futhark.Representation.AST.Attributes.Aliases.CanBeAliased (Futhark.Representation.Kernels.Kernel.HostOp lore inner)
+ Futhark.Representation.Kernels.Kernel: instance Futhark.Representation.AST.Attributes.IsOp inner => Futhark.Representation.AST.Attributes.IsOp (Futhark.Representation.Kernels.Kernel.HostOp lore inner)
+ Futhark.Representation.Kernels.Kernel: instance Futhark.Representation.AST.Attributes.Names.FreeIn inner => Futhark.Representation.AST.Attributes.Names.FreeIn (Futhark.Representation.Kernels.Kernel.HostOp lore inner)
+ Futhark.Representation.Kernels.Kernel: instance Futhark.Representation.AST.Attributes.Ranges.CanBeRanged inner => Futhark.Representation.AST.Attributes.Ranges.CanBeRanged (Futhark.Representation.Kernels.Kernel.HostOp lore inner)
+ Futhark.Representation.Kernels.Kernel: instance Futhark.Representation.AST.Attributes.Ranges.RangedOp inner => Futhark.Representation.AST.Attributes.Ranges.RangedOp (Futhark.Representation.Kernels.Kernel.HostOp lore inner)
+ Futhark.Representation.Kernels.Kernel: instance Futhark.Representation.AST.Attributes.TypeOf.TypedOp inner => Futhark.Representation.AST.Attributes.TypeOf.TypedOp (Futhark.Representation.Kernels.Kernel.HostOp lore inner)
+ Futhark.Representation.Kernels.Kernel: instance Futhark.Transform.Rename.Rename inner => Futhark.Transform.Rename.Rename (Futhark.Representation.Kernels.Kernel.HostOp lore inner)
+ Futhark.Representation.Kernels.Kernel: instance Futhark.Transform.Substitute.Substitute inner => Futhark.Transform.Substitute.Substitute (Futhark.Representation.Kernels.Kernel.HostOp lore inner)
+ Futhark.Representation.Kernels.Kernel: instance GHC.Classes.Eq inner => GHC.Classes.Eq (Futhark.Representation.Kernels.Kernel.HostOp lore inner)
+ Futhark.Representation.Kernels.Kernel: instance GHC.Classes.Ord inner => GHC.Classes.Ord (Futhark.Representation.Kernels.Kernel.HostOp lore inner)
+ Futhark.Representation.Kernels.Kernel: instance GHC.Show.Show inner => GHC.Show.Show (Futhark.Representation.Kernels.Kernel.HostOp lore inner)
+ Futhark.Representation.Kernels.Kernel: instance Text.PrettyPrint.Mainland.Class.Pretty inner => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.Representation.Kernels.Kernel.HostOp lore inner)
+ Futhark.Representation.Kernels.Kernel: typeCheckHostOp :: Checkable lore => (inner -> TypeM lore ()) -> HostOp (Aliases lore) inner -> TypeM lore ()
+ Futhark.Representation.SOACS: ObservePrim :: Diet
+ Language.Futhark.Attributes: anyDimShapeAnnotations :: TypeBase (DimDecl vn) as -> TypeBase (DimDecl vn) as
+ Language.Futhark.Attributes: combineTypeShapes :: (Monoid as, ArrayDim dim) => TypeBase dim as -> TypeBase dim as -> TypeBase dim as
+ Language.Futhark.Attributes: patternIdents :: (Functor f, Ord vn) => PatternBase f vn -> Set (IdentBase f vn)
+ Language.Futhark.Attributes: unscopeType :: Set VName -> PatternType -> PatternType
+ Language.Futhark.Syntax: instance GHC.Classes.Eq (Language.Futhark.Syntax.DimDecl Language.Futhark.Core.Name)
+ Language.Futhark.Syntax: instance GHC.Classes.Eq (Language.Futhark.Syntax.DimDecl Language.Futhark.Core.VName)
+ Language.Futhark.Syntax: instance GHC.Classes.Eq (Language.Futhark.Syntax.QualName Language.Futhark.Core.Name)
+ Language.Futhark.Syntax: instance GHC.Classes.Eq (Language.Futhark.Syntax.QualName Language.Futhark.Core.VName)
+ Language.Futhark.Syntax: instance GHC.Classes.Eq (Language.Futhark.Syntax.TypeArgExp Language.Futhark.Core.Name)
+ Language.Futhark.Syntax: instance GHC.Classes.Eq (Language.Futhark.Syntax.TypeArgExp Language.Futhark.Core.VName)
+ Language.Futhark.Syntax: instance GHC.Classes.Eq (Language.Futhark.Syntax.TypeExp Language.Futhark.Core.Name)
+ Language.Futhark.Syntax: instance GHC.Classes.Eq (Language.Futhark.Syntax.TypeExp Language.Futhark.Core.VName)
+ Language.Futhark.Syntax: instance GHC.Classes.Ord (Language.Futhark.Syntax.QualName Language.Futhark.Core.Name)
+ Language.Futhark.Syntax: instance GHC.Classes.Ord (Language.Futhark.Syntax.QualName Language.Futhark.Core.VName)
+ Language.Futhark.Syntax: instance Language.Futhark.Syntax.ArrayDim (Language.Futhark.Syntax.DimDecl Language.Futhark.Core.VName)
- Futhark.Pass.ExtractKernels.BlockedKernel: getSize :: (MonadBinder m, Op (Lore m) ~ Kernel innerlore) => String -> SizeClass -> m SubExp
+ Futhark.Pass.ExtractKernels.BlockedKernel: getSize :: (MonadBinder m, Op (Lore m) ~ HostOp (Lore m) inner) => String -> SizeClass -> m SubExp
- Futhark.Representation.Kernels.Kernel: CmpSizeLe :: Name -> SizeClass -> SubExp -> Kernel lore
+ Futhark.Representation.Kernels.Kernel: CmpSizeLe :: Name -> SizeClass -> SubExp -> HostOp lore inner
- Futhark.Representation.Kernels.Kernel: GetSize :: Name -> SizeClass -> Kernel lore
+ Futhark.Representation.Kernels.Kernel: GetSize :: Name -> SizeClass -> HostOp lore inner
- Futhark.Representation.Kernels.Kernel: GetSizeMax :: SizeClass -> Kernel lore
+ Futhark.Representation.Kernels.Kernel: GetSizeMax :: SizeClass -> HostOp lore inner
- Futhark.Representation.Kernels.Simplify: simplifyKernelOp :: (SimplifiableLore lore, SimplifiableLore outerlore, BodyAttr outerlore ~ (), BodyAttr lore ~ (), ExpAttr lore ~ ExpAttr outerlore, SameScope lore outerlore, RetType lore ~ RetType outerlore, BranchType lore ~ BranchType outerlore) => (KernelSpace -> SimpleOps lore) -> Env lore -> Kernel lore -> SimpleM outerlore (Kernel (Wise lore), Stms (Wise outerlore))
+ Futhark.Representation.Kernels.Simplify: simplifyKernelOp :: (SimplifiableLore lore, SimplifiableLore outerlore, BodyAttr outerlore ~ (), BodyAttr lore ~ (), ExpAttr lore ~ ExpAttr outerlore, SameScope lore outerlore, RetType lore ~ RetType outerlore, BranchType lore ~ BranchType outerlore) => (KernelSpace -> SimpleOps lore) -> Env lore -> HostOp outerlore (Kernel lore) -> SimpleM outerlore (HostOp (Wise outerlore) (Kernel (Wise lore)), Stms (Wise outerlore))
- Language.Futhark.Attributes: patternType :: PatternBase Info VName -> CompType
+ Language.Futhark.Attributes: patternType :: PatternBase Info VName -> PatternType
- Language.Futhark.Attributes: removeShapeAnnotations :: TypeBase dim as -> TypeBase () as
+ Language.Futhark.Attributes: removeShapeAnnotations :: TypeBase (DimDecl vn) as -> TypeBase () as
- Language.Futhark.Attributes: typeOf :: ExpBase Info VName -> CompType
+ Language.Futhark.Attributes: typeOf :: ExpBase Info VName -> PatternType
- Language.Futhark.Attributes: vacuousShapeAnnotations :: TypeBase dim as -> TypeBase (DimDecl vn) as
+ Language.Futhark.Attributes: vacuousShapeAnnotations :: TypeBase () as -> TypeBase (DimDecl vn) as
- Language.Futhark.Syntax: ArrayLit :: [ExpBase f vn] -> f CompType -> SrcLoc -> ExpBase f vn
+ Language.Futhark.Syntax: ArrayLit :: [ExpBase f vn] -> f PatternType -> SrcLoc -> ExpBase f vn
- Language.Futhark.Syntax: Ascript :: ExpBase f vn -> TypeDeclBase f vn -> SrcLoc -> ExpBase f vn
+ Language.Futhark.Syntax: Ascript :: ExpBase f vn -> TypeDeclBase f vn -> f PatternType -> SrcLoc -> ExpBase f vn
- Language.Futhark.Syntax: FloatLit :: Double -> f (TypeBase () ()) -> SrcLoc -> ExpBase f vn
+ Language.Futhark.Syntax: FloatLit :: Double -> f PatternType -> SrcLoc -> ExpBase f vn
- Language.Futhark.Syntax: Ident :: vn -> f CompType -> SrcLoc -> IdentBase f vn
+ Language.Futhark.Syntax: Ident :: vn -> f PatternType -> SrcLoc -> IdentBase f vn
- Language.Futhark.Syntax: If :: ExpBase f vn -> ExpBase f vn -> ExpBase f vn -> f CompType -> SrcLoc -> ExpBase f vn
+ Language.Futhark.Syntax: If :: ExpBase f vn -> ExpBase f vn -> ExpBase f vn -> f PatternType -> SrcLoc -> ExpBase f vn
- Language.Futhark.Syntax: Index :: ExpBase f vn -> [DimIndexBase f vn] -> f CompType -> SrcLoc -> ExpBase f vn
+ Language.Futhark.Syntax: Index :: ExpBase f vn -> [DimIndexBase f vn] -> f PatternType -> SrcLoc -> ExpBase f vn
- Language.Futhark.Syntax: IntLit :: Integer -> f (TypeBase () ()) -> SrcLoc -> ExpBase f vn
+ Language.Futhark.Syntax: IntLit :: Integer -> f PatternType -> SrcLoc -> ExpBase f vn
- Language.Futhark.Syntax: Lambda :: [TypeParamBase vn] -> [PatternBase f vn] -> ExpBase f vn -> Maybe (TypeDeclBase f vn) -> f (Aliasing, StructType) -> SrcLoc -> ExpBase f vn
+ Language.Futhark.Syntax: Lambda :: [TypeParamBase vn] -> [PatternBase f vn] -> ExpBase f vn -> Maybe (TypeExp vn) -> f (Aliasing, StructType) -> SrcLoc -> ExpBase f vn
- Language.Futhark.Syntax: LetPat :: [TypeParamBase vn] -> PatternBase f vn -> ExpBase f vn -> ExpBase f vn -> SrcLoc -> ExpBase f vn
+ Language.Futhark.Syntax: LetPat :: [TypeParamBase vn] -> PatternBase f vn -> ExpBase f vn -> ExpBase f vn -> f PatternType -> SrcLoc -> ExpBase f vn
- Language.Futhark.Syntax: LetWith :: IdentBase f vn -> IdentBase f vn -> [DimIndexBase f vn] -> ExpBase f vn -> ExpBase f vn -> SrcLoc -> ExpBase f vn
+ Language.Futhark.Syntax: LetWith :: IdentBase f vn -> IdentBase f vn -> [DimIndexBase f vn] -> ExpBase f vn -> ExpBase f vn -> f PatternType -> SrcLoc -> ExpBase f vn
- Language.Futhark.Syntax: Match :: ExpBase f vn -> [CaseBase f vn] -> f CompType -> SrcLoc -> ExpBase f vn
+ Language.Futhark.Syntax: Match :: ExpBase f vn -> [CaseBase f vn] -> f PatternType -> SrcLoc -> ExpBase f vn
- Language.Futhark.Syntax: Project :: Name -> ExpBase f vn -> f CompType -> SrcLoc -> ExpBase f vn
+ Language.Futhark.Syntax: Project :: Name -> ExpBase f vn -> f PatternType -> SrcLoc -> ExpBase f vn
- Language.Futhark.Syntax: Range :: ExpBase f vn -> Maybe (ExpBase f vn) -> Inclusiveness (ExpBase f vn) -> f CompType -> SrcLoc -> ExpBase f vn
+ Language.Futhark.Syntax: Range :: ExpBase f vn -> Maybe (ExpBase f vn) -> Inclusiveness (ExpBase f vn) -> f PatternType -> SrcLoc -> ExpBase f vn
- Language.Futhark.Syntax: RecordFieldImplicit :: vn -> f CompType -> SrcLoc -> FieldBase f vn
+ Language.Futhark.Syntax: RecordFieldImplicit :: vn -> f PatternType -> SrcLoc -> FieldBase f vn
- Language.Futhark.Syntax: VConstr0 :: Name -> f CompType -> SrcLoc -> ExpBase f vn
+ Language.Futhark.Syntax: VConstr0 :: Name -> f PatternType -> SrcLoc -> ExpBase f vn
- Language.Futhark.Syntax: [identType] :: IdentBase f vn -> f CompType
+ Language.Futhark.Syntax: [identType] :: IdentBase f vn -> f PatternType
- Language.Futhark.Syntax: class (Eq dim, Ord dim) => ArrayDim dim
+ Language.Futhark.Syntax: class Eq dim => ArrayDim dim
- Language.Futhark.Traversals: ASTMapper :: (ExpBase Info VName -> m (ExpBase Info VName)) -> (VName -> m VName) -> (QualName VName -> m (QualName VName)) -> (TypeBase () () -> m (TypeBase () ())) -> (CompType -> m CompType) -> (StructType -> m StructType) -> (PatternType -> m PatternType) -> ASTMapper m
+ Language.Futhark.Traversals: ASTMapper :: (ExpBase Info VName -> m (ExpBase Info VName)) -> (VName -> m VName) -> (QualName VName -> m (QualName VName)) -> (StructType -> m StructType) -> (PatternType -> m PatternType) -> ASTMapper m
- Language.Futhark.TypeChecker.Monad: lookupVar :: MonadTypeChecker m => SrcLoc -> QualName Name -> m (QualName VName, CompType)
+ Language.Futhark.TypeChecker.Monad: lookupVar :: MonadTypeChecker m => SrcLoc -> QualName Name -> m (QualName VName, PatternType)

Files

futhark.cabal view
@@ -2,10 +2,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: ca599dc882c25837255ce48c8e6ab8c5a9f1ff05234e05f6d73705f5cf9fe1c6+-- hash: befc35fd82c38f76939296d95942a59561978305f93fb1599eb91ea20a6af5fe  name:           futhark-version:        0.10.1+version:        0.10.2 synopsis:       An optimising compiler for a functional, array-oriented language. description:    Futhark is a small programming language designed to be compiled to                 efficient parallel code. It is a statically typed, data-parallel,@@ -98,6 +98,7 @@     , srcloc >=0.4     , template-haskell >=2.11.1     , temporary+    , terminal-size >=0.3     , text >=1.2.2.2     , time >=1.6.0.1     , transformers >=0.3
futlib/array.fut view
@@ -50,7 +50,7 @@ -- | Rotate an array some number of elements to the left.  A negative -- rotation amount is also supported. ----- For example, if `b==rotate 1 i a`, then `b[x,y+1] = a[x,y]`.+-- For example, if `b==rotate r a`, then `b[x+r] = a[x]`. let rotate 't (r: i32) (xs: []t) = intrinsics.rotate (r, xs)  -- | Replace an element of the array with a new value.
rts/c/opencl.h view
@@ -27,6 +27,7 @@   int preferred_device_num;   const char *preferred_platform;   const char *preferred_device;+  int ignore_blacklist;    const char* dump_program_to;   const char* load_program_from;@@ -59,6 +60,7 @@   cfg->preferred_device_num = 0;   cfg->preferred_platform = "";   cfg->preferred_device = "";+  cfg->ignore_blacklist = 0;   cfg->dump_program_to = NULL;   cfg->load_program_from = NULL;   cfg->dump_binary_to = NULL;@@ -225,6 +227,7 @@  void set_preferred_platform(struct opencl_config *cfg, const char *s) {   cfg->preferred_platform = s;+  cfg->ignore_blacklist = 1; }  void set_preferred_device(struct opencl_config *cfg, const char *s) {@@ -241,6 +244,7 @@   }   cfg->preferred_device = s;   cfg->preferred_device_num = x;+  cfg->ignore_blacklist = 1; }  static char* opencl_platform_info(cl_platform_id platform,@@ -347,6 +351,45 @@   *num_devices_out = num_devices; } +// Returns 0 on success.+static int select_device_interactively(struct opencl_config *cfg) {+  struct opencl_device_option *devices;+  size_t num_devices;+  int ret = 1;++  opencl_all_device_options(&devices, &num_devices);++  printf("Choose OpenCL device:\n");+  const char *cur_platform = "";+  for (size_t i = 0; i < num_devices; i++) {+    struct opencl_device_option device = devices[i];+    if (strcmp(cur_platform, device.platform_name) != 0) {+      printf("Platform: %s\n", device.platform_name);+      cur_platform = device.platform_name;+    }+    printf("[%d] %s\n", (int)i, device.device_name);+  }++  int selection;+  printf("Choice: ");+  if (scanf("%d", &selection) == 1) {+    ret = 0;+    cfg->preferred_platform = "";+    cfg->preferred_device = "";+    cfg->preferred_device_num = selection;+    cfg->ignore_blacklist = 1;+  }++  // Free all the platform and device names.+  for (size_t j = 0; j < num_devices; j++) {+    free(devices[j].platform_name);+    free(devices[j].device_name);+  }+  free(devices);++  return ret;+}+ static int is_blacklisted(const char *platform_name, const char *device_name,                           const struct opencl_config *cfg) {   if (strcmp(cfg->preferred_platform, "") != 0 ||@@ -370,9 +413,10 @@    for (size_t i = 0; i < num_devices; i++) {     struct opencl_device_option device = devices[i];-    if (!is_blacklisted(device.platform_name, device.device_name, cfg) &&-        strstr(device.platform_name, cfg->preferred_platform) != NULL &&+    if (strstr(device.platform_name, cfg->preferred_platform) != NULL &&         strstr(device.device_name, cfg->preferred_device) != NULL &&+        (cfg->ignore_blacklist ||+         !is_blacklisted(device.platform_name, device.device_name, cfg)) &&         num_device_matches++ == cfg->preferred_device_num) {       // Free all the platform and device names, except the ones we have chosen.       for (size_t j = 0; j < num_devices; j++) {
rts/c/values.h view
@@ -434,6 +434,20 @@ #define BINARY_FORMAT_VERSION 2 #define IS_BIG_ENDIAN (!*(unsigned char *)&(uint16_t){1}) +// On Windows we need to explicitly set the file mode to not mangle+// newline characters.  On *nix there is no difference.+#ifdef _WIN32+#include <io.h>+#include <fcntl.h>+static void set_binary_mode(FILE *f) {+  setmode(fileno(f), O_BINARY);+}+#else+static void set_binary_mode(FILE *f) {+  (void)f;+}+#endif+ // Reading little-endian byte sequences.  On big-endian hosts, we flip // the resulting bytes. 
src/Futhark/CLI/REPL.hs view
@@ -84,10 +84,10 @@    maybe_init_state <- liftIO $ newFutharkiState 0 Nothing   case maybe_init_state of-    Left err -> error $ "Failed to initialise intepreter state: " ++ err+    Left err -> error $ "Failed to initialise interpreter state: " ++ err     Right init_state -> Haskeline.runInputT Haskeline.defaultSettings $ toploop init_state -  putStrLn "Leaving futharki."+  putStrLn "Leaving 'futhark repl'."  confirmQuit :: Haskeline.InputT IO Bool confirmQuit = do
src/Futhark/CLI/Test.hs view
@@ -22,6 +22,7 @@ import System.Exit import System.FilePath import System.Console.GetOpt+import qualified System.Console.Terminal.Size as Terminal import System.IO import Text.Regex.TDFA @@ -348,9 +349,10 @@   moveCursorToTableTop   putStrLn $ statusTable ts   clearLine-  putStrLn $ atMostChars 60 running-  where running    = "Now testing: " ++-                     (unwords . reverse . map testCaseProgram . testStatusRun) ts+  w <- maybe 80 Terminal.width <$> Terminal.size+  putStrLn $ atMostChars (w-length labelstr) running+  where running = labelstr ++ (unwords . reverse . map testCaseProgram . testStatusRun) ts+        labelstr = "Now testing: "  moveCursorToTableTop :: IO () moveCursorToTableTop = cursorUpLine tableLines
src/Futhark/CodeGen/Backends/COpenCL/Boilerplate.hs view
@@ -124,6 +124,12 @@                          set_preferred_platform(&cfg->opencl, s);                        }|]) +  GC.publicDef_ "context_config_select_device_interactively" GC.InitDecl $ \s ->+    ([C.cedecl|void $id:s(struct $id:cfg* cfg);|],+     [C.cedecl|void $id:s(struct $id:cfg* cfg) {+                         select_device_interactively(&cfg->opencl);+                       }|])+   GC.publicDef_ "context_config_dump_program_to" GC.InitDecl $ \s ->     ([C.cedecl|void $id:s(struct $id:cfg* cfg, const char *path);|],      [C.cedecl|void $id:s(struct $id:cfg* cfg, const char *path) {
src/Futhark/CodeGen/Backends/GenericC.hs view
@@ -1186,6 +1186,7 @@     int time_runs;      /* Declare and read input. */+    set_binary_mode(stdin);     $items:input_items     $items:output_decls @@ -1208,6 +1209,9 @@     $stms:free_parsed      /* Print the final result. */+    if (binary_output) {+      set_binary_mode(stdout);+    }     $stms:printstms      $stms:free_outputs
src/Futhark/CodeGen/ImpGen/Kernels.hs view
@@ -48,8 +48,22 @@            -> CallKernelGen () opCompiler dest (Alloc e space) =   ImpGen.compileAlloc dest e space-opCompiler dest (Inner kernel) =+opCompiler (Pattern _ [pe]) (Inner (GetSize key size_class)) = do+  fname <- asks ImpGen.envFunction+  sOp $ Imp.GetSize (patElemName pe) (keyWithEntryPoint fname key) $+    sizeClassWithEntryPoint fname size_class+opCompiler (Pattern _ [pe]) (Inner (CmpSizeLe key size_class x)) = do+  fname <- asks ImpGen.envFunction+  let size_class' = sizeClassWithEntryPoint fname size_class+  sOp . Imp.CmpSizeLe (patElemName pe) (keyWithEntryPoint fname key) size_class'+    =<< ImpGen.compileSubExp x+opCompiler (Pattern _ [pe]) (Inner (GetSizeMax size_class)) =+  sOp $ Imp.GetSizeMax (patElemName pe) size_class+opCompiler dest (Inner (HostOp kernel)) =   kernelCompiler dest kernel+opCompiler pat e =+  compilerBugS $ "ImpGen.opCompiler: Invalid pattern\n  " +++  pretty pat ++ "\nfor expression\n  " ++ pretty e  sizeClassWithEntryPoint :: Name -> Imp.SizeClass -> Imp.SizeClass sizeClassWithEntryPoint fname (Imp.SizeThreshold path) =@@ -60,20 +74,6 @@ kernelCompiler :: Pattern ExplicitMemory -> Kernel InKernel                -> CallKernelGen () -kernelCompiler (Pattern _ [pe]) (GetSize key size_class) = do-  fname <- asks ImpGen.envFunction-  sOp $ Imp.GetSize (patElemName pe) (keyWithEntryPoint fname key) $-    sizeClassWithEntryPoint fname size_class--kernelCompiler (Pattern _ [pe]) (CmpSizeLe key size_class x) = do-  fname <- asks ImpGen.envFunction-  let size_class' = sizeClassWithEntryPoint fname size_class-  sOp . Imp.CmpSizeLe (patElemName pe) (keyWithEntryPoint fname key) size_class'-    =<< ImpGen.compileSubExp x--kernelCompiler (Pattern _ [pe]) (GetSizeMax size_class) =-  sOp $ Imp.GetSizeMax (patElemName pe) size_class- kernelCompiler pat (Kernel desc space _ kernel_body) = do   (constants, init_constants) <- kernelInitialisation space @@ -113,10 +113,6 @@  kernelCompiler pat (SegGenRed space ops _ body) =   compileSegGenRed pat space ops body--kernelCompiler pat e =-  compilerBugS $ "ImpGen.kernelCompiler: Invalid pattern\n  " ++-  pretty pat ++ "\nfor expression\n  " ++ pretty e  expCompiler :: ImpGen.ExpCompiler ExplicitMemory Imp.HostOp 
src/Futhark/CodeGen/ImpGen/Kernels/Base.hs view
@@ -339,13 +339,13 @@  atomicUpdateLocking lam   | Just ops_and_ts <- splitOp lam,-    all (\(_, t, _) -> primBitSize t == 32) ops_and_ts = Left $ \arrs bucket ->+    all (\(_, t, _, _) -> primBitSize t == 32) ops_and_ts = Left $ \arrs bucket ->   -- If the operator is a vectorised binary operator on 32-bit values,   -- we can use a particularly efficient implementation. If the   -- operator has an atomic implementation we use that, otherwise it   -- is still a binary operator which can be implemented by atomic   -- compare-and-swap if 32 bits.-  forM_ (zip arrs ops_and_ts) $ \(a, (op, t, val)) -> do+  forM_ (zip arrs ops_and_ts) $ \(a, (op, t, x, y)) -> do    -- Common variables.   old <- dPrim "old" t@@ -353,47 +353,26 @@   (arr', _a_space, bucket_offset) <- ImpGen.fullyIndexArray a bucket    case opHasAtomicSupport old arr' bucket_offset op of-    Just f -> sOp $ f val--    Nothing -> do-      -- Code generation target:-      ---      -- old = d_his[idx];-      -- do {-      --   assumed = old;-      --   tmp = OP::apply(val, assumed);-      --   old = atomicCAS(&d_his[idx], assumed, tmp);-      -- } while(assumed != old);-      assumed <- dPrim "assumed" t-      run_loop <- dPrimV "run_loop" 1-      ImpGen.copyDWIM old [] (Var a) bucket--      -- Critical section-      x <- dPrim "x" t-      y <- dPrim "y" t+    Just f -> sOp $ f $ Imp.var y t -      -- While-loop: Try to insert your value-      let (toBits, fromBits) =-            case t of FloatType Float32 -> (\v -> Imp.FunExp "to_bits32" [v] int32,-                                            \v -> Imp.FunExp "from_bits32" [v] t)-                      _                 -> (id, id)-      sWhile (Imp.var run_loop int32) $ do-        assumed <-- Imp.var old t-        x <-- val-        y <-- Imp.var assumed t-        x <-- Imp.BinOpExp op (Imp.var x t) (Imp.var y t)-        old_bits <- dPrim "old_bits" int32-        sOp $ Imp.Atomic $-          Imp.AtomicCmpXchg old_bits arr' bucket_offset-          (toBits (Imp.var assumed t)) (toBits (Imp.var x t))-        old <-- fromBits (Imp.var old_bits int32)-        sWhen (toBits (Imp.var assumed t) .==. Imp.var old_bits int32)-          (run_loop <-- 0)+    Nothing -> atomicUpdateCAS t a old bucket x $+      x <-- Imp.BinOpExp op (Imp.var x t) (Imp.var y t)    where opHasAtomicSupport old arr' bucket' bop = do           let atomic f = Imp.Atomic . f old arr' bucket'           atomic <$> Imp.atomicBinOp bop +-- If the operator functions purely on single 32-bit values, we can+-- use an implementation based on CAS, no matter what the operator+-- does.+atomicUpdateLocking op+  | [Prim t] <- lambdaReturnType op,+    [xp, _] <- lambdaParams op,+    primBitSize t == 32 = Left $ \[arr] bucket -> do+      old <- dPrim "old" t+      atomicUpdateCAS t arr old bucket (paramName xp) $+        ImpGen.compileBody' [xp] $ lambdaBody op+ atomicUpdateLocking op = Right $ \locking arrs bucket -> do   old <- dPrim "old" int32   continue <- dPrimV "continue" true@@ -453,8 +432,45 @@     sOp Imp.MemFence   where writeArray bucket arr val = ImpGen.copyDWIM arr bucket val [] +atomicUpdateCAS :: PrimType+                -> VName -> VName+                -> [Imp.Exp] -> VName+                -> ImpGen.ImpM lore Imp.KernelOp ()+                -> ImpGen.ImpM lore Imp.KernelOp ()+atomicUpdateCAS t arr old bucket x do_op = do+  -- Code generation target:+  --+  -- old = d_his[idx];+  -- do {+  --   assumed = old;+  --   x = do_op(assumed, y);+  --   old = atomicCAS(&d_his[idx], assumed, tmp);+  -- } while(assumed != old);+  assumed <- dPrim "assumed" t+  run_loop <- dPrimV "run_loop" 1+  ImpGen.copyDWIM old [] (Var arr) bucket++  (arr', _a_space, bucket_offset) <- ImpGen.fullyIndexArray arr bucket++  -- While-loop: Try to insert your value+  let (toBits, fromBits) =+        case t of FloatType Float32 -> (\v -> Imp.FunExp "to_bits32" [v] int32,+                                        \v -> Imp.FunExp "from_bits32" [v] t)+                  _                 -> (id, id)+  sWhile (Imp.var run_loop int32) $ do+    assumed <-- Imp.var old t+    x <-- Imp.var assumed t+    do_op+    old_bits <- dPrim "old_bits" int32+    sOp $ Imp.Atomic $+      Imp.AtomicCmpXchg old_bits arr' bucket_offset+      (toBits (Imp.var assumed t)) (toBits (Imp.var x t))+    old <-- fromBits (Imp.var old_bits int32)+    sWhen (toBits (Imp.var assumed t) .==. Imp.var old_bits int32)+      (run_loop <-- 0)+ -- | Horizontally fission a lambda that models a binary operator.-splitOp :: Attributes lore => Lambda lore -> Maybe [(BinOp, PrimType, Imp.Exp)]+splitOp :: Attributes lore => Lambda lore -> Maybe [(BinOp, PrimType, VName, VName)] splitOp lam = mapM splitStm $ bodyResult $ lambdaBody lam   where n = length $ lambdaReturnType lam         splitStm (Var res) = do@@ -467,7 +483,7 @@           guard $ paramName xp == x           guard $ paramName yp == y           Prim t <- Just $ patElemType pe-          return (op, t, Imp.var (paramName yp) t)+          return (op, t, paramName xp, paramName yp)         splitStm _ = Nothing  computeKernelUses :: FreeIn a =>
src/Futhark/CodeGen/ImpGen/Kernels/SegGenRed.hs view
@@ -202,7 +202,7 @@                 vs_params = takeLast (length vs') $ lambdaParams lam              sWhen bucket_in_bounds $ do-              ImpGen.dLParams vs_params+              ImpGen.dLParams $ lambdaParams lam               vectorLoops [] (shapeDims shape) $ \is -> do                 forM_ (zip vs_params vs') $ \(p, v) ->                   ImpGen.copyDWIM (paramName p) [] v is
src/Futhark/Doc/Generator.hs view
@@ -311,7 +311,7 @@ valBindHtml name (ValBind _ _ retdecl (Info rettype) tparams params _ _ _) = do   let tparams' = mconcat $ map ((" "<>) . typeParamHtml) tparams       noLink' = noLink $ map typeParamName tparams ++-                map identName (S.toList $ mconcat $ map patIdentSet params)+                map identName (S.toList $ mconcat $ map patternIdents params)   rettype' <- noLink' $ maybe (typeHtml rettype) typeExpHtml retdecl   params' <- noLink' $ mapM patternHtml params   return (keyword "val " <> (H.span ! A.class_ "decl_name") name,
src/Futhark/Internalise.hs view
@@ -2,7 +2,7 @@ {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE OverloadedStrings #-}-{-# OPTIONS_GHC -fmax-pmcheck-iterations=2500000#-}+{-# OPTIONS_GHC -fmax-pmcheck-iterations=25000000#-} -- | -- -- This module implements a transformation from source to core@@ -128,7 +128,7 @@   -- parameters here.   bindingParams [] (map E.patternNoShapeAnnotations params) $   \_ shapeparams params' -> do-    (entry_rettype, _) <- internaliseEntryReturnType $ E.vacuousShapeAnnotations rettype+    (entry_rettype, _) <- internaliseEntryReturnType $ anyDimShapeAnnotations rettype     let entry' = entryPoint (zip params params') (retdecl, rettype, entry_rettype)         args = map (I.Var . I.paramName) $ concat params' @@ -232,8 +232,7 @@       is_const <- lookupConstant loc name       case is_const of         Just ses -> return ses-        Nothing -> (:[]) . I.Var <$> internaliseIdent (E.Ident name (Info t') loc)-  where t' = removeShapeAnnotations t+        Nothing -> (:[]) . I.Var <$> internaliseIdent (E.Ident name (Info t) loc)  internaliseExp desc (E.Index e idxs _ loc) = do   vs <- internaliseExpToVars "indexed" e@@ -253,7 +252,7 @@           M.singleton name <$> internaliseExp desc e         internaliseField (E.RecordFieldImplicit name t loc) =           internaliseField $ E.RecordFieldExplicit (baseName name)-          (E.Var (E.qualName name) (vacuousShapeAnnotations <$> t) loc) loc+          (E.Var (E.qualName name) t loc) loc  internaliseExp desc (E.ArrayLit es (Info arr_t) loc)   -- If this is a multidimensional array literal of primitives, we@@ -278,7 +277,7 @@   es' <- mapM (internaliseExp "arr_elem") es   case es' of     [] -> do-      rowtypes <- internaliseType (rowtype `setAliases` ())+      rowtypes <- internaliseType $ toStructural rowtype       let arraylit rt = I.BasicOp $ I.ArrayLit [] rt       letSubExps desc $ map (arraylit . zeroDim . fromDecl) rowtypes     e' : _ -> do@@ -391,7 +390,7 @@                (eBody [eDivRoundingUp Int32 (eSubExp distance) (eSubExp pos_step)])   pure <$> letSubExp desc (I.BasicOp $ I.Iota num_elems start' step it) -internaliseExp desc (E.Ascript e (TypeDecl dt (Info et)) loc) = do+internaliseExp desc (E.Ascript e (TypeDecl dt (Info et)) _ loc) = do   es <- internaliseExp desc e   (ts, cm) <- internaliseReturnType et   mapM_ (uncurry (internaliseDimConstant loc)) cm@@ -432,7 +431,7 @@            args' <- concat <$> mapM (internaliseExp "arg") args            fst <$> funcall desc qfname args' loc -internaliseExp desc (E.LetPat tparams pat e body loc) =+internaliseExp desc (E.LetPat tparams pat e body _ loc) =   internalisePat desc tparams pat e body loc (internaliseExp desc)  internaliseExp desc (E.LetFun ofname (tparams, params, retdecl, Info rettype, body) letbody loc) = do@@ -581,11 +580,11 @@                    loop_initial_cond : mergeinit,                    init_loop_cond_bnds)) -internaliseExp desc (E.LetWith name src idxs ve body loc) = do-  let pat = E.Id (E.identName name) (E.vacuousShapeAnnotations <$> E.identType name) loc-      src_t = E.fromStruct . E.vacuousShapeAnnotations <$> E.identType src+internaliseExp desc (E.LetWith name src idxs ve body t loc) = do+  let pat = E.Id (E.identName name) (E.identType name) loc+      src_t = E.fromStruct <$> E.identType src       e = E.Update (E.Var (E.qualName $ E.identName src) src_t loc) idxs ve loc-  internaliseExp desc $ E.LetPat [] pat e body loc+  internaliseExp desc $ E.LetPat [] pat e body t loc  internaliseExp desc (E.Update src slice ve loc) = do   ves <- internaliseExp "lw_val" ve@@ -633,143 +632,6 @@           letBindNames_ [v'] $ I.BasicOp $ I.SubExp v           return $ I.Var v' -internaliseExp desc (E.Map lam arr _ _) = do-  arr' <- internaliseExpToVars "map_arr" arr-  lam' <- internaliseMapLambda internaliseLambda lam $ map I.Var arr'-  w <- arraysSize 0 <$> mapM lookupType arr'-  letTupExp' desc $ I.Op $-    I.Screma w (I.mapSOAC lam') arr'--internaliseExp desc (E.Reduce comm lam ne arr loc) =-  internaliseScanOrReduce desc "reduce" reduce (lam, ne, arr, loc)-  where reduce w red_lam nes arrs =-          I.Screma w <$> I.reduceSOAC comm red_lam nes <*> pure arrs--internaliseExp desc (E.GenReduce hist op ne buckets img loc) = do-  ne' <- internaliseExp "gen_reduce_ne" ne-  hist' <- internaliseExpToVars "gen_reduce_hist" hist-  buckets' <- letExp "gen_reduce_buckets" . BasicOp . SubExp =<<-              internaliseExp1 "gen_reduce_buckets" buckets-  img' <- internaliseExpToVars "gen_reduce_img" img--  -- reshape neutral element to have same size as the destination array-  ne_shp <- forM (zip ne' hist') $ \(n, h) -> do-    rowtype <- I.stripArray 1 <$> lookupType h-    ensureShape asserting-      "Row shape of destination array does not match shape of neutral element"-      loc rowtype "gen_reduce_ne_right_shape" n-  ne_ts <- mapM I.subExpType ne_shp-  his_ts <- mapM lookupType hist'-  op' <- internaliseFoldLambda internaliseLambda op ne_ts his_ts--  -- reshape return type of bucket function to have same size as neutral element-  -- (modulo the index)-  bucket_param <- newParam "bucket_p" $ I.Prim int32-  img_params <- mapM (newParam "img_p" . rowType) =<< mapM lookupType img'-  let params = bucket_param : img_params-      rettype = I.Prim int32 : ne_ts-      body = mkBody mempty $ map (I.Var . paramName) params-  body' <- localScope (scopeOfLParams params) $-           ensureResultShape asserting-           "Row shape of value array does not match row shape of gen_reduce target"-           (srclocOf img) rettype body--  -- get sizes of histogram and image arrays-  w_hist <- arraysSize 0 <$> mapM lookupType hist'-  w_img <- arraysSize 0 <$> mapM lookupType img'--  -- Generate an assertion and reshapes to ensure that buckets' and-  -- img' are the same size.-  b_shape <- arrayShape <$> lookupType buckets'-  let b_w = shapeSize 0 b_shape-  cmp <- letSubExp "bucket_cmp" $ I.BasicOp $ I.CmpOp (I.CmpEq I.int32) b_w w_img-  c <- assertingOne $-    letExp "bucket_cert" $ I.BasicOp $-    I.Assert cmp "length of index and value array does not match" (loc, mempty)-  buckets'' <- certifying c $ letExp (baseString buckets') $-    I.BasicOp $ I.Reshape (reshapeOuter [DimCoercion w_img] 1 b_shape) buckets'--  letTupExp' desc $ I.Op $-    I.GenReduce w_img [GenReduceOp w_hist hist' ne_shp op'] (I.Lambda params body' rettype) $ buckets'' : img'--internaliseExp desc (E.Scan lam ne arr loc) =-  internaliseScanOrReduce desc "scan" scan (lam, ne, arr, loc)-  where scan w scan_lam nes arrs =-          I.Screma w <$> I.scanSOAC scan_lam nes <*> pure arrs--internaliseExp _ (E.Filter lam arr _) = do-  arrs <- internaliseExpToVars "filter_input" arr-  lam' <- internalisePartitionLambda internaliseLambda 1 lam $ map I.Var arrs-  uncurry (++) <$> partitionWithSOACS 1 lam' arrs--internaliseExp _ (E.Partition k lam arr _) = do-  arrs <- internaliseExpToVars "partition_input" arr-  lam' <- internalisePartitionLambda internaliseLambda k lam $ map I.Var arrs-  uncurry (++) <$> partitionWithSOACS k lam' arrs--internaliseExp desc (E.Stream (E.MapLike o) lam arr _) = do-  arrs <- internaliseExpToVars "stream_input" arr-  lam' <- internaliseStreamMapLambda internaliseLambda lam $ map I.Var arrs-  w <- arraysSize 0 <$> mapM lookupType arrs-  let form = I.Parallel o Commutative (I.Lambda [] (mkBody mempty []) []) []-  letTupExp' desc $ I.Op $ I.Stream w form lam' arrs---- If the stream form is a reduce, we also have to fiddle with the--- lambda to incorporate the reduce function.  FIXME: can't we just--- modify the internal representation of reduction streams?-internaliseExp desc (E.Stream (E.RedLike o comm lam0) lam arr _) = do-  arrs <- internaliseExpToVars "stream_input" arr-  rowts <- mapM (fmap I.rowType . lookupType) arrs-  (lam_params, lam_body) <--    internaliseStreamLambda internaliseLambda lam rowts-  let (chunk_param, _, lam_val_params) =-        partitionChunkedFoldParameters 0 lam_params--  -- Synthesize neutral elements by applying the fold function-  -- to an empty chunk.-  letBindNames_ [I.paramName chunk_param] $-    I.BasicOp $ I.SubExp $ constant (0::Int32)-  forM_ lam_val_params $ \p ->-    letBindNames_ [I.paramName p] $-    I.BasicOp $ I.Scratch (I.elemType $ I.paramType p) $-    I.arrayDims $ I.paramType p-  accs <- bodyBind =<< renameBody lam_body--  acctps <- mapM I.subExpType accs-  outsz  <- arraysSize 0 <$> mapM lookupType arrs-  let acc_arr_tps = [ I.arrayOf t (I.Shape [outsz]) NoUniqueness | t <- acctps ]-  lam0'  <- internaliseFoldLambda internaliseLambda lam0 acctps acc_arr_tps-  let lam0_acc_params = fst $ splitAt (length accs) $ I.lambdaParams lam0'-  acc_params <- forM lam0_acc_params $ \p -> do-    name <- newVName $ baseString $ I.paramName p-    return p { I.paramName = name }--  body_with_lam0 <--    ensureResultShape asserting "shape of result does not match shape of initial value"-    (srclocOf lam0) acctps <=< insertStmsM $ do-      lam_res <- bodyBind lam_body--      let consumed = consumedByLambda $ Alias.analyseLambda lam0'-          copyIfConsumed p (I.Var v)-            | I.paramName p `S.member` consumed =-                letSubExp "acc_copy" $ I.BasicOp $ I.Copy v-          copyIfConsumed _ x = return x--      accs' <- zipWithM copyIfConsumed (I.lambdaParams lam0') accs-      lam_res' <- ensureArgShapes asserting-                  "shape of chunk function result does not match shape of initial value"-                  (srclocOf lam) [] (map I.typeOf $ I.lambdaParams lam0') lam_res-      new_lam_res <- eLambda lam0' $ map eSubExp $ accs' ++ lam_res'-      return $ resultBody new_lam_res--  -- Make sure the chunk size parameter comes first.-  let form = I.Parallel o comm lam0' accs-      lam' = I.Lambda { lambdaParams = chunk_param : acc_params ++ lam_val_params-                      , lambdaBody = body_with_lam0-                      , lambdaReturnType = acctps }-  w <- arraysSize 0 <$> mapM lookupType arrs-  letTupExp' desc $ I.Op $ I.Stream w form lam' arrs- internaliseExp _ (E.VConstr0 c (Info t) loc) =   case t of     Enum cs ->@@ -860,9 +722,9 @@ andExp l r = E.If l r (E.Literal (E.BoolValue False) noLoc) (Info (E.Prim E.Bool)) noLoc  eqExp :: E.Exp -> E.Exp -> E.Exp-eqExp l r = E.BinOp eq (Info $ vacuousShapeAnnotations ft)+eqExp l r = E.BinOp eq (Info ft)             (l, sType l) (r, sType r) (Info (E.Prim E.Bool)) noLoc-  where sType e = Info $ toStruct $ vacuousShapeAnnotations $ E.typeOf e+  where sType e = Info $ toStruct $ E.typeOf e         arrow   = Arrow S.empty Nothing         ft      = E.typeOf l `arrow` E.typeOf r `arrow` E.Prim E.Bool         eq      = qualName $ VName "==" (-1)@@ -871,7 +733,7 @@ generateCond p e = foldr andExp (E.Literal (E.BoolValue True) noLoc) conds   where conds = mapMaybe ((<*> pure e) . fst) $ generateCond' p -        generateCond' :: E.Pattern -> [(Maybe (E.Exp -> E.Exp), CompType)]+        generateCond' :: E.Pattern -> [(Maybe (E.Exp -> E.Exp), PatternType)]         generateCond' (E.TuplePattern ps loc) = generateCond' (E.RecordPattern fs loc)           where fs = zipWith (\i p' -> (nameFromString (show i), p')) ([1..] :: [Integer]) ps         generateCond' (E.RecordPattern fs _) = concatMap instCond holes@@ -885,12 +747,12 @@                 instCond (condHoles, f) = map (projectHole f) condHoles         generateCond' (E.PatternParens p' _) = generateCond' p'         generateCond' (E.Id _ (Info t) _) =-          [(Nothing, removeShapeAnnotations t)]+          [(Nothing, t)]         generateCond' (E.Wildcard (Info t) _)=-          [(Nothing, removeShapeAnnotations t)]+          [(Nothing, t)]         generateCond' (E.PatternAscription p' _ _) = generateCond' p'         generateCond' (E.PatternLit ePat (Info t) _) =-          [(Just (eqExp ePat), removeShapeAnnotations t)]+          [(Just (eqExp ePat), t)]   generateCaseIf :: String -> E.Exp -> Case -> I.Body -> InternaliseM I.Exp@@ -1024,6 +886,121 @@   w <- arraysSize 0 <$> mapM lookupType arrs   letTupExp' desc . I.Op =<< f w lam' nes' arrs +internaliseGenReduce :: String+                     -> E.Exp -> E.Exp -> E.Exp -> E.Exp -> E.Exp -> SrcLoc+                     -> InternaliseM [SubExp]+internaliseGenReduce desc hist op ne buckets img loc = do+  ne' <- internaliseExp "gen_reduce_ne" ne+  hist' <- internaliseExpToVars "gen_reduce_hist" hist+  buckets' <- letExp "gen_reduce_buckets" . BasicOp . SubExp =<<+              internaliseExp1 "gen_reduce_buckets" buckets+  img' <- internaliseExpToVars "gen_reduce_img" img++  -- reshape neutral element to have same size as the destination array+  ne_shp <- forM (zip ne' hist') $ \(n, h) -> do+    rowtype <- I.stripArray 1 <$> lookupType h+    ensureShape asserting+      "Row shape of destination array does not match shape of neutral element"+      loc rowtype "gen_reduce_ne_right_shape" n+  ne_ts <- mapM I.subExpType ne_shp+  his_ts <- mapM lookupType hist'+  op' <- internaliseFoldLambda internaliseLambda op ne_ts his_ts++  -- reshape return type of bucket function to have same size as neutral element+  -- (modulo the index)+  bucket_param <- newParam "bucket_p" $ I.Prim int32+  img_params <- mapM (newParam "img_p" . rowType) =<< mapM lookupType img'+  let params = bucket_param : img_params+      rettype = I.Prim int32 : ne_ts+      body = mkBody mempty $ map (I.Var . paramName) params+  body' <- localScope (scopeOfLParams params) $+           ensureResultShape asserting+           "Row shape of value array does not match row shape of gen_reduce target"+           (srclocOf img) rettype body++  -- get sizes of histogram and image arrays+  w_hist <- arraysSize 0 <$> mapM lookupType hist'+  w_img <- arraysSize 0 <$> mapM lookupType img'++  -- Generate an assertion and reshapes to ensure that buckets' and+  -- img' are the same size.+  b_shape <- arrayShape <$> lookupType buckets'+  let b_w = shapeSize 0 b_shape+  cmp <- letSubExp "bucket_cmp" $ I.BasicOp $ I.CmpOp (I.CmpEq I.int32) b_w w_img+  c <- assertingOne $+    letExp "bucket_cert" $ I.BasicOp $+    I.Assert cmp "length of index and value array does not match" (loc, mempty)+  buckets'' <- certifying c $ letExp (baseString buckets') $+    I.BasicOp $ I.Reshape (reshapeOuter [DimCoercion w_img] 1 b_shape) buckets'++  letTupExp' desc $ I.Op $+    I.GenReduce w_img [GenReduceOp w_hist hist' ne_shp op'] (I.Lambda params body' rettype) $ buckets'' : img'++internaliseStreamMap :: String -> StreamOrd -> E.Exp -> E.Exp+                     -> InternaliseM [SubExp]+internaliseStreamMap desc o lam arr = do+  arrs <- internaliseExpToVars "stream_input" arr+  lam' <- internaliseStreamMapLambda internaliseLambda lam $ map I.Var arrs+  w <- arraysSize 0 <$> mapM lookupType arrs+  let form = I.Parallel o Commutative (I.Lambda [] (mkBody mempty []) []) []+  letTupExp' desc $ I.Op $ I.Stream w form lam' arrs++internaliseStreamRed :: String -> StreamOrd -> Commutativity+                     -> E.Exp -> E.Exp -> E.Exp+                     -> InternaliseM [SubExp]+internaliseStreamRed desc o comm lam0 lam arr = do+  arrs <- internaliseExpToVars "stream_input" arr+  rowts <- mapM (fmap I.rowType . lookupType) arrs+  (lam_params, lam_body) <-+    internaliseStreamLambda internaliseLambda lam rowts+  let (chunk_param, _, lam_val_params) =+        partitionChunkedFoldParameters 0 lam_params++  -- Synthesize neutral elements by applying the fold function+  -- to an empty chunk.+  letBindNames_ [I.paramName chunk_param] $+    I.BasicOp $ I.SubExp $ constant (0::Int32)+  forM_ lam_val_params $ \p ->+    letBindNames_ [I.paramName p] $+    I.BasicOp $ I.Scratch (I.elemType $ I.paramType p) $+    I.arrayDims $ I.paramType p+  accs <- bodyBind =<< renameBody lam_body++  acctps <- mapM I.subExpType accs+  outsz  <- arraysSize 0 <$> mapM lookupType arrs+  let acc_arr_tps = [ I.arrayOf t (I.Shape [outsz]) NoUniqueness | t <- acctps ]+  lam0'  <- internaliseFoldLambda internaliseLambda lam0 acctps acc_arr_tps+  let lam0_acc_params = fst $ splitAt (length accs) $ I.lambdaParams lam0'+  acc_params <- forM lam0_acc_params $ \p -> do+    name <- newVName $ baseString $ I.paramName p+    return p { I.paramName = name }++  body_with_lam0 <-+    ensureResultShape asserting "shape of result does not match shape of initial value"+    (srclocOf lam0) acctps <=< insertStmsM $ do+      lam_res <- bodyBind lam_body++      let consumed = consumedByLambda $ Alias.analyseLambda lam0'+          copyIfConsumed p (I.Var v)+            | I.paramName p `S.member` consumed =+                letSubExp "acc_copy" $ I.BasicOp $ I.Copy v+          copyIfConsumed _ x = return x++      accs' <- zipWithM copyIfConsumed (I.lambdaParams lam0') accs+      lam_res' <- ensureArgShapes asserting+                  "shape of chunk function result does not match shape of initial value"+                  (srclocOf lam) [] (map I.typeOf $ I.lambdaParams lam0') lam_res+      new_lam_res <- eLambda lam0' $ map eSubExp $ accs' ++ lam_res'+      return $ resultBody new_lam_res++  -- Make sure the chunk size parameter comes first.+  let form = I.Parallel o comm lam0' accs+      lam' = I.Lambda { lambdaParams = chunk_param : acc_params ++ lam_val_params+                      , lambdaBody = body_with_lam0+                      , lambdaReturnType = acctps }+  w <- arraysSize 0 <$> mapM lookupType arrs+  letTupExp' desc $ I.Op $ I.Stream w form lam' arrs+ internaliseExp1 :: String -> E.Exp -> InternaliseM I.SubExp internaliseExp1 desc e = do   vs <- internaliseExp desc e@@ -1204,27 +1181,7 @@     mapM_ (uncurry (internaliseDimConstant loc)) $ pcm<>rcm     return (params', body', map I.fromDecl rettype') -internaliseLambda E.OpSection{} _ = fail "internaliseLambda: unexpected OpSection"--internaliseLambda E.OpSectionLeft{} _ = fail "internaliseLambda: unexpected OpSectionLeft"--internaliseLambda E.OpSectionRight{} _ = fail "internaliseLambda: unexpected OpSectionRight"--internaliseLambda e rowtypes = do-  (_, _, remaining_params_ts) <- findFuncall e-  (params, param_args) <- fmap unzip $ forM remaining_params_ts $ \et -> do-    name <- newVName "not_curried"-    return (E.Id name (Info $ E.vacuousShapeAnnotations $ et `setAliases` mempty) loc,-            E.Var (E.qualName name)-             (Info (et `setAliases` mempty)) loc)-  let rettype = E.typeOf e-      body = foldl (\f arg -> E.Apply f arg (Info E.Observe)-                              (Info $ E.vacuousShapeAnnotations rettype) loc)-                   e-                   param_args-      rettype' = E.vacuousShapeAnnotations $ rettype `E.setAliases` ()-  internaliseLambda (E.Lambda [] params body Nothing (Info (mempty, rettype')) loc) rowtypes-  where loc = srclocOf e+internaliseLambda e _ = fail $ "internaliseLambda: unexpected expression:\n" ++ pretty e  internaliseDimConstant :: SrcLoc -> Name -> VName -> InternaliseM () internaliseDimConstant loc fname name =@@ -1411,6 +1368,60 @@       (++) <$> internaliseExp (desc ++ "_zip_x") x            <*> internaliseExp (desc ++ "_zip_y") y +    handle [TupLit [lam, arr] _] "map" = Just $ \desc -> do+      arr' <- internaliseExpToVars "map_arr" arr+      lam' <- internaliseMapLambda internaliseLambda lam $ map I.Var arr'+      w <- arraysSize 0 <$> mapM lookupType arr'+      letTupExp' desc $ I.Op $+        I.Screma w (I.mapSOAC lam') arr'++    handle [TupLit [lam, arr] _] "filter" = Just $ \_desc -> do+      arrs <- internaliseExpToVars "filter_input" arr+      lam' <- internalisePartitionLambda internaliseLambda 1 lam $ map I.Var arrs+      uncurry (++) <$> partitionWithSOACS 1 lam' arrs++    handle [TupLit [k, lam, arr] _] "partition" = do+      k' <- fromIntegral <$> isInt32 k+      Just $ \_desc -> do+        arrs <- internaliseExpToVars "partition_input" arr+        lam' <- internalisePartitionLambda internaliseLambda k' lam $ map I.Var arrs+        uncurry (++) <$> partitionWithSOACS k' lam' arrs+        where isInt32 (Literal (SignedValue (Int32Value k')) _) = Just k'+              isInt32 (IntLit k' (Info (E.Prim (Signed Int32))) _) = Just $ fromInteger k'+              isInt32 _ = Nothing++    handle [TupLit [lam, ne, arr] _] "reduce" = Just $ \desc ->+      internaliseScanOrReduce desc "reduce" reduce (lam, ne, arr, loc)+      where reduce w red_lam nes arrs =+              I.Screma w <$>+              I.reduceSOAC Noncommutative red_lam nes <*> pure arrs++    handle [TupLit [lam, ne, arr] _] "reduce_comm" = Just $ \desc ->+      internaliseScanOrReduce desc "reduce" reduce (lam, ne, arr, loc)+      where reduce w red_lam nes arrs =+              I.Screma w <$>+              I.reduceSOAC Commutative red_lam nes <*> pure arrs++    handle [TupLit [lam, ne, arr] _] "scan" = Just $ \desc ->+      internaliseScanOrReduce desc "scan" reduce (lam, ne, arr, loc)+      where reduce w scan_lam nes arrs =+              I.Screma w <$> I.scanSOAC scan_lam nes <*> pure arrs++    handle [TupLit [op, f, arr] _] "stream_red" = Just $ \desc ->+      internaliseStreamRed desc InOrder Noncommutative op f arr++    handle [TupLit [op, f, arr] _] "stream_red_per" = Just $ \desc ->+      internaliseStreamRed desc Disorder Commutative op f arr++    handle [TupLit [f, arr] _] "stream_map" = Just $ \desc ->+      internaliseStreamMap desc InOrder f arr++    handle [TupLit [f, arr] _] "stream_map_per" = Just $ \desc ->+      internaliseStreamMap desc Disorder f arr++    handle [TupLit [dest, op, ne, buckets, img] _] "gen_reduce" = Just $ \desc ->+      internaliseGenReduce desc dest op ne buckets img loc+     handle [x] "unzip" = Just $ flip internaliseExp x     handle [x] "trace" = Just $ flip internaliseExp x     handle [x] "break" = Just $ flip internaliseExp x@@ -1556,7 +1567,7 @@           safety <- askSafety           se <- letSubExp (baseString name ++ "_arg") $                 I.Apply fname [] [I.Prim I.int32] (safety, loc, [])-          return (se, I.Observe, I.Prim I.int32)+          return (se, I.ObservePrim, I.Prim I.int32)  funcall :: String -> QualName VName -> [SubExp] -> SrcLoc         -> InternaliseM ([SubExp], [I.ExtType])@@ -1567,7 +1578,7 @@   argts <- mapM subExpType args   closure_ts <- mapM lookupType closure   shapeargs <- argShapes shapes value_paramts argts-  let diets = const_ds ++ replicate (length closure + length shapeargs) I.Observe +++  let diets = const_ds ++ replicate (length closure + length shapeargs) I.ObservePrim ++               map I.diet value_paramts       constOrShape = const $ I.Prim int32       paramts = map constOrShape constargs ++ closure_ts ++
src/Futhark/Internalise/Bindings.hs view
@@ -101,8 +101,7 @@       -- XXX: we gotta be screwing up somehow by ignoring the extra       -- return values.  If not, why not?       (tss, _) <- internaliseParamTypes nothing_bound mempty-                  [flip E.setAliases () $ E.vacuousShapeAnnotations $-                   E.unInfo $ E.identType bindee]+                  [flip E.setAliases () $ E.unInfo $ E.identType bindee]       case concat tss of         [t] -> return [(name, t)]         tss' -> forM tss' $ \t -> do@@ -131,8 +130,7 @@           flattenPattern' $ E.Id name t loc         flattenPattern' (E.Id v (Info t) loc) = do           new_name <- newVName $ baseString v-          return [((E.Ident v (Info (E.removeShapeAnnotations t)) loc,-                    new_name),+          return [((E.Ident v (Info t) loc, new_name),                    t `E.setAliases` ())]         flattenPattern' (E.TuplePattern pats _) =           concat <$> mapM flattenPattern' pats
src/Futhark/Internalise/Defunctionalise.hs view
@@ -19,7 +19,7 @@  -- | A static value stores additional information about the result of -- defunctionalization of an expression, aside from the residual expression.-data StaticVal = Dynamic CompType+data StaticVal = Dynamic PatternType                | LambdaSV [VName] Pattern StructType Exp Env                  -- ^ The 'VName's are shape parameters that are bound                  -- by the 'Pattern'.@@ -171,31 +171,29 @@       (pats, body, tp) <- etaExpand e       defuncExp $ Lambda [] pats body Nothing (Info (mempty, tp)) noLoc     _ -> let tp = typeFromSV sv-         in return (Var qn (Info (vacuousShapeAnnotations tp)) loc, sv)+         in return (Var qn (Info tp) loc, sv) -defuncExp (Ascript e0 tydecl loc)+defuncExp (Ascript e0 tydecl t loc)   | orderZero (typeOf e0) = do (e0', sv) <- defuncExp e0-                               return (Ascript e0' tydecl loc, sv)+                               return (Ascript e0' tydecl t loc, sv)   | otherwise = defuncExp e0 -defuncExp (LetPat tparams pat e1 e2 loc) = do+defuncExp (LetPat tparams pat e1 e2 _ loc) = do   let env_dim = envFromShapeParams tparams   (e1', sv1) <- localEnv env_dim $ defuncExp e1   let env  = matchPatternSV pat sv1       pat' = updatePattern pat sv1   (e2', sv2) <- localEnv (env <> env_dim) $ defuncExp e2-  return (LetPat tparams pat' e1' e2' loc, sv2)+  return (LetPat tparams pat' e1' e2' (Info $ typeOf e2') loc, sv2)  defuncExp (LetFun vn (dims, pats, _, rettype@(Info ret), e1) e2 loc) = do   let env_dim = envFromShapeParams dims   (pats', e1', sv1) <- localEnv env_dim $ defuncLet dims pats e1 rettype   (e2', sv2) <- extendEnv vn sv1 $ defuncExp e2   case pats' of-    []  -> let t1 = combineTypeShapes (fromStruct ret) $-                    vacuousShapeAnnotations $ typeOf e1'-           in return (LetPat dims (Id vn (Info t1) noLoc) e1' e2' loc, sv2)-    _:_ -> let t1 = combineTypeShapes ret $-                    vacuousShapeAnnotations . toStruct $ typeOf e1'+    []  -> let t1 = combineTypeShapes (fromStruct ret) $ typeOf e1'+           in return (LetPat dims (Id vn (Info t1) noLoc) e1' e2' (Info $ typeOf e2') loc, sv2)+    _:_ -> let t1 = combineTypeShapes ret $ toStruct $ typeOf e1'            in return (LetFun vn (dims, pats', Nothing, Info t1, e1') e2' loc, sv2)  defuncExp (If e1 e2 e3 tp loc) = do@@ -204,6 +202,14 @@   (e3', _ ) <- defuncExp e3   return (If e1' e2' e3' tp loc, sv) +defuncExp e@(Apply f@(Var f' _ _) arg d t loc)+  | baseTag (qualLeaf f') <= maxIntrinsicTag,+    TupLit es tuploc <- arg = do+      -- defuncSoacExp also works fine for non-SOACs.+      es' <- mapM defuncSoacExp es+      return (Apply f (TupLit es' tuploc) d t loc,+              Dynamic $ typeOf e)+ defuncExp e@Apply{} = defuncApply 0 e  defuncExp (Negate e0 loc) = do@@ -242,7 +248,7 @@          closureFromDynamicFun (vn, sv) =           let name = nameFromString $ pretty vn-              tp' = vacuousShapeAnnotations $ typeFromSV sv+              tp' = typeFromSV sv           in (RecordFieldExplicit name                (Var (qualName vn) (Info tp') noLoc) noLoc, (vn, sv)) @@ -267,7 +273,8 @@                         return (While e2', mempty)   (e3', sv) <- localEnv (env1 <> env2 <> env_dim) $ defuncExp e3   return (DoLoop tparams pat e1' form' e3' loc, sv)-  where envFromIdent (Ident vn (Info tp) _) = M.singleton vn $ Dynamic tp+  where envFromIdent (Ident vn (Info tp) _) =+          M.singleton vn $ Dynamic tp  -- We handle BinOps by turning them into ordinary function applications. defuncExp (BinOp qn (Info t) (e1, Info pt1) (e2, Info pt2) (Info ret) loc) =@@ -284,12 +291,12 @@     Dynamic _ -> return (Project vn e0' tp loc, Dynamic tp')     _ -> error $ "Projection of an expression with static value " ++ show sv0 -defuncExp (LetWith id1 id2 idxs e1 body loc) = do+defuncExp (LetWith id1 id2 idxs e1 body t loc) = do   e1' <- defuncExp' e1   sv1 <- lookupVar (identSrcLoc id2) $ identName id2   idxs' <- mapM defuncDimIndex idxs   (body', sv) <- extendEnv (identName id1) sv1 $ defuncExp body-  return (LetWith id1 id2 idxs' e1' body' loc, sv)+  return (LetWith id1 id2 idxs' e1' body' t loc, sv)  defuncExp expr@(Index e0 idxs info loc) = do   e0' <- defuncExp' e0@@ -309,8 +316,7 @@   (e1', sv1) <- defuncExp e1   (e2', sv2) <- defuncExp e2   let sv = staticField sv1 sv2 fs-  return (RecordUpdate e1' fs e2'-           (Info $ vacuousShapeAnnotations $ typeFromSV sv1) loc,+  return (RecordUpdate e1' fs e2' (Info $ typeFromSV sv1) loc,           sv)   where staticField (RecordSV svs) sv2 (f:fs') =           case lookup f svs of@@ -321,48 +327,6 @@           staticField (svFromType t) sv2 fs'         staticField _ sv2 _ = sv2 -defuncExp e@(Map fun arr t loc) = do-  fun' <- defuncSoacExp fun-  arr' <- defuncExp' arr-  return (Map fun' arr' t loc, Dynamic $ typeOf e)--defuncExp e@(Reduce comm fun ne arr loc) = do-  fun' <- defuncSoacExp fun-  ne' <- defuncExp' ne-  arr' <- defuncExp' arr-  return (Reduce comm fun' ne' arr' loc, Dynamic $ typeOf e)--defuncExp e@(GenReduce hist op ne bfun img loc) = do-  hist' <- defuncExp' hist-  op' <- defuncSoacExp op-  ne' <- defuncExp' ne-  bfun' <- defuncSoacExp bfun-  img' <- defuncExp' img-  return (GenReduce hist' op' ne' bfun' img' loc, Dynamic $ typeOf e)--defuncExp e@(Scan fun ne arr loc) =-  (,) <$> (Scan <$> defuncSoacExp fun <*> defuncExp' ne <*> defuncExp' arr-                <*> pure loc)-      <*> pure (Dynamic $ typeOf e)--defuncExp e@(Filter fun arr loc) = do-  fun' <- defuncSoacExp fun-  arr' <- defuncExp' arr-  return (Filter fun' arr' loc, Dynamic $ typeOf e)--defuncExp e@(Partition k fun arr loc) = do-  fun' <- defuncSoacExp fun-  arr' <- defuncExp' arr-  return (Partition k fun' arr' loc, Dynamic $ typeOf e)--defuncExp e@(Stream form lam arr loc) = do-  form' <- case form of-             MapLike _          -> return form-             RedLike so comm e' -> RedLike so comm <$> defuncSoacExp e'-  lam' <- defuncSoacExp lam-  arr' <- defuncExp' arr-  return (Stream form' lam' arr' loc, Dynamic $ typeOf e)- defuncExp (Unsafe e1 loc) = do   (e1', sv) <- defuncExp e1   return (Unsafe e1' loc, sv)@@ -424,15 +388,13 @@   let (ps, ret) = getType $ typeOf e   (pats, vars) <- fmap unzip . forM ps $ \t -> do     x <- newNameFromString "x"-    let t' = vacuousShapeAnnotations t-    return (Id x (Info t') noLoc,-            Var (qualName x) (Info t') noLoc)-  let ps_st = map vacuousShapeAnnotations ps-      e' = foldl' (\e1 (e2, t2, argtypes) ->+    return (Id x (Info t) noLoc,+            Var (qualName x) (Info t) noLoc)+  let e' = foldl' (\e1 (e2, t2, argtypes) ->                      Apply e1 e2 (Info $ diet t2)-                     (Info (foldFunType argtypes (vacuousShapeAnnotations ret))) noLoc)-           e $ zip3 vars ps (drop 1 $ tails ps_st)-  return (pats, e', vacuousShapeAnnotations $ toStruct ret)+                     (Info (foldFunType argtypes ret)) noLoc)+           e $ zip3 vars ps (drop 1 $ tails ps)+  return (pats, e', toStruct ret)    where getType (Arrow _ _ t1 t2) =           let (ps, r) = getType t2 in (t1 : ps, r)@@ -464,7 +426,7 @@   (body', sv) <- defuncExp body   return ([], body', imposeType sv rettype )   where imposeType Dynamic{} t =-          Dynamic $ fromStruct $ removeShapeAnnotations t+          Dynamic $ fromStruct t         imposeType (RecordSV fs1) (Record fs2) =           RecordSV $ M.toList $ M.intersectionWith imposeType (M.fromList fs1) fs2         imposeType sv _ = sv@@ -496,7 +458,8 @@           params_for_rettype = params ++ svParams sv1 ++ svParams sv2           svParams (LambdaSV _ sv_pat _ _ _) = [sv_pat]           svParams _                         = []-          rettype = buildRetType closure_env params_for_rettype e0_t $ typeOf e0'+          rettype = buildRetType closure_env params_for_rettype e0_t $+                    anyDimShapeAnnotations $ typeOf e0'            -- Embed some information about the original function           -- into the name of the lifted function, to make the@@ -509,8 +472,8 @@       fname <- newNameFromString $ liftedName (0::Int) e1       liftValDec fname rettype dims params e0' -      let t1 = vacuousShapeAnnotations . toStruct $ typeOf e1'-          t2 = vacuousShapeAnnotations . toStruct $ typeOf e2'+      let t1 = toStruct $ typeOf e1'+          t2 = toStruct $ typeOf e2'           fname' = qualName fname       return (Parens (Apply (Apply (Var fname' (Info (Arrow mempty Nothing (fromStruct t1) $                                                       Arrow mempty Nothing (fromStruct t2) rettype)) loc)@@ -556,7 +519,7 @@        IntrinsicSV -> return (e, IntrinsicSV) -      _ -> return (Var qn (Info (vacuousShapeAnnotations $ typeFromSV sv)) loc, sv)+      _ -> return (Var qn (Info (typeFromSV sv)) loc, sv)  defuncApply _ expr = defuncExp expr @@ -587,7 +550,7 @@   TuplePattern ps _       -> foldMap envFromPattern ps   RecordPattern fs _      -> foldMap (envFromPattern . snd) fs   PatternParens p _       -> envFromPattern p-  Id vn (Info t) _        -> M.singleton vn $ Dynamic $ removeShapeAnnotations t+  Id vn (Info t) _        -> M.singleton vn $ Dynamic t   Wildcard _ _            -> mempty   PatternAscription p _ _ -> envFromPattern p   PatternLit{}            -> mempty@@ -609,7 +572,7 @@ liftValDec :: VName -> PatternType -> [VName] -> [Pattern] -> Exp -> DefM () liftValDec fname rettype dims pats body = tell $ Seq.singleton dec   where dims' = map (flip TypeParamDim noLoc) dims-        rettype_st = vacuousShapeAnnotations $ toStruct rettype+        rettype_st = anyDimShapeAnnotations $ toStruct rettype         dec = ValBind           { valBindEntryPoint = False           , valBindName       = fname@@ -626,9 +589,8 @@ -- binds the closed over variables. buildEnvPattern :: Env -> Pattern buildEnvPattern env = RecordPattern (map buildField $ M.toList env) noLoc-  where buildField (vn, sv) = let tp = vacuousShapeAnnotations (typeFromSV sv)-                              in (nameFromString (pretty vn),-                                  Id vn (Info tp) noLoc)+  where buildField (vn, sv) = (nameFromString (pretty vn),+                               Id vn (Info $ anyDimShapeAnnotations $ typeFromSV sv) noLoc)  -- | Given a closure environment pattern and the type of a term, -- construct the type of that term, where uniqueness is set to@@ -637,16 +599,16 @@ -- lifted function can create unique arrays as long as they do not -- alias any of its parameters.  XXX: it is not clear that this is a -- sufficient property, unfortunately.-buildRetType :: Env -> [Pattern] -> StructType -> CompType -> PatternType+buildRetType :: Env -> [Pattern] -> StructType -> PatternType -> PatternType buildRetType env pats = comb   where bound = foldMap oneName (M.keys env) <> foldMap patternVars pats         boundAsUnique v =           maybe False (unique . unInfo . identType) $-          find ((==v) . identName) $ S.toList $ foldMap patIdentSet pats+          find ((==v) . identName) $ S.toList $ foldMap patternIdents pats         problematic v = (v `member` bound) && not (boundAsUnique v)         comb (Record fs_annot) (Record fs_got) =           Record $ M.intersectionWith comb fs_annot fs_got-        comb Arrow{} t = vacuousShapeAnnotations $ descend t+        comb Arrow{} t = descend t         comb got et = descend $ fromStruct got `setUniqueness` uniqueness et `setAliases` aliases et          descend t@Array{}@@ -655,15 +617,15 @@         descend t = t  -- | Compute the corresponding type for a given static value.-typeFromSV :: StaticVal -> CompType-typeFromSV (Dynamic tp)           = tp+typeFromSV :: StaticVal -> PatternType+typeFromSV (Dynamic tp)           = anyDimShapeAnnotations tp typeFromSV (LambdaSV _ _ _ _ env) = typeFromEnv env typeFromSV (RecordSV ls)          = Record $ M.fromList $ map (fmap typeFromSV) ls typeFromSV (DynamicFun (_, sv) _) = typeFromSV sv typeFromSV IntrinsicSV            = error $ "Tried to get the type from the "                                          ++ "static value of an intrinsic." -typeFromEnv :: Env -> CompType+typeFromEnv :: Env -> PatternType typeFromEnv = Record . M.fromList .               map (bimap (nameFromString . pretty) typeFromSV) . M.toList @@ -672,7 +634,7 @@ dynamicFunType :: StaticVal -> [PatternType] -> ([PatternType], PatternType) dynamicFunType (DynamicFun _ sv) (p:ps) =   let (ps', ret) = dynamicFunType sv ps in (p : ps', ret)-dynamicFunType sv _ = ([], vacuousShapeAnnotations $ typeFromSV sv)+dynamicFunType sv _ = ([], typeFromSV sv)  -- | Match a pattern with its static value. Returns an environment with -- the identifier components of the pattern mapped to the corresponding@@ -690,7 +652,7 @@   -- the pattern wins out.  This is important when matching a   -- nonunique pattern with a unique value.   if orderZeroSV sv-  then M.singleton vn $ Dynamic $ removeShapeAnnotations t+  then M.singleton vn $ Dynamic t   else M.singleton vn sv matchPatternSV (Wildcard _ _) _ = mempty matchPatternSV (PatternAscription pat _ _) sv = matchPatternSV pat sv@@ -717,11 +679,10 @@   PatternParens (updatePattern pat sv) loc updatePattern pat@(Id vn (Info tp) loc) sv   | orderZero tp = pat-  | otherwise = Id vn (Info . vacuousShapeAnnotations $-                       typeFromSV sv `setUniqueness` Nonunique) loc+  | otherwise = Id vn (Info $ typeFromSV sv `setUniqueness` Nonunique) loc updatePattern pat@(Wildcard (Info tp) loc) sv   | orderZero tp = pat-  | otherwise = Wildcard (Info . vacuousShapeAnnotations $ typeFromSV sv) loc+  | otherwise = Wildcard (Info $ typeFromSV sv) loc updatePattern (PatternAscription pat tydecl loc) sv   | orderZero . unInfo $ expandedType tydecl =       PatternAscription (updatePattern pat sv) tydecl loc@@ -734,7 +695,7 @@  -- | Convert a record (or tuple) type to a record static value. This is used for -- "unwrapping" tuples and records that are nested in 'Dynamic' static values.-svFromType :: CompType -> StaticVal+svFromType :: PatternType -> StaticVal svFromType (Record fs) = RecordSV . M.toList $ M.map svFromType fs svFromType t           = Dynamic t @@ -780,9 +741,9 @@   Range e me incl _ _  -> freeVars e <> foldMap freeVars me <>                           foldMap freeVars incl   Var qn (Info t) _    -> NameSet $ M.singleton (qualLeaf qn) $ uniqueness t-  Ascript e t _        -> freeVars e <> names (typeDimNames $ unInfo $ expandedType t)-  LetPat _ pat e1 e2 _ -> freeVars e1 <> ((names (patternDimNames pat) <> freeVars e2)-                                          `without` patternVars pat)+  Ascript e t _ _      -> freeVars e <> names (typeDimNames $ unInfo $ expandedType t)+  LetPat _ pat e1 e2 _ _ -> freeVars e1 <> ((names (patternDimNames pat) <> freeVars e2)+                                            `without` patternVars pat)    LetFun vn (_, pats, _, _, e1) e2 _ ->     ((freeVars e1 <> names (foldMap patternDimNames pats))@@ -812,7 +773,7 @@                                     freeVars e1 <> freeVars e2   Project _ e _ _                -> freeVars e -  LetWith id1 id2 idxs e1 e2 _ ->+  LetWith id1 id2 idxs e1 e2 _ _ ->     ident id2 <> foldMap freeDimIndex idxs <> freeVars e1 <>     (freeVars e2 `without` ident id1) @@ -820,17 +781,6 @@   Update e1 idxs e2 _ -> freeVars e1 <> foldMap freeDimIndex idxs <> freeVars e2   RecordUpdate e1 _ e2 _ _ -> freeVars e1 <> freeVars e2 -  Map e1 e2 _ _       -> freeVars e1 <> freeVars e2-  Reduce _ e1 e2 e3 _ -> freeVars e1 <> freeVars e2 <> freeVars e3-  GenReduce e1 e2 e3 e4 e5 _ -> freeVars e1 <> freeVars e2 <> freeVars e3 <>-                                freeVars e4 <> freeVars e5-  Scan e1 e2 e3 _     -> freeVars e1 <> freeVars e2 <> freeVars e3-  Filter e1 e2 _      -> freeVars e1 <> freeVars e2-  Partition _ e1 e2 _ -> freeVars e1 <> freeVars e2-  Stream form e1 e2 _ -> freeInForm form <> freeVars e1 <> freeVars e2-    where freeInForm (RedLike _ _ e) = freeVars e-          freeInForm _ = mempty-   Unsafe e _          -> freeVars e   Assert e1 e2 _ _    -> freeVars e1 <> freeVars e2   VConstr0{}          -> mempty@@ -845,41 +795,7 @@  -- | Extract all the variable names bound in a pattern. patternVars :: Pattern -> NameSet-patternVars = mconcat . map ident . S.toList . patIdentSet---- | Combine the shape information of types as much as possible. The first--- argument is the orignal type and the second is the type of the transformed--- expression. This is necessary since the original type may contain additional--- information (e.g., shape restrictions) from the user given annotation.-combineTypeShapes :: (Monoid as, ArrayDim dim) =>-                     TypeBase dim as -> TypeBase dim as -> TypeBase dim as-combineTypeShapes (Record ts1) (Record ts2)-  | M.keys ts1 == M.keys ts2 =-      Record $ M.map (uncurry combineTypeShapes) (M.intersectionWith (,) ts1 ts2)-combineTypeShapes (Array als1 u1 et1 shape1) (Array als2 _u2 et2 shape2)-  | Just new_shape <- unifyShapes shape1 shape2 =-      Array (als1<>als2) u1 (combineElemTypeInfo et1 et2) new_shape-combineTypeShapes _ new_tp = new_tp--combineElemTypeInfo :: ArrayDim dim =>-                       ArrayElemTypeBase dim-                    -> ArrayElemTypeBase dim -> ArrayElemTypeBase dim-combineElemTypeInfo (ArrayRecordElem et1) (ArrayRecordElem et2) =-  ArrayRecordElem $ M.map (uncurry combineRecordArrayTypeInfo)-                          (M.intersectionWith (,) et1 et2)-combineElemTypeInfo _ new_tp = new_tp--combineRecordArrayTypeInfo :: ArrayDim dim =>-                              RecordArrayElemTypeBase dim-                           -> RecordArrayElemTypeBase dim-                           -> RecordArrayElemTypeBase dim-combineRecordArrayTypeInfo (RecordArrayElem et1) (RecordArrayElem et2) =-  RecordArrayElem $ combineElemTypeInfo et1 et2-combineRecordArrayTypeInfo (RecordArrayArrayElem et1 shape1)-                           (RecordArrayArrayElem et2 shape2)-  | Just new_shape <- unifyShapes shape1 shape2 =-      RecordArrayArrayElem (combineElemTypeInfo et1 et2) new_shape-combineRecordArrayTypeInfo _ new_tp = new_tp+patternVars = mconcat . map ident . S.toList . patternIdents  -- | Defunctionalize a top-level value binding. Returns the -- transformed result as well as an environment that binds the name of@@ -908,7 +824,7 @@   let dim_names = foldMap patternDimNames params'       tparams' = filter ((`S.member` dim_names) . typeParamName) tparams -  let rettype' = vacuousShapeAnnotations . toStruct $ typeOf body'+  let rettype' = anyDimShapeAnnotations $ toStruct $ typeOf body'   return ( valbind { valBindRetDecl    = retdecl                    , valBindRetType    = Info $ combineTypeShapes                                          (unInfo rettype) rettype'
src/Futhark/Internalise/Defunctorise.hs view
@@ -144,12 +144,23 @@   where forward v = lookupSubst v mod_substs         substs' = M.map forward substs +extendAbsTypes :: Substitutions -> TransformM a -> TransformM a+extendAbsTypes ascript_substs m = do+  abs <- asks envAbs+  -- Some abstract types may have a different name on the inside, and+  -- we need to make them visible, because substitutions involving+  -- abstract types must be lifted out in transformModBind.+  let subst_abs = S.fromList $ map snd $ filter ((`S.member` abs) . fst) $+                  M.toList ascript_substs+  bindingAbs subst_abs m+ evalModExp :: ModExp -> TransformM Mod evalModExp (ModVar qn _) = lookupMod qn evalModExp (ModParens e _) = evalModExp e evalModExp (ModDecs decs _) = ModMod <$> transformDecs decs evalModExp (ModImport _ (Info fpath) _) = ModMod <$> lookupImport fpath evalModExp (ModAscript me _ (Info ascript_substs) _) =+  extendAbsTypes ascript_substs $   substituteInMod ascript_substs <$> evalModExp me evalModExp (ModApply f arg (Info p_substs) (Info b_substs) loc) = do   f_mod <- evalModExp f@@ -159,7 +170,7 @@       fail $ "Cannot apply non-parametric module at " ++ locStr loc     ModFun f_abs f_closure f_p f_body ->       bindingAbs (f_abs <> S.fromList (unInfo (modParamAbs f_p))) $-      extendScope f_closure $ generating $ do+      extendAbsTypes b_substs $ extendScope f_closure $ generating $ do         outer_substs <- scopeSubsts <$> askScope         abs <- asks envAbs         let forward (k,v) = (lookupSubst k outer_substs, v)@@ -196,8 +207,6 @@                         return $ qualLeaf $ fst $ lookupSubstInScope (qualName v) scope                     , mapOnQualName = \v ->                         return $ fst $ lookupSubstInScope v scope-                    , mapOnType = astMap (substituter scope)-                    , mapOnCompType = astMap (substituter scope)                     , mapOnStructType = astMap (substituter scope)                     , mapOnPatternType = astMap (substituter scope)                     }@@ -247,7 +256,12 @@          (maybeAscript (srclocOf mb) (modSignature mb) $ modExp mb) $          modParams mb   mname <- transformName $ modName mb-  return $ Scope mempty $ M.singleton mname mod+  abs <- asks envAbs+  -- Copy substitutions involving abstract types out, because they are+  -- always resolved at the outermost level.+  let abs_substs = M.filterWithKey (const . flip S.member abs) $+                   scopeSubsts $ modScope mod+  return $ Scope abs_substs $ M.singleton mname mod  transformDecs :: [Dec] -> TransformM Scope transformDecs ds =
src/Futhark/Internalise/Monomorphise.hs view
@@ -180,7 +180,7 @@         transformField (RecordFieldImplicit v t _) = do           t' <- traverse transformType t           transformField $ RecordFieldExplicit (baseName v)-            (Var (qualName v) (vacuousShapeAnnotations <$> t') loc) loc+            (Var (qualName v) t' loc) loc  transformExp (ArrayLit es tp loc) =   ArrayLit <$> mapM transformExp es <*> pure tp <*> pure loc@@ -197,7 +197,7 @@     Just fs -> do       let toField (f, (f_v, f_t)) = do             f_t' <- transformType f_t-            let f_v' = Var (qualName f_v) (Info $ vacuousShapeAnnotations f_t') loc+            let f_v' = Var (qualName f_v) (Info f_t') loc             return $ RecordFieldExplicit f f_v' loc       RecordLit <$> mapM toField (M.toList fs) <*> pure loc     Nothing -> do@@ -205,13 +205,15 @@       t' <- transformType t       return $ Var (QualName qs fname') (Info t') loc -transformExp (Ascript e tp loc) =-  Ascript <$> transformExp e <*> pure tp <*> pure loc+transformExp (Ascript e tp t loc) =+  Ascript <$> transformExp e <*> pure tp <*> pure t <*> pure loc -transformExp (LetPat tparams pat e1 e2 loc) = do+transformExp (LetPat tparams pat e1 e2 (Info t) loc) = do   (pat', rr) <- expandRecordPattern pat+  t' <- transformType t   LetPat tparams pat' <$> transformExp e1 <*>-    withRecordReplacements rr (transformExp e2) <*> pure loc+    withRecordReplacements rr (transformExp e2) <*>+    pure (Info t') <*> pure loc  transformExp (LetFun fname (tparams, params, retdecl, Info ret, body) e loc)   | any isTypeParam tparams = do@@ -226,9 +228,9 @@         return (unfoldLetFuns (map snd $ toList bs_local) e', const bs_prop)    | otherwise =-      transformExp $ LetPat [] (Id fname (Info ft) loc) lam e loc+      transformExp $ LetPat [] (Id fname (Info ft) loc) lam e (Info $ fromStruct ret) loc         where lam = Lambda tparams params body Nothing (Info (mempty, ret)) loc-              ft = foldFunType (map (vacuousShapeAnnotations . patternType) params) $ fromStruct ret+              ft = foldFunType (map patternType params) $ fromStruct ret  transformExp (If e1 e2 e3 tp loc) = do   e1' <- transformExp e1@@ -237,53 +239,11 @@   tp' <- traverse transformType tp   return $ If e1' e2' e3' tp' loc -transformExp (Apply e1 e2 d tp loc) =-  -- We handle on an ad-hoc basis certain polymorphic higher-order-  -- intrinsics here.  They can only be used in very particular ways,-  -- or the compiler will fail.  In practice they will only be used-  -- once, in the basis library, to define normal functions.-  case (e1, e2) of-    (Var v _ _, TupLit [op, ne, arr] _)-      | intrinsic "reduce" v ->-          transformExp $ Reduce Noncommutative op ne arr loc-      | intrinsic "reduce_comm" v ->-          transformExp $ Reduce Commutative op ne arr loc-      | intrinsic "scan" v ->-          transformExp $ Scan op ne arr loc-    (Var v _ _, TupLit [f, arr] _)-      | intrinsic "map" v ->-          transformExp $ Map f arr (removeShapeAnnotations <$> tp) loc-      | intrinsic "filter" v ->-          transformExp $ Filter f arr loc-    (Var v _ _, TupLit [k, f, arr] _)-      | intrinsic "partition" v,-        Just k' <- isInt32 k ->-          transformExp $ Partition (fromIntegral k') f arr loc-    (Var v _ _, TupLit [op, f, arr] _)-      | intrinsic "stream_red" v ->-          transformExp $ Stream (RedLike InOrder Noncommutative op) f arr loc-      | intrinsic "stream_red_per" v ->-          transformExp $ Stream (RedLike Disorder Commutative op) f arr loc-    (Var v _ _, TupLit [f, arr] _)-      | intrinsic "stream_map" v ->-          transformExp $ Stream (MapLike InOrder) f arr loc-      | intrinsic "stream_map_per" v ->-          transformExp $ Stream (MapLike Disorder) f arr loc-    (Var v _ _, TupLit [dest, op, ne, buckets, img] _)-      | intrinsic "gen_reduce" v ->-          transformExp $ GenReduce dest op ne buckets img loc--    _ -> do-      e1' <- transformExp e1-      e2' <- transformExp e2-      tp' <- traverse transformType tp-      return $ Apply e1' e2' d tp' loc-  where intrinsic s (QualName _ v) =-          baseTag v <= maxIntrinsicTag && baseName v == nameFromString s--        isInt32 (Literal (SignedValue (Int32Value k)) _) = Just k-        isInt32 (IntLit k (Info (Prim (Signed Int32))) _) = Just $ fromInteger k-        isInt32 _ = Nothing+transformExp (Apply e1 e2 d tp loc) = do+  e1' <- transformExp e1+  e2' <- transformExp e2+  tp' <- traverse transformType tp+  return $ Apply e1' e2' d tp' loc  transformExp (Negate e loc) =   Negate <$> transformExp e <*> pure loc@@ -334,16 +294,17 @@     _          -> return Nothing   case maybe_fs of     Just m | Just (v, _) <- M.lookup n m ->-               return $ Var (qualName v) (vacuousShapeAnnotations <$> tp) loc+               return $ Var (qualName v) tp loc     _ -> do       e' <- transformExp e       return $ Project n e' tp loc -transformExp (LetWith id1 id2 idxs e1 body loc) = do+transformExp (LetWith id1 id2 idxs e1 body (Info t) loc) = do   idxs' <- mapM transformDimIndex idxs   e1' <- transformExp e1   body' <- transformExp body-  return $ LetWith id1 id2 idxs' e1' body' loc+  t' <- transformType t+  return $ LetWith id1 id2 idxs' e1' body' (Info t') loc  transformExp (Index e0 idxs info loc) =   Index <$> transformExp e0 <*> mapM transformDimIndex idxs <*> pure info <*> pure loc@@ -356,37 +317,6 @@   RecordUpdate <$> transformExp e1 <*> pure fs                <*> transformExp e2 <*> pure t <*> pure loc -transformExp (Map e1 es t loc) =-  Map <$> transformExp e1 <*> transformExp es <*> pure t <*> pure loc--transformExp (Reduce comm e1 e2 e3 loc) =-  Reduce comm <$> transformExp e1 <*> transformExp e2-              <*> transformExp e3 <*> pure loc--transformExp (Scan e1 e2 e3 loc) =-  Scan <$> transformExp e1 <*> transformExp e2 <*> transformExp e3 <*> pure loc--transformExp (Filter e1 e2 loc) =-  Filter <$> transformExp e1 <*> transformExp e2 <*> pure loc--transformExp (Partition k f e0 loc) =-  Partition k <$> transformExp f <*> transformExp e0 <*> pure loc--transformExp (Stream form e1 e2 loc) = do-  form' <- case form of-             MapLike _         -> return form-             RedLike so comm e -> RedLike so comm <$> transformExp e-  Stream form' <$> transformExp e1 <*> transformExp e2 <*> pure loc--transformExp (GenReduce e1 e2 e3 e4 e5 loc) =-  GenReduce-    <$> transformExp e1 -- hist-    <*> transformExp e2 -- operator-    <*> transformExp e3 -- neutral element-    <*> transformExp e4 -- buckets-    <*> transformExp e5 -- input image-    <*> pure loc- transformExp (Unsafe e1 loc) =   Unsafe <$> transformExp e1 <*> pure loc @@ -415,7 +345,7 @@   (e1, p1) <- makeVarParam e_left $ fromStruct xtype   (e2, p2) <- makeVarParam e_right $ fromStruct ytype   let body = BinOp qn (Info t) (e1, Info xtype) (e2, Info ytype) (Info rettype) loc-      rettype' = vacuousShapeAnnotations $ toStruct rettype+      rettype' = toStruct rettype   return $ Lambda [] (p1 ++ p2) body Nothing (Info (mempty, rettype')) loc    where makeVarParam (Just e) _ = return (e, [])@@ -440,9 +370,8 @@ desugarIndexSection :: [DimIndex] -> PatternType -> SrcLoc -> MonoM Exp desugarIndexSection idxs (Arrow _ _ t1 t2) loc = do   p <- newVName "index_i"-  let body = Index (Var (qualName p) (Info t1) loc) idxs (Info t2') loc+  let body = Index (Var (qualName p) (Info t1) loc) idxs (Info t2) loc   return $ Lambda [] [Id p (Info t1) noLoc] body Nothing (Info (mempty, toStruct t2)) loc-  where t2' = removeShapeAnnotations t2 desugarIndexSection  _ t _ = error $ "desugarIndexSection: not a function type: " ++ pretty t  noticeDims :: TypeBase (DimDecl VName) as -> MonoM ()@@ -517,8 +446,6 @@         mapper substs = ASTMapper { mapOnExp         = astMap $ mapper substs                                   , mapOnName        = pure                                   , mapOnQualName    = pure-                                  , mapOnType        = pure . applySubst substs-                                  , mapOnCompType    = pure . applySubst substs                                   , mapOnStructType  = pure . applySubst substs                                   , mapOnPatternType = pure . applySubst substs                                   }@@ -557,9 +484,9 @@           | Just t1' <- peelArray (arrayRank t1) t1,             Just t2' <- peelArray (arrayRank t1) t2 =               sub pos t1' t2'-        sub pos (Arrow _ _ t1a t1b) (Arrow _ _ t2a t2b) = do+        sub _ (Arrow _ _ t1a t1b) (Arrow _ _ t2a t2b) = do           sub False t1a t2a-          sub pos t1b t2b+          sub False t1b t2b          sub _ t1 t2 = error $ unlines ["typeSubstsM: mismatched types:", pretty t1, pretty t2] @@ -600,11 +527,6 @@           mapOnExp         = astMap mapper         , mapOnName        = pure         , mapOnQualName    = pure-        , mapOnType        = pure . removeShapeAnnotations .-                             substituteTypes subs . vacuousShapeAnnotations-        , mapOnCompType    = pure . removeShapeAnnotations .-                             substituteTypes subs .-                             vacuousShapeAnnotations         , mapOnStructType  = pure . substituteTypes subs         , mapOnPatternType = pure . substituteTypes subs         }@@ -616,7 +538,7 @@                  , valBindBody    = body'                  } -removeTypeVariablesInType :: TypeBase dim () -> MonoM (TypeBase () ())+removeTypeVariablesInType :: TypeBase () () -> MonoM (TypeBase () ()) removeTypeVariablesInType t = do   subs <- asks $ M.map TypeSub . envTypeBindings   return $ removeShapeAnnotations $ substituteTypes subs $ vacuousShapeAnnotations t
src/Futhark/Internalise/TypesValues.hs view
@@ -139,7 +139,7 @@ -- | How many core language values are needed to represent one source -- language value of the given type? internalisedTypeSize :: E.TypeBase dim () -> InternaliseM Int-internalisedTypeSize = fmap length . internaliseType . E.removeShapeAnnotations+internalisedTypeSize = fmap length . internaliseType . E.toStructural  -- | Convert an external primitive to an internal primitive. internalisePrimType :: E.PrimType -> I.PrimType
src/Futhark/Optimise/CSE.hs view
@@ -177,6 +177,10 @@   CSEState _ cse_arrays <- ask   return $ runReader m $ newCSEState cse_arrays +instance CSEInOp op => CSEInOp (Kernel.HostOp lore op) where+  cseInOp (Kernel.HostOp op) = Kernel.HostOp <$> cseInOp op+  cseInOp x = return x+ instance (Attributes lore, Aliased lore, CSEInOp (Op lore)) => CSEInOp (Kernel.Kernel lore) where   cseInOp = subCSE .             Kernel.mapKernelM
src/Futhark/Optimise/DoubleBuffer.hs view
@@ -60,10 +60,10 @@   in (fundec { funDefBody = body' }, src')   where env = Env mempty optimiseKernelOp doNotTouchLoop -        optimiseKernelOp (Inner k) = do+        optimiseKernelOp (Inner (HostOp k)) = do           scope <- castScope <$> askScope           modifyNameSource $-            runState (runReaderT (runDoubleBufferM $ Inner <$> optimiseKernel k) $+            runState (runReaderT (runDoubleBufferM $ Inner . HostOp <$> optimiseKernel k) $                       Env scope optimiseInKernelOp optimiseLoop)           where optimiseKernel =                   mapKernelM identityKernelMapper
src/Futhark/Optimise/InPlaceLowering.hs view
@@ -156,13 +156,13 @@   where optimise = identityMapper { mapOnBody = const optimiseBody                                   } onKernelOp :: OnOp Kernels-onKernelOp (Kernel debug kspace ts kbody) = do+onKernelOp (HostOp (Kernel debug kspace ts kbody)) = do   old_scope <- askScope   modifyNameSource $ runForwardingM lowerUpdateInKernel onKernelExp $     bindingScope (castScope old_scope <> scopeOfKernelSpace kspace) $ do     stms <- deepen $ optimiseStms (stmsToList (kernelBodyStms kbody)) $             mapM_ seenVar $ freeIn $ kernelBodyResult kbody-    return $ Kernel debug kspace ts $ kbody { kernelBodyStms = stmsFromList stms }+    return $ HostOp $ Kernel debug kspace ts $ kbody { kernelBodyStms = stmsFromList stms } onKernelOp op = return op  onKernelExp :: OnOp InKernel
src/Futhark/Optimise/InPlaceLowering/LowerIntoStm.hs view
@@ -65,14 +65,14 @@  lowerUpdateKernels :: MonadFreshNames m => LowerUpdate Kernels m lowerUpdateKernels-  (Let (Pattern [] [PatElem v v_attr]) aux (Op (Kernel debug kspace ts kbody)))+  (Let (Pattern [] [PatElem v v_attr]) aux (Op (HostOp (Kernel debug kspace ts kbody))))   [update@(DesiredUpdate bindee_nm bindee_attr cs _src is val)]   | v == val = do     kbody' <- lowerUpdateIntoKernel update kspace kbody     let is' = fullSlice (typeOf bindee_attr) is     Just $ return [certify (stmAuxCerts aux <> cs) $                     mkLet [] [Ident bindee_nm $ typeOf bindee_attr] $-                    Op $ Kernel debug kspace ts kbody',+                    Op $ HostOp $ Kernel debug kspace ts kbody',                    mkLet [] [Ident v $ typeOf v_attr] $ BasicOp $ Index bindee_nm is'] lowerUpdateKernels stm updates = lowerUpdate stm updates 
src/Futhark/Optimise/TileLoops.hs view
@@ -40,7 +40,7 @@   Body () <$> (mconcat <$> mapM optimiseStm (stmsToList bnds)) <*> pure res  optimiseStm :: Stm Kernels -> TileM (Stms Kernels)-optimiseStm stmt@(Let pat aux (Op old_kernel@(Kernel desc space ts body))) = do+optimiseStm stmt@(Let pat aux (Op (HostOp old_kernel@(Kernel desc space ts body)))) = do   res3dtiling <- doRegTiling3D stmt   case res3dtiling of     Just (extra_bnds, stmt') -> return $ extra_bnds <> oneStm stmt'@@ -51,8 +51,8 @@           -- changing the number of groups being used for a kernel that           -- returns a result-per-group).           if kernelType old_kernel == kernelType new_kernel-            then return $ extra_bnds <> oneStm (Let pat aux $ Op new_kernel)-            else return $ oneStm $ Let pat aux $ Op old_kernel+            then return $ extra_bnds <> oneStm (Let pat aux $ Op $ HostOp new_kernel)+            else return $ oneStm $ Let pat aux $ Op $ HostOp old_kernel   where initial_variance = M.map mempty $ scopeOfKernelSpace space optimiseStm (Let pat aux e) =   pure <$> (Let pat aux <$> mapExpM optimise e)
src/Futhark/Optimise/TileLoops/RegTiling3D.hs view
@@ -102,7 +102,7 @@ --     } -- doRegTiling3D :: Stm Kernels -> TileM (Maybe (Stms Kernels, Stm Kernels))-doRegTiling3D (Let pat aux (Op old_kernel))+doRegTiling3D (Let pat aux (Op (HostOp old_kernel)))   | Kernel kerhint space kertp (KernelBody () kstms kres) <- old_kernel,     FlatThreadSpace gspace <- spaceStructure space,     initial_variance <- M.map mempty $ scopeOfKernelSpace space,@@ -211,7 +211,7 @@       -- finally, put everything together           kstms' = stmsFromList $ mask_stm : mm_stmt : stm_loop : (code2_inv ++ unrolled_code)           ker_body = KernelBody () kstms' kres'-          new_ker = Op $ Kernel kerhint kspace' kertp' ker_body+          new_ker = Op $ HostOp $ Kernel kerhint kspace' kertp' ker_body           extra_stms = space_stms <> stmsFromList (scratch_stms ++ manif_stms)       return $ Just (extra_stms, Let pat aux new_ker) 
src/Futhark/Optimise/Unstream.hs view
@@ -39,11 +39,12 @@   Body () <$> (stmsFromList . concat <$> mapM optimiseStm (stmsToList stms)) <*> pure res  optimiseStm :: Stm Kernels -> UnstreamM [Stm Kernels]-optimiseStm (Let pat aux (Op (Kernel desc space ts body))) = do+optimiseStm (Let pat aux (Op (HostOp (Kernel desc space ts body)))) = do   inv <- S.fromList . M.keys <$> askScope   stms' <- localScope (scopeOfKernelSpace space) $            runBinder_ $ optimiseInKernelStms inv $ kernelBodyStms body-  return [Let pat aux $ Op $ Kernel desc space ts $ body { kernelBodyStms = stms' }]+  return [Let pat aux $ Op $ HostOp $+          Kernel desc space ts $ body { kernelBodyStms = stms' }] optimiseStm (Let pat aux e) =   pure <$> (Let pat aux <$> mapExpM optimise e)   where optimise = identityMapper { mapOnBody = \scope -> localScope scope . optimiseBody }
src/Futhark/Pass/ExpandAllocations.hs view
@@ -72,7 +72,7 @@  transformExp :: Exp ExplicitMemory -> ExpandM (Stms ExplicitMemory, Exp ExplicitMemory) -transformExp (Op (Inner (Kernel desc kspace ts kbody))) = do+transformExp (Op (Inner (HostOp (Kernel desc kspace ts kbody)))) = do   let (kbody', allocs) = extractKernelBodyAllocations kbody       variantAlloc (Var v) = v `S.member` bound_in_kernel       variantAlloc _ = False@@ -87,13 +87,13 @@              runOffsetM scope' alloc_offsets $ offsetMemoryInKernelBody kbody'    return (alloc_stms,-          Op $ Inner $ Kernel desc kspace ts kbody'')+          Op $ Inner $ HostOp $ Kernel desc kspace ts kbody'')    where bound_in_kernel =           S.fromList $ M.keys $ scopeOfKernelSpace kspace <>           scopeOf (kernelBodyStms kbody) -transformExp (Op (Inner (SegRed kspace comm red_op nes ts kbody))) = do+transformExp (Op (Inner (HostOp (SegRed kspace comm red_op nes ts kbody)))) = do   let (kbody', kbody_allocs) = extractBodyAllocations kbody       (red_op', red_op_allocs) = extractLambdaAllocations red_op       variantAlloc (Var v) = v `S.member` bound_in_kernel@@ -111,14 +111,14 @@     red_op'' <- localScope (scopeOf red_op') $ offsetMemoryInLambda red_op'      return (alloc_stms,-            Op $ Inner $ SegRed kspace comm red_op'' nes ts kbody'')+            Op $ Inner $ HostOp $ SegRed kspace comm red_op'' nes ts kbody'')    where bound_in_kernel =           S.fromList $ map fst (spaceDimensions kspace) ++           M.keys (scopeOfKernelSpace kspace <>                   scopeOf (bodyStms kbody)) -transformExp (Op (Inner (SegGenRed kspace ops ts kbody))) = do+transformExp (Op (Inner (HostOp (SegGenRed kspace ops ts kbody)))) = do   let (kbody', kbody_allocs) = extractBodyAllocations kbody       (ops', ops_allocs) = unzip $ map extractGenRedOpAllocations ops       variantAlloc (Var v) = v `S.member` bound_in_kernel@@ -130,7 +130,7 @@     ops'' <- mapM offsetMemoryInGenRedOp ops'      return (alloc_stms,-            Op $ Inner $ SegGenRed kspace ops'' ts kbody'')+            Op $ Inner $ HostOp $ SegGenRed kspace ops'' ts kbody'')    where bound_in_kernel =           S.fromList $ map fst (spaceDimensions kspace) ++
src/Futhark/Pass/ExplicitAllocations.hs view
@@ -503,7 +503,7 @@                              Stms Kernels -> m (Stms ExplicitMemory) explicitAllocationsInStms stms = do   scope <- askScope-  runAllocM handleKernel $ localScope scope $ allocInStms stms return+  runAllocM handleHostOp $ localScope scope $ allocInStms stms return  memoryInRetType :: [RetType Kernels] -> [RetType ExplicitMemory] memoryInRetType ts = evalState (mapM addAttr ts) $ startOfFreeIDRange ts@@ -522,35 +522,35 @@  allocInFun :: MonadFreshNames m => FunDef Kernels -> m (FunDef ExplicitMemory) allocInFun (FunDef entry fname rettype params fbody) =-  runAllocM handleKernel $+  runAllocM handleHostOp $   allocInFParams (zip params $ repeat DefaultSpace) $ \params' -> do     fbody' <- insertStmsM $ allocInFunBody               (map (const $ Just DefaultSpace) rettype) fbody     return $ FunDef entry fname (memoryInRetType rettype) params' fbody' -handleKernel :: Kernel InInKernel-             -> AllocM Kernels ExplicitMemory (MemOp (Kernel OutInKernel))-handleKernel (GetSize key size_class) =+handleHostOp :: HostOp Kernels (Kernel InInKernel)+             -> AllocM Kernels ExplicitMemory (MemOp (HostOp ExplicitMemory (Kernel OutInKernel)))+handleHostOp (GetSize key size_class) =   return $ Inner $ GetSize key size_class-handleKernel (GetSizeMax size_class) =+handleHostOp (GetSizeMax size_class) =   return $ Inner $ GetSizeMax size_class-handleKernel (CmpSizeLe key size_class x) =+handleHostOp (CmpSizeLe key size_class x) =   return $ Inner $ CmpSizeLe key size_class x-handleKernel (Kernel desc space kernel_ts kbody) = subInKernel $-  Inner . Kernel desc space kernel_ts <$>+handleHostOp (HostOp (Kernel desc space kernel_ts kbody)) = subInKernel $+  Inner . HostOp . Kernel desc space kernel_ts <$>   localScope (scopeOfKernelSpace space) (allocInKernelBody kbody) -handleKernel (SegRed space comm red_op nes ts body) = do+handleHostOp (HostOp (SegRed space comm red_op nes ts body)) = do   body' <- subInKernel $ localScope (scopeOfKernelSpace space) $ allocInBodyNoDirect body   red_op' <- allocInSegRedLambda (spaceGlobalId space) (spaceNumThreads space) red_op-  return $ Inner $ SegRed space comm red_op' nes ts body'+  return $ Inner $ HostOp $ SegRed space comm red_op' nes ts body' -handleKernel (SegGenRed space ops ts body) = do+handleHostOp (HostOp (SegGenRed space ops ts body)) = do   body' <- subInKernel $ localScope (scopeOfKernelSpace space) $ allocInBodyNoDirect body   ops' <- forM ops $ \op -> do     lam <- allocInSegRedLambda (spaceGlobalId space) (spaceNumThreads space) $ genReduceOp op     return op { genReduceOp = lam }-  return $ Inner $ SegGenRed space ops' ts body'+  return $ Inner $ HostOp $ SegGenRed space ops' ts body'  subInKernel :: AllocM InInKernel OutInKernel a             -> AllocM fromlore2 ExplicitMemory a@@ -873,6 +873,10 @@ class SizeSubst op where   opSizeSubst :: PatternT attr -> op -> ChunkMap +instance SizeSubst op => SizeSubst (HostOp lore op) where+  opSizeSubst pat (HostOp op) = opSizeSubst pat op+  opSizeSubst _ _ = mempty+ instance SizeSubst (Kernel lore) where   opSizeSubst _ _ = mempty @@ -1010,7 +1014,7 @@ data ExpHint = NoHint              | Hint IxFun Space -kernelExpHints :: (Allocator lore m, Op lore ~ MemOp (Kernel somelore)) =>+kernelExpHints :: (Allocator lore m, Op lore ~ MemOp (HostOp lore (Kernel somelore))) =>                   Exp lore -> m [ExpHint] kernelExpHints (BasicOp (Manifest perm v)) = do   dims <- arrayDims <$> lookupType v@@ -1020,7 +1024,7 @@               perm_inv   return [Hint ixfun DefaultSpace] -kernelExpHints (Op (Inner (Kernel _ space rets kbody))) =+kernelExpHints (Op (Inner (HostOp (Kernel _ space rets kbody)))) =   zipWithM hint rets $ kernelBodyResult kbody   where num_threads = spaceNumThreads space @@ -1053,7 +1057,7 @@          hint _ _ = return NoHint -kernelExpHints (Op (Inner (SegRed space _ _ nes ts body))) =+kernelExpHints (Op (Inner (HostOp (SegRed space _ _ nes ts body)))) =   (map (const NoHint) red_res <>) <$> zipWithM mapHint (drop (length nes) ts) map_res   where (red_res, map_res) = splitAt (length nes) $ bodyResult body 
src/Futhark/Pass/ExtractKernels.hs view
@@ -461,7 +461,7 @@     mapKernel w (FlatThreadSpace [(write_i,w)]) inputs (map rowType $ patternTypes pat) body   certifying cs $ do     addStms bnds-    letBind_ pat $ Op kernel+    letBind_ pat $ Op $ HostOp kernel  transformStm _ (Let orig_pat (StmAux cs _) (Op (GenReduce w ops bucket_fun imgs))) = do   bfun' <- Kernelise.transformLambda bucket_fun@@ -1268,7 +1268,7 @@     let pat = Pattern [] $ rearrangeShape perm $               patternValueElements $ loopNestingPattern $ fst nest -    certifying cs $ letBind_ pat $ Op k+    certifying cs $ letBind_ pat $ Op $ HostOp k   where findInput kernel_inps a =           maybe bad return $ find ((==a) . kernelInputName) kernel_inps         bad = fail "Ill-typed nested scatter encountered."
src/Futhark/Pass/ExtractKernels/BlockedKernel.hs view
@@ -46,7 +46,7 @@ import Futhark.Util import Futhark.Util.IntegralExp -getSize :: (MonadBinder m, Op (Lore m) ~ Kernel innerlore) =>+getSize :: (MonadBinder m, Op (Lore m) ~ HostOp (Lore m) inner) =>            String -> SizeClass -> m SubExp getSize desc size_class = do   size_key <- nameFromString . pretty <$> newVName desc@@ -95,7 +95,7 @@    step_one <- chunkedReduceKernel w step_one_size comm reduce_lam' fold_lam'               ispace nes arrs_copies-  addStm =<< renameStm (Let step_one_pat (defAux ()) $ Op step_one)+  addStm =<< renameStm (Let step_one_pat (defAux ()) $ Op $ HostOp step_one)    step_two_pat <- basicPattern [] <$>                   mapM (mkIntermediateIdent $ constant (1 :: Int32)) acc_idents@@ -104,7 +104,7 @@    step_two <- reduceKernel step_two_size reduce_lam' nes $ take (length nes) $ patternNames step_one_pat -  addStm $ Let step_two_pat (defAux ()) $ Op step_two+  addStm $ Let step_two_pat (defAux ()) $ Op $ HostOp step_two    forM_ (zip (patternIdents step_two_pat) (patternIdents pat)) $ \(arr, x) ->     addStm $ mkLet [] [x] $ BasicOp $ Index (identName arr) $@@ -308,7 +308,7 @@         BasicOp $ Index arr $ fullSlice arr_t [DimFix $ Var gtid]     return $ lambdaBody map_lam -  letBind_ pat $ Op $+  letBind_ pat $ Op $ HostOp $     SegRed kspace comm reduce_lam nes (lambdaReturnType map_lam) body  nonSegRed :: (MonadFreshNames m, HasScope Kernels m) =>@@ -385,7 +385,7 @@         BasicOp $ Index arr $ fullSlice arr_t [DimFix $ Var gtid]     return $ lambdaBody lam -  letBind_ pat $ Op $ SegGenRed kspace ops (lambdaReturnType lam) body+  letBind_ pat $ Op $ HostOp $ SegGenRed kspace ops (lambdaReturnType lam) body  blockedMap :: (MonadFreshNames m, HasScope Kernels m) =>               Pattern Kernels -> SubExp@@ -421,7 +421,7 @@   concat_rets <- forM chunk_map_pes $ \pe ->     return $ ConcatReturns ordering' w elems_per_thread Nothing $ patElemName pe -  return $ Let pat (defAux ()) $ Op $ Kernel (KernelDebugHints "chunked_map" []) space ts $+  return $ Let pat (defAux ()) $ Op $ HostOp $ Kernel (KernelDebugHints "chunked_map" []) space ts $     KernelBody () chunk_and_fold $ nonconcat_rets ++ concat_rets  blockedPerThread :: (MonadBinder m, Lore m ~ InKernel) =>@@ -835,7 +835,7 @@               mapM (mkIntermediateIdent "red_carry_out" [num_groups]) red_idents,               pure arr_idents] -  addStm . Let first_scan_pat (defAux ()) . Op =<< scanKernel1 w first_scan_size+  addStm . Let first_scan_pat (defAux ()) . Op . HostOp =<< scanKernel1 w first_scan_size     (first_scan_lam, scan_nes)     (comm, first_scan_red_lam, red_nes)     first_scan_foldlam arrs@@ -846,7 +846,7 @@   let second_scan_size = KernelSize one num_groups one num_groups num_groups   unless (null group_red_res) $ do     second_stage_red_lam <- renameLambda first_scan_red_lam-    red_res <- letTupExp "red_res" . Op =<<+    red_res <- letTupExp "red_res" . Op . HostOp =<<                reduceKernel second_scan_size second_stage_red_lam red_nes group_red_res     forM_ (zip red_idents red_res) $ \(dest, arr) -> do       arr_t <- lookupType arr@@ -856,7 +856,7 @@   second_scan_lam <- renameLambda first_scan_lam    group_carry_out_scanned <--    letTupExp "group_carry_out_scanned" . Op =<<+    letTupExp "group_carry_out_scanned" . Op . HostOp =<<     scanKernel2 second_scan_size     second_scan_lam (zip scan_nes group_carry_out) @@ -902,7 +902,7 @@   (mapk_bnds, mapk) <- mapKernelFromBody w (FlatThreadSpace [(j, w)]) result_map_input                        (lambdaReturnType scan_lam) result_map_body   addStms mapk_bnds-  letBind_ final_res_pat $ Op mapk+  letBind_ final_res_pat $ Op $ HostOp mapk    return carries   where one = constant (1 :: Int32)@@ -936,7 +936,7 @@  -- Given the desired minium number of threads, compute the group size, -- number of groups and total number of threads.-numThreadsAndGroups :: (MonadBinder m, Op (Lore m) ~ Kernel innerlore) =>+numThreadsAndGroups :: (MonadBinder m, Op (Lore m) ~ HostOp (Lore m) inner) =>                        SubExp -> m (SubExp, SubExp, SubExp) numThreadsAndGroups w = do   group_size <- getSize "group_size" SizeGroup
src/Futhark/Pass/ExtractKernels/Distribution.hs view
@@ -253,7 +253,7 @@   let kbnds = w_bnds <> ksize_bnds   return (kbnds,           w,-          Let (loopNestingPattern first_nest) (StmAux cs ()) $ Op k)+          Let (loopNestingPattern first_nest) (StmAux cs ()) $ Op $ HostOp k)   where     first_nest = fst kernel_nest     inputIsUsed input = kernelInputName input `S.member`
src/Futhark/Pass/ExtractKernels/Intragroup.hs view
@@ -103,7 +103,7 @@         return $ PatElem name t'   flat_pat <- lift $ Pattern [] <$> mapM flatPatElem (patternValueElements nested_pat) -  let kstm = Let flat_pat (StmAux cs ()) $ Op $+  let kstm = Let flat_pat (StmAux cs ()) $ Op $ HostOp $              Kernel (KernelDebugHints "map_intra_group" []) kspace rts kbody'       reshapeStm nested_pe flat_pe =         Let (Pattern [] [nested_pe]) (StmAux cs ()) $
src/Futhark/Pass/ExtractKernels/Segmented.hs view
@@ -69,7 +69,7 @@       return $ resultBody [flag]   (mapk_bnds, mapk) <- mapKernelFromBody w (FlatThreadSpace [(flags_i, w)]) [] [Prim Bool] flags_body   addStms mapk_bnds-  flags <- letExp "flags" $ Op mapk+  flags <- letExp "flags" $ Op $ HostOp mapk    lam' <- addFlagToLambda nes lam 
src/Futhark/Pass/KernelBabysitting.hs view
@@ -56,7 +56,7 @@     Just (Let _ _ (BasicOp (Rearrange perm _))) -> Just $ Just $ rearrangeInverse perm     Just (Let _ _ (BasicOp (Reshape _ arr))) -> nonlinearInMemory arr m     Just (Let _ _ (BasicOp (Manifest perm _))) -> Just $ Just perm-    Just (Let pat _ (Op (Kernel _ _ ts _))) ->+    Just (Let pat _ (Op (HostOp (Kernel _ _ ts _)))) ->       nonlinear =<< find ((==name) . patElemName . fst)       (zip (patternElements pat) ts)     _ -> Nothing@@ -68,7 +68,7 @@  transformStm :: ExpMap -> Stm Kernels -> BabysitM ExpMap -transformStm expmap (Let pat aux ke@(Op (Kernel desc space ts kbody))) = do+transformStm expmap (Let pat aux ke@(Op (HostOp (Kernel desc space ts kbody)))) = do   -- Go spelunking for accesses to arrays that are defined outside the   -- kernel body and where the indices are kernel thread indices.   scope <- askScope@@ -83,7 +83,7 @@                          kbody)              mempty -  let bnd' = Let pat aux $ Op $ Kernel desc space ts kbody''+  let bnd' = Let pat aux $ Op $ HostOp $ Kernel desc space ts kbody''   addStm bnd'   return $ M.fromList [ (name, bnd') | name <- patternNames pat ] <> expmap   where num_threads = spaceNumThreads space
src/Futhark/Representation/AST/Attributes/Aliases.hs view
@@ -102,7 +102,7 @@   funcallAliases args $ retTypeValues t expAliases (Op op) = opAliases op -returnAliases :: [TypeBase shaper Uniqueness] -> [(Names, Diet)] -> [Names]+returnAliases :: [TypeBase shape Uniqueness] -> [(Names, Diet)] -> [Names] returnAliases rts args = map returnType' rts   where returnType' (Array _ _ Nonunique) =           mconcat $ map (uncurry maskAliases) args@@ -115,6 +115,7 @@  maskAliases :: Names -> Diet -> Names maskAliases _   Consume = mempty+maskAliases _   ObservePrim = mempty maskAliases als Observe = als  consumedInStm :: Aliased lore => Stm lore -> Names@@ -124,7 +125,7 @@ consumedInExp (Apply _ args _ _) =   mconcat (map (consumeArg . first subExpAliases) args)   where consumeArg (als, Consume) = als-        consumeArg (_,   Observe) = mempty+        consumeArg _              = mempty consumedInExp (If _ tb fb _) =   consumedInBody tb <> consumedInBody fb consumedInExp (DoLoop _ merge _ _) =
src/Futhark/Representation/AST/Attributes/Types.hs view
@@ -301,7 +301,7 @@ -- | @diet t@ returns a description of how a function parameter of -- type @t@ might consume its argument. diet :: TypeBase shape Uniqueness -> Diet-diet (Prim _) = Observe+diet (Prim _) = ObservePrim diet (Array _ _ Unique) = Consume diet (Array _ _ Nonunique) = Observe diet Mem{} = Observe
src/Futhark/Representation/AST/Pretty.hs view
@@ -225,7 +225,7 @@   ppr (Apply fname args _ (safety, _, _)) =     text (nameToString fname) <> safety' <> apply (map (align . pprArg) args)     where pprArg (arg, Consume) = text "*" <> ppr arg-          pprArg (arg, Observe) = ppr arg+          pprArg (arg, _)       = ppr arg           safety' = case safety of Unsafe -> text "<unsafe>"                                    Safe   -> mempty   ppr (Op op) = ppr op
src/Futhark/Representation/AST/Syntax/Core.hs view
@@ -191,7 +191,10 @@ -- Observe]@. data Diet = Consume -- ^ Consumes this value.           | Observe -- ^ Only observes value in this position, does-                    -- not consume.+                    -- not consume.  A result may alias this.+          | ObservePrim -- ^ As 'Observe', but the result will not+                        -- alias, because the parameter does not carry+                        -- aliases.             deriving (Eq, Ord, Show)  -- | An identifier consists of its name and the type of the value
src/Futhark/Representation/AST/Traversals.hs view
@@ -1,4 +1,3 @@------------------------------------------------------------------------------ -- | -- -- Functions for generic traversals across Futhark syntax trees.  The@@ -16,14 +15,12 @@ -- tree.  The implementation is rather tedious, but the interface is -- easy to use. ----- A traversal of the Futhark syntax tree is expressed as a tuple of+-- A traversal of the Futhark syntax tree is expressed as a record of -- functions expressing the operations to be performed on the various -- types of nodes. ----- The "Futhark.Transform.Rename" is a simple example of how to use--- this facility.---------------------------------------------------------------------------------+-- The "Futhark.Transform.Rename" module is a simple example of how to+-- use this facility. module Futhark.Representation.AST.Traversals   (   -- * Mapping
src/Futhark/Representation/ExplicitMemory.hs view
@@ -231,7 +231,7 @@   type LParamAttr ExplicitMemory = MemInfo SubExp NoUniqueness MemBind   type RetType    ExplicitMemory = FunReturns   type BranchType ExplicitMemory = BodyReturns-  type Op         ExplicitMemory = MemOp (Kernel InKernel)+  type Op         ExplicitMemory = MemOp (HostOp ExplicitMemory (Kernel InKernel))  instance Annotations InKernel where   type LetAttr    InKernel = MemInfo SubExp NoUniqueness MemBind@@ -505,7 +505,7 @@  instance TC.CheckableOp ExplicitMemory where   checkOp (Alloc size _) = TC.require [Prim int64] size-  checkOp (Inner k) = TC.subCheck $ typeCheckKernel k+  checkOp (Inner op) = typeCheckHostOp (TC.subCheck . typeCheckKernel) op  instance TC.CheckableOp InKernel where   checkOp (Alloc size _) = TC.require [Prim int64] size@@ -1010,14 +1010,14 @@ instance OpReturns ExplicitMemory where   opReturns (Alloc size space) =     return [MemMem (Free size) space]-  opReturns (Inner k@(Kernel _ _ _ body)) =+  opReturns (Inner (HostOp k@(Kernel _ _ _ body))) =     zipWithM correct (kernelBodyResult body) =<< (extReturns <$> opType k)     where correct (WriteReturn _ arr _) _ = varReturns arr           correct (KernelInPlaceReturn arr) _ =             extendedScope (varReturns arr)             (castScope $ scopeOf $ kernelBodyStms body)           correct _ ret = return ret-  opReturns (Inner (SegGenRed _ ops _ _)) =+  opReturns (Inner (HostOp (SegGenRed _ ops _ _))) =     concat <$> mapM (mapM varReturns . genReduceDest) ops   opReturns k =     extReturns <$> opType k
src/Futhark/Representation/Kernels.hs view
@@ -34,7 +34,7 @@ data Kernels  instance Annotations Kernels where-  type Op Kernels = Kernel InKernel+  type Op Kernels = HostOp Kernels (Kernel InKernel) instance Attributes Kernels where   expTypesFromPattern = return . expExtTypesFromPattern @@ -46,7 +46,7 @@ instance PrettyLore InKernel where  instance TypeCheck.CheckableOp Kernels where-  checkOp = TypeCheck.subCheck . typeCheckKernel+  checkOp = typeCheckHostOp $ TypeCheck.subCheck . typeCheckKernel  instance TypeCheck.CheckableOp InKernel where   checkOp = TypeCheck.subCheck . typeCheckKernelExp
src/Futhark/Representation/Kernels/Kernel.hs view
@@ -33,6 +33,10 @@        , KernelWalker(..)        , identityKernelWalker        , walkKernelM++       -- * Host operations+       , HostOp(..)+       , typeCheckHostOp        )        where @@ -95,12 +99,8 @@               }   deriving (Eq, Ord, Show) -data Kernel lore =-    GetSize Name SizeClass -- ^ Produce some runtime-configurable size.-  | GetSizeMax SizeClass -- ^ The maximum size of some class.-  | CmpSizeLe Name SizeClass SubExp-    -- ^ Compare size (likely a threshold) with some Int32 value.-  | Kernel KernelDebugHints KernelSpace [Type] (KernelBody lore)+data Kernel lore+  = Kernel KernelDebugHints KernelSpace [Type] (KernelBody lore)   | SegRed KernelSpace Commutativity (Lambda lore) [SubExp] [Type] (Body lore)     -- ^ The KernelSpace must always have at least two dimensions,     -- implying that the result of a SegRed is always an array.@@ -203,12 +203,6 @@ -- and is done left-to-right. mapKernelM :: (Applicative m, Monad m) =>               KernelMapper flore tlore m -> Kernel flore -> m (Kernel tlore)-mapKernelM _ (GetSize name size_class) =-  pure $ GetSize name size_class-mapKernelM _ (GetSizeMax size_class) =-  pure $ GetSizeMax size_class-mapKernelM tv (CmpSizeLe name size_class x) =-  CmpSizeLe name size_class <$> mapOnKernelSubExp tv x mapKernelM tv (SegRed space comm red_op nes ts lam) =   SegRed   <$> mapOnKernelSpace tv space@@ -457,10 +451,6 @@   where dims = map snd $ spaceDimensions space         segment_dims = init dims -kernelType GetSize{} = [Prim int32]-kernelType GetSizeMax{} = [Prim int32]-kernelType CmpSizeLe{} = [Prim Bool]- chunkedKernelNonconcatOutputs :: Lambda lore -> Int chunkedKernelNonconcatOutputs fun =   length $ takeWhile (not . outerSizeIsChunk) $ lambdaReturnType fun@@ -609,9 +599,6 @@   usageInOp (SegGenRed _ ops _ body) =     mconcat $ map UT.consumedUsage $ S.toList (consumedInBody body) <>     concatMap genReduceDest ops-  usageInOp GetSize{} = mempty-  usageInOp GetSizeMax{} = mempty-  usageInOp CmpSizeLe{} = mempty  consumedInKernelBody :: Aliased lore =>                         KernelBody lore -> Names@@ -620,10 +607,6 @@  typeCheckKernel :: TC.Checkable lore => Kernel (Aliases lore) -> TC.TypeM lore () -typeCheckKernel GetSize{} = return ()-typeCheckKernel GetSizeMax{} = return ()-typeCheckKernel (CmpSizeLe _ _ x) = TC.require [Prim int32] x- typeCheckKernel (SegRed space _ red_op nes ts body) = do   checkSpace space   mapM_ TC.checkType ts@@ -747,21 +730,8 @@   opMetrics (SegGenRed _ ops _ body) =     inside "SegGenRed" $ do mapM_ (lambdaMetrics . genReduceOp) ops                             bodyMetrics body-  opMetrics GetSize{} = seen "GetSize"-  opMetrics GetSizeMax{} = seen "GetSizeMax"-  opMetrics CmpSizeLe{} = seen "CmpSizeLe"  instance PrettyLore lore => PP.Pretty (Kernel lore) where-  ppr (GetSize name size_class) =-    text "get_size" <> parens (commasep [ppr name, ppr size_class])--  ppr (GetSizeMax size_class) =-    text "get_size_max" <> parens (ppr size_class)--  ppr (CmpSizeLe name size_class x) =-    text "get_size" <> parens (commasep [ppr name, ppr size_class]) <+>-    text "<" <+> ppr x-   ppr (Kernel desc space ts body) =     text "kernel" <+> text (kernelName desc) <>     PP.align (ppr space) <+>@@ -835,3 +805,129 @@                                        Just se -> "," <+> "offset=" <> ppr se   ppr (KernelInPlaceReturn what) =     text "kernel returns" <+> ppr what++--- Host operations++-- | A host-level operation; parameterised by what else it can do.+data HostOp lore inner+  = GetSize Name SizeClass+    -- ^ Produce some runtime-configurable size.+  | GetSizeMax SizeClass+    -- ^ The maximum size of some class.+  | CmpSizeLe Name SizeClass SubExp+    -- ^ Compare size (likely a threshold) with some Int32 value.+  | HostOp inner+    -- ^ The arbitrary operation.+  deriving (Eq, Ord, Show)++instance Substitute inner => Substitute (HostOp lore inner) where+  substituteNames substs (HostOp op) =+    HostOp $ substituteNames substs op+  substituteNames substs (CmpSizeLe name sclass x) =+    CmpSizeLe name sclass $ substituteNames substs x+  substituteNames _ x = x++instance Rename inner => Rename (HostOp lore inner) where+  rename (HostOp op) = HostOp <$> rename op+  rename (CmpSizeLe name sclass x) = CmpSizeLe name sclass <$> rename x+  rename x = pure x++instance IsOp inner => IsOp (HostOp lore inner) where+  safeOp (HostOp op) = safeOp op+  safeOp _ = True+  cheapOp (HostOp op) = cheapOp op+  cheapOp _ = True++instance TypedOp inner => TypedOp (HostOp lore inner) where+  opType GetSize{} = pure [Prim int32]+  opType GetSizeMax{} = pure [Prim int32]+  opType CmpSizeLe{} = pure [Prim Bool]+  opType (HostOp op) = opType op++instance AliasedOp inner => AliasedOp (HostOp lore inner) where+  opAliases (HostOp op) = opAliases op+  opAliases _ = [mempty]++  consumedInOp (HostOp op) = consumedInOp op+  consumedInOp _ = mempty++instance RangedOp inner => RangedOp (HostOp lore inner) where+  opRanges (HostOp op) = opRanges op+  opRanges _ = [unknownRange]++instance FreeIn inner => FreeIn (HostOp lore inner) where+  freeIn (HostOp op) = freeIn op+  freeIn (CmpSizeLe _ _ x) = freeIn x+  freeIn _ = mempty++instance CanBeAliased inner => CanBeAliased (HostOp lore inner) where+  type OpWithAliases (HostOp lore inner) = HostOp (Aliases lore) (OpWithAliases inner)++  addOpAliases (HostOp op) = HostOp $ addOpAliases op+  addOpAliases (GetSize name sclass) = GetSize name sclass+  addOpAliases (GetSizeMax sclass) = GetSizeMax sclass+  addOpAliases (CmpSizeLe name sclass x) = CmpSizeLe name sclass x++  removeOpAliases (HostOp op) = HostOp $ removeOpAliases op+  removeOpAliases (GetSize name sclass) = GetSize name sclass+  removeOpAliases (GetSizeMax sclass) = GetSizeMax sclass+  removeOpAliases (CmpSizeLe name sclass x) = CmpSizeLe name sclass x++instance CanBeRanged inner => CanBeRanged (HostOp lore inner) where+  type OpWithRanges (HostOp lore inner) = HostOp (Ranges lore) (OpWithRanges inner)++  addOpRanges (HostOp op) = HostOp $ addOpRanges op+  addOpRanges (GetSize name sclass) = GetSize name sclass+  addOpRanges (GetSizeMax sclass) = GetSizeMax sclass+  addOpRanges (CmpSizeLe name sclass x) = CmpSizeLe name sclass x++  removeOpRanges (HostOp op) = HostOp $ removeOpRanges op+  removeOpRanges (GetSize name sclass) = GetSize name sclass+  removeOpRanges (GetSizeMax sclass) = GetSizeMax sclass+  removeOpRanges (CmpSizeLe name sclass x) = CmpSizeLe name sclass x++instance CanBeWise inner => CanBeWise (HostOp lore inner) where+  type OpWithWisdom (HostOp lore inner) = HostOp (Wise lore) (OpWithWisdom inner)++  removeOpWisdom (HostOp op) = HostOp $ removeOpWisdom op+  removeOpWisdom (GetSize name sclass) = GetSize name sclass+  removeOpWisdom (GetSizeMax sclass) = GetSizeMax sclass+  removeOpWisdom (CmpSizeLe name sclass x) = CmpSizeLe name sclass x++instance ST.IndexOp op => ST.IndexOp (HostOp lore op) where+  indexOp vtable k (HostOp op) is = ST.indexOp vtable k op is+  indexOp _ _ _ _ = Nothing++instance PP.Pretty inner => PP.Pretty (HostOp lore inner) where+  ppr (GetSize name size_class) =+    text "get_size" <> parens (commasep [ppr name, ppr size_class])++  ppr (GetSizeMax size_class) =+    text "get_size_max" <> parens (ppr size_class)++  ppr (CmpSizeLe name size_class x) =+    text "get_size" <> parens (commasep [ppr name, ppr size_class]) <+>+    text "<" <+> ppr x++  ppr (HostOp op) = ppr op++instance OpMetrics inner => OpMetrics (HostOp lore inner) where+  opMetrics GetSize{} = seen "GetSize"+  opMetrics GetSizeMax{} = seen "GetSizeMax"+  opMetrics CmpSizeLe{} = seen "CmpSizeLe"+  opMetrics (HostOp op) = opMetrics op++instance UsageInOp inner => UsageInOp (HostOp lore inner) where+  usageInOp GetSize{} = mempty+  usageInOp GetSizeMax{} = mempty+  usageInOp CmpSizeLe{} = mempty+  usageInOp (HostOp op) = usageInOp op++typeCheckHostOp :: TC.Checkable lore =>+                   (inner -> TC.TypeM lore ())+                -> HostOp (Aliases lore) inner+                -> TC.TypeM lore ()+typeCheckHostOp _ GetSize{} = return ()+typeCheckHostOp _ GetSizeMax{} = return ()+typeCheckHostOp _ (CmpSizeLe _ _ x) = TC.require [Prim int32] x+typeCheckHostOp f (HostOp op) = f op
src/Futhark/Representation/Kernels/Simplify.hs view
@@ -59,8 +59,11 @@                      RetType lore ~ RetType outerlore,                      BranchType lore ~ BranchType outerlore) =>                     (KernelSpace -> Engine.SimpleOps lore) -> Engine.Env lore-                 -> Kernel lore -> Engine.SimpleM outerlore (Kernel (Wise lore), Stms (Wise outerlore))-simplifyKernelOp mk_ops env (Kernel desc space ts kbody) = do+                 -> HostOp outerlore (Kernel lore)+                 -> Engine.SimpleM outerlore (HostOp (Wise outerlore) (Kernel (Wise lore)),+                                              Stms (Wise outerlore))++simplifyKernelOp mk_ops env (HostOp (Kernel desc space ts kbody)) = do   space' <- Engine.simplify space   ts' <- mapM Engine.simplify ts   outer_vtable <- Engine.askVtable@@ -74,13 +77,13 @@                         `Engine.orIf` Engine.isConsumed) $         simplifyKernelBodyM kbody   kbody_hoisted' <- mapM processHoistedStm kbody_hoisted-  return (Kernel desc space' ts' $ mkWiseKernelBody () kbody_stms kbody_res,+  return (HostOp $ Kernel desc space' ts' $ mkWiseKernelBody () kbody_stms kbody_res,           kbody_hoisted')   where scope = scopeOfKernelSpace space         scope_vtable = ST.fromScope scope         bound_here = S.fromList $ M.keys scope -simplifyKernelOp mk_ops env (SegRed space comm red_op nes ts body) = do+simplifyKernelOp mk_ops env (HostOp (SegRed space comm red_op nes ts body)) = do   space' <- Engine.simplify space   nes' <- mapM Engine.simplify nes   ts' <- mapM Engine.simplify ts@@ -94,13 +97,13 @@    (body', body_hoisted) <- hoistFromBody space' (mk_ops space') env ts body -  return (SegRed space' comm red_op' nes' ts' body',+  return (HostOp $ SegRed space' comm red_op' nes' ts' body',           red_op_hoisted' <> body_hoisted)    where scope_vtable = ST.fromScope scope         scope = scopeOfKernelSpace space -simplifyKernelOp mk_ops env (SegGenRed space ops ts body) = do+simplifyKernelOp mk_ops env (HostOp (SegGenRed space ops ts body)) = do   outer_vtable <- Engine.askVtable    space' <- Engine.simplify space@@ -124,14 +127,16 @@    (body', body_hoisted) <- hoistFromBody space' (mk_ops space') env ts body -  return (SegGenRed space' ops' ts' body',+  return (HostOp $ SegGenRed space' ops' ts' body',           red_op_hoisted' <> body_hoisted)    where scope_vtable = ST.fromScope scope         scope = scopeOfKernelSpace space -simplifyKernelOp _ _ (GetSize key size_class) = return (GetSize key size_class, mempty)-simplifyKernelOp _ _ (GetSizeMax size_class) = return (GetSizeMax size_class, mempty)+simplifyKernelOp _ _ (GetSize key size_class) =+  return (GetSize key size_class, mempty)+simplifyKernelOp _ _ (GetSizeMax size_class) =+  return (GetSizeMax size_class, mempty) simplifyKernelOp _ _ (CmpSizeLe key size_class x) = do   x' <- Engine.simplify x   return (CmpSizeLe key size_class x', mempty)@@ -410,7 +415,7 @@ -- into a replicate. removeInvariantKernelResults :: TopDownRuleOp (Wise Kernels) removeInvariantKernelResults vtable (Pattern [] kpes) attr-                                    (Kernel desc space ts (KernelBody _ kstms kres)) = do+                             (HostOp (Kernel desc space ts (KernelBody _ kstms kres))) = do   (ts', kpes', kres') <-     unzip3 <$> filterM checkForInvarianceResult (zip3 ts kpes kres) @@ -418,7 +423,7 @@   when (kres == kres')     cannotSimplify -  addStm $ Let (Pattern [] kpes') attr $ Op $ Kernel desc space ts' $+  addStm $ Let (Pattern [] kpes') attr $ Op $ HostOp $ Kernel desc space ts' $     mkWiseKernelBody () kstms kres'   where isInvariant Constant{} = True         isInvariant (Var v) = isJust $ ST.lookup v vtable@@ -447,7 +452,7 @@ -- simplify further analysis. distributeKernelResults :: BottomUpRuleOp (Wise Kernels) distributeKernelResults (vtable, used)-  (Pattern [] kpes) attr (Kernel desc kspace kts (KernelBody _ kstms kres)) = do+  (Pattern [] kpes) attr (HostOp (Kernel desc kspace kts (KernelBody _ kstms kres))) = do   -- Iterate through the bindings.  For each, we check whether it is   -- in kres and can be moved outside.  If so, we remove it from kres   -- and kpes and make it a binding outside.@@ -457,8 +462,8 @@   when (kpes' == kpes)     cannotSimplify -  addStm $ Let (Pattern [] kpes') attr $-    Op $ Kernel desc kspace kts' $ mkWiseKernelBody () (stmsFromList $ reverse kstms_rev) kres'+  addStm $ Let (Pattern [] kpes') attr $ Op $ HostOp $+    Kernel desc kspace kts' $ mkWiseKernelBody () (stmsFromList $ reverse kstms_rev) kres'   where     free_in_kstms = fold $ fmap freeInStm kstms 
src/Futhark/TypeCheck.hs view
@@ -17,8 +17,6 @@   , lookupVar   , lookupAliases   , Occurences-  , UsageMap-  , usageMap   , collectOccurences   , subCheck @@ -184,15 +182,6 @@  type Occurences = [Occurence] -type UsageMap = M.Map VName [Usage]--usageMap :: Occurences -> UsageMap-usageMap = foldl comb M.empty-  where comb m (Occurence obs cons) =-          let m' = S.foldl' (ins Observed) m obs-          in S.foldl' (ins Consumed) m' cons-        ins v m k = M.insertWith (++) k [v] m- allConsumed :: Occurences -> Names allConsumed = S.unions . map consumed @@ -378,20 +367,12 @@         bindVar env name (LetInfo (Names' als, attr)) =           let als' | primType (typeOf attr) = mempty                    | otherwise = expandAliases als env-              inedges = S.toList als'-              update (LetInfo (Names' thesenames, thisattr)) =-                LetInfo (Names' $ S.insert name thesenames, thisattr)-              update b = b           in env { envVtable =-                      M.insert name (LetInfo (Names' als', attr)) $-                      adjustSeveral update inedges $-                      envVtable env+                     M.insert name (LetInfo (Names' als', attr)) $ envVtable env                  }         bindVar env name attr =           env { envVtable = M.insert name attr $ envVtable env } -        adjustSeveral f = flip $ foldl $ flip $ M.adjust f-         -- Check whether the bound variables have been used correctly         -- within their scope.         check m = do@@ -511,7 +492,7 @@                body) consumable $ do       checkFunParams params       checkRetType rettype-      checkFunBody rettype body+      context "When checking function body" $ checkFunBody rettype body         where consumable = [ (paramName param, mempty)                            | param <- params                            , unique $ paramDeclType param@@ -550,7 +531,8 @@       check       scope <- askScope       let isArray = maybe False ((>0) . arrayRank . typeOf) . (`M.lookup` scope)-      checkReturnAlias $ map (S.filter isArray) $ bodyAliases body+      context ("When checking the body aliases: " ++ pretty (bodyAliases body)) $+        checkReturnAlias $ map (S.filter isArray) $ bodyAliases body   where param_names = map fst params          checkNoDuplicateParams = foldM_ expand [] param_names@@ -928,7 +910,8 @@  checkPatElem :: Checkable lore =>                 PatElemT (LetAttr lore) -> TypeM lore ()-checkPatElem (PatElem name attr) = checkLetBoundLore name attr+checkPatElem (PatElem name attr) = context ("When checking pattern element " ++ pretty name) $+                                   checkLetBoundLore name attr  checkDimIndex :: Checkable lore =>                  DimIndex SubExp -> TypeM lore ()@@ -940,8 +923,8 @@          -> TypeM lore a          -> TypeM lore a checkStm stm@(Let pat (StmAux (Certificates cs) (_,attr)) e) m = do-  mapM_ (requireI [Prim Cert]) cs-  checkExpLore attr+  context "When checking certificates" $ mapM_ (requireI [Prim Cert]) cs+  context "When checking expression annotation" $ checkExpLore attr   context ("When matching\n" ++ message "  " pat ++ "\nwith\n" ++ message "  " e) $     matchPattern pat e   binding (scopeOf stm) $ do@@ -1029,7 +1012,7 @@   forM_ (zip (map diet paramts) args) $ \(d, (_, als)) ->     occur [consumption (consumeArg als d)]   where consumeArg als Consume = als-        consumeArg _   Observe = mempty+        consumeArg _   _       = mempty  checkLambda :: Checkable lore =>                Lambda (Aliases lore) -> [Arg] -> TypeM lore ()
src/Language/Futhark/Attributes.hs view
@@ -26,7 +26,7 @@   , typeOf    -- * Queries on patterns and params-  , patIdentSet+  , patternIdents   , patternType   , patternStructType   , patternPatternType@@ -42,8 +42,6 @@   , diet   , arrayRank   , nestedDims-  , returnType-  , concreteType   , orderZero   , unfoldFunType   , foldFunType@@ -55,18 +53,15 @@   , peelArray   , stripArray   , arrayOf-  , arrayOfWithAliases   , toStructural   , toStruct   , fromStruct   , setAliases   , addAliases   , setUniqueness-  , modifyShapeAnnotations-  , setArrayShape   , removeShapeAnnotations   , vacuousShapeAnnotations-  , typeToRecordArrayElem+  , anyDimShapeAnnotations   , recordArrayElemToType   , tupleRecord   , isTupleRecord@@ -74,6 +69,8 @@   , tupleFieldNames   , sortFields   , isTypeParam+  , combineTypeShapes+  , unscopeType    -- | Values of these types are produces by the parser.  They use   -- unadorned names and have no type information, apart from that@@ -156,20 +153,18 @@         notV Nothing  = const True         notV (Just v) = (/=NamedDim (qualName v)) --- | Set the dimensions of an array.  If the given type is not an--- array, return the type unchanged.-setArrayShape :: TypeBase dim as -> ShapeDecl dim -> TypeBase dim as-setArrayShape (Array a u t _) ds = Array a u t ds-setArrayShape t _ = t- -- | Change the shape of a type to be just the 'Rank'.-removeShapeAnnotations :: TypeBase dim as -> TypeBase () as+removeShapeAnnotations :: TypeBase (DimDecl vn) as -> TypeBase () as removeShapeAnnotations = modifyShapeAnnotations $ const () --- | Change all size annotations to be 'AnyDim'.-vacuousShapeAnnotations :: TypeBase dim as -> TypeBase (DimDecl vn) as+-- | Add size annotations that are all 'AnyDim'.+vacuousShapeAnnotations :: TypeBase () as -> TypeBase (DimDecl vn) as vacuousShapeAnnotations = modifyShapeAnnotations $ const AnyDim +-- | Change all size annotations to be 'AnyDim'.+anyDimShapeAnnotations :: TypeBase (DimDecl vn) as -> TypeBase (DimDecl vn) as+anyDimShapeAnnotations = modifyShapeAnnotations $ const AnyDim+ -- | Change the size annotations of a type. modifyShapeAnnotations :: (oldshape -> newshape)                        -> TypeBase oldshape as@@ -202,24 +197,11 @@ diet (Array _ Nonunique _ _) = Observe diet (Enum _)                = Observe --- | @t `maskAliases` d@ removes aliases (sets them to 'mempty') from--- the parts of @t@ that are denoted as 'Consumed' by the 'Diet' @d@.-maskAliases :: Monoid as =>-               TypeBase shape as-            -> Diet-            -> TypeBase shape as-maskAliases t Consume = t `setAliases` mempty-maskAliases t Observe = t-maskAliases (Record ets) (RecordDiet ds) =-  Record $ M.intersectionWith maskAliases ets ds-maskAliases t FuncDiet{} = t-maskAliases _ _ = error "Invalid arguments passed to maskAliases."- -- | Convert any type to one that has rank information, no alias -- information, and no embedded names. toStructural :: TypeBase dim as              -> TypeBase () ()-toStructural = removeNames . removeShapeAnnotations+toStructural = flip setAliases () . modifyShapeAnnotations (const ())  -- | Remove aliasing information from a type. toStruct :: TypeBase dim as@@ -258,12 +240,6 @@   return $ Array als u et shape' peelArray _ _ = Nothing --- | Remove names from a type - this involves removing all size--- annotations from arrays, as well as all aliasing.-removeNames :: TypeBase dim as-            -> TypeBase () ()-removeNames = flip setAliases () . removeShapeAnnotations- -- | @arrayOf t s u@ constructs an array type.  The convenience -- compared to using the 'Array' constructor directly is that @t@ can -- itself be an array.  If @t@ is an @n@-dimensional array, and @s@ is@@ -370,7 +346,40 @@ isTypeParam TypeParamType{}       = True isTypeParam TypeParamDim{}        = False +-- | Combine the shape information of types as much as possible. The first+-- argument is the orignal type and the second is the type of the transformed+-- expression. This is necessary since the original type may contain additional+-- information (e.g., shape restrictions) from the user given annotation.+combineTypeShapes :: (Monoid as, ArrayDim dim) =>+                     TypeBase dim as -> TypeBase dim as -> TypeBase dim as+combineTypeShapes (Record ts1) (Record ts2)+  | M.keys ts1 == M.keys ts2 =+      Record $ M.map (uncurry combineTypeShapes) (M.intersectionWith (,) ts1 ts2)+combineTypeShapes (Array als1 u1 et1 shape1) (Array als2 _u2 et2 shape2)+  | Just new_shape <- unifyShapes shape1 shape2 =+      Array (als1<>als2) u1 (combineElemTypeInfo et1 et2) new_shape+combineTypeShapes _ new_tp = new_tp +combineElemTypeInfo :: ArrayDim dim =>+                       ArrayElemTypeBase dim+                    -> ArrayElemTypeBase dim -> ArrayElemTypeBase dim+combineElemTypeInfo (ArrayRecordElem et1) (ArrayRecordElem et2) =+  ArrayRecordElem $ M.map (uncurry combineRecordArrayTypeInfo)+                          (M.intersectionWith (,) et1 et2)+combineElemTypeInfo _ new_tp = new_tp++combineRecordArrayTypeInfo :: ArrayDim dim =>+                              RecordArrayElemTypeBase dim+                           -> RecordArrayElemTypeBase dim+                           -> RecordArrayElemTypeBase dim+combineRecordArrayTypeInfo (RecordArrayElem et1) (RecordArrayElem et2) =+  RecordArrayElem $ combineElemTypeInfo et1 et2+combineRecordArrayTypeInfo (RecordArrayArrayElem et1 shape1)+                           (RecordArrayArrayElem et2 shape2)+  | Just new_shape <- unifyShapes shape1 shape2 =+      RecordArrayArrayElem (combineElemTypeInfo et1 et2) new_shape+combineRecordArrayTypeInfo _ new_tp = new_tp+ -- | Set the uniqueness attribute of a type.  If the type is a tuple, -- the uniqueness of its components will be modified. setUniqueness :: TypeBase dim as -> Uniqueness -> TypeBase dim as@@ -419,17 +428,22 @@ rank :: Int -> ShapeDecl () rank n = ShapeDecl $ replicate n () -unscopeAliases :: S.Set VName -> CompType -> CompType-unscopeAliases bound_here t = t `addAliases` S.map unbind+-- | The type is leaving a scope, so clean up any aliases that+-- reference the bound variables, and turn any dimensions that name+-- them into AnyDim instead.+unscopeType :: S.Set VName -> PatternType -> PatternType+unscopeType bound_here t = modifyShapeAnnotations onDim $ t `addAliases` S.map unbind   where unbind (AliasBound v) | v `S.member` bound_here = AliasFree v         unbind a = a+        onDim (NamedDim qn) | qualLeaf qn `S.member` bound_here = AnyDim+        onDim d = d  -- | The type of an Futhark term.  The aliasing will refer to itself, if -- the term is a non-tuple-typed variable.-typeOf :: ExpBase Info VName -> CompType+typeOf :: ExpBase Info VName -> PatternType typeOf (Literal val _) = Prim $ primValueType val-typeOf (IntLit _ (Info t) _) = fromStruct t-typeOf (FloatLit _ (Info t) _) = fromStruct t+typeOf (IntLit _ (Info t) _) = t+typeOf (FloatLit _ (Info t) _) = t typeOf (Parens e _) = typeOf e typeOf (QualParens _ e _) = typeOf e typeOf (TupLit es _) = tupleRecord $ map typeOf es@@ -438,57 +452,39 @@   Record $ M.unions $ reverse $ map record fs   where record (RecordFieldExplicit name e _) = M.singleton name $ typeOf e         record (RecordFieldImplicit name (Info t) _) =-          M.singleton (baseName name) $ t `addAliases` S.insert (AliasBound name)+          M.singleton (baseName name) $ t+          `addAliases` S.insert (AliasBound name) typeOf (ArrayLit _ (Info t) _) = t typeOf (Range _ _ _ (Info t) _) = t-typeOf (BinOp _ _ _ _ (Info t) _) = removeShapeAnnotations t+typeOf (BinOp _ _ _ _ (Info t) _) = t typeOf (Project _ _ (Info t) _) = t typeOf (If _ _ _ (Info t) _) = t-typeOf (Var _ (Info t) _) = removeShapeAnnotations t-typeOf (Ascript e _ _) = typeOf e-typeOf (Apply _ _ _ (Info t) _) = removeShapeAnnotations t+typeOf (Var _ (Info t) _) = t+typeOf (Ascript _ _ (Info t) _) = t+typeOf (Apply _ _ _ (Info t) _) = t typeOf (Negate e _) = typeOf e-typeOf (LetPat _ pat _ body _) =-  unscopeAliases (S.map identName $ patIdentSet pat) $ typeOf body+typeOf (LetPat _ _ _ _ (Info t) _) = t typeOf (LetFun _ _ body _) = typeOf body-typeOf (LetWith dest _ _ _ body _) =-  unscopeAliases (S.singleton $ identName dest) $ typeOf body+typeOf (LetWith _ _ _ _ _ (Info t) _) = t typeOf (Index _ _ (Info t) _) = t typeOf (Update e _ _ _) = typeOf e `setAliases` mempty-typeOf (RecordUpdate _ _ _ (Info t) _) = removeShapeAnnotations t+typeOf (RecordUpdate _ _ _ (Info t) _) = t typeOf (Unsafe e _) = typeOf e typeOf (Assert _ e _ _) = typeOf e-typeOf (Map _ _ (Info t) _) = t `setUniqueness` Unique-typeOf (Reduce _ _ _ arr _) =-  stripArray 1 (typeOf arr) `setAliases` mempty-typeOf (GenReduce hist _ _ _ _ _) =-  typeOf hist `setAliases` mempty `setUniqueness` Unique-typeOf (Scan _ _ arr _) = typeOf arr `setAliases` mempty `setUniqueness` Unique-typeOf (Filter _ arr _) = typeOf arr `setAliases` mempty `setUniqueness` Unique-typeOf (Partition _ _ arr _) =-  tupleRecord [typeOf arr `setAliases` mempty `setUniqueness` Unique,-               Array mempty Unique (ArrayPrimElem (Signed Int32)) (rank 1)]-typeOf (Stream _ lam _ _) =-  rettype (typeOf lam) `setUniqueness` Unique-  where rettype (Arrow _ _ _ t) = rettype t-        rettype t = t typeOf (DoLoop _ pat _ _ _ _) = patternType pat typeOf (Lambda tparams params _ _ (Info (als, t)) _) =-  unscopeAliases bound_here $-  removeShapeAnnotations (foldr (uncurry (Arrow ()) . patternParam) t params)-  `setAliases` als+  unscopeType bound_here $+  foldr (uncurry (Arrow ()) . patternParam) t params `setAliases` als   where bound_here = S.fromList (map typeParamName tparams) <>-                     S.map identName (mconcat $ map patIdentSet params)+                     S.map identName (mconcat $ map patternIdents params) typeOf (OpSection _ (Info t) _) =-  removeShapeAnnotations t+  t typeOf (OpSectionLeft _ _ _ (_, Info pt2) (Info ret) _)  =-  removeShapeAnnotations $ foldFunType [fromStruct pt2] ret+  foldFunType [fromStruct pt2] ret typeOf (OpSectionRight _ _ _ (Info pt1, _) (Info ret) _) =-  removeShapeAnnotations $ foldFunType [fromStruct pt1] ret-typeOf (ProjectSection _ (Info t) _) =-  removeShapeAnnotations t-typeOf (IndexSection _ (Info t) _) =-  removeShapeAnnotations t+  foldFunType [fromStruct pt1] ret+typeOf (ProjectSection _ (Info t) _) = t+typeOf (IndexSection _ (Info t) _) = t typeOf (VConstr0 _ (Info t) _)  = t typeOf (Match _ _ (Info t) _) = t @@ -525,47 +521,6 @@         typeArgFree (TypeArgType ta _) = typeVars ta         typeArgFree TypeArgDim{} = mempty --- | The result of applying the arguments of the given types to a--- function with the given return type, consuming its parameters with--- the given diets.-returnType :: TypeBase dim Aliasing-           -> Diet-           -> CompType-           -> TypeBase dim Aliasing-returnType (Array _ Unique et shape) _ _ =-  Array mempty Unique et shape-returnType (Array als Nonunique et shape) d arg =-  Array (als<>arg_als) Unique et shape -- Intentional!-  where arg_als = aliases $ maskAliases arg d-returnType (Record fs) d arg =-  Record $ fmap (\et -> returnType et d arg) fs-returnType (Prim t) _ _ = Prim t-returnType (TypeVar _ Unique t targs) _ _ =-  TypeVar mempty Unique t targs-returnType (TypeVar als Nonunique t targs) d arg =-  TypeVar (als<>arg_als) Unique t targs -- Intentional!-  where arg_als = aliases $ maskAliases arg d-returnType (Arrow _ v t1 t2) d arg =-  Arrow als v (bimap id (const mempty) t1) (t2 `setAliases` als)-  where als = aliases $ maskAliases arg d-returnType (Enum cs) _ _ = Enum cs---- | Is the type concrete, i.e, without any type variables or function arrows?-concreteType :: TypeBase f vn -> Bool-concreteType Prim{} = True-concreteType TypeVar{} = False-concreteType Arrow{} = False-concreteType (Record ts) = all concreteType ts-concreteType Enum{} = True-concreteType (Array _ _ at _) = concreteArrayType at-  where concreteArrayType ArrayPrimElem{}      = True-        concreteArrayType ArrayPolyElem{}      = False-        concreteArrayType (ArrayRecordElem ts) = all concreteRecordArrayElem ts-        concreteArrayType ArrayEnumElem{}      = True--        concreteRecordArrayElem (RecordArrayElem et) = concreteArrayType et-        concreteRecordArrayElem (RecordArrayArrayElem et _) = concreteArrayType et- -- | @orderZero t@ is 'True' if the argument type has order 0, i.e., it is not -- a function type, does not contain a function type as a subcomponent, and may -- not be instantiated with a function type.@@ -608,24 +563,24 @@   PatternLit _ (Info t) _ -> orderZero t  -- | The set of identifiers bound in a pattern.-patIdentSet :: (Functor f, Ord vn) => PatternBase f vn -> S.Set (IdentBase f vn)-patIdentSet (Id v t loc)              = S.singleton $ Ident v (removeShapeAnnotations <$> t) loc-patIdentSet (PatternParens p _)       = patIdentSet p-patIdentSet (TuplePattern pats _)     = mconcat $ map patIdentSet pats-patIdentSet (RecordPattern fs _)      = mconcat $ map (patIdentSet . snd) fs-patIdentSet Wildcard{}                = mempty-patIdentSet (PatternAscription p _ _) = patIdentSet p-patIdentSet PatternLit{}              = mempty+patternIdents :: (Functor f, Ord vn) => PatternBase f vn -> S.Set (IdentBase f vn)+patternIdents (Id v t loc)              = S.singleton $ Ident v t loc+patternIdents (PatternParens p _)       = patternIdents p+patternIdents (TuplePattern pats _)     = mconcat $ map patternIdents pats+patternIdents (RecordPattern fs _)      = mconcat $ map (patternIdents . snd) fs+patternIdents Wildcard{}                = mempty+patternIdents (PatternAscription p _ _) = patternIdents p+patternIdents PatternLit{}              = mempty  -- | The type of values bound by the pattern.-patternType :: PatternBase Info VName -> CompType-patternType (Wildcard (Info t) _)     = removeShapeAnnotations t+patternType :: PatternBase Info VName -> PatternType+patternType (Wildcard (Info t) _)     = t patternType (PatternParens p _)       = patternType p-patternType (Id _ (Info t) _)         = removeShapeAnnotations t+patternType (Id _ (Info t) _)         = t patternType (TuplePattern pats _)     = tupleRecord $ map patternType pats patternType (RecordPattern fs _)      = Record $ patternType <$> M.fromList fs patternType (PatternAscription p _ _) = patternType p-patternType (PatternLit _ (Info t) _) = removeShapeAnnotations t+patternType (PatternLit _ (Info t) _) = t  -- | The type of a pattern, including shape annotations. patternPatternType :: PatternBase Info VName -> PatternType@@ -656,19 +611,19 @@ patternNoShapeAnnotations :: PatternBase Info VName -> PatternBase Info VName patternNoShapeAnnotations (PatternAscription p (TypeDecl te (Info t)) loc) =   PatternAscription (patternNoShapeAnnotations p)-  (TypeDecl te $ Info $ vacuousShapeAnnotations t) loc+  (TypeDecl te $ Info $ anyDimShapeAnnotations t) loc patternNoShapeAnnotations (PatternParens p loc) =   PatternParens (patternNoShapeAnnotations p) loc patternNoShapeAnnotations (Id v (Info t) loc) =-  Id v (Info $ vacuousShapeAnnotations t) loc+  Id v (Info $ anyDimShapeAnnotations t) loc patternNoShapeAnnotations (TuplePattern ps loc) =   TuplePattern (map patternNoShapeAnnotations ps) loc patternNoShapeAnnotations (RecordPattern ps loc) =   RecordPattern (map (fmap patternNoShapeAnnotations) ps) loc patternNoShapeAnnotations (Wildcard (Info t) loc) =-  Wildcard (Info (vacuousShapeAnnotations t)) loc+  Wildcard (Info (anyDimShapeAnnotations t)) loc patternNoShapeAnnotations (PatternLit e (Info t) loc) =-  PatternLit e (Info (vacuousShapeAnnotations t)) loc+  PatternLit e (Info (anyDimShapeAnnotations t)) loc  -- | Names of primitive types to types.  This is only valid if no -- shadowing is going on, but useful for tools.@@ -739,7 +694,7 @@                          [arr_a, arr_a] uarr_a),               ("rotate", IntrinsicPolyFun [tp_a]                          [Prim $ Signed Int32, arr_a] arr_a),-              ("transpose", IntrinsicPolyFun [tp_a] [arr_a] arr_a),+              ("transpose", IntrinsicPolyFun [tp_a] [arr_2d_a] arr_2d_a),                ("cmp_threshold", IntrinsicPolyFun []                                 [Prim $ Signed Int32,@@ -799,6 +754,7 @@         tv_a' = typeName tv_a         t_a = TypeVar () Nonunique tv_a' []         arr_a = Array () Nonunique (ArrayPolyElem tv_a' []) (rank 1)+        arr_2d_a = Array () Nonunique (ArrayPolyElem tv_a' []) (rank 2)         uarr_a = Array () Unique (ArrayPolyElem tv_a' []) (rank 1)         tp_a = TypeParamType Unlifted tv_a noLoc 
src/Language/Futhark/Interpreter.hs view
@@ -555,7 +555,7 @@           v <- eval env e           return (k, v)         evalField (RecordFieldImplicit k t loc) = do-          v <- eval env $ Var (qualName k) (vacuousShapeAnnotations <$> t) loc+          v <- eval env $ Var (qualName k) t loc           return (baseName k, v)  eval env (ArrayLit vs _ _) = toArray =<< mapM (eval env) vs@@ -584,7 +584,7 @@  eval env (Var qv _ _) = evalTermVar env qv -eval env (Ascript e td loc) = do+eval env (Ascript e td _ loc) = do   v <- eval env e   let t = evalType env $ unInfo $ expandedType td   case matchValueToType env t v of@@ -592,7 +592,7 @@     Left err -> bad loc env $ "Value `" <> pretty v <> "` cannot match shape of type `" <>                 pretty (declaredType td) <> "` (`" <> pretty t <> "`): " ++ err -eval env (LetPat _ p e body _) = do+eval env (LetPat _ p e body _ _) = do   v <- eval env e   env' <- matchPattern env p v   eval env' body@@ -677,11 +677,11 @@               ValueRecord $ M.insert f (update f_v fs v') src'         update _ _ _ = error "eval RecordUpdate: invalid value." -eval env (LetWith dest src is v body loc) = do+eval env (LetWith dest src is v body _ loc) = do   dest' <- maybe oob return =<<     updateArray <$> mapM (evalDimIndex env) is <*>     evalTermVar env (qualName $ identName src) <*> eval env v-  let t = T.BoundV [] $ vacuousShapeAnnotations $ toStruct $ unInfo $ identType dest+  let t = T.BoundV [] $ toStruct $ unInfo $ identType dest   eval (valEnv (M.singleton (identName dest) (Just t, dest')) <> env) body   where oob = bad loc env "Bad update" @@ -795,8 +795,6 @@           case c' of             Just v' -> return v'             Nothing -> match v cs'--eval _ e = error $ "eval not yet: " ++ show e  evalCase :: Value -> Env -> CaseBase Info VName          -> EvalM (Maybe Value)
src/Language/Futhark/Parser/Parser.y view
@@ -512,7 +512,7 @@ -- permit inside array indices operations (there is an ambiguity with -- array slices). Exp :: { UncheckedExp }-     : Exp ':' TypeExpDecl { Ascript $1 $3 (srcspan $1 $>) }+     : Exp ':' TypeExpDecl { Ascript $1 $3 NoInfo (srcspan $1 $>) }      | Exp2 %prec ':'      { $1 }  Exp2 :: { UncheckedExp }@@ -581,7 +581,7 @@        { RecordUpdate $1 (map fst $3) $5 NoInfo (srcspan $1 $>) }       | '\\' TypeParams FunParams1 maybeAscription(TypeExpTerm) '->' Exp-       { Lambda $2 (fst $3 : snd $3) $6 (fmap (flip TypeDecl NoInfo) $4) NoInfo (srcspan $1 $>) }+       { Lambda $2 (fst $3 : snd $3) $6 $4 NoInfo (srcspan $1 $>) }       | Apply { $1 } @@ -696,9 +696,9 @@  LetExp :: { UncheckedExp }      : let Pattern '=' Exp LetBody-                      { LetPat [] $2 $4 $5 (srcspan $1 $>) }+                      { LetPat [] $2 $4 $5 NoInfo (srcspan $1 $>) }      | let TypeParams1 Pattern '=' Exp LetBody-                      { LetPat (fst $2 : snd $2) $3 $5 $6 (srcspan $1 $>) }+                      { LetPat (fst $2 : snd $2) $3 $5 $6 NoInfo (srcspan $1 $>) }       | let id TypeParams FunParams1 maybeAscription(TypeExpDecl) '=' Exp LetBody        { let L _ (ID name) = $2@@ -706,7 +706,7 @@       | let VarSlice '=' Exp LetBody                       { let (v,slice,loc) = $2; ident = Ident v NoInfo loc-                        in LetWith ident ident slice $4 $5 (srcspan $1 $>) }+                        in LetWith ident ident slice $4 $5 NoInfo (srcspan $1 $>) }  LetBody :: { UncheckedExp }     : in Exp %prec letprec { $2 }
src/Language/Futhark/Pretty.hs view
@@ -201,7 +201,7 @@   pprPrec _ (Var name _ _) = ppr name   pprPrec _ (Parens e _) = align $ parens $ ppr e   pprPrec _ (QualParens v e _) = ppr v <> text "." <> align (parens $ ppr e)-  pprPrec _ (Ascript e t _) = pprPrec 0 e <> colon <+> pprPrec 0 t+  pprPrec _ (Ascript e t _ _) = pprPrec 0 e <> colon <+> pprPrec 0 t   pprPrec _ (Literal v _) = ppr v   pprPrec _ (IntLit v _ _) = ppr v   pprPrec _ (FloatLit v _ _) = ppr v@@ -230,7 +230,7 @@   pprPrec p (Apply f arg _ _ _) =     parensIf (p >= 10) $ ppr f <+> pprPrec 10 arg   pprPrec _ (Negate e _) = text "-" <> ppr e-  pprPrec p (LetPat tparams pat e body _) =+  pprPrec p (LetPat tparams pat e body _ _) =     parensIf (p /= -1) $ align $     text "let" <+> align (spread $ map ppr tparams ++ [ppr pat]) <+>     (if linebreak@@ -239,11 +239,6 @@     (case body of LetPat{} -> ppr body                   _        -> text "in" <+> align (ppr body))     where linebreak = case e of-                        Map{}       -> True-                        Reduce{}    -> True-                        GenReduce{} -> True-                        Filter{}    -> True-                        Scan{}      -> True                         DoLoop{}    -> True                         LetPat{}    -> True                         LetWith{}   -> True@@ -257,7 +252,7 @@     where retdecl' = case (ppr <$> unAnnot rettype) `mplus` (ppr <$> retdecl) of                        Just rettype' -> text ":" <+> rettype'                        Nothing       -> mempty-  pprPrec _ (LetWith dest src idxs ve body _)+  pprPrec _ (LetWith dest src idxs ve body _ _)     | dest == src =       text "let" <+> ppr dest <> list (map ppr idxs) <+>       equals <+> align (ppr ve) <+>@@ -277,32 +272,12 @@     text "<-" <+> align (ppr ve)   pprPrec _ (Index e idxs _ _) =     pprPrec 9 e <> brackets (commasep (map ppr idxs))-  pprPrec _ (Map lam a _ _) = ppSOAC "map" [lam] [a]-  pprPrec _ (Reduce Commutative lam e a _) = ppSOAC "reduce_comm" [lam] [e, a]-  pprPrec _ (Reduce Noncommutative lam e a _) = ppSOAC "reduce" [lam] [e, a]-  pprPrec _ (GenReduce hist op ne bfun img _) =-    ppSOAC "gen_reduce" [op, bfun] [hist, ne, img] -- do this manually-  pprPrec _ (Stream form lam arr _) =-    case form of-      MapLike o ->-        let ord_str = if o == Disorder then "_per" else ""-        in  text ("stream_map"++ord_str) <>-            ppr lam </> pprPrec 10 arr-      RedLike o comm lam0 ->-        let ord_str = if o == Disorder then "_per" else ""-            comm_str = case comm of Commutative    -> "_comm"-                                    Noncommutative -> ""-        in  text ("stream_red"++ord_str++comm_str) <>-            ppr lam0 </> ppr lam </> pprPrec 10 arr-  pprPrec _ (Scan lam e a _) = ppSOAC "scan" [lam] [e, a]-  pprPrec _ (Filter lam a _) = ppSOAC "filter" [lam] [a]-  pprPrec _ (Partition k lam a _) = text "partition" <+> ppr k <+> spread (map (pprPrec 10) [lam, a])   pprPrec _ (Unsafe e _) = text "unsafe" <+> pprPrec (-1) e   pprPrec _ (Assert e1 e2 _ _) = text "assert" <+> pprPrec 10 e1 <+> pprPrec 10 e2-  pprPrec p (Lambda tparams params body ascript _ _) =+  pprPrec p (Lambda tparams params body rettype _ _) =     parensIf (p /= -1) $     text "\\" <> spread (map ppr tparams ++ map ppr params) <>-    ppAscription ascript <+>+    ppAscription rettype <+>     text "->" </> indent 2 (ppr body)   pprPrec _ (OpSection binop _ _) =     parens $ ppr binop@@ -351,7 +326,7 @@                                     Nothing -> text "_"   ppr (PatternLit e _ _)        = ppr e -ppAscription :: (Eq vn, IsName vn, Annot f) => Maybe (TypeDeclBase f vn) -> Doc+ppAscription :: Pretty t => Maybe t -> Doc ppAscription Nothing  = mempty ppAscription (Just t) = text ":" <> ppr t @@ -474,9 +449,3 @@         rprecedence Minus  = 10         rprecedence Divide = 10         rprecedence op     = precedence op--ppSOAC :: (Eq vn, IsName vn, Pretty fn, Annot f) =>-          String -> [fn] -> [ExpBase f vn] -> Doc-ppSOAC name funs es =-  text name <+> align (spread (map (parens . ppr) funs) </>-                       spread (map (pprPrec 10) es))
src/Language/Futhark/Syntax.hs view
@@ -31,7 +31,6 @@   , TypeArgExp(..)   , RecordArrayElemTypeBase(..)   , ArrayElemTypeBase(..)-  , CompType   , PatternType   , StructType   , Diet(..)@@ -54,7 +53,6 @@   , CaseBase(..)   , LoopFormBase (..)   , PatternBase(..)-  , StreamForm(..)    -- * Module language   , SpecBase(..)@@ -113,17 +111,12 @@        Show (f String),        Show (f [VName]),        Show (f PatternType),-       Show (f CompType),-       Show (f (TypeBase () ())),        Show (f Int),-       Show (f [TypeBase () ()]),        Show (f StructType),        Show (f (Aliasing, StructType)),-       Show (f ([TypeBase () ()], PatternType)),        Show (f (M.Map VName VName)),        Show (f [RecordArrayElemTypeBase ()]),-       Show (f Uniqueness),-       Show (f ([CompType], CompType))) => Showable f vn where+       Show (f Uniqueness)) => Showable f vn where  -- | No information functor.  Usually used for placeholder type- or -- aliasing information.@@ -197,7 +190,7 @@ instance IsPrimValue Bool where   primValue = BoolValue -class (Eq dim, Ord dim) => ArrayDim dim where+class Eq dim => ArrayDim dim where   -- | @unifyDims x y@ combines @x@ and @y@ to contain their maximum   -- common information, and fails if they conflict.   unifyDims :: dim -> dim -> Maybe dim@@ -214,7 +207,9 @@                   -- ^ The size is a constant.                 | AnyDim                   -- ^ No dimension declaration.-                deriving (Eq, Ord, Show)+                deriving Show+deriving instance Eq (DimDecl Name)+deriving instance Eq (DimDecl VName)  instance Functor DimDecl where   fmap = fmapDefault@@ -227,7 +222,7 @@   traverse _ (ConstDim x) = pure $ ConstDim x   traverse _ AnyDim = pure AnyDim -instance (Eq vn, Ord vn) => ArrayDim (DimDecl vn) where+instance ArrayDim (DimDecl VName) where   unifyDims AnyDim y = Just y   unifyDims x AnyDim = Just x   unifyDims (NamedDim x) (NamedDim y) | x == y = Just $ NamedDim x@@ -397,14 +392,14 @@ -- aliased. type Aliasing = S.Set Alias --- | A type with aliasing information and no shape annotations, used--- for describing the type of a computation.-type CompType = TypeBase () Aliasing- -- | A type with aliasing information and shape annotations, used for--- describing the type of a pattern.+-- describing the type patterns and expressions. type PatternType = TypeBase (DimDecl VName) Aliasing +-- | A "structural" type with shape annotations and no aliasing+-- information, used for declarations.+type StructType = TypeBase (DimDecl VName) ()+ -- | An unstructured type with type variables and possibly shape -- declarations - this is what the user types in the source program. data TypeExp vn = TEVar (QualName vn) SrcLoc@@ -415,7 +410,9 @@                 | TEApply (TypeExp vn) (TypeArgExp vn) SrcLoc                 | TEArrow (Maybe vn) (TypeExp vn) (TypeExp vn) SrcLoc                 | TEEnum [Name] SrcLoc-                 deriving (Eq, Show)+                 deriving (Show)+deriving instance Eq (TypeExp Name)+deriving instance Eq (TypeExp VName)  instance Located (TypeExp vn) where   locOf (TEArray _ _ loc)   = locOf loc@@ -429,16 +426,14 @@  data TypeArgExp vn = TypeArgExpDim (DimDecl vn) SrcLoc                    | TypeArgExpType (TypeExp vn)-                deriving (Eq, Show)+                deriving (Show)+deriving instance Eq (TypeArgExp Name)+deriving instance Eq (TypeArgExp VName)  instance Located (TypeArgExp vn) where   locOf (TypeArgExpDim _ loc) = locOf loc   locOf (TypeArgExpType t)    = locOf t --- | A "structural" type with shape annotations and no aliasing--- information, used for declarations.-type StructType = TypeBase (DimDecl VName) ()- -- | A declaration of the type of something. data TypeDeclBase f vn =   TypeDecl { declaredType :: TypeExp vn@@ -473,7 +468,7 @@ -- | An identifier consists of its name and the type of the value -- bound to the identifier. data IdentBase f vn = Ident { identName   :: vn-                            , identType   :: f CompType+                            , identType   :: f PatternType                             , identSrcLoc :: SrcLoc                             } deriving instance Showable f vn => Show (IdentBase f vn)@@ -555,8 +550,20 @@ data QualName vn = QualName { qualQuals :: ![vn]                             , qualLeaf  :: !vn                             }-  deriving (Eq, Ord, Show)+  deriving (Show) +instance Eq (QualName Name) where+  QualName qs1 v1 == QualName qs2 v2 = qs1 == qs2 && v1 == v2++instance Eq (QualName VName) where+  QualName _ v1 == QualName _ v2 = v1 == v2++instance Ord (QualName Name) where+  QualName qs1 v1 `compare` QualName qs2 v2 = compare (qs1, v1) (qs2, v2)++instance Ord (QualName VName) where+  QualName _ v1 `compare` QualName _ v2 = compare v1 v2+ instance Functor QualName where   fmap = fmapDefault @@ -579,10 +586,10 @@ data ExpBase f vn =               Literal PrimValue SrcLoc -            | IntLit Integer (f (TypeBase () ())) SrcLoc+            | IntLit Integer (f PatternType) SrcLoc             -- ^ A polymorphic integral literal. -            | FloatLit Double (f (TypeBase () ())) SrcLoc+            | FloatLit Double (f PatternType) SrcLoc             -- ^ A polymorphic decimal literal.              | Parens (ExpBase f vn) SrcLoc@@ -596,23 +603,23 @@             | RecordLit [FieldBase f vn] SrcLoc             -- ^ Record literals, e.g. @{x=2,y=3,z}@. -            | ArrayLit  [ExpBase f vn] (f CompType) SrcLoc+            | ArrayLit  [ExpBase f vn] (f PatternType) SrcLoc             -- ^ Array literals, e.g., @[ [1+x, 3], [2, 1+4] ]@.             -- Second arg is the row type of the rows of the array. -            | Range (ExpBase f vn) (Maybe (ExpBase f vn)) (Inclusiveness (ExpBase f vn)) (f CompType) SrcLoc+            | Range (ExpBase f vn) (Maybe (ExpBase f vn)) (Inclusiveness (ExpBase f vn)) (f PatternType) SrcLoc              | Var (QualName vn) (f PatternType) SrcLoc -            | Ascript (ExpBase f vn) (TypeDeclBase f vn) SrcLoc+            | Ascript (ExpBase f vn) (TypeDeclBase f vn) (f PatternType) SrcLoc             -- ^ Type ascription: @e : t@. -            | LetPat [TypeParamBase vn] (PatternBase f vn) (ExpBase f vn) (ExpBase f vn) SrcLoc+            | LetPat [TypeParamBase vn] (PatternBase f vn) (ExpBase f vn) (ExpBase f vn) (f PatternType) SrcLoc              | LetFun vn ([TypeParamBase vn], [PatternBase f vn], Maybe (TypeExp vn), f StructType, ExpBase f vn)               (ExpBase f vn) SrcLoc -            | If     (ExpBase f vn) (ExpBase f vn) (ExpBase f vn) (f CompType) SrcLoc+            | If     (ExpBase f vn) (ExpBase f vn) (ExpBase f vn) (f PatternType) SrcLoc              | Apply (ExpBase f vn) (ExpBase f vn) (f Diet) (f PatternType) SrcLoc @@ -620,7 +627,7 @@               -- ^ Numeric negation (ugly special case; Haskell did it first).              | Lambda [TypeParamBase vn] [PatternBase f vn] (ExpBase f vn)-              (Maybe (TypeDeclBase f vn)) (f (Aliasing, StructType)) SrcLoc+              (Maybe (TypeExp vn)) (f (Aliasing, StructType)) SrcLoc              | OpSection (QualName vn) (f PatternType) SrcLoc               -- ^ @+@; first two types are operands, third is result.@@ -647,70 +654,19 @@               (ExpBase f vn, f StructType) (ExpBase f vn, f StructType)               (f PatternType) SrcLoc -            | Project Name (ExpBase f vn) (f CompType) SrcLoc+            | Project Name (ExpBase f vn) (f PatternType) SrcLoc              -- Primitive array operations             | LetWith (IdentBase f vn) (IdentBase f vn)                       [DimIndexBase f vn] (ExpBase f vn)-                      (ExpBase f vn) SrcLoc+                      (ExpBase f vn) (f PatternType) SrcLoc -            | Index (ExpBase f vn) [DimIndexBase f vn] (f CompType) SrcLoc+            | Index (ExpBase f vn) [DimIndexBase f vn] (f PatternType) SrcLoc              | Update (ExpBase f vn) [DimIndexBase f vn] (ExpBase f vn) SrcLoc              | RecordUpdate (ExpBase f vn) [Name] (ExpBase f vn) (f PatternType) SrcLoc -            -- Second-Order Array Combinators accept curried and-            -- anonymous functions as first params.-            | Map (ExpBase f vn) (ExpBase f vn) (f CompType) SrcLoc-             -- ^ @map (+1) [1, 2, ..., n] = [2, 3, ..., n+1]@.--            | Reduce Commutativity (ExpBase f vn) (ExpBase f vn) (ExpBase f vn) SrcLoc-             -- ^ @reduce (+) 0 ([1,2,...,n]) = (0+1+2+...+n)@.--            | GenReduce (ExpBase f vn) (ExpBase f vn) (ExpBase f vn)-                        (ExpBase f vn) (ExpBase f vn) SrcLoc-             -- ^ @gen_reduce [1,1,1] (+) 0 [1,1,1] [1,1,1] = [4,1,1]@--            | Scan (ExpBase f vn) (ExpBase f vn) (ExpBase f vn) SrcLoc-             -- ^ @scan (+) 0 ([ 1, 2, 3 ]) = [ 1, 3, 6 ]@.--            | Filter (ExpBase f vn) (ExpBase f vn) SrcLoc-            -- ^ Return those elements of the array that satisfy the-            -- predicate.--            | Partition Int (ExpBase f vn) (ExpBase f vn) SrcLoc-            -- ^ @partition k f a@, where @f@ returns an integer,-            -- returns a tuple @(a', is)@ that describes a-            -- partitioning of @a@ into @n@ equivalence classes.-            -- Here, @a'@ is a re-ordering of @a@, and @is@ is an-            -- array of @k@ offsets into @a'@.--            | Stream (StreamForm f vn) (ExpBase f vn) (ExpBase f vn) SrcLoc-            -- ^ Streaming: intuitively, this gives a size-parameterized-            -- composition for SOACs that cannot be fused, e.g., due to scan.-            -- For example, assuming @A : [int], f : int->int, g : real->real@,-            -- the code: @let x = map(f,A) in let y = scan(op+,0,x) in map(g,y)@-            -- can be re-written (streamed) in the source-Futhark language as:-            -- @let (acc, z) =@-            -- @  stream (fn (int,[real]) (real chunk, real acc, [int] a) =>@-            -- @            let x = map (f,         A )@-            -- @            let y0= scan(op +, 0,   x )@-            -- @            let y = map (op +(acc), y0)@-            -- @            ( acc+y0[chunk-1], map(g, y) )@-            -- @         ) 0 A@-            -- where (i)  @chunk@ is a symbolic int denoting the chunk-            -- size, (ii) @0@ is the initial value of the accumulator,-            -- which allows the streaming of @scan@.-            -- Finally, the unnamed function (@fn...@) implements the a fold that:-            -- computes the accumulator of @scan@, as defined inside its body, AND-            -- implicitly concatenates each of the result arrays across-            -- the iteration space.-            -- In essence, sequential codegen can choose chunk = 1 and thus-            -- eliminate the SOACs on the outermost level, while parallel codegen-            -- may choose the maximal chunk size that still satisfies the memory-            -- requirements of the device.-             | Unsafe (ExpBase f vn) SrcLoc             -- ^ Explore the Danger Zone and elide safety checks on             -- array operations and other assertions during execution@@ -722,18 +678,14 @@             -- and return the value of the second expression if it             -- does. -            | VConstr0 Name (f CompType) SrcLoc+            | VConstr0 Name (f PatternType) SrcLoc             -- ^ An enum element, e.g., @#foo@. -            | Match (ExpBase f vn) [CaseBase f vn] (f CompType) SrcLoc+            | Match (ExpBase f vn) [CaseBase f vn] (f PatternType) SrcLoc             -- ^ A match expression.  deriving instance Showable f vn => Show (ExpBase f vn) -data StreamForm f vn = MapLike    StreamOrd-                     | RedLike    StreamOrd Commutativity (ExpBase f vn)-deriving instance Showable f vn => Show (StreamForm f vn)- instance Located (ExpBase f vn) where   locOf (Literal _ loc)                = locOf loc   locOf (IntLit _ _ loc)               = locOf loc@@ -748,21 +700,15 @@   locOf (BinOp _ _ _ _ _ pos)          = locOf pos   locOf (If _ _ _ _ pos)               = locOf pos   locOf (Var _ _ loc)                  = locOf loc-  locOf (Ascript _ _ loc)              = locOf loc+  locOf (Ascript _ _ _ loc)            = locOf loc   locOf (Negate _ pos)                 = locOf pos   locOf (Apply _ _ _ _ pos)            = locOf pos-  locOf (LetPat _ _ _ _ pos)           = locOf pos+  locOf (LetPat _ _ _ _ _ loc)         = locOf loc   locOf (LetFun _ _ _ loc)             = locOf loc-  locOf (LetWith _ _ _ _ _ pos)        = locOf pos+  locOf (LetWith _ _ _ _ _ _ loc)      = locOf loc   locOf (Index _ _ _ loc)              = locOf loc   locOf (Update _ _ _ pos)             = locOf pos   locOf (RecordUpdate _ _ _ _ pos)     = locOf pos-  locOf (Map _ _ _ loc)                = locOf loc-  locOf (Reduce _ _ _ _ pos)           = locOf pos-  locOf (GenReduce _ _ _ _ _ pos)      = locOf pos-  locOf (Scan _ _ _ pos)               = locOf pos-  locOf (Filter _ _ pos)               = locOf pos-  locOf (Partition _ _ _ loc)          = locOf loc   locOf (Lambda _ _ _ _ _ loc)         = locOf loc   locOf (OpSection _ _ loc)            = locOf loc   locOf (OpSectionLeft _ _ _ _ _ loc)  = locOf loc@@ -770,7 +716,6 @@   locOf (ProjectSection _ _ loc)       = locOf loc   locOf (IndexSection _ _ loc)         = locOf loc   locOf (DoLoop _ _ _ _ _ pos)         = locOf pos-  locOf (Stream _ _ _  pos)            = locOf pos   locOf (Unsafe _ loc)                 = locOf loc   locOf (Assert _ _ _ loc)             = locOf loc   locOf (VConstr0 _ _ loc)             = locOf loc@@ -778,7 +723,7 @@  -- | An entry in a record literal. data FieldBase f vn = RecordFieldExplicit Name (ExpBase f vn) SrcLoc-                    | RecordFieldImplicit vn (f CompType) SrcLoc+                    | RecordFieldImplicit vn (f PatternType) SrcLoc  deriving instance Showable f vn => Show (FieldBase f vn) 
src/Language/Futhark/Traversals.hs view
@@ -16,7 +16,7 @@ -- tree.  The implementation is rather tedious, but the interface is -- easy to use. ----- A traversal of the Futhark syntax tree is expressed as a tuple of+-- A traversal of the Futhark syntax tree is expressed as a record of -- functions expressing the operations to be performed on the various -- types of nodes. module Language.Futhark.Traversals@@ -35,8 +35,6 @@     mapOnExp         :: ExpBase Info VName -> m (ExpBase Info VName)   , mapOnName        :: VName -> m VName   , mapOnQualName    :: QualName VName -> m (QualName VName)-  , mapOnType        :: TypeBase () () -> m (TypeBase () ())-  , mapOnCompType    :: CompType -> m CompType   , mapOnStructType  :: StructType -> m StructType   , mapOnPatternType :: PatternType -> m PatternType   }@@ -55,9 +53,9 @@   astMap _ (Literal val loc) =     pure $ Literal val loc   astMap tv (IntLit val t loc) =-    IntLit val <$> traverse (mapOnType tv) t <*> pure loc+    IntLit val <$> traverse (mapOnPatternType tv) t <*> pure loc   astMap tv (FloatLit val t loc) =-    FloatLit val <$> traverse (mapOnType tv) t <*> pure loc+    FloatLit val <$> traverse (mapOnPatternType tv) t <*> pure loc   astMap tv (Parens e loc) =     Parens <$> mapOnExp tv e <*> pure loc   astMap tv (QualParens name e loc) =@@ -67,12 +65,13 @@   astMap tv (RecordLit fields loc) =     RecordLit <$> astMap tv fields <*> pure loc   astMap tv (ArrayLit els t loc) =-    ArrayLit <$> mapM (mapOnExp tv) els <*> traverse (mapOnCompType tv) t <*> pure loc+    ArrayLit <$> mapM (mapOnExp tv) els <*> traverse (mapOnPatternType tv) t <*> pure loc   astMap tv (Range start next end t loc) =     Range <$> mapOnExp tv start <*> traverse (mapOnExp tv) next <*>-    traverse (mapOnExp tv) end <*> traverse (mapOnCompType tv) t <*> pure loc-  astMap tv (Ascript e tdecl loc) =-    Ascript <$> mapOnExp tv e <*> astMap tv tdecl <*> pure loc+    traverse (mapOnExp tv) end <*> traverse (mapOnPatternType tv) t <*> pure loc+  astMap tv (Ascript e tdecl t loc) =+    Ascript <$> mapOnExp tv e <*> astMap tv tdecl <*>+    traverse (mapOnPatternType tv) t <*> pure loc   astMap tv (BinOp fname t (x,xt) (y,yt) (Info rt) loc) =     BinOp <$> mapOnQualName tv fname <*> traverse (mapOnPatternType tv) t <*>     ((,) <$> mapOnExp tv x <*> traverse (mapOnStructType tv) xt) <*>@@ -82,26 +81,26 @@     Negate <$> mapOnExp tv x <*> pure loc   astMap tv (If c texp fexp t loc) =     If <$> mapOnExp tv c <*> mapOnExp tv texp <*> mapOnExp tv fexp <*>-    traverse (mapOnCompType tv) t <*> pure loc+    traverse (mapOnPatternType tv) t <*> pure loc   astMap tv (Apply f arg d (Info t) loc) =     Apply <$> mapOnExp tv f <*> mapOnExp tv arg <*>     pure d <*> (Info <$> mapOnPatternType tv t) <*>     pure loc-  astMap tv (LetPat tparams pat e body loc) =+  astMap tv (LetPat tparams pat e body t loc) =     LetPat <$> mapM (astMap tv) tparams <*>     astMap tv pat <*> mapOnExp tv e <*>-    mapOnExp tv body <*> pure loc+    mapOnExp tv body <*> traverse (mapOnPatternType tv) t <*> pure loc   astMap tv (LetFun name (fparams, params, ret, t, e) body loc) =     LetFun <$> mapOnName tv name <*>     ((,,,,) <$> mapM (astMap tv) fparams <*> mapM (astMap tv) params <*>      traverse (astMap tv) ret <*> traverse (mapOnStructType tv) t <*>      mapOnExp tv e) <*>     mapOnExp tv body <*> pure loc-  astMap tv (LetWith dest src idxexps vexp body loc) =+  astMap tv (LetWith dest src idxexps vexp body t loc) =     pure LetWith <*>          astMap tv dest <*> astMap tv src <*>          mapM (astMap tv) idxexps <*> mapOnExp tv vexp <*>-         mapOnExp tv body <*> pure loc+         mapOnExp tv body <*> traverse (mapOnPatternType tv) t <*> pure loc   astMap tv (Update src slice v loc) =     Update <$> mapOnExp tv src <*> mapM (astMap tv) slice <*>     mapOnExp tv v <*> pure loc@@ -109,40 +108,17 @@     RecordUpdate <$> mapOnExp tv src <*> pure fs <*>     mapOnExp tv v <*> (Info <$> mapOnPatternType tv t) <*> pure loc   astMap tv (Project field e t loc) =-    Project field <$> mapOnExp tv e <*> traverse (mapOnCompType tv) t <*> pure loc+    Project field <$> mapOnExp tv e <*> traverse (mapOnPatternType tv) t <*> pure loc   astMap tv (Index arr idxexps t loc) =     pure Index <*>          astMap tv arr <*>          mapM (astMap tv) idxexps <*>-         traverse (mapOnCompType tv) t <*>+         traverse (mapOnPatternType tv) t <*>          pure loc-  astMap tv (Map fun e t loc) =-    Map <$> mapOnExp tv fun <*> mapOnExp tv e <*>-    traverse (mapOnCompType tv) t <*> pure loc-  astMap tv (Reduce comm fun startexp arrexp loc) =-    Reduce comm <$> mapOnExp tv fun <*>-    mapOnExp tv startexp <*> mapOnExp tv arrexp <*> pure loc-  astMap tv (GenReduce hist op ne bfun img loc) =-    GenReduce <$> mapOnExp tv hist <*> mapOnExp tv op <*> mapOnExp tv ne-    <*> mapOnExp tv bfun <*> mapOnExp tv img <*> pure loc   astMap tv (Unsafe e loc) =     Unsafe <$> mapOnExp tv e <*> pure loc   astMap tv (Assert e1 e2 desc loc) =     Assert <$> mapOnExp tv e1 <*> mapOnExp tv e2 <*> pure desc <*> pure loc-  astMap tv (Scan fun startexp arrexp loc) =-    pure Scan <*> mapOnExp tv fun <*>-         mapOnExp tv startexp <*> mapOnExp tv arrexp <*>-         pure loc-  astMap tv (Filter fun arrexp loc) =-    pure Filter <*> mapOnExp tv fun <*> mapOnExp tv arrexp <*> pure loc-  astMap tv (Partition k fun arrexp loc) =-    Partition k <$> mapOnExp tv fun <*> mapOnExp tv arrexp <*> pure loc-  astMap tv (Stream form fun arr loc) =-    pure Stream <*> mapOnStreamForm form <*> mapOnExp tv fun <*>-         mapOnExp tv arr <*> pure loc-    where mapOnStreamForm (MapLike o) = pure $ MapLike o-          mapOnStreamForm (RedLike o comm lam) =-              RedLike o comm <$> mapOnExp tv lam   astMap tv (Lambda tparams params body ret t loc) =     Lambda <$> mapM (astMap tv) tparams <*> mapM (astMap tv) params <*>     astMap tv body <*> traverse (astMap tv) ret <*>@@ -172,10 +148,10 @@     mapOnExp tv mergeexp <*> astMap tv form <*>     mapOnExp tv loopbody <*> pure loc   astMap tv (VConstr0 name t loc) =-    VConstr0 name <$> traverse (mapOnCompType tv) t <*> pure loc+    VConstr0 name <$> traverse (mapOnPatternType tv) t <*> pure loc   astMap tv (Match e cases t loc) =     Match <$> mapOnExp tv e <*> astMap tv cases-          <*> traverse (mapOnCompType tv) t <*> pure loc+          <*> traverse (mapOnPatternType tv) t <*> pure loc  instance ASTMappable (LoopFormBase Info VName) where   astMap tv (For i bound) = For <$> astMap tv i <*> astMap tv bound@@ -267,14 +243,6 @@ traverseTypeArg _ g (TypeArgDim d loc) = TypeArgDim <$> g d <*> pure loc traverseTypeArg f g (TypeArgType t loc) = TypeArgType <$> traverseType f g pure t <*> pure loc -instance ASTMappable (TypeBase () ()) where-  astMap tv = traverseType f pure pure-    where f = fmap typeNameFromQualName . mapOnQualName tv . qualNameFromTypeName--instance ASTMappable CompType where-  astMap tv = traverseType f pure (astMap tv)-    where f = fmap typeNameFromQualName . mapOnQualName tv . qualNameFromTypeName- instance ASTMappable StructType where   astMap tv = traverseType f (astMap tv) pure     where f = fmap typeNameFromQualName . mapOnQualName tv . qualNameFromTypeName@@ -289,7 +257,7 @@  instance ASTMappable (IdentBase Info VName) where   astMap tv (Ident name (Info t) loc) =-    Ident <$> mapOnName tv name <*> (Info <$> mapOnCompType tv t) <*> pure loc+    Ident <$> mapOnName tv name <*> (Info <$> mapOnPatternType tv t) <*> pure loc  instance ASTMappable (PatternBase Info VName) where   astMap tv (Id name (Info t) loc) =@@ -312,7 +280,7 @@     RecordFieldExplicit name <$> mapOnExp tv e <*> pure loc   astMap tv (RecordFieldImplicit name t loc) =     RecordFieldImplicit <$> mapOnName tv name-    <*> traverse (mapOnCompType tv) t <*> pure loc+    <*> traverse (mapOnPatternType tv) t <*> pure loc  instance ASTMappable (CaseBase Info VName) where   astMap tv (CasePat pat e loc) =
src/Language/Futhark/TypeChecker.hs view
@@ -389,8 +389,11 @@    -- Apply type abbreviations from a_mty to body_mty.   let a_abbrs = mtyTypeAbbrs a_mty-  let type_subst = M.mapMaybe (fmap TypeSub . (`M.lookup` a_abbrs)) p_subst-  let body_mty' = substituteTypesInMTy type_subst body_mty+      isSub v = case M.lookup v a_abbrs of+                  Just abbr -> Just $ TypeSub abbr+                  _  -> Just $ DimSub $ NamedDim $ qualName v+      type_subst = M.mapMaybe isSub p_subst+      body_mty' = substituteTypesInMTy type_subst body_mty   (body_mty'', body_subst) <- newNamesForMTy body_mty'   return (body_mty'', p_subst, body_subst) @@ -696,8 +699,11 @@     matchVal loc spec_name spec_t name t       | matchFunBinding loc spec_t t = return (spec_name, name)     matchVal loc spec_name spec_v _ v =-      Left $ TypeError loc $ "Value " ++ quote (baseString spec_name) ++ " specified as type " ++-      ppValBind spec_v ++ " in signature, but has " ++ ppValBind v ++ " in structure."+      Left $ TypeError loc $ unlines $+      ["Module type specifies"] +++      map ("  "++) (lines $ ppValBind spec_name spec_v) +++      ["but module provides"] +++      map ("  "++) (lines $ppValBind spec_name v)      matchFunBinding :: SrcLoc -> BoundV -> BoundV -> Bool     matchFunBinding loc (BoundV _ orig_spec_t) (BoundV tps orig_t) =@@ -752,7 +758,8 @@                indent $ ppTypeAbbr abs name mod_t,                "but module type requires this type to be non-functional."] -    ppValBind (BoundV tps t) = unwords $ map pretty tps ++ [pretty t]+    ppValBind v (BoundV tps t) =+      unwords $ ["val", prettyName v] ++ map pretty tps ++ [":", pretty t]      ppTypeAbbr abs name (ps, t) =       "type " ++ unwords (pretty name : map pretty ps) ++ t'@@ -804,6 +811,10 @@   where subT name _           | Just (TypeSub (TypeAbbr l ps t)) <- M.lookup name substs = TypeAbbr l ps t         subT _ (TypeAbbr l ps t) = TypeAbbr l ps $ substituteTypes substs t++substituteTypesInBoundV :: TypeSubs -> BoundV -> BoundV+substituteTypesInBoundV substs (BoundV tps t) =+  BoundV tps (substituteTypes substs t)  allNamesInMTy :: MTy -> S.Set VName allNamesInMTy (MTy abs mod) =
src/Language/Futhark/TypeChecker/Monad.hs view
@@ -208,7 +208,7 @@   lookupMod :: SrcLoc -> QualName Name -> m (QualName VName, Mod)   lookupMTy :: SrcLoc -> QualName Name -> m (QualName VName, MTy)   lookupImport :: SrcLoc -> FilePath -> m (FilePath, Env)-  lookupVar :: SrcLoc -> QualName Name -> m (QualName VName, CompType)+  lookupVar :: SrcLoc -> QualName Name -> m (QualName VName, PatternType)  checkName :: MonadTypeChecker m => Namespace -> Name -> SrcLoc -> m VName checkName space name loc = qualLeaf <$> checkQualName space (qualName name) loc@@ -278,7 +278,7 @@             case getType t of               Left{} -> throwError $ TypeError loc $                         "Attempt to use function " ++ baseString name ++ " as value."-              Right t' -> return (qn', removeShapeAnnotations $ fromStruct $+              Right t' -> return (qn', fromStruct $                                        qualifyTypeVars outer_env mempty qs t')  -- | Extract from a type either a function type comprising a list of@@ -320,8 +320,6 @@   where mapper = ASTMapper { mapOnExp = pure                            , mapOnName = pure                            , mapOnQualName = pure . qual-                           , mapOnType = pure-                           , mapOnCompType = pure                            , mapOnStructType = pure                            , mapOnPatternType = pure                            }
src/Language/Futhark/TypeChecker/Terms.hs view
@@ -183,7 +183,7 @@ -- | Get the type of an expression, with all type variables -- substituted.  Never call 'typeOf' directly (except in a few -- carefully inspected locations)!-expType :: Exp -> TermTypeM CompType+expType :: Exp -> TermTypeM PatternType expType = normaliseType . typeOf  -- | The state is a set of constraints and a counter for generating@@ -295,7 +295,7 @@      t <- case M.lookup name $ scopeVtable scope of       Nothing -> throwError $ TypeError loc $-                 "Missing component for module " ++ quote (pretty qn) ++ "."+                 "Unknown variable " ++ quote (pretty qn) ++ "."        Just (WasConsumed wloc) -> useAfterConsume (baseName name) loc wloc @@ -304,7 +304,7 @@         | otherwise -> do             (tnames, t') <- instantiateTypeScheme loc tparams t             let qual = qualifyTypeVars outer_env tnames qs-            qual . removeShapeAnnotations <$> normaliseType t'+            qual . anyDimShapeAnnotations <$> normaliseType t'        Just OpaqueF -> do         argtype <- newTypeVar loc "t"@@ -320,7 +320,8 @@         argtype <- newTypeVar loc "t"         mustBeOneOf ts loc argtype         let (pts', rt') = instOverloaded argtype pts rt-        return $ fromStruct $ foldr (Arrow mempty Nothing) rt' pts'+        return $ fromStruct $ vacuousShapeAnnotations $+         foldr (Arrow mempty Nothing) rt' pts'      observe $ Ident name (Info t) loc     return (qn', t)@@ -379,20 +380,19 @@ instantiateTypeScheme loc tparams t = do   let tparams' = filter isTypeParam tparams       tnames = map typeParamName tparams'-  (fresh_tnames, inst_list) <- unzip <$> mapM (instantiateTypeParam loc) tparams'-  let substs = M.fromList $ zip tnames $-               map (Subst . vacuousShapeAnnotations) inst_list-      t' = substTypesAny (`M.lookup` substs) t+  (fresh_tnames, substs) <- unzip <$> mapM (instantiateTypeParam loc) tparams'+  let substs' = M.fromList $ zip tnames substs+      t' = substTypesAny (`M.lookup` substs') t   return (fresh_tnames, t')  -- | Create a new type name and insert it (unconstrained) in the -- substitution map.-instantiateTypeParam :: Monoid as => SrcLoc -> TypeParam -> TermTypeM (VName, TypeBase dim as)+instantiateTypeParam :: Monoid as => SrcLoc -> TypeParam -> TermTypeM (VName, Subst (TypeBase dim as)) instantiateTypeParam loc tparam = do   i <- incCounter   v <- newID $ mkTypeVarName (takeWhile isAlpha (baseString (typeParamName tparam))) i   modifyConstraints $ M.insert v $ NoConstraint (Just l) loc-  return (v, TypeVar mempty Nonunique (typeName v) [])+  return (v, Subst $ TypeVar mempty Nonunique (typeName v) [])   where l = case tparam of TypeParamType x _ _ -> x                            _                   -> Lifted @@ -438,15 +438,15 @@ -- | Determine if two types are identical, ignoring uniqueness. -- Causes a 'TypeError' if they fail to match, and otherwise returns -- one of them.-unifyExpTypes :: Exp -> Exp -> TermTypeM CompType+unifyExpTypes :: Exp -> Exp -> TermTypeM PatternType unifyExpTypes e1 e2 = do   e1_t <- expType e1   e2_t <- expType e2-  unify (srclocOf e2) (toStruct e1_t) (toStruct e2_t)+  unify (srclocOf e2) (toStructural e1_t) (toStructural e2_t)   return $ unifyTypeAliases e1_t e2_t  -- | Assumes that the two types have already been unified.-unifyTypeAliases :: CompType -> CompType -> CompType+unifyTypeAliases :: PatternType -> PatternType -> PatternType unifyTypeAliases t1 t2 =   case (t1, t2) of     (Array als1 u1 et1 shape1, Array als2 u2 et2 _) ->@@ -558,15 +558,15 @@   e' <- checkExp e   t' <- expType e'   unify loc (toStructural t') (toStructural t)-  return $ PatternLit e' (Info (vacuousShapeAnnotations t')) loc+  return $ PatternLit e' (Info t') loc  checkPattern' (PatternLit e NoInfo loc) NoneInferred = do   e' <- checkExp e   t' <- expType e'-  return $ PatternLit e' (Info (vacuousShapeAnnotations t')) loc+  return $ PatternLit e' (Info t') loc  bindPatternNames :: PatternBase NoInfo Name -> TermTypeM a -> TermTypeM a-bindPatternNames = bindSpaced . map asTerm . S.toList . patIdentSet+bindPatternNames = bindSpaced . map asTerm . S.toList . patternIdents   where asTerm v = (Term, identName v)  checkPattern :: UncheckedPattern -> InferredType -> (Pattern -> TermTypeM a)@@ -592,7 +592,7 @@                 | otherwise = BoundV l tparams (in_t `addAliases` S.insert (AliasBound name))               update b = b -              tp' = vacuousShapeAnnotations tp `addAliases` S.insert (AliasBound name)+              tp' = tp `addAliases` S.insert (AliasBound name)           in scope { scopeVtable = M.insert name (BoundV Local [] tp') $                                    adjustSeveral update inedges $                                    scopeVtable scope@@ -649,7 +649,7 @@   Just $ Ident v (Info (Prim (Signed Int32))) loc typeParamIdent _ = Nothing -bindingIdent :: IdentBase NoInfo Name -> CompType -> (Ident -> TermTypeM a)+bindingIdent :: IdentBase NoInfo Name -> PatternType -> (Ident -> TermTypeM a)              -> TermTypeM a bindingIdent (Ident v NoInfo vloc) t m =   bindSpaced [(Term, v)] $ do@@ -658,14 +658,14 @@     binding [ident] $ m ident  bindingPatternGroup :: [UncheckedTypeParam]-                    -> [(UncheckedPattern, InferredType)]+                    -> [UncheckedPattern]                     -> ([TypeParam] -> [Pattern] -> TermTypeM a) -> TermTypeM a bindingPatternGroup tps orig_ps m = do-  checkForDuplicateNames $ map fst orig_ps+  checkForDuplicateNames orig_ps   checkTypeParams tps $ \tps' -> bindingTypeParams tps' $ do-    let descend ps' ((p,t):ps) =-          checkPattern p t $ \p' ->-            binding (S.toList $ patIdentSet p') $ descend (p':ps') ps+    let descend ps' (p:ps) =+          checkPattern p NoneInferred $ \p' ->+            binding (S.toList $ patternIdents p') $ descend (p':ps') ps         descend ps' [] = do           -- Perform an observation of every type parameter.  This           -- prevents unused-name warnings for otherwise unused@@ -684,7 +684,7 @@ bindingPattern tps p t m = do   checkForDuplicateNames [p]   checkTypeParams tps $ \tps' -> bindingTypeParams tps' $-    checkPattern p t $ \p' -> binding (S.toList $ patIdentSet p') $ do+    checkPattern p t $ \p' -> binding (S.toList $ patternIdents p') $ do       -- Perform an observation of every declared dimension.  This       -- prevents unused-name warnings for otherwise unused dimensions.       mapM_ observe $ patternDims p'@@ -727,12 +727,12 @@ -- | @require ts e@ causes a 'TypeError' if @expType e@ is not one of -- the types in @ts@.  Otherwise, simply returns @e@. require :: [PrimType] -> Exp -> TermTypeM Exp-require ts e = do mustBeOneOf ts (srclocOf e) . toStruct =<< expType e+require ts e = do mustBeOneOf ts (srclocOf e) . toStructural =<< expType e                   return e  unifies :: TypeBase () () -> Exp -> TermTypeM Exp unifies t e = do-  unify (srclocOf e) t =<< toStruct <$> expType e+  unify (srclocOf e) t =<< toStructural <$> expType e   return e  -- The closure of a lambda or local function are those variables that@@ -745,7 +745,7 @@                     _ -> False   return $ S.map AliasBound $ S.filter isLocal $     allOccuring closure S.\\-    S.map identName (mconcat (map patIdentSet params))+    S.map identName (mconcat (map patternIdents params))  checkExp :: UncheckedExp -> TermTypeM Exp @@ -755,12 +755,12 @@ checkExp (IntLit val NoInfo loc) = do   t <- newTypeVar loc "t"   mustBeOneOf anyNumberType loc t-  return $ IntLit val (Info t) loc+  return $ IntLit val (Info $ vacuousShapeAnnotations $ fromStruct t) loc  checkExp (FloatLit val NoInfo loc) = do   t <- newTypeVar loc "t"   mustBeOneOf anyFloatType loc t-  return $ FloatLit val (Info t) loc+  return $ FloatLit val (Info $ vacuousShapeAnnotations $ fromStruct t) loc  checkExp (TupLit es loc) =   TupLit <$> mapM checkExp es <*> pure loc@@ -795,14 +795,14 @@   -- multidimensional array literals.   case all_es of     [] -> do et <- newTypeVar loc "t"-             t <- arrayOfM loc et (rank 1) Unique+             t <- arrayOfM loc et (ShapeDecl [AnyDim]) Unique              return $ ArrayLit [] (Info t) loc     e:es -> do       e' <- checkExp e       et <- expType e'       es' <- mapM (unifies (toStructural et) <=< checkExp) es       et' <- normaliseType et-      t <- arrayOfM loc et' (rank 1) Unique+      t <- arrayOfM loc et' (ShapeDecl [AnyDim]) Unique       return $ ArrayLit (e':es') (Info t) loc  checkExp (Range start maybe_step end NoInfo loc) = do@@ -825,24 +825,25 @@    t <- arrayOfM loc start_t (rank 1) Unique -  return $ Range start' maybe_step' end' (Info (t `setAliases` mempty)) loc+  return $ Range start' maybe_step' end'+    (Info (vacuousShapeAnnotations t `setAliases` mempty)) loc -checkExp (Ascript e decl loc) = do+checkExp (Ascript e decl NoInfo loc) = do   decl' <- checkTypeDecl decl   e' <- checkExp e-  t <- toStruct <$> expType e'-  let decl_t = removeShapeAnnotations $ unInfo $ expandedType decl'-  unify loc decl_t t+  t <- expType e'+  let decl_t = unInfo $ expandedType decl'+  unify loc (toStructural decl_t) (toStructural t)    -- We also have to make sure that uniqueness matches.  This is done   -- explicitly, because uniqueness is ignored by unification.   t' <- normaliseType t   decl_t' <- normaliseType decl_t-  unless (t' `subtypeOf` decl_t') $-    typeError loc $ "Type \"" ++ pretty t' ++ " is not a subtype of \"" ++-    pretty decl_t' ++ "\"."+  unless (t' `subtypeOf` anyDimShapeAnnotations decl_t') $+    typeError loc $ "Type " ++ quote (pretty t') ++ " is not a subtype of " +++    quote (pretty decl_t') ++ "." -  return $ Ascript e' decl' loc+  return $ Ascript e' decl' (Info (combineTypeShapes t $ fromStruct decl_t)) loc  checkExp (BinOp op NoInfo (e1,_) (e2,_) NoInfo loc) = do   (op', ftype) <- lookupVar loc op@@ -850,9 +851,9 @@   (e2', e2_arg) <- checkArg e2    (p1_t, rt) <- checkApply loc ftype e1_arg-  (p2_t, rt') <- checkApply loc (removeShapeAnnotations rt) e2_arg+  (p2_t, rt') <- checkApply loc rt e2_arg -  return $ BinOp op' (Info (vacuousShapeAnnotations ftype))+  return $ BinOp op' (Info ftype)     (e1', Info $ toStruct p1_t) (e2', Info $ toStruct p2_t)     (Info rt') loc @@ -871,7 +872,7 @@   return $ If e1' e2' e3' (Info t') loc   where checkCond = do           e1' <- checkExp e1-          unify (srclocOf e1') (Prim Bool) . toStruct =<< expType e1'+          unify (srclocOf e1') (Prim Bool) . toStructural =<< expType e1'           return e1'  checkExp (Parens e loc) =@@ -899,7 +900,7 @@    (qn', t, fields) <- findRootVar (qualQuals qn) (qualLeaf qn) -  foldM checkField (Var qn' (Info $ vacuousShapeAnnotations t) loc) fields+  foldM checkField (Var qn' (Info t) loc) fields    where findRootVar qs name =           (whenFound <$> lookupVar loc (QualName qs name)) `catchError` notFound qs name@@ -929,7 +930,7 @@   (t1, rt) <- checkApply loc t arg   return $ Apply e1' e2' (Info $ diet t1) (Info rt) loc -checkExp (LetPat tparams pat e body loc) = do+checkExp (LetPat tparams pat e body NoInfo loc) = do   noTypeParamsPermitted tparams   sequentially (checkExp e) $ \e' e_occs -> do     -- Not technically an ascription, but we want the pattern to have@@ -940,9 +941,10 @@         let msg = "of value computed with consumption at " ++ locStr (location c)         in zeroOrderType loc msg t       _ -> return ()-    bindingPattern tparams pat (Ascribed $ vacuousShapeAnnotations t) $ \tparams' pat' -> do+    bindingPattern tparams pat (Ascribed $ anyDimShapeAnnotations t) $ \tparams' pat' -> do       body' <- checkExp body-      return $ LetPat tparams' pat' e' body' loc+      body_t <- unscopeType (S.map identName $ patternIdents pat') <$> expType body'+      return $ LetPat tparams' pat' e' body' (Info body_t) loc  checkExp (LetFun name (tparams, params, maybe_retdecl, NoInfo, e) body loc) =   sequentially (checkFunDef' (name, maybe_retdecl, tparams, params, e, loc)) $@@ -959,13 +961,11 @@      return $ LetFun name' (tparams', params', maybe_retdecl', Info rettype, e') body' loc -checkExp (LetWith dest src idxes ve body loc) = do+checkExp (LetWith dest src idxes ve body NoInfo loc) = do   (t, _) <- newArrayType (srclocOf src) "src" $ length idxes   let elemt = stripArray (length $ filter isFix idxes) t   sequentially (checkIdent src) $ \src' _ -> do-    let src'' = Var (qualName $ identName src')-                    (vacuousShapeAnnotations <$> identType src')-                    (srclocOf src)+    let src'' = Var (qualName $ identName src') (identType src') (srclocOf src)     void $ unifies t src''      unless (unique $ unInfo $ identType src') $@@ -988,7 +988,8 @@        bindingIdent dest (unInfo (identType src') `setAliases` S.empty) $ \dest' -> do         body' <- consuming src' $ checkExp body-        return $ LetWith dest' src' idxes' ve' body' loc+        body_t <- unscopeType (S.singleton $ identName dest') <$> expType body'+        return $ LetWith dest' src' idxes' ve' body' (Info body_t) loc   where isFix DimFix{} = True         isFix _        = False @@ -1019,15 +1020,16 @@   ve' <- checkExp ve   a <- expType src'   r <- foldM (flip $ mustHaveField loc) a fields-  unify loc (toStruct r) . toStruct =<< expType ve'-  return $ RecordUpdate src' fields ve'-    (Info $ vacuousShapeAnnotations $ fromStruct a) loc+  unify loc (toStructural r) . toStructural =<< expType ve'+  return $ RecordUpdate src' fields ve' (Info $ fromStruct a) loc  checkExp (Index e idxes NoInfo loc) = do   (t, _) <- newArrayType (srclocOf e) "e" $ length idxes   e' <- unifies t =<< checkExp e   idxes' <- mapM checkDimIndex idxes-  t' <- stripArray (length $ filter isFix idxes) <$> normaliseType (typeOf e')+  t' <- anyDimShapeAnnotations .+        stripArray (length $ filter isFix idxes) <$>+        normaliseType (typeOf e')   return $ Index e' idxes' (Info t') loc   where isFix DimFix{} = True         isFix _        = False@@ -1040,34 +1042,30 @@   e2' <- checkExp e2   return $ Assert e1' e2' (Info (pretty e1)) loc -checkExp Map{} = error "Map nodes should not appear in source program"-checkExp Reduce{} = error "Reduce nodes should not appear in source program"-checkExp GenReduce{} = error "GenReduce nodes should not appear in source program"-checkExp Scan{} = error "Scan nodes should not appear in source program"-checkExp Filter{} = error "Filter nodes should not appear in source program"-checkExp Partition{} = error "Partition nodes should not appear in source program"-checkExp Stream{} = error "Stream nodes should not appear in source program"--checkExp (Lambda tparams params body maybe_retdecl NoInfo loc) =+checkExp (Lambda tparams params body rettype_te NoInfo loc) =   removeSeminullOccurences $-  bindingPatternGroup tparams (zip params $ repeat NoneInferred) $ \tparams' params' -> do-    maybe_retdecl' <- traverse checkTypeDecl maybe_retdecl-    (body', closure) <- tapOccurences $ noUnique $-                        checkFunBody body (unInfo . expandedType <$> maybe_retdecl') loc+  bindingPatternGroup tparams params $ \tparams' params' -> do+    rettype_checked <- traverse checkTypeExp rettype_te+    let declared_rettype =+          case rettype_checked of Just (_, st, _) -> Just st+                                  Nothing -> Nothing+    (body', closure) <-+      tapOccurences $ noUnique $ checkFunBody body declared_rettype loc     body_t <- expType body'-    let (maybe_retdecl'', rettype) =-          case maybe_retdecl' of-            Just retdecl'@(TypeDecl _ (Info st)) -> (Just retdecl', st)+    let (rettype', rettype_st) =+          case rettype_checked of+            Just (te, st, _) -> (Just te, st)             Nothing -> (Nothing, inferReturnUniqueness params' body_t)      checkGlobalAliases params' body_t loc      closure' <- lexicalClosure params' closure-    return $ Lambda tparams' params' body' maybe_retdecl'' (Info (closure', rettype)) loc +    return $ Lambda tparams' params' body' rettype' (Info (closure', rettype_st)) loc+ checkExp (OpSection op _ loc) = do   (op', ftype) <- lookupVar loc op-  return $ OpSection op' (Info $ vacuousShapeAnnotations ftype) loc+  return $ OpSection op' (Info ftype) loc  checkExp (OpSectionLeft op _ e _ _ loc) = do   (op', ftype) <- lookupVar loc op@@ -1075,7 +1073,7 @@   (t1, rt) <- checkApply loc ftype e_arg   case rt of     Arrow _ _ t2 rettype ->-      return $ OpSectionLeft op' (Info (vacuousShapeAnnotations ftype)) e'+      return $ OpSectionLeft op' (Info ftype) e'       (Info $ toStruct t1, Info $ toStruct t2) (Info rettype) loc     _ -> typeError loc $          "Operator section with invalid operator of type " ++ pretty ftype@@ -1087,7 +1085,7 @@     Arrow as1 m1 t1 (Arrow as2 m2 t2 ret) -> do       (t2', Arrow _ _ t1' rettype) <-         checkApply loc (Arrow as2 m2 t2 (Arrow as1 m1 t1 ret)) e_arg-      return $ OpSectionRight op' (Info (vacuousShapeAnnotations ftype)) e'+      return $ OpSectionRight op' (Info ftype) e'         (Info $ toStruct t1', Info $ toStruct t2') (Info rettype) loc     _ -> typeError loc $          "Operator section with invalid operator of type " ++ pretty ftype@@ -1115,7 +1113,7 @@    merge_t <- do     merge_t <- expType mergeexp'-    return $ Ascribed $ vacuousShapeAnnotations $ merge_t `setAliases` mempty+    return $ Ascribed $ anyDimShapeAnnotations $ merge_t `setAliases` mempty    -- First we do a basic check of the loop body to figure out which of   -- the merge parameters are being consumed.  For this, we first need@@ -1144,7 +1142,7 @@         t <- expType e'         case t of           _ | Just t' <- peelArray 1 t ->-                bindingPattern [] xpat (Ascribed $ vacuousShapeAnnotations t') $ \_ xpat' ->+                bindingPattern [] xpat (Ascribed t') $ \_ xpat' ->                 noUnique $ bindingPattern tparams mergepat merge_t $                 \tparams' mergepat' -> onlySelfAliasing $ tapOccurences $ do                   loopbody' <- checkExp loopbody@@ -1185,7 +1183,7 @@    where     convergePattern pat body_cons body_t body_loc = do-      let consumed_merge = S.map identName (patIdentSet pat) `S.intersection`+      let consumed_merge = S.map identName (patternIdents pat) `S.intersection`                            body_cons           uniquePat (Wildcard (Info t) wloc) =             Wildcard (Info $ t `setUniqueness` Nonunique) wloc@@ -1211,7 +1209,7 @@           pat' = uniquePat pat        -- Now check that the loop returned the right type.-      unify body_loc (toStruct body_t) $ toStruct $ patternType pat'+      unify body_loc (toStructural body_t) $ toStructural $ patternType pat'       body_t' <- normaliseType body_t       pat_t <- normaliseType $ patternType pat'       unless (body_t' `subtypeOf` pat_t) $@@ -1272,25 +1270,25 @@     zeroOrderType loc "returned from pattern match" t     return $ Match e' cs' (Info t) loc -checkCases :: CompType+checkCases :: PatternType            -> CaseBase NoInfo Name            -> [CaseBase NoInfo Name]-           -> TermTypeM ([CaseBase Info VName], CompType)+           -> TermTypeM ([CaseBase Info VName], PatternType) checkCases mt c [] = do   (c', t) <- checkCase mt c   return ([c'], t) checkCases mt c (c2:cs) = do   (((c', c_t), (cs', cs_t)), dflow) <-     tapOccurences $ checkCase mt c `alternative` checkCases mt c2 cs-  unify (srclocOf c) (toStruct c_t) (toStruct cs_t)+  unify (srclocOf c) (toStructural c_t) (toStructural cs_t)   let t = unifyTypeAliases c_t cs_t `addAliases`         (`S.difference` S.map AliasBound (allConsumed dflow))   return (c':cs', t) -checkCase :: CompType -> CaseBase NoInfo Name-          -> TermTypeM (CaseBase Info VName, CompType)+checkCase :: PatternType -> CaseBase NoInfo Name+          -> TermTypeM (CaseBase Info VName, PatternType) checkCase mt (CasePat p caseExp loc) =-  bindingPattern [] p (Ascribed $ vacuousShapeAnnotations mt) $ \_ p' -> do+  bindingPattern [] p (Ascribed mt) $ \_ p' -> do     caseExp' <- checkExp caseExp     caseType <- expType caseExp'     return (CasePat p' caseExp' loc, caseType)@@ -1355,8 +1353,6 @@                            \e' -> checkUnmatched' e' >> return e'                        , mapOnName        = pure                        , mapOnQualName    = pure-                       , mapOnType        = pure-                       , mapOnCompType    = pure                        , mapOnStructType  = pure                        , mapOnPatternType = pure                        }@@ -1377,7 +1373,7 @@         localUnmatched :: [Pattern] -> [Unmatched Pattern]         localUnmatched [] = []         localUnmatched ps'@(p':_) =-          case vacuousShapeAnnotations $ patternType p'  of+          case patternType p'  of             Enum cs'' ->               let matched = nub $ mapMaybe (pExp >=> constr) ps'               in map (UnmatchedEnum . buildEnum (Enum cs'')) $ cs'' \\ matched@@ -1400,7 +1396,7 @@         pExp _ = Nothing          constr (VConstr0 c _ _) = Just c-        constr (Ascript e' _ _)  = constr e'+        constr (Ascript e' _ _ _)  = constr e'         constr _ = Nothing          isPatternLit PatternLit{} = True@@ -1418,7 +1414,7 @@         bool _ = Nothing          buildEnum t c =-          PatternLit (VConstr0 c (Info t) noLoc) (Info (vacuousShapeAnnotations t)) noLoc+          PatternLit (VConstr0 c (Info t) noLoc) (Info t) noLoc         buildBool t b =           PatternLit (Literal (BoolValue b) noLoc) (Info (vacuousShapeAnnotations t)) noLoc         buildId t n =@@ -1449,9 +1445,9 @@   occur $ m1flow `seqOccurences` m2flow   return b -type Arg = (CompType, Occurences, SrcLoc)+type Arg = (PatternType, Occurences, SrcLoc) -argType :: Arg -> CompType+argType :: Arg -> PatternType argType (t, _, _) = t  checkArg :: UncheckedExp -> TermTypeM (Exp, Arg)@@ -1460,10 +1456,10 @@   arg_t <- expType arg'   return (arg', (arg_t, dflow, srclocOf arg')) -checkApply :: SrcLoc -> CompType -> Arg+checkApply :: SrcLoc -> PatternType -> Arg            -> TermTypeM (PatternType, PatternType) checkApply loc (Arrow as _ tp1 tp2) (argtype, dflow, argloc) = do-  unify argloc (toStruct tp1) (toStruct argtype)+  unify argloc (toStructural tp1) (toStructural argtype)    -- Perform substitutions of instantiated variables in the types.   tp1' <- normaliseType tp1@@ -1482,12 +1478,12 @@     _ -> return ()    occur $ dflow `seqOccurences` occurs-  let tp2'' = vacuousShapeAnnotations $ returnType tp2' (diet tp1') argtype'-  return (vacuousShapeAnnotations tp1', tp2'')+  let tp2'' = anyDimShapeAnnotations $ returnType tp2' (diet tp1') argtype'+  return (tp1', tp2'')  checkApply loc tfun@TypeVar{} arg = do   tv <- newTypeVar loc "b"-  unify loc (toStruct tfun) $ Arrow mempty Nothing (toStruct (argType arg)) tv+  unify loc (toStructural tfun) $ Arrow mempty Nothing (toStructural (argType arg)) tv   constraints <- getConstraints   checkApply loc (applySubst (`lookupSubst` constraints) tfun) arg @@ -1496,7 +1492,45 @@   "Attempt to apply an expression of type " ++ pretty ftype ++   " to an argument of type " ++ pretty (argType arg) ++ "." -consumeArg :: SrcLoc -> CompType -> Diet -> TermTypeM [Occurence]+-- | @returnType ret_type arg_diet arg_type@ gives result of applying+-- an argument the given types to a function with the given return+-- type, consuming the argument with the given diet.+returnType :: PatternType+           -> Diet+           -> PatternType+           -> PatternType+returnType (Array _ Unique et shape) _ _ =+  Array mempty Unique et shape+returnType (Array als Nonunique et shape) d arg =+  Array (als<>arg_als) Unique et shape -- Intentional!+  where arg_als = aliases $ maskAliases arg d+returnType (Record fs) d arg =+  Record $ fmap (\et -> returnType et d arg) fs+returnType (Prim t) _ _ = Prim t+returnType (TypeVar _ Unique t targs) _ _ =+  TypeVar mempty Unique t targs+returnType (TypeVar als Nonunique t targs) d arg =+  TypeVar (als<>arg_als) Unique t targs -- Intentional!+  where arg_als = aliases $ maskAliases arg d+returnType (Arrow _ v t1 t2) d arg =+  Arrow als v (t1 `setAliases` mempty) (t2 `setAliases` als)+  where als = aliases $ maskAliases arg d+returnType (Enum cs) _ _ = Enum cs++-- | @t `maskAliases` d@ removes aliases (sets them to 'mempty') from+-- the parts of @t@ that are denoted as 'Consumed' by the 'Diet' @d@.+maskAliases :: Monoid as =>+               TypeBase shape as+            -> Diet+            -> TypeBase shape as+maskAliases t Consume = t `setAliases` mempty+maskAliases t Observe = t+maskAliases (Record ets) (RecordDiet ds) =+  Record $ M.intersectionWith maskAliases ets ds+maskAliases t FuncDiet{} = t+maskAliases _ _ = error "Invalid arguments passed to maskAliases."++consumeArg :: SrcLoc -> PatternType -> Diet -> TermTypeM [Occurence] consumeArg loc (Record ets) (RecordDiet ds) =   concat . M.elems <$> traverse (uncurry $ consumeArg loc) (M.intersectionWith (,) ets ds) consumeArg loc (Array _ Nonunique _ _) Consume =@@ -1522,8 +1556,8 @@ checkOneExp :: UncheckedExp -> TypeM ([TypeParam], Exp) checkOneExp e = fmap fst . runTermTypeM $ do   e' <- checkExp e-  let t = vacuousShapeAnnotations $ toStruct $ typeOf e'-  tparams <- letGeneralise [] [t] mempty+  let t = toStruct $ typeOf e'+  tparams <- letGeneralise [] t mempty   fixOverloadedTypes   e'' <- updateExpTypes e'   return (tparams, e'')@@ -1603,7 +1637,7 @@    then_substs <- getConstraints -  bindingPatternGroup tparams (zip params $ repeat NoneInferred) $ \tparams' params' -> do+  bindingPatternGroup tparams params $ \tparams' params' -> do     maybe_retdecl' <- traverse checkTypeExp maybe_retdecl      body' <- checkFunBody body ((\(_,t,_)->t) <$> maybe_retdecl') (maybe loc srclocOf maybe_retdecl)@@ -1618,14 +1652,17 @@          when (null params) $ nothingMustBeUnique loc rettype_structural +        warnOnDubiousShapeAnnotations loc params'' retdecl_type+         return (Just retdecl', retdecl_type)       Nothing         | null params ->-            return (Nothing, vacuousShapeAnnotations $ toStruct $ body_t `setUniqueness` Nonunique)+            return (Nothing, toStruct $ body_t `setUniqueness` Nonunique)         | otherwise ->             return (Nothing, inferReturnUniqueness params'' body_t) -    tparams'' <- letGeneralise tparams' (rettype : map patternStructType params'') then_substs+    let fun_t = foldFunType (map patternStructType params'') rettype+    tparams'' <- letGeneralise tparams' fun_t then_substs      bindSpaced [(Term, fname)] $ do       fname' <- checkName Term fname loc@@ -1651,7 +1688,7 @@           forM_ params' $ \p ->           let consumedNonunique p' =                 not (unique $ unInfo $ identType p') && (identName p' `S.member` names)-          in case find consumedNonunique $ S.toList $ patIdentSet p of+          in case find consumedNonunique $ S.toList $ patternIdents p of                Just p' ->                  returnAliased fname (baseName $ identName p') loc                Nothing ->@@ -1664,7 +1701,23 @@         returnAliasing expected got =           [(uniqueness expected, S.map aliasVar $ aliases got)] -checkGlobalAliases :: [Pattern] -> CompType -> SrcLoc -> TermTypeM ()+warnOnDubiousShapeAnnotations :: SrcLoc -> [Pattern] -> StructType -> TermTypeM ()+warnOnDubiousShapeAnnotations loc params rettype =+  onDubiousNames $ S.filter patternNameButNotParamName $+  mconcat $ map typeDimNames $+  rettype : map patternStructType params+  where param_names = S.fromList $ mapMaybe (fst . patternParam) params+        all_pattern_names = S.map identName $ mconcat $ map patternIdents params+        patternNameButNotParamName v = v `S.member` all_pattern_names && not (v `S.member` param_names)+        onDubiousNames dubious+          | S.null dubious = return ()+          | otherwise = warn loc $ unlines+                        [ "Size annotations in parameter and/or return type refers to the following names,"+                        , "which will not be visible to the caller, because they are nested in tuples or records:"+                        , "  " ++ intercalate ", " (map (quote . prettyName) $ S.toList dubious)+                        , "To eliminate this warning, make these names parameters on their own."]++checkGlobalAliases :: [Pattern] -> PatternType -> SrcLoc -> TermTypeM () checkGlobalAliases params body_t loc = do   vtable <- asks scopeVtable   let isLocal v = case v `M.lookup` vtable of@@ -1672,7 +1725,7 @@                     _ -> False   let als = filter (not . isLocal) $ S.toList $             boundArrayAliases body_t `S.difference`-            S.map identName (mconcat (map patIdentSet params))+            S.map identName (mconcat (map patternIdents params))   case als of     v:_ | not $ null params ->       typeError loc $@@ -1683,7 +1736,7 @@       return ()  -inferReturnUniqueness :: [Pattern] -> CompType -> StructType+inferReturnUniqueness :: [Pattern] -> PatternType -> StructType inferReturnUniqueness params t =   let forbidden = aliasesMultipleTimes t       uniques = uniqueParamNames params@@ -1695,10 +1748,10 @@             toStruct t'         | otherwise =             toStruct $ t' `setUniqueness` Nonunique-  in vacuousShapeAnnotations $ delve t+  in delve t  -- An alias inhibits uniqueness if it is used in disjoint values.-aliasesMultipleTimes :: CompType -> Names+aliasesMultipleTimes :: PatternType -> Names aliasesMultipleTimes = S.fromList . map fst . filter ((>1) . snd) . M.toList . delve   where delve (Record fs) =           foldl' (M.unionWith (+)) mempty $ map delve $ M.elems fs@@ -1709,9 +1762,9 @@ uniqueParamNames =   S.fromList . map identName   . filter (unique . unInfo . identType)-  . S.toList . mconcat . map patIdentSet+  . S.toList . mconcat . map patternIdents -boundArrayAliases :: CompType -> S.Set VName+boundArrayAliases :: PatternType -> S.Set VName boundArrayAliases (Array als _ _ _) = boundAliases als boundArrayAliases Prim{} = mempty boundArrayAliases Enum{} = mempty@@ -1734,10 +1787,10 @@         bad = typeError loc "A top-level constant cannot have a unique type."  letGeneralise :: [TypeParam]-              -> [StructType]+              -> StructType               -> Constraints               -> TermTypeM [TypeParam]-letGeneralise tparams ts then_substs = do+letGeneralise tparams t then_substs = do   now_substs <- getConstraints   -- Candidates for let-generalisation are those type variables that   --@@ -1758,7 +1811,7 @@                             overloadedTypeVars now_substs    let new_substs = M.filterWithKey (\k _ -> not (k `S.member` keep_type_variables)) now_substs-  tparams' <- closeOverTypes new_substs tparams ts+  tparams' <- closeOverTypes new_substs tparams t    -- We keep those type variables that were not closed over by   -- let-generalisation.@@ -1780,12 +1833,12 @@       void $ unifies rettype_structural body'       -- We also have to make sure that uniqueness matches.  This is done       -- explicitly, because uniqueness is ignored by unification.-      rettype_structural' <- normaliseType rettype_structural+      rettype' <- normaliseType rettype       body_t <- expType body'-      unless (body_t `subtypeOf` rettype_structural') $+      unless (body_t `subtypeOf` anyDimShapeAnnotations rettype') $         typeError (srclocOf body) $ "Body type " ++ quote (pretty body_t) ++         " is not a subtype of annotated type " ++-        quote (pretty rettype_structural') ++ "."+        quote (pretty rettype') ++ "."      Nothing -> return () @@ -1795,14 +1848,14 @@ -- the constraints, and produce type parameters that close over them. -- Produce an error if the given list of type parameters is non-empty, -- yet does not cover all type variables in the type.-closeOverTypes :: Constraints -> [TypeParam] -> [StructType] -> TermTypeM [TypeParam]-closeOverTypes substs tparams ts =+closeOverTypes :: Constraints -> [TypeParam] -> StructType -> TermTypeM [TypeParam]+closeOverTypes substs tparams t =   case tparams of     [] -> fmap catMaybes $ mapM closeOver $ M.toList substs'     _ -> do mapM_ checkClosedOver $ M.toList substs'             return tparams   where substs' = M.filterWithKey (\k _ -> k `S.member` visible) substs-        visible = mconcat (map typeVars ts)+        visible = typeVars t          checkClosedOver (k, v)           | not (canBeClosedOver v) ||@@ -1922,8 +1975,6 @@       tv = ASTMapper { mapOnExp         = astMap tv                      , mapOnName        = pure                      , mapOnQualName    = pure-                     , mapOnType        = pure . applySubst look-                     , mapOnCompType    = pure . applySubst look                      , mapOnStructType  = pure . applySubst look                      , mapOnPatternType = pure . applySubst look                      }
src/Language/Futhark/TypeChecker/Types.hs view
@@ -16,7 +16,6 @@   , TypeSub(..)   , TypeSubs   , substituteTypes-  , substituteTypesInBoundV    , Subst(..)   , Substitutable(..)@@ -419,10 +418,6 @@         substituteInDim (NamedDim v)           | Just (DimSub d) <- M.lookup (qualLeaf v) substs = d         substituteInDim d = d--substituteTypesInBoundV :: TypeSubs -> BoundV -> BoundV-substituteTypesInBoundV substs (BoundV tps t) =-  BoundV tps (substituteTypes substs t)  applyType :: Monoid als =>              [TypeParam] -> TypeBase (DimDecl VName) als -> [StructTypeArg] -> TypeBase (DimDecl VName) als
src/Language/Futhark/TypeChecker/Unify.hs view
@@ -151,11 +151,11 @@             unifyTypeArg _ _ = typeError loc               "Cannot unify a type argument with a dimension argument (or vice versa)." -applySubstInConstraint :: VName -> TypeBase () () -> Constraint -> Constraint-applySubstInConstraint vn tp (Constraint t loc) =-  Constraint (applySubst (flip M.lookup $ M.singleton vn $ Subst tp) t) loc-applySubstInConstraint vn tp (HasFields fs loc) =-  HasFields (M.map (applySubst (flip M.lookup $ M.singleton vn $ Subst tp)) fs) loc+applySubstInConstraint :: VName -> Subst (TypeBase () ()) -> Constraint -> Constraint+applySubstInConstraint vn subst (Constraint t loc) =+  Constraint (applySubst (flip M.lookup $ M.singleton vn subst) t) loc+applySubstInConstraint vn subst (HasFields fs loc) =+  HasFields (M.map (applySubst (flip M.lookup $ M.singleton vn subst)) fs) loc applySubstInConstraint _ _ (NoConstraint l loc) = NoConstraint l loc applySubstInConstraint _ _ (Overloaded ts loc) = Overloaded ts loc applySubstInConstraint _ _ (Equality loc) = Equality loc@@ -169,7 +169,7 @@     then typeError loc $ "Occurs check: cannot instantiate " ++          prettyName vn ++ " with " ++ pretty tp'     else do modifyConstraints $ M.insert vn $ Constraint tp' loc-            modifyConstraints $ M.map $ applySubstInConstraint vn tp'+            modifyConstraints $ M.map $ applySubstInConstraint vn $ Subst tp'             case M.lookup vn constraints of               Just (NoConstraint (Just Unlifted) unlift_loc) ->                 zeroOrderType loc ("used at " ++ locStr unlift_loc) tp'