packages feed

futhark 0.24.1 → 0.24.2

raw patch · 128 files changed

+2286/−1239 lines, 128 filesdep ~futhark-serverPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: futhark-server

API changes (from Hackage documentation)

- Futhark.IR.Aliases: instance (Futhark.IR.Prop.ASTRep rep, Futhark.IR.Prop.Aliases.AliasedOp (Futhark.IR.Rep.OpC rep (Futhark.IR.Aliases.Aliases rep))) => Futhark.IR.Pretty.PrettyRep (Futhark.IR.Aliases.Aliases rep)
- Futhark.IR.Aliases: instance (Futhark.IR.Prop.ASTRep rep, Futhark.IR.Prop.Aliases.AliasedOp (Futhark.IR.Rep.OpC rep (Futhark.IR.Aliases.Aliases rep))) => Futhark.IR.Prop.ASTRep (Futhark.IR.Aliases.Aliases rep)
- Futhark.Optimise.Simplify.Rep: instance Futhark.Optimise.Simplify.Rep.Informing rep => Futhark.IR.Pretty.PrettyRep (Futhark.Optimise.Simplify.Rep.Wise rep)
- Futhark.Optimise.Simplify.Rep: instance Futhark.Optimise.Simplify.Rep.Informing rep => Futhark.IR.Prop.ASTRep (Futhark.Optimise.Simplify.Rep.Wise rep)
- Futhark.Optimise.Simplify.Rep: instance Futhark.Optimise.Simplify.Rep.Informing rep => Futhark.IR.Rep.RepTypes (Futhark.Optimise.Simplify.Rep.Wise rep)
- Futhark.Util: pairs :: [a] -> [(a, a)]
- Futhark.Util: unpairs :: [(a, a)] -> [a]
- Futhark.Util.Pretty: semisep :: [Doc a] -> Doc a
+ Futhark.IR.Aliases: instance (Futhark.IR.Prop.ASTRep rep, Futhark.IR.Prop.Aliases.AliasedOp (Futhark.IR.Rep.OpC rep (Futhark.IR.Aliases.Aliases rep)), Futhark.IR.Prop.IsOp (Futhark.IR.Rep.OpC rep (Futhark.IR.Aliases.Aliases rep))) => Futhark.IR.Prop.ASTRep (Futhark.IR.Aliases.Aliases rep)
+ Futhark.IR.Aliases: instance (Futhark.IR.Prop.ASTRep rep, Futhark.IR.Prop.Aliases.AliasedOp (Futhark.IR.Rep.OpC rep (Futhark.IR.Aliases.Aliases rep)), Prettyprinter.Internal.Pretty (Futhark.IR.Rep.OpC rep (Futhark.IR.Aliases.Aliases rep))) => Futhark.IR.Pretty.PrettyRep (Futhark.IR.Aliases.Aliases rep)
+ Futhark.IR.Syntax.Core: instance GHC.Base.Functor (Futhark.IR.Syntax.Core.TypeBase shape)
+ Futhark.Optimise.Simplify.Rep: instance (Futhark.Optimise.Simplify.Rep.Informing rep, Futhark.IR.Prop.IsOp (Futhark.IR.Rep.OpC rep (Futhark.Optimise.Simplify.Rep.Wise rep))) => Futhark.IR.Prop.ASTRep (Futhark.Optimise.Simplify.Rep.Wise rep)
+ Futhark.Optimise.Simplify.Rep: instance (Futhark.Optimise.Simplify.Rep.Informing rep, GHC.Classes.Ord (Futhark.IR.Rep.OpC rep (Futhark.Optimise.Simplify.Rep.Wise rep)), GHC.Classes.Eq (Futhark.IR.Rep.OpC rep (Futhark.Optimise.Simplify.Rep.Wise rep)), GHC.Show.Show (Futhark.IR.Rep.OpC rep (Futhark.Optimise.Simplify.Rep.Wise rep)), Futhark.IR.Prop.IsOp (Futhark.IR.Rep.OpC rep (Futhark.Optimise.Simplify.Rep.Wise rep)), Prettyprinter.Internal.Pretty (Futhark.IR.Rep.OpC rep (Futhark.Optimise.Simplify.Rep.Wise rep))) => Futhark.IR.Rep.RepTypes (Futhark.Optimise.Simplify.Rep.Wise rep)
+ Futhark.Optimise.Simplify.Rep: instance (Futhark.Optimise.Simplify.Rep.Informing rep, Prettyprinter.Internal.Pretty (Futhark.IR.Rep.OpC rep (Futhark.Optimise.Simplify.Rep.Wise rep))) => Futhark.IR.Pretty.PrettyRep (Futhark.Optimise.Simplify.Rep.Wise rep)
+ Language.Futhark.Syntax: instance GHC.Base.Functor (Language.Futhark.Syntax.RetTypeBase dim)
+ Language.Futhark.Syntax: instance GHC.Base.Functor (Language.Futhark.Syntax.ScalarTypeBase dim)
+ Language.Futhark.Syntax: instance GHC.Base.Functor (Language.Futhark.Syntax.TypeBase dim)
- Futhark.IR.GPU: identitySOACMapper :: Monad m => SOACMapper rep rep m
+ Futhark.IR.GPU: identitySOACMapper :: forall rep m. Monad m => SOACMapper rep rep m
- Futhark.IR.MC: identitySOACMapper :: Monad m => SOACMapper rep rep m
+ Futhark.IR.MC: identitySOACMapper :: forall rep m. Monad m => SOACMapper rep rep m
- Futhark.IR.SOACS.SOAC: identitySOACMapper :: Monad m => SOACMapper rep rep m
+ Futhark.IR.SOACS.SOAC: identitySOACMapper :: forall rep m. Monad m => SOACMapper rep rep m
- Futhark.IR.Traversals: identityMapper :: Monad m => Mapper rep rep m
+ Futhark.IR.Traversals: identityMapper :: forall rep m. Monad m => Mapper rep rep m
- Futhark.IR.Traversals: identityWalker :: Monad m => Walker rep m
+ Futhark.IR.Traversals: identityWalker :: forall rep m. Monad m => Walker rep m
- Language.Futhark.Interpreter.Values: structTypeShape :: Map VName ValueShape -> StructType -> Shape (Maybe Int64)
+ Language.Futhark.Interpreter.Values: structTypeShape :: StructType -> Shape (Maybe Int64)
- Language.Futhark.Interpreter.Values: typeShape :: Map VName (Shape d) -> TypeBase d () -> Shape d
+ Language.Futhark.Interpreter.Values: typeShape :: TypeBase d () -> Shape d
- Language.Futhark.Parser.Monad: applyExp :: [UncheckedExp] -> ParserMonad UncheckedExp
+ Language.Futhark.Parser.Monad: applyExp :: NonEmpty UncheckedExp -> ParserMonad UncheckedExp

Files

docs/c-api.rst view
@@ -332,7 +332,8 @@     * If ``*p`` is ``NULL``, the function will allocate sufficient      storage with ``malloc()``, serialise the value, and write the-     address of the byte representation to ``*p``.+     address of the byte representation to ``*p``.  The caller gains+     ownership of this allocation and is responsible for freeing it.     * Otherwise, the serialised representation of the value will be      stored at ``*p``, which *must* have room for at least ``*n``@@ -380,7 +381,7 @@ .. c:function:: int futhark_new_opaque_t(struct futhark_context *ctx, struct futhark_opaque_t **out, const struct futhark_opaque_t2 *bar, const struct futhark_opaque_t1 *foo);     Construct a record in ``*out`` which has the given values for the-   ``bar`` and ``foo`` fields.  The parameter ordering constitutes the+   ``bar`` and ``foo`` fields.  The parameters are the    fields in alphabetic order.  Tuple fields are named ``vX`` where    ``X`` is an integer.  The resulting record *aliases* the values    provided for ``bar`` and ``foo``, but has its own lifetime, and all@@ -416,8 +417,8 @@    sure to call :c:func:`futhark_context_sync` before using the value    of ``out0``. -Errors are indicated by a nonzero return value.  On error, nothing is-written to the *out*-parameters.+Errors are indicated by a nonzero return value.  On error, the+*out*-parameters are not touched.  The precise semantics of the return value depends on the backend.  For the sequential C backend, errors will always be available when the@@ -618,6 +619,10 @@    * A list of all *outputs*, including their type (as a name) and     *whether they are unique*.++  * A list of all *tuning parameters* that can influence the execution+    of this entry point.  These are not necessarily unique to the+    entry point.  * A mapping from the name of each non-scalar type to: 
docs/conf.py view
@@ -19,43 +19,49 @@ from pygments.lexer import RegexLexer, bygroups from pygments import token from pygments import unistring as uni-from pygments.token import Text, Comment, Operator, Keyword, Name, String, \-    Number, Punctuation, Whitespace+from pygments.token import (+    Text,+    Comment,+    Operator,+    Keyword,+    Name,+    String,+    Number,+    Punctuation,+    Whitespace,+) from sphinx.highlighting import lexers  # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here.-#sys.path.insert(0, os.path.abspath('.'))+# sys.path.insert(0, os.path.abspath('.'))  # -- General configuration ------------------------------------------------  # If your documentation needs a minimal Sphinx version, state it here.-#needs_sphinx = '1.0'+# needs_sphinx = '1.0'  # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones.-extensions = [-    'sphinx.ext.todo',-    'sphinx.ext.mathjax'-]+extensions = ["sphinx.ext.todo", "sphinx.ext.mathjax"]  # Add any paths that contain templates here, relative to this directory.-templates_path = ['_templates']+templates_path = ["_templates"]  # The suffix of source filenames.-source_suffix = '.rst'+source_suffix = ".rst"  # The encoding of source files.-#source_encoding = 'utf-8-sig'+# source_encoding = 'utf-8-sig'  # The master toctree document.-master_doc = 'index'+master_doc = "index"  # General information about the project.-project = 'Futhark'-copyright = '2013-2020, DIKU, University of Copenhagen'+project = "Futhark"+copyright = "2013-2020, DIKU, University of Copenhagen"  # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the@@ -63,48 +69,52 @@ # # The short X.Y version. + # No reason for a cabal file parser; let's just hack it. def get_version():     # Get cabal file-    cabal_file = open('../futhark.cabal', 'r').read()+    cabal_file = open("../futhark.cabal", "r").read()     # Extract version-    return re.search(r'^version:[ ]*([^ ]*)$', cabal_file, flags=re.MULTILINE).group(1)+    return re.search(+        r"^version:[ ]*([^ ]*)$", cabal_file, flags=re.MULTILINE+    ).group(1) + version = get_version() # The full version, including alpha/beta/rc tags. release = version  # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages.-#language = None+# language = None  # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used:-#today = ''+# today = '' # Else, today_fmt is used as the format for a strftime call.-#today_fmt = '%B %d, %Y'+# today_fmt = '%B %d, %Y'  # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files.-exclude_patterns = ['_build', 'lib']+exclude_patterns = ["_build", "lib"]  # The reST default role (used for this markup: `text`) to use for all # documents.-#default_role = None+# default_role = None  # If true, '()' will be appended to :func: etc. cross-reference text.-#add_function_parentheses = True+# add_function_parentheses = True  # If true, the current module name will be prepended to all description # unit titles (such as .. function::).-#add_module_names = True+# add_module_names = True  # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default.-#show_authors = false+# show_authors = false  # The name of the Pygments (syntax highlighting) style to use.-pygments_style = 'sphinx'+pygments_style = "sphinx"   class FutharkLexer(RegexLexer):@@ -113,105 +123,171 @@      .. versionadded:: 2.8     """-    name = 'Futhark'-    url = 'https://futhark-lang.org/'-    aliases = ['futhark']-    filenames = ['*.fut']-    mimetypes = ['text/x-futhark'] -    num_types = ('i8', 'i16', 'i32', 'i64', 'u8', 'u16', 'u32', 'u64', 'f32', 'f64')+    name = "Futhark"+    url = "https://futhark-lang.org/"+    aliases = ["futhark"]+    filenames = ["*.fut"]+    mimetypes = ["text/x-futhark"] -    other_types = ('bool', )+    num_types = (+        "i8",+        "i16",+        "i32",+        "i64",+        "u8",+        "u16",+        "u32",+        "u64",+        "f32",+        "f64",+    ) -    reserved = ('if', 'then', 'else', 'def', 'let', 'loop', 'in', 'with', 'type',-                'val', 'entry', 'for', 'while', 'do', 'case', 'match',-                'include', 'import', 'module', 'open', 'local', 'assert', '_')+    other_types = ("bool",) -    ascii = ('NUL', 'SOH', '[SE]TX', 'EOT', 'ENQ', 'ACK',-             'BEL', 'BS', 'HT', 'LF', 'VT', 'FF', 'CR', 'S[OI]', 'DLE',-             'DC[1-4]', 'NAK', 'SYN', 'ETB', 'CAN',-             'EM', 'SUB', 'ESC', '[FGRU]S', 'SP', 'DEL')+    reserved = (+        "if",+        "then",+        "else",+        "def",+        "let",+        "loop",+        "in",+        "with",+        "type",+        "val",+        "entry",+        "for",+        "while",+        "do",+        "case",+        "match",+        "include",+        "import",+        "module",+        "open",+        "local",+        "assert",+        "_",+    ) -    num_postfix = r'(%s)?' % '|'.join(num_types)+    ascii = (+        "NUL",+        "SOH",+        "[SE]TX",+        "EOT",+        "ENQ",+        "ACK",+        "BEL",+        "BS",+        "HT",+        "LF",+        "VT",+        "FF",+        "CR",+        "S[OI]",+        "DLE",+        "DC[1-4]",+        "NAK",+        "SYN",+        "ETB",+        "CAN",+        "EM",+        "SUB",+        "ESC",+        "[FGRU]S",+        "SP",+        "DEL",+    ) -    identifier_re = '[a-zA-Z_][a-zA-Z_0-9\']*'+    num_postfix = r"(%s)?" % "|".join(num_types) +    identifier_re = "[a-zA-Z_][a-zA-Z_0-9']*"+     # opstart_re = '+\-\*/%=\!><\|&\^'      tokens = {-        'root': [-            (r'--(.*?)$', Comment.Single),-            (r'\s+', Whitespace),-            (r'\(\)', Punctuation),-            (r'\b(%s)(?!\')\b' % '|'.join(reserved), Keyword.Reserved),-            (r'\b(%s)(?!\')\b' % '|'.join(num_types + other_types), Keyword.Type),-+        "root": [+            (r"--(.*?)$", Comment.Single),+            (r"\s+", Whitespace),+            (r"\(\)", Punctuation),+            (r"\b(%s)(?!\')\b" % "|".join(reserved), Keyword.Reserved),+            (+                r"\b(%s)(?!\')\b" % "|".join(num_types + other_types),+                Keyword.Type,+            ),             # Identifiers-            (r'#\[([a-zA-Z_\(\) ]*)\]', Comment.Preproc),-            (r'[#!]?(%s\.)*%s' % (identifier_re, identifier_re), Name),--            (r'\\', Operator),-            (r'[-+/%=!><|&*^][-+/%=!><|&*^.]*', Operator),-            (r'[][(),:;`{}?.\']', Punctuation),-+            (r"#\[([a-zA-Z_\(\) ]*)\]", Comment.Preproc),+            (r"[#!]?(%s\.)*%s" % (identifier_re, identifier_re), Name),+            (r"\\", Operator),+            (r"[-+/%=!><|&*^][-+/%=!><|&*^.]*", Operator),+            (r"[][(),:;`{}?.\']", Punctuation),             #  Numbers-            (r'0[xX]_*[\da-fA-F](_*[\da-fA-F])*_*[pP][+-]?\d(_*\d)*' + num_postfix,-             Number.Float),-            (r'0[xX]_*[\da-fA-F](_*[\da-fA-F])*\.[\da-fA-F](_*[\da-fA-F])*'-             r'(_*[pP][+-]?\d(_*\d)*)?' + num_postfix, Number.Float),-            (r'\d(_*\d)*_*[eE][+-]?\d(_*\d)*' + num_postfix, Number.Float),-            (r'\d(_*\d)*\.\d(_*\d)*(_*[eE][+-]?\d(_*\d)*)?' + num_postfix, Number.Float),-            (r'0[bB]_*[01](_*[01])*' + num_postfix, Number.Bin),-            (r'0[xX]_*[\da-fA-F](_*[\da-fA-F])*' + num_postfix, Number.Hex),-            (r'\d(_*\d)*' + num_postfix, Number.Integer),-+            (+                r"0[xX]_*[\da-fA-F](_*[\da-fA-F])*_*[pP][+-]?\d(_*\d)*"+                + num_postfix,+                Number.Float,+            ),+            (+                r"0[xX]_*[\da-fA-F](_*[\da-fA-F])*\.[\da-fA-F](_*[\da-fA-F])*"+                r"(_*[pP][+-]?\d(_*\d)*)?" + num_postfix,+                Number.Float,+            ),+            (r"\d(_*\d)*_*[eE][+-]?\d(_*\d)*" + num_postfix, Number.Float),+            (+                r"\d(_*\d)*\.\d(_*\d)*(_*[eE][+-]?\d(_*\d)*)?" + num_postfix,+                Number.Float,+            ),+            (r"0[bB]_*[01](_*[01])*" + num_postfix, Number.Bin),+            (r"0[xX]_*[\da-fA-F](_*[\da-fA-F])*" + num_postfix, Number.Hex),+            (r"\d(_*\d)*" + num_postfix, Number.Integer),             #  Character/String Literals-            (r"'", String.Char, 'character'),-            (r'"', String, 'string'),+            (r"'", String.Char, "character"),+            (r'"', String, "string"),             #  Special-            (r'\[[a-zA-Z_\d]*\]', Keyword.Type),-            (r'\(\)', Name.Builtin),+            (r"\[[a-zA-Z_\d]*\]", Keyword.Type),+            (r"\(\)", Name.Builtin),         ],-        'character': [+        "character": [             # Allows multi-chars, incorrectly.-            (r"[^\\']'", String.Char, '#pop'),-            (r"\\", String.Escape, 'escape'),-            ("'", String.Char, '#pop'),+            (r"[^\\']'", String.Char, "#pop"),+            (r"\\", String.Escape, "escape"),+            ("'", String.Char, "#pop"),         ],-        'string': [+        "string": [             (r'[^\\"]+', String),-            (r"\\", String.Escape, 'escape'),-            ('"', String, '#pop'),+            (r"\\", String.Escape, "escape"),+            ('"', String, "#pop"),         ],--        'escape': [-            (r'[abfnrtv"\'&\\]', String.Escape, '#pop'),-            (r'\^[][' + uni.Lu + r'@^_]', String.Escape, '#pop'),-            ('|'.join(ascii), String.Escape, '#pop'),-            (r'o[0-7]+', String.Escape, '#pop'),-            (r'x[\da-fA-F]+', String.Escape, '#pop'),-            (r'\d+', String.Escape, '#pop'),-            (r'(\s+)(\\)', bygroups(Whitespace, String.Escape), '#pop'),+        "escape": [+            (r'[abfnrtv"\'&\\]', String.Escape, "#pop"),+            (r"\^[][" + uni.Lu + r"@^_]", String.Escape, "#pop"),+            ("|".join(ascii), String.Escape, "#pop"),+            (r"o[0-7]+", String.Escape, "#pop"),+            (r"x[\da-fA-F]+", String.Escape, "#pop"),+            (r"\d+", String.Escape, "#pop"),+            (r"(\s+)(\\)", bygroups(Whitespace, String.Escape), "#pop"),         ],     } -lexers['futhark'] = FutharkLexer() -highlight_language = 'text'+lexers["futhark"] = FutharkLexer() +highlight_language = "text"+ # A list of ignored prefixes for module index sorting.-#modindex_common_prefix = []+# modindex_common_prefix = []  # If true, keep warnings as "system message" paragraphs in the built documents.-#keep_warnings = false+# keep_warnings = false   # -- Options for HTML output ----------------------------------------------  # The theme to use for HTML and HTML Help pages.  See the documentation for # a list of builtin themes.-html_theme = 'futhark'-html_theme_path = ['_theme']+html_theme = "futhark"+html_theme_path = ["_theme"]  # Theme options are theme-specific and customize the look and feel of a theme # further.  For a list of options available for each theme, see the@@ -219,23 +295,23 @@ html_theme_options = {}  # Add any paths that contain custom themes here, relative to this directory.-#html_theme_path = []+# html_theme_path = []  # The name for this set of Sphinx documents.  If None, it defaults to # "<project> v<release> documentation".-#html_title = None+# html_title = None  # A shorter title for the navigation bar.  Default is the same as html_title.-#html_short_title = None+# html_short_title = None  # The name of an image file (relative to this directory) to place at the top # of the sidebar.-#html_logo = None+# html_logo = None  # The name of an image file (within the static path) to use as favicon of the # docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large.-#html_favicon = None+# html_favicon = None  # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files,@@ -245,93 +321,97 @@ # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation.-#html_extra_path = []+# html_extra_path = []  # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format.-#html_last_updated_fmt = '%b %d, %Y'+# html_last_updated_fmt = '%b %d, %Y'  # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities.-#html_use_smartypants = True+# html_use_smartypants = True  # Custom sidebar templates, maps document names to template names.-html_sidebars = { '**': ['globaltoc.html', 'relations.html', 'sourcelink.html', 'searchbox.html'] }+html_sidebars = {+    "**": [+        "globaltoc.html",+        "relations.html",+        "sourcelink.html",+        "searchbox.html",+    ]+}  # Additional templates that should be rendered to pages, maps page names to # template names.-#html_additional_pages = {}+# html_additional_pages = {}  # If false, no module index is generated.-#html_domain_indices = True+# html_domain_indices = True  # If false, no index is generated.-#html_use_index = True+# html_use_index = True  # If true, the index is split into individual pages for each letter.-#html_split_index = false+# html_split_index = false  # If true, links to the reST sources are added to the pages.-#html_show_sourcelink = True+# html_show_sourcelink = True  # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.-#html_show_sphinx = True+# html_show_sphinx = True  # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.-#html_show_copyright = True+# html_show_copyright = True  # If true, an OpenSearch description file will be output, and all pages will # contain a <link> tag referring to it.  The value of this option must be the # base URL from which the finished HTML is served.-#html_use_opensearch = ''+# html_use_opensearch = ''  # This is the file name suffix for HTML files (e.g. ".xhtml").-#html_file_suffix = None+# html_file_suffix = None  # Output file base name for HTML help builder.-htmlhelp_basename = 'Futharkdoc'+htmlhelp_basename = "Futharkdoc"   # -- Options for LaTeX output ---------------------------------------------  latex_elements = {-# The paper size ('letterpaper' or 'a4paper').-#'papersize': 'letterpaper',--# The font size ('10pt', '11pt' or '12pt').-#'pointsize': '10pt',--# Additional stuff for the LaTeX preamble.-#'preamble': '',+    # The paper size ('letterpaper' or 'a4paper').+    #'papersize': 'letterpaper',+    # The font size ('10pt', '11pt' or '12pt').+    #'pointsize': '10pt',+    # Additional stuff for the LaTeX preamble.+    #'preamble': '', }  # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, #  author, documentclass [howto, manual, or own class]). latex_documents = [-  ('index', 'Futhark.tex', 'Futhark User\'s Guide',-   'DIKU', 'manual'),+    ("index", "Futhark.tex", "Futhark User's Guide", "DIKU", "manual"), ]  # The name of an image file (relative to this directory) to place at the top of # the title page.-#latex_logo = None+# latex_logo = None  # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters.-#latex_use_parts = false+# latex_use_parts = false  # If true, show page references after internal links.-#latex_show_pagerefs = false+# latex_show_pagerefs = false  # If true, show URL addresses after external links.-#latex_show_urls = false+# latex_show_urls = false  # Documents to append as an appendix to all manuals.-#latex_appendices = []+# latex_appendices = []  # If false, no module index is generated.-#latex_domain_indices = True+# latex_domain_indices = True   # -- Options for manual page output ---------------------------------------@@ -339,29 +419,107 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [-    ('man/futhark', 'futhark', 'a parallel functional array language', [], 1),-    ('man/futhark-autotune', 'futhark-autotune', 'calibrate run-time parameters', [], 1),-    ('man/futhark-c', 'futhark-c', 'compile Futhark to sequential C', [], 1),-    ('man/futhark-multicore', 'futhark-multicore', 'compile Futhark to multithreaded C', [], 1),-    ('man/futhark-ispc', 'futhark-ispc', 'compile Futhark to multithreaded ISPC', [], 1),-    ('man/futhark-opencl', 'futhark-opencl', 'compile Futhark to OpenCL', [], 1),-    ('man/futhark-cuda', 'futhark-cuda', 'compile Futhark to CUDA', [], 1),-    ('man/futhark-python', 'futhark-python', 'compile Futhark to sequential Python', [], 1),-    ('man/futhark-pyopencl', 'futhark-pyopencl', 'compile Futhark to Python and OpenCL', [], 1),-    ('man/futhark-wasm', 'futhark-wasm', 'compile Futhark to WebAssembly', [], 1),-    ('man/futhark-wasm-multicore', 'futhark-wasm-multicore', 'compile Futhark to parallel WebAssembly', [], 1),-    ('man/futhark-run', 'futhark-run', 'interpret Futhark program', [], 1),-    ('man/futhark-repl', 'futhark-repl', 'interactive Futhark read-eval-print-loop', [], 1),-    ('man/futhark-test', 'futhark-test', 'test Futhark programs', [], 1),-    ('man/futhark-bench', 'futhark-bench', 'benchmark Futhark programs', [], 1),-    ('man/futhark-doc', 'futhark-doc', 'generate documentation for Futhark code', [], 1),-    ('man/futhark-dataset', 'futhark-dataset', 'generate random data sets', [], 1),-    ('man/futhark-pkg', 'futhark-pkg', 'manage Futhark packages', [], 1),-    ('man/futhark-literate', 'futhark-literate', 'execute literate Futhark program', [], 1)+    ("man/futhark", "futhark", "a parallel functional array language", [], 1),+    (+        "man/futhark-autotune",+        "futhark-autotune",+        "calibrate run-time parameters",+        [],+        1,+    ),+    ("man/futhark-c", "futhark-c", "compile Futhark to sequential C", [], 1),+    (+        "man/futhark-multicore",+        "futhark-multicore",+        "compile Futhark to multithreaded C",+        [],+        1,+    ),+    (+        "man/futhark-ispc",+        "futhark-ispc",+        "compile Futhark to multithreaded ISPC",+        [],+        1,+    ),+    (+        "man/futhark-opencl",+        "futhark-opencl",+        "compile Futhark to OpenCL",+        [],+        1,+    ),+    ("man/futhark-cuda", "futhark-cuda", "compile Futhark to CUDA", [], 1),+    (+        "man/futhark-python",+        "futhark-python",+        "compile Futhark to sequential Python",+        [],+        1,+    ),+    (+        "man/futhark-pyopencl",+        "futhark-pyopencl",+        "compile Futhark to Python and OpenCL",+        [],+        1,+    ),+    (+        "man/futhark-wasm",+        "futhark-wasm",+        "compile Futhark to WebAssembly",+        [],+        1,+    ),+    (+        "man/futhark-wasm-multicore",+        "futhark-wasm-multicore",+        "compile Futhark to parallel WebAssembly",+        [],+        1,+    ),+    ("man/futhark-run", "futhark-run", "interpret Futhark program", [], 1),+    (+        "man/futhark-repl",+        "futhark-repl",+        "interactive Futhark read-eval-print-loop",+        [],+        1,+    ),+    ("man/futhark-test", "futhark-test", "test Futhark programs", [], 1),+    (+        "man/futhark-bench",+        "futhark-bench",+        "benchmark Futhark programs",+        [],+        1,+    ),+    (+        "man/futhark-doc",+        "futhark-doc",+        "generate documentation for Futhark code",+        [],+        1,+    ),+    (+        "man/futhark-dataset",+        "futhark-dataset",+        "generate random data sets",+        [],+        1,+    ),+    ("man/futhark-pkg", "futhark-pkg", "manage Futhark packages", [], 1),+    (+        "man/futhark-literate",+        "futhark-literate",+        "execute literate Futhark program",+        [],+        1,+    ), ]  # If true, show URL addresses after external links.-#man_show_urls = false+# man_show_urls = false   # -- Options for Texinfo output -------------------------------------------@@ -370,19 +528,25 @@ # (source start file, target name, title, author, #  dir menu entry, description, category) texinfo_documents = [-  ('index', 'Futhark', 'Futhark Documentation',-   'DIKU', 'Futhark', 'One line description of project.',-   'Miscellaneous'),+    (+        "index",+        "Futhark",+        "Futhark Documentation",+        "DIKU",+        "Futhark",+        "One line description of project.",+        "Miscellaneous",+    ), ]  # Documents to append as an appendix to all manuals.-#texinfo_appendices = []+# texinfo_appendices = []  # If false, no module index is generated.-#texinfo_domain_indices = True+# texinfo_domain_indices = True  # How to display URL addresses: 'footnote', 'no', or 'inline'.-#texinfo_show_urls = 'footnote'+# texinfo_show_urls = 'footnote'  # If true, do not generate a @detailmenu in the "Top" node's menu.-#texinfo_no_detailmenu = false+# texinfo_no_detailmenu = false
docs/error-index.rst view
@@ -505,6 +505,27 @@  Such an array will take up no space at runtime. +.. _anonymous-nonconstructive:++"Type abbreviation contains an anonymous size not used constructively as an array size."+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++This error occurs for type abbreviations that use anonymous sizes,+such as the following:++.. code-block:: futhark++   type^ t = []bool -> bool++Such an abbreviation is actually shorthand for++.. code-block:: futhark++   type^ t = ?[n].[n]bool -> bool++which is erroneous, but with workarounds, as explained in+:ref:`unused-existential`.+ .. _unify-param-existential:  "Parameter *x* used as size would go out of scope."
+ docs/glossary.rst view
@@ -0,0 +1,242 @@+.. _glossary:++Glossary+========++The following defines various Futhark-specific terms used in the+documentation and in compiler output.++.. glossary::+   :sorted:++   Aliases++     The *aliases* of a variable is a set of those other variables+     with which it might be :term:`aliased<aliasing>`.++   Aliasing++     Whether two values might potentially share the same memory at+     run-time.  Clearly, after ``let y = x``, ``x`` and ``y`` are+     aliased.  Also, the slice ``x[i:j]`` is also aliased with ``x``.+     Aliasing is used to type-check :ref:`in-place-updates`.++   Anonymous size++     In a type expression, a size of the form `[]`.  Will be+     :term:`elaborated<elaboration>` to some name (possibly+     :term:`existentially bound<existential size>`) by the type+     checker.++   Attribute++     Auxiliary information attached to an expression or declaration,+     which the compiler or other tool might use for various purposes.+     See :ref:`attributes`.++   Coercion++     Shorthand for a :ref:`size-coercion`.++   Compiler backend++     A Futhark compiler backend is technically only responsible for+     the final compilation result, but from the user's perspective is+     also coupled with a :term:`compiler pipeline`.  The backend+     corresponds to compiler subcommand, such as ``futhark c``,+     ``futhark cuda``, ``futhark multicore``, etc.++   Compiler frontend++     The part of the compiler responsible for reading code from files,+     parsing it, and type checking it.++   Compiler pipeline++     The series of compiler passes that lie between the+     :term:`compiler frontend` and the :term:`compiler backend`.+     Responsible for the majority of program optimisations.  In+     principle the pipeline could be configurable, but in practice+     each backend is coupled with a specific pipeline.++   Constructive use++     A variable ``n`` is used *constructively* in a type if it is used+     as the size of an array at least once outside of any function+     arrows.  For example, the following types use ``n``+     constructively:++       * ``[n]bool``+       * ``([n]bool, bool -> [n]bool)``++     The following do not:++       * ``[n+1]bool``+       * ``bool -> [n]bool``++   Consumption++     If a value is passed for a *consuming* function parameter, that+     value may no longer be used.  We say that a an expression is+     *with consumption* if any values are consumed in the expression.+     This is banned in some cases where that expression might+     otherwise be evaluated multiple times. See+     :ref:`in-place-updates`.++   Data parallelism++     Performing the same operation on multiple elements of a+     collection, such as an array.  The ``map`` :term:`SOAC` is the+     simplest example.  This is the form of parallelism supported by+     Futhark. `See also Wikipedia+     <https://en.wikipedia.org/wiki/Data_parallelism>`_.++   Elaboration++     The process conducted out by the type checker, where it infers+     and inserts information not explicitly provided in the program.+     The most important part of this is type inference, but also+     includes various other things.++   Existential size++     An existential size is a size that is bound by the existential+     quantifier ``?`` in the same type.  For example, in a type+     ``[n]bool -> ?[m].[m]bool``, the size ``m`` is existential.  When+     such a function is applied, each existential size is instantiated+     as an :term:`unknown size`.++   Functor++     The Standard ML term for what Futhark calls a :term:`parametric+     module`.++   GPU backend++     A :term:`compiler backend` that ultimately produces GPU code.+     The backends ``opencl`` and ``gpu`` are GPU backends.  These have+     more restrictions than some other backends, particularly with+     respect to :term:`irregular nested data parallelism`.++   In-place updates++     A somewhat misleading term for the syntactic forms ``x with [i] =+     v`` and ``let x[i] = v``.  These are not semantic in-place+     updates, but can be operationally understood as thus.  See+     :ref:`in-place-updates`.++   Irregular++     Something that is not regular.  Usually used as shorthand for+     :term:`irregular nested data parallelism` or :term:`irregular+     array`.++   Irregular array++     An array where the elements do not have the same size.  For+     example, ``[[1], [2,3]`` is irregular.  These are not supported+     in Futhark.++   Irregular nested data parallelism++     An instance of :term:`nested data parallelism`, where the+     :term:`parallel width` of inner parallelism is term:`variant` to+     the outer parallelism.  For example, the expression following+     expression exhibits irregular nested data parallelism::++       map (\n -> reduce (+) 0 (iota n)) ns++     Because the width of the inner ``reduce`` is ``n``, and every+     iteration of the outer ``map`` has a (potentially) different+     ``n``.  The Futhark :term:`GPU backends<GPU backend>` *currently*+     do not support irregular nested data parallelism well, and will+     usually sequentialise the irregular loops.  In cases that require+     an :term:`irregular memory allocation`, the compiler may entirely+     fail to generate code.++   Irregular memory allocation++     A situation that occurs when the generated code has to allocate+     memory inside of an instance of :term:`nested data parallelism`,+     where the amount to allocate is variant to the outer parallel+     levels.  As a contrived example (that the actual compiler would+     just optimise away), consider::++       map (\n -> let A = iota n+                  in A[10])+           ns++     To construct the array ``A`` in memory, we require ``8n`` bytes,+     but ``n`` is not known until we start executing the body of the+     ``map``.  While such simple cases are handled, more complicated+     ones that involve nested sequential loops are not supported by+     the :term:`GPU backends<GPU backend>`.++   Parametric module++     A function from :term:`modules<module>` to modules.  The most+     powerful form of abstraction provided by Futhark.++   Lifted type++     A type that may contain functions.  These have various+     restrictions on their use.  See :ref:`hofs`.++   Module++     A mapping from names to definitions of types, values, or nested+     modules.  See :ref:`module-system`.++   Nested data parallelism++     Nested :term:`data parallelism` occurs when a parallel construct+     is used inside of another parallel construct.  For example, a+     ``reduce`` might be used inside a function passed to ``map``.++   Parallel width++     A somewhat informal term used to describe the size of an array on+     which we apply a :term:`SOAC`.  For example, if ``x`` has type+     ``[1000]i32``, then ``map f x`` has a parallel width of 1000.+     Intuitively, the "amount of processors" that would be needed to+     fully exploit the parallelism of the program, although+     :term:`nested data parallelism` muddles the picture.++   Regular nested data parallelism++     An instance of :term:`nested data parallelism` that is not+     :term:`irregular`.  Fully supports by any :term:`GPU backend`.++   Size types+   Size-dependent types++     An umbrella term for the part of Futhark's type system that+     tracks array sizes.  See :ref:`size-types`.++   Size-lifted type++     A type that may contain internal hidden sizes.  These cannot be+     array elements, as that might potentially result in an+     :term:`irregular array`.  See :ref:`typeabbrevs`.++   SOAC+   Second Order Array Combinator++     A term covering the main parallel building blocks provided by+     Futhark: functions such as ``map``, ``reduce``, ``scan``, and so+     on.  They are *second order* because they accept a functional+     argument, and so permit :term:`nested data parallelism`.++   Uniqueness types++     A somewhat misleading term that describes Futhark's system of+     allowing :term:`consumption` of values, in the interest of+     allowing :term:`in-place updates`.  The only place where+     *uniqueness* truly occurs is in return types, where e.g. the+     return type of ``copy`` is *unique* to indicate that the result+     does not :term:`alias<aliasing>` the argument.++   Unknown size++     A size produced by invoking a function whose result type contains+     an existentially quantified size, such as ``filter``.
docs/index.rst view
@@ -39,6 +39,7 @@    c-porting-guide.rst    versus-other-languages.rst    binary-data-format.rst+   glossary.rst  .. toctree::    :caption: Manual Pages
docs/language-reference.rst view
@@ -1245,6 +1245,8 @@ Adding type annotations to the loop parameter can be used to resolve this. +.. _size-coercion:+ Size coercion ~~~~~~~~~~~~~ 
docs/versus-other-languages.rst view
@@ -19,7 +19,7 @@ various quirks and unexpected limitations imposed by Futhark. We also recommended reading some of the `example programs`_ along with this guide.  The guide does *not* cover all Futhark features worth knowing,-so do also skim :ref:`language-reference`.+so do also skim :ref:`language-reference` and the :ref:`glossary`.  .. _`example programs`: https://futhark-lang.org/examples.html 
futhark.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name:           futhark-version:        0.24.1+version:        0.24.2 synopsis:       An optimising compiler for a functional, array-oriented language.  description:    Futhark is a small programming language designed to be compiled to@@ -483,7 +483,7 @@     , filepath >=1.4.1.1     , free >=4.12.4     , futhark-data >= 1.1.0.0-    , futhark-server >= 1.2.2.0+    , futhark-server >= 1.2.2.1     , futhark-manifest >= 1.2.0.1     , githash >=0.1.6.1     , half >= 0.3
rts/python/memory.py view
@@ -2,44 +2,57 @@  import ctypes as ct + def addressOffset(x, offset, bt):-  return ct.cast(ct.addressof(x.contents)+int(offset), ct.POINTER(bt))+    return ct.cast(ct.addressof(x.contents) + int(offset), ct.POINTER(bt)) + def allocateMem(size):-  return ct.cast((ct.c_byte * max(0,size))(), ct.POINTER(ct.c_byte))+    return ct.cast((ct.c_byte * max(0, size))(), ct.POINTER(ct.c_byte)) + # Copy an array if its is not-None.  This is important for treating # Numpy arrays as flat memory, but has some overhead. def normaliseArray(x):-  if (x.base is x) or (x.base is None):-    return x-  else:-    return x.copy()+    if (x.base is x) or (x.base is None):+        return x+    else:+        return x.copy() + def unwrapArray(x):-  return normaliseArray(x).ctypes.data_as(ct.POINTER(ct.c_byte))+    return normaliseArray(x).ctypes.data_as(ct.POINTER(ct.c_byte)) + def createArray(x, shape, t):-  # HACK: np.ctypeslib.as_array may fail if the shape contains zeroes,-  # for some reason.-  if any(map(lambda x: x == 0, shape)):-      return np.ndarray(shape, dtype=t)-  else:-      return np.ctypeslib.as_array(x, shape=shape).view(t)+    # HACK: np.ctypeslib.as_array may fail if the shape contains zeroes,+    # for some reason.+    if any(map(lambda x: x == 0, shape)):+        return np.ndarray(shape, dtype=t)+    else:+        return np.ctypeslib.as_array(x, shape=shape).view(t) + def indexArray(x, offset, bt):-  return addressOffset(x, offset*ct.sizeof(bt), bt)[0]+    return addressOffset(x, offset * ct.sizeof(bt), bt)[0] + def writeScalarArray(x, offset, v):-  ct.memmove(ct.addressof(x.contents)+int(offset)*ct.sizeof(v), ct.addressof(v), ct.sizeof(v))+    ct.memmove(+        ct.addressof(x.contents) + int(offset) * ct.sizeof(v),+        ct.addressof(v),+        ct.sizeof(v),+    ) + # An opaque Futhark value. class opaque(object):-  def __init__(self, desc, *payload):-    self.data = payload-    self.desc = desc+    def __init__(self, desc, *payload):+        self.data = payload+        self.desc = desc -  def __repr__(self):-    return "<opaque Futhark value of type {}>".format(self.desc)+    def __repr__(self):+        return "<opaque Futhark value of type {}>".format(self.desc)+  # End of memory.py.
rts/python/opencl.py view
@@ -4,13 +4,16 @@ import numpy as np import sys -if cl.version.VERSION < (2015,2):-    raise Exception('Futhark requires at least PyOpenCL version 2015.2.  Installed version is %s.' %-                    cl.version.VERSION_TEXT)+if cl.version.VERSION < (2015, 2):+    raise Exception(+        "Futhark requires at least PyOpenCL version 2015.2.  Installed version is %s."+        % cl.version.VERSION_TEXT+    ) + def parse_preferred_device(s):     pref_num = 0-    if len(s) > 1 and s[0] == '#':+    if len(s) > 1 and s[0] == "#":         i = 1         while i < len(s):             if not s[i].isdigit():@@ -24,7 +27,10 @@     else:         return (s, 0) -def get_prefered_context(interactive=False, platform_pref=None, device_pref=None):++def get_prefered_context(+    interactive=False, platform_pref=None, device_pref=None+):     if device_pref != None:         (device_pref, device_num) = parse_preferred_device(device_pref)     else:@@ -34,10 +40,16 @@         return cl.create_some_context(interactive=True)      def blacklisted(p, d):-        return platform_pref == None and device_pref == None and \-            p.name == "Apple" and d.name.find("Intel(R) Core(TM)") >= 0+        return (+            platform_pref == None+            and device_pref == None+            and p.name == "Apple"+            and d.name.find("Intel(R) Core(TM)") >= 0+        )+     def platform_ok(p):         return not platform_pref or p.name.find(platform_pref) >= 0+     def device_ok(d):         return not device_pref or d.name.find(device_pref) >= 0 @@ -47,49 +59,67 @@         if not platform_ok(p):             continue         for d in p.get_devices():-            if blacklisted(p,d) or not device_ok(d):+            if blacklisted(p, d) or not device_ok(d):                 continue             if device_matches == device_num:                 return cl.Context(devices=[d])             else:                 device_matches += 1-    raise Exception('No OpenCL platform and device matching constraints found.')+    raise Exception(+        "No OpenCL platform and device matching constraints found."+    ) + def param_assignment(s):-    name, value = s.split('=')+    name, value = s.split("=")     return (name, int(value)) + def check_types(self, required_types):-    if 'f64' in required_types:-        if self.device.get_info(cl.device_info.PREFERRED_VECTOR_WIDTH_DOUBLE) == 0:-            raise Exception('Program uses double-precision floats, but this is not supported on chosen device: %s' % self.device.name)+    if "f64" in required_types:+        if (+            self.device.get_info(cl.device_info.PREFERRED_VECTOR_WIDTH_DOUBLE)+            == 0+        ):+            raise Exception(+                "Program uses double-precision floats, but this is not supported on chosen device: %s"+                % self.device.name+            ) + def apply_size_heuristics(self, size_heuristics, sizes):-    for (platform_name, device_type, size, valuef) in size_heuristics:-        if sizes[size] == None \-           and self.platform.name.find(platform_name) >= 0 \-           and (self.device.type & device_type) == device_type:-               sizes[size] = valuef(self.device)+    for platform_name, device_type, size, valuef in size_heuristics:+        if (+            sizes[size] == None+            and self.platform.name.find(platform_name) >= 0+            and (self.device.type & device_type) == device_type+        ):+            sizes[size] = valuef(self.device)     return sizes -def initialise_opencl_object(self,-                             program_src='',-                             build_options=[],-                             command_queue=None,-                             interactive=False,-                             platform_pref=None,-                             device_pref=None,-                             default_group_size=None,-                             default_num_groups=None,-                             default_tile_size=None,-                             default_reg_tile_size=None,-                             default_threshold=None,-                             size_heuristics=[],-                             required_types=[],-                             all_sizes={},-                             user_sizes={}):++def initialise_opencl_object(+    self,+    program_src="",+    build_options=[],+    command_queue=None,+    interactive=False,+    platform_pref=None,+    device_pref=None,+    default_group_size=None,+    default_num_groups=None,+    default_tile_size=None,+    default_reg_tile_size=None,+    default_threshold=None,+    size_heuristics=[],+    required_types=[],+    all_sizes={},+    user_sizes={},+):     if command_queue is None:-        self.ctx = get_prefered_context(interactive, platform_pref, device_pref)+        self.ctx = get_prefered_context(+            interactive, platform_pref, device_pref+        )         self.queue = cl.CommandQueue(self.ctx)     else:         self.ctx = command_queue.context@@ -115,140 +145,181 @@     self.max_local_memory -= 4      # See comment in rts/c/opencl.h.-    if self.platform.name.find('NVIDIA CUDA') >= 0:+    if self.platform.name.find("NVIDIA CUDA") >= 0:         self.max_local_memory -= 12-    elif self.platform.name.find('AMD') >= 0:+    elif self.platform.name.find("AMD") >= 0:         self.max_local_memory -= 16      self.free_list = {}      self.global_failure = self.pool.allocate(np.int32().itemsize)-    cl.enqueue_fill_buffer(self.queue, self.global_failure, np.int32(-1), 0, np.int32().itemsize)-    self.global_failure_args = self.pool.allocate(np.int64().itemsize *-                                                  (self.global_failure_args_max+1))+    cl.enqueue_fill_buffer(+        self.queue, self.global_failure, np.int32(-1), 0, np.int32().itemsize+    )+    self.global_failure_args = self.pool.allocate(+        np.int64().itemsize * (self.global_failure_args_max + 1)+    )     self.failure_is_an_option = np.int32(0) -    if 'default_group_size' in sizes:-        default_group_size = sizes['default_group_size']-        del sizes['default_group_size']+    if "default_group_size" in sizes:+        default_group_size = sizes["default_group_size"]+        del sizes["default_group_size"] -    if 'default_num_groups' in sizes:-        default_num_groups = sizes['default_num_groups']-        del sizes['default_num_groups']+    if "default_num_groups" in sizes:+        default_num_groups = sizes["default_num_groups"]+        del sizes["default_num_groups"] -    if 'default_tile_size' in sizes:-        default_tile_size = sizes['default_tile_size']-        del sizes['default_tile_size']+    if "default_tile_size" in sizes:+        default_tile_size = sizes["default_tile_size"]+        del sizes["default_tile_size"] -    if 'default_reg_tile_size' in sizes:-        default_reg_tile_size = sizes['default_reg_tile_size']-        del sizes['default_reg_tile_size']+    if "default_reg_tile_size" in sizes:+        default_reg_tile_size = sizes["default_reg_tile_size"]+        del sizes["default_reg_tile_size"] -    if 'default_threshold' in sizes:-        default_threshold = sizes['default_threshold']-        del sizes['default_threshold']+    if "default_threshold" in sizes:+        default_threshold = sizes["default_threshold"]+        del sizes["default_threshold"]      default_group_size_set = default_group_size != None     default_tile_size_set = default_tile_size != None-    default_sizes = apply_size_heuristics(self, size_heuristics,-                                          {'group_size': default_group_size,-                                           'tile_size': default_tile_size,-                                           'reg_tile_size': default_reg_tile_size,-                                           'num_groups': default_num_groups,-                                           'lockstep_width': None,-                                           'threshold': default_threshold})-    default_group_size = default_sizes['group_size']-    default_num_groups = default_sizes['num_groups']-    default_threshold = default_sizes['threshold']-    default_tile_size = default_sizes['tile_size']-    default_reg_tile_size = default_sizes['reg_tile_size']-    lockstep_width = default_sizes['lockstep_width']+    default_sizes = apply_size_heuristics(+        self,+        size_heuristics,+        {+            "group_size": default_group_size,+            "tile_size": default_tile_size,+            "reg_tile_size": default_reg_tile_size,+            "num_groups": default_num_groups,+            "lockstep_width": None,+            "threshold": default_threshold,+        },+    )+    default_group_size = default_sizes["group_size"]+    default_num_groups = default_sizes["num_groups"]+    default_threshold = default_sizes["threshold"]+    default_tile_size = default_sizes["tile_size"]+    default_reg_tile_size = default_sizes["reg_tile_size"]+    lockstep_width = default_sizes["lockstep_width"]      if default_group_size > max_group_size:         if default_group_size_set:-            sys.stderr.write('Note: Device limits group size to {} (down from {})\n'.-                             format(max_tile_size, default_group_size))+            sys.stderr.write(+                "Note: Device limits group size to {} (down from {})\n".format(+                    max_tile_size, default_group_size+                )+            )         default_group_size = max_group_size      if default_tile_size > max_tile_size:         if default_tile_size_set:-            sys.stderr.write('Note: Device limits tile size to {} (down from {})\n'.-                             format(max_tile_size, default_tile_size))+            sys.stderr.write(+                "Note: Device limits tile size to {} (down from {})\n".format(+                    max_tile_size, default_tile_size+                )+            )         default_tile_size = max_tile_size -    for (k,v) in user_sizes.items():+    for k, v in user_sizes.items():         if k in all_sizes:-            all_sizes[k]['value'] = v+            all_sizes[k]["value"] = v         else:-            raise Exception('Unknown size: {}\nKnown sizes: {}'.format(k, ' '.join(all_sizes.keys())))+            raise Exception(+                "Unknown size: {}\nKnown sizes: {}".format(+                    k, " ".join(all_sizes.keys())+                )+            )      self.sizes = {}-    for (k,v) in all_sizes.items():-        if v['class'] == 'group_size':+    for k, v in all_sizes.items():+        if v["class"] == "group_size":             max_value = max_group_size             default_value = default_group_size-        elif v['class'] == 'num_groups':-            max_value = max_group_size # Intentional!+        elif v["class"] == "num_groups":+            max_value = max_group_size  # Intentional!             default_value = default_num_groups-        elif v['class'] == 'tile_size':+        elif v["class"] == "tile_size":             max_value = max_tile_size             default_value = default_tile_size-        elif v['class'] == 'reg_tile_size':+        elif v["class"] == "reg_tile_size":             max_value = None             default_value = default_reg_tile_size-        elif v['class'].startswith('threshold'):+        elif v["class"].startswith("threshold"):             max_value = None             default_value = default_threshold         else:             # Bespoke sizes have no limit or default.             max_value = None-        if v['value'] == None:+        if v["value"] == None:             self.sizes[k] = default_value-        elif max_value != None and v['value'] > max_value:-            sys.stderr.write('Note: Device limits {} to {} (down from {}\n'.-                             format(k, max_value, v['value']))+        elif max_value != None and v["value"] > max_value:+            sys.stderr.write(+                "Note: Device limits {} to {} (down from {}\n".format(+                    k, max_value, v["value"]+                )+            )             self.sizes[k] = max_value         else:-            self.sizes[k] = v['value']+            self.sizes[k] = v["value"]      # XXX: we perform only a subset of z-encoding here.  Really, the     # compiler should provide us with the variables to which     # parameters are mapped.-    if (len(program_src) >= 0):+    if len(program_src) >= 0:         build_options += ["-DLOCKSTEP_WIDTH={}".format(lockstep_width)] -        build_options += ["-D{}={}".format('max_group_size', max_group_size)]+        build_options += ["-D{}={}".format("max_group_size", max_group_size)] -        build_options += ["-D{}={}".format(s.-                                           replace('z', 'zz').-                                           replace('.', 'zi').-                                           replace('#', 'zh').-                                           replace('\'', 'zq'),-                                           v) for (s,v) in self.sizes.items()]+        build_options += [+            "-D{}={}".format(+                s.replace("z", "zz")+                .replace(".", "zi")+                .replace("#", "zh")+                .replace("'", "zq"),+                v,+            )+            for (s, v) in self.sizes.items()+        ] -        if (self.platform.name == 'Oclgrind'):-            build_options += ['-DEMULATE_F16']+        if self.platform.name == "Oclgrind":+            build_options += ["-DEMULATE_F16"]          return cl.Program(self.ctx, program_src).build(build_options) + def opencl_alloc(self, min_size, tag):     min_size = 1 if min_size == 0 else min_size     assert min_size > 0     return self.pool.allocate(min_size) + def opencl_free_all(self):     self.pool.free_held() + def sync(self):     failure = np.empty(1, dtype=np.int32)     cl.enqueue_copy(self.queue, failure, self.global_failure, is_blocking=True)     self.failure_is_an_option = np.int32(0)     if failure[0] >= 0:         # Reset failure information.-        cl.enqueue_fill_buffer(self.queue, self.global_failure, np.int32(-1), 0, np.int32().itemsize)+        cl.enqueue_fill_buffer(+            self.queue,+            self.global_failure,+            np.int32(-1),+            0,+            np.int32().itemsize,+        )          # Read failure args.-        failure_args = np.empty(self.global_failure_args_max+1, dtype=np.int64)-        cl.enqueue_copy(self.queue, failure_args, self.global_failure_args, is_blocking=True)+        failure_args = np.empty(+            self.global_failure_args_max + 1, dtype=np.int64+        )+        cl.enqueue_copy(+            self.queue,+            failure_args,+            self.global_failure_args,+            is_blocking=True,+        )          raise Exception(self.failure_msgs[failure[0]].format(*failure_args))
rts/python/panic.py view
@@ -1,9 +1,11 @@ # Start of panic.py. + def panic(exitcode, fmt, *args):-    sys.stderr.write('%s: ' % sys.argv[0])+    sys.stderr.write("%s: " % sys.argv[0])     sys.stderr.write(fmt % args)-    sys.stderr.write('\n')+    sys.stderr.write("\n")     sys.exit(exitcode)+  # End of panic.py.
rts/python/scalar.py view
@@ -4,228 +4,291 @@ import math import struct + def intlit(t, x):-  if t == np.int8:-    return np.int8(x)-  elif t == np.int16:-    return np.int16(x)-  elif t == np.int32:-    return np.int32(x)-  else:-    return np.int64(x)+    if t == np.int8:+        return np.int8(x)+    elif t == np.int16:+        return np.int16(x)+    elif t == np.int32:+        return np.int32(x)+    else:+        return np.int64(x) + def signed(x):-  if type(x) == np.uint8:-    return np.int8(x)-  elif type(x) == np.uint16:-    return np.int16(x)-  elif type(x) == np.uint32:-    return np.int32(x)-  else:-    return np.int64(x)+    if type(x) == np.uint8:+        return np.int8(x)+    elif type(x) == np.uint16:+        return np.int16(x)+    elif type(x) == np.uint32:+        return np.int32(x)+    else:+        return np.int64(x) + def unsigned(x):-  if type(x) == np.int8:-    return np.uint8(x)-  elif type(x) == np.int16:-    return np.uint16(x)-  elif type(x) == np.int32:-    return np.uint32(x)-  else:-    return np.uint64(x)+    if type(x) == np.int8:+        return np.uint8(x)+    elif type(x) == np.int16:+        return np.uint16(x)+    elif type(x) == np.int32:+        return np.uint32(x)+    else:+        return np.uint64(x) -def shlN(x,y):-  return x << y -def ashrN(x,y):-  return x >> y+def shlN(x, y):+    return x << y ++def ashrN(x, y):+    return x >> y++ # Python is so slow that we just make all the unsafe operations safe, # always. -def sdivN(x,y):-  if y == 0:-    return intlit(type(x), 0)-  else:-    return x // y -def sdiv_upN(x,y):-  if y == 0:-    return intlit(type(x), 0)-  else:-    return (x+y-intlit(type(x), 1)) // y+def sdivN(x, y):+    if y == 0:+        return intlit(type(x), 0)+    else:+        return x // y -def smodN(x,y):-  if y == 0:-    return intlit(type(x), 0)-  else:-    return x % y -def udivN(x,y):-  if y == 0:-    return intlit(type(x), 0)-  else:-    return signed(unsigned(x) // unsigned(y))+def sdiv_upN(x, y):+    if y == 0:+        return intlit(type(x), 0)+    else:+        return (x + y - intlit(type(x), 1)) // y -def udiv_upN(x,y):-  if y == 0:-    return intlit(type(x), 0)-  else:-    return signed((unsigned(x)+unsigned(y)-unsigned(intlit(type(x),1))) // unsigned(y)) -def umodN(x,y):-  if y == 0:-    return intlit(type(x), 0)-  else:-    return signed(unsigned(x) % unsigned(y))+def smodN(x, y):+    if y == 0:+        return intlit(type(x), 0)+    else:+        return x % y -def squotN(x,y):-  if y == 0:-    return intlit(type(x), 0)-  else:-    return np.floor_divide(np.abs(x), np.abs(y)) * np.sign(x) * np.sign(y) -def sremN(x,y):-  if y == 0:-    return intlit(type(x), 0)-  else:-    return np.remainder(np.abs(x), np.abs(y)) * np.sign(x)+def udivN(x, y):+    if y == 0:+        return intlit(type(x), 0)+    else:+        return signed(unsigned(x) // unsigned(y)) -def sminN(x,y):-  return min(x,y) -def smaxN(x,y):-  return max(x,y)+def udiv_upN(x, y):+    if y == 0:+        return intlit(type(x), 0)+    else:+        return signed(+            (unsigned(x) + unsigned(y) - unsigned(intlit(type(x), 1)))+            // unsigned(y)+        ) -def uminN(x,y):-  return signed(min(unsigned(x),unsigned(y))) -def umaxN(x,y):-  return signed(max(unsigned(x),unsigned(y)))+def umodN(x, y):+    if y == 0:+        return intlit(type(x), 0)+    else:+        return signed(unsigned(x) % unsigned(y)) -def fminN(x,y):-  return np.fmin(x,y) -def fmaxN(x,y):-  return np.fmax(x,y)+def squotN(x, y):+    if y == 0:+        return intlit(type(x), 0)+    else:+        return np.floor_divide(np.abs(x), np.abs(y)) * np.sign(x) * np.sign(y) -def powN(x,y):-  return x ** y -def fpowN(x,y):-  return x ** y+def sremN(x, y):+    if y == 0:+        return intlit(type(x), 0)+    else:+        return np.remainder(np.abs(x), np.abs(y)) * np.sign(x) -def sleN(x,y):-  return x <= y -def sltN(x,y):-  return x < y+def sminN(x, y):+    return min(x, y) -def uleN(x,y):-  return unsigned(x) <= unsigned(y) -def ultN(x,y):-  return unsigned(x) < unsigned(y)+def smaxN(x, y):+    return max(x, y) -def lshr8(x,y):-  return np.int8(np.uint8(x) >> np.uint8(y)) -def lshr16(x,y):-  return np.int16(np.uint16(x) >> np.uint16(y))+def uminN(x, y):+    return signed(min(unsigned(x), unsigned(y))) -def lshr32(x,y):-  return np.int32(np.uint32(x) >> np.uint32(y)) -def lshr64(x,y):-  return np.int64(np.uint64(x) >> np.uint64(y))+def umaxN(x, y):+    return signed(max(unsigned(x), unsigned(y))) ++def fminN(x, y):+    return np.fmin(x, y)+++def fmaxN(x, y):+    return np.fmax(x, y)+++def powN(x, y):+    return x**y+++def fpowN(x, y):+    return x**y+++def sleN(x, y):+    return x <= y+++def sltN(x, y):+    return x < y+++def uleN(x, y):+    return unsigned(x) <= unsigned(y)+++def ultN(x, y):+    return unsigned(x) < unsigned(y)+++def lshr8(x, y):+    return np.int8(np.uint8(x) >> np.uint8(y))+++def lshr16(x, y):+    return np.int16(np.uint16(x) >> np.uint16(y))+++def lshr32(x, y):+    return np.int32(np.uint32(x) >> np.uint32(y))+++def lshr64(x, y):+    return np.int64(np.uint64(x) >> np.uint64(y))++ def sext_T_i8(x):-  return np.int8(x)+    return np.int8(x) + def sext_T_i16(x):-  return np.int16(x)+    return np.int16(x) + def sext_T_i32(x):-  return np.int32(x)+    return np.int32(x) + def sext_T_i64(x):-  return np.int64(x)+    return np.int64(x) + def itob_T_bool(x):-  return bool(x)+    return bool(x) + def btoi_bool_i8(x):-  return np.int8(x)+    return np.int8(x) + def btoi_bool_i16(x):-  return np.int16(x)+    return np.int16(x) + def btoi_bool_i32(x):-  return np.int32(x)+    return np.int32(x) + def btoi_bool_i64(x):-  return np.int64(x)+    return np.int64(x) + def ftob_T_bool(x):-  return bool(x)+    return bool(x) + def btof_bool_f16(x):-  return np.float16(x)+    return np.float16(x) + def btof_bool_f32(x):-  return np.float32(x)+    return np.float32(x) + def btof_bool_f64(x):-  return np.float64(x)+    return np.float64(x) + def zext_i8_i8(x):-  return np.int8(np.uint8(x))+    return np.int8(np.uint8(x)) + def zext_i8_i16(x):-  return np.int16(np.uint8(x))+    return np.int16(np.uint8(x)) + def zext_i8_i32(x):-  return np.int32(np.uint8(x))+    return np.int32(np.uint8(x)) + def zext_i8_i64(x):-  return np.int64(np.uint8(x))+    return np.int64(np.uint8(x)) + def zext_i16_i8(x):-  return np.int8(np.uint16(x))+    return np.int8(np.uint16(x)) + def zext_i16_i16(x):-  return np.int16(np.uint16(x))+    return np.int16(np.uint16(x)) + def zext_i16_i32(x):-  return np.int32(np.uint16(x))+    return np.int32(np.uint16(x)) + def zext_i16_i64(x):-  return np.int64(np.uint16(x))+    return np.int64(np.uint16(x)) + def zext_i32_i8(x):-  return np.int8(np.uint32(x))+    return np.int8(np.uint32(x)) + def zext_i32_i16(x):-  return np.int16(np.uint32(x))+    return np.int16(np.uint32(x)) + def zext_i32_i32(x):-  return np.int32(np.uint32(x))+    return np.int32(np.uint32(x)) + def zext_i32_i64(x):-  return np.int64(np.uint32(x))+    return np.int64(np.uint32(x)) + def zext_i64_i8(x):-  return np.int8(np.uint64(x))+    return np.int8(np.uint64(x)) + def zext_i64_i16(x):-  return np.int16(np.uint64(x))+    return np.int16(np.uint64(x)) + def zext_i64_i32(x):-  return np.int32(np.uint64(x))+    return np.int32(np.uint64(x)) + def zext_i64_i64(x):-  return np.int64(np.uint64(x))+    return np.int64(np.uint64(x)) + sdiv8 = sdiv16 = sdiv32 = sdiv64 = sdivN sdiv_up8 = sdiv1_up6 = sdiv_up32 = sdiv_up64 = sdiv_upN sdiv_safe8 = sdiv1_safe6 = sdiv_safe32 = sdiv_safe64 = sdivN@@ -264,497 +327,691 @@ itob_i8_bool = itob_i16_bool = itob_i32_bool = itob_i64_bool = itob_T_bool ftob_f16_bool = ftob_f32_bool = ftob_f64_bool = ftob_T_bool + def clz_T(x):-  n = np.int32(0)-  bits = x.itemsize * 8-  for i in range(bits):-    if x < 0:-      break-    n += 1-    x <<= np.int8(1)-  return n+    n = np.int32(0)+    bits = x.itemsize * 8+    for i in range(bits):+        if x < 0:+            break+        n += 1+        x <<= np.int8(1)+    return n + def ctz_T(x):-  n = np.int32(0)-  bits = x.itemsize * 8-  for i in range(bits):-    if (x & 1) == 1:-      break-    n += 1-    x >>= np.int8(1)-  return n+    n = np.int32(0)+    bits = x.itemsize * 8+    for i in range(bits):+        if (x & 1) == 1:+            break+        n += 1+        x >>= np.int8(1)+    return n + def popc_T(x):-  c = np.int32(0)-  while x != 0:-    x &= x - np.int8(1)-    c += np.int8(1)-  return c+    c = np.int32(0)+    while x != 0:+        x &= x - np.int8(1)+        c += np.int8(1)+    return c + futhark_popc8 = futhark_popc16 = futhark_popc32 = futhark_popc64 = popc_T futhark_clzz8 = futhark_clzz16 = futhark_clzz32 = futhark_clzz64 = clz_T futhark_ctzz8 = futhark_ctzz16 = futhark_ctzz32 = futhark_ctzz64 = ctz_T + def ssignum(x):-  return np.sign(x)+    return np.sign(x) + def usignum(x):-  if x < 0:-    return ssignum(-x)-  else:-    return ssignum(x)+    if x < 0:+        return ssignum(-x)+    else:+        return ssignum(x) + def sitofp_T_f32(x):-  return np.float32(x)+    return np.float32(x)++ sitofp_i8_f32 = sitofp_i16_f32 = sitofp_i32_f32 = sitofp_i64_f32 = sitofp_T_f32 + def sitofp_T_f64(x):-  return np.float64(x)+    return np.float64(x)++ sitofp_i8_f64 = sitofp_i16_f64 = sitofp_i32_f64 = sitofp_i64_f64 = sitofp_T_f64 + def uitofp_T_f32(x):-  return np.float32(unsigned(x))+    return np.float32(unsigned(x))++ uitofp_i8_f32 = uitofp_i16_f32 = uitofp_i32_f32 = uitofp_i64_f32 = uitofp_T_f32 + def uitofp_T_f64(x):-  return np.float64(unsigned(x))+    return np.float64(unsigned(x))++ uitofp_i8_f64 = uitofp_i16_f64 = uitofp_i32_f64 = uitofp_i64_f64 = uitofp_T_f64 + def fptosi_T_i8(x):-  if np.isnan(x) or np.isinf(x):-    return np.int8(0)-  else:-    return np.int8(np.trunc(x))+    if np.isnan(x) or np.isinf(x):+        return np.int8(0)+    else:+        return np.int8(np.trunc(x))++ fptosi_f16_i8 = fptosi_f32_i8 = fptosi_f64_i8 = fptosi_T_i8 + def fptosi_T_i16(x):-  if np.isnan(x) or np.isinf(x):-    return np.int16(0)-  else:-    return np.int16(np.trunc(x))+    if np.isnan(x) or np.isinf(x):+        return np.int16(0)+    else:+        return np.int16(np.trunc(x))++ fptosi_f16_i16 = fptosi_f32_i16 = fptosi_f64_i16 = fptosi_T_i16 + def fptosi_T_i32(x):-  if np.isnan(x) or np.isinf(x):-    return np.int32(0)-  else:-    return np.int32(np.trunc(x))+    if np.isnan(x) or np.isinf(x):+        return np.int32(0)+    else:+        return np.int32(np.trunc(x))++ fptosi_f16_i32 = fptosi_f32_i32 = fptosi_f64_i32 = fptosi_T_i32 + def fptosi_T_i64(x):-  if np.isnan(x) or np.isinf(x):-    return np.int64(0)-  else:-    return np.int64(np.trunc(x))+    if np.isnan(x) or np.isinf(x):+        return np.int64(0)+    else:+        return np.int64(np.trunc(x))++ fptosi_f16_i64 = fptosi_f32_i64 = fptosi_f64_i64 = fptosi_T_i64 + def fptoui_T_i8(x):-  if np.isnan(x) or np.isinf(x):-    return np.int8(0)-  else:-    return np.int8(np.trunc(x))+    if np.isnan(x) or np.isinf(x):+        return np.int8(0)+    else:+        return np.int8(np.trunc(x))++ fptoui_f16_i8 = fptoui_f32_i8 = fptoui_f64_i8 = fptoui_T_i8 + def fptoui_T_i16(x):-  if np.isnan(x) or np.isinf(x):-    return np.int16(0)-  else:-    return np.int16(np.trunc(x))+    if np.isnan(x) or np.isinf(x):+        return np.int16(0)+    else:+        return np.int16(np.trunc(x))++ fptoui_f16_i16 = fptoui_f32_i16 = fptoui_f64_i16 = fptoui_T_i16 + def fptoui_T_i32(x):-  if np.isnan(x) or np.isinf(x):-    return np.int32(0)-  else:-    return np.int32(np.trunc(x))+    if np.isnan(x) or np.isinf(x):+        return np.int32(0)+    else:+        return np.int32(np.trunc(x))++ fptoui_f16_i32 = fptoui_f32_i32 = fptoui_f64_i32 = fptoui_T_i32 + def fptoui_T_i64(x):-  if np.isnan(x) or np.isinf(x):-    return np.int64(0)-  else:-    return np.int64(np.trunc(x))+    if np.isnan(x) or np.isinf(x):+        return np.int64(0)+    else:+        return np.int64(np.trunc(x))++ fptoui_f16_i64 = fptoui_f32_i64 = fptoui_f64_i64 = fptoui_T_i64 + def fpconv_f16_f32(x):-  return np.float32(x)+    return np.float32(x) + def fpconv_f16_f64(x):-  return np.float64(x)+    return np.float64(x) + def fpconv_f32_f16(x):-  return np.float16(x)+    return np.float16(x) + def fpconv_f32_f64(x):-  return np.float64(x)+    return np.float64(x) + def fpconv_f64_f16(x):-  return np.float16(x)+    return np.float16(x) + def fpconv_f64_f32(x):-  return np.float32(x)+    return np.float32(x) + def futhark_umul_hi8(a, b):-  return np.int8((np.uint64(np.uint8(a))*np.uint64(np.uint8(b))) >> np.uint64(8))+    return np.int8(+        (np.uint64(np.uint8(a)) * np.uint64(np.uint8(b))) >> np.uint64(8)+    ) + def futhark_umul_hi16(a, b):-  return np.int16((np.uint64(np.uint16(a))*np.uint64(np.uint16(b))) >> np.uint64(16))+    return np.int16(+        (np.uint64(np.uint16(a)) * np.uint64(np.uint16(b))) >> np.uint64(16)+    ) + def futhark_umul_hi32(a, b):-  return np.int32((np.uint64(np.uint32(a))*np.uint64(np.uint32(b))) >> np.uint64(32))+    return np.int32(+        (np.uint64(np.uint32(a)) * np.uint64(np.uint32(b))) >> np.uint64(32)+    ) + def futhark_umul_hi64(a, b):-  return np.int64(np.uint64(int(np.uint64(a))*int(np.uint64(b)) >> 64))+    return np.int64(np.uint64(int(np.uint64(a)) * int(np.uint64(b)) >> 64)) + def futhark_smul_hi8(a, b):-  return np.int8((np.int64(a)*np.int64(b)) >> np.int64(8))+    return np.int8((np.int64(a) * np.int64(b)) >> np.int64(8)) + def futhark_smul_hi16(a, b):-  return np.int16((np.int64(a)*np.int64(b)) >> np.int64(16))+    return np.int16((np.int64(a) * np.int64(b)) >> np.int64(16)) + def futhark_smul_hi32(a, b):-  return np.int32((np.int64(a)*np.int64(b)) >> np.int64(32))+    return np.int32((np.int64(a) * np.int64(b)) >> np.int64(32)) + def futhark_smul_hi64(a, b):-  return np.int64(int(a)*int(b) >> 64)+    return np.int64(int(a) * int(b) >> 64) -def futhark_umad_hi8(a, b, c):  return futhark_umul_hi8(a,b) + c-def futhark_umad_hi16(a, b, c): return futhark_umul_hi16(a,b) + c-def futhark_umad_hi32(a, b, c): return futhark_umul_hi32(a,b) + c-def futhark_umad_hi64(a, b, c): return futhark_umul_hi64(a,b) + c-def futhark_smad_hi8(a, b, c):  return futhark_smul_hi8(a,b) + c-def futhark_smad_hi16(a, b, c): return futhark_smul_hi16(a,b) + c-def futhark_smad_hi32(a, b, c): return futhark_smul_hi32(a,b) + c-def futhark_smad_hi64(a, b, c): return futhark_smul_hi64(a,b) + c +def futhark_umad_hi8(a, b, c):+    return futhark_umul_hi8(a, b) + c+++def futhark_umad_hi16(a, b, c):+    return futhark_umul_hi16(a, b) + c+++def futhark_umad_hi32(a, b, c):+    return futhark_umul_hi32(a, b) + c+++def futhark_umad_hi64(a, b, c):+    return futhark_umul_hi64(a, b) + c+++def futhark_smad_hi8(a, b, c):+    return futhark_smul_hi8(a, b) + c+++def futhark_smad_hi16(a, b, c):+    return futhark_smul_hi16(a, b) + c+++def futhark_smad_hi32(a, b, c):+    return futhark_smul_hi32(a, b) + c+++def futhark_smad_hi64(a, b, c):+    return futhark_smul_hi64(a, b) + c++ def futhark_log64(x):-  return np.float64(np.log(x))+    return np.float64(np.log(x)) + def futhark_log2_64(x):-  return np.float64(np.log2(x))+    return np.float64(np.log2(x)) + def futhark_log10_64(x):-  return np.float64(np.log10(x))+    return np.float64(np.log10(x)) + def futhark_log1p_64(x):-  return np.float64(np.log1p(x))+    return np.float64(np.log1p(x)) + def futhark_sqrt64(x):-  return np.sqrt(x)+    return np.sqrt(x) + def futhark_cbrt64(x):-  return np.cbrt(x)+    return np.cbrt(x) + def futhark_exp64(x):-  return np.exp(x)+    return np.exp(x) + def futhark_cos64(x):-  return np.cos(x)+    return np.cos(x) + def futhark_sin64(x):-  return np.sin(x)+    return np.sin(x) + def futhark_tan64(x):-  return np.tan(x)+    return np.tan(x) + def futhark_acos64(x):-  return np.arccos(x)+    return np.arccos(x) + def futhark_asin64(x):-  return np.arcsin(x)+    return np.arcsin(x) + def futhark_atan64(x):-  return np.arctan(x)+    return np.arctan(x) + def futhark_cosh64(x):-  return np.cosh(x)+    return np.cosh(x) + def futhark_sinh64(x):-  return np.sinh(x)+    return np.sinh(x) + def futhark_tanh64(x):-  return np.tanh(x)+    return np.tanh(x) + def futhark_acosh64(x):-  return np.arccosh(x)+    return np.arccosh(x) + def futhark_asinh64(x):-  return np.arcsinh(x)+    return np.arcsinh(x) + def futhark_atanh64(x):-  return np.arctanh(x)+    return np.arctanh(x) + def futhark_atan2_64(x, y):-  return np.arctan2(x, y)+    return np.arctan2(x, y) + def futhark_hypot64(x, y):-  return np.hypot(x, y)+    return np.hypot(x, y) + def futhark_gamma64(x):-  return np.float64(math.gamma(x))+    return np.float64(math.gamma(x)) + def futhark_lgamma64(x):-  return np.float64(math.lgamma(x))+    return np.float64(math.lgamma(x)) + def futhark_erf64(x):-  return np.float64(math.erf(x))+    return np.float64(math.erf(x)) + def futhark_erfc64(x):-  return np.float64(math.erfc(x))+    return np.float64(math.erfc(x)) + def futhark_round64(x):-  return np.round(x)+    return np.round(x) + def futhark_ceil64(x):-  return np.ceil(x)+    return np.ceil(x) + def futhark_floor64(x):-  return np.floor(x)+    return np.floor(x) + def futhark_nextafter64(x, y):-  return np.nextafter(x, y)+    return np.nextafter(x, y) + def futhark_isnan64(x):-  return np.isnan(x)+    return np.isnan(x) + def futhark_isinf64(x):-  return np.isinf(x)+    return np.isinf(x) + def futhark_to_bits64(x):-  s = struct.pack('>d', x)-  return np.int64(struct.unpack('>q', s)[0])+    s = struct.pack(">d", x)+    return np.int64(struct.unpack(">q", s)[0]) + def futhark_from_bits64(x):-  s = struct.pack('>q', x)-  return np.float64(struct.unpack('>d', s)[0])+    s = struct.pack(">q", x)+    return np.float64(struct.unpack(">d", s)[0]) + def futhark_log32(x):-  return np.float32(np.log(x))+    return np.float32(np.log(x)) + def futhark_log2_32(x):-  return np.float32(np.log2(x))+    return np.float32(np.log2(x)) + def futhark_log10_32(x):-  return np.float32(np.log10(x))+    return np.float32(np.log10(x)) + def futhark_log1p_32(x):-  return np.float32(np.log1p(x))+    return np.float32(np.log1p(x)) + def futhark_sqrt32(x):-  return np.float32(np.sqrt(x))+    return np.float32(np.sqrt(x)) + def futhark_cbrt32(x):-  return np.float32(np.cbrt(x))+    return np.float32(np.cbrt(x)) + def futhark_exp32(x):-  return np.exp(x)+    return np.exp(x) + def futhark_cos32(x):-  return np.cos(x)+    return np.cos(x) + def futhark_sin32(x):-  return np.sin(x)+    return np.sin(x) + def futhark_tan32(x):-  return np.tan(x)+    return np.tan(x) + def futhark_acos32(x):-  return np.arccos(x)+    return np.arccos(x) + def futhark_asin32(x):-  return np.arcsin(x)+    return np.arcsin(x) + def futhark_atan32(x):-  return np.arctan(x)+    return np.arctan(x) + def futhark_cosh32(x):-  return np.cosh(x)+    return np.cosh(x) + def futhark_sinh32(x):-  return np.sinh(x)+    return np.sinh(x) + def futhark_tanh32(x):-  return np.tanh(x)+    return np.tanh(x) + def futhark_acosh32(x):-  return np.arccosh(x)+    return np.arccosh(x) + def futhark_asinh32(x):-  return np.arcsinh(x)+    return np.arcsinh(x) + def futhark_atanh32(x):-  return np.arctanh(x)+    return np.arctanh(x) + def futhark_atan2_32(x, y):-  return np.arctan2(x, y)+    return np.arctan2(x, y) + def futhark_hypot32(x, y):-  return np.hypot(x, y)+    return np.hypot(x, y) + def futhark_gamma32(x):-  return np.float32(math.gamma(x))+    return np.float32(math.gamma(x)) + def futhark_lgamma32(x):-  return np.float32(math.lgamma(x))+    return np.float32(math.lgamma(x)) + def futhark_erf32(x):-  return np.float32(math.erf(x))+    return np.float32(math.erf(x)) + def futhark_erfc32(x):-  return np.float32(math.erfc(x))+    return np.float32(math.erfc(x)) + def futhark_round32(x):-  return np.round(x)+    return np.round(x) + def futhark_ceil32(x):-  return np.ceil(x)+    return np.ceil(x) + def futhark_floor32(x):-  return np.floor(x)+    return np.floor(x) + def futhark_nextafter32(x, y):-  return np.nextafter(x, y)+    return np.nextafter(x, y) + def futhark_isnan32(x):-  return np.isnan(x)+    return np.isnan(x) + def futhark_isinf32(x):-  return np.isinf(x)+    return np.isinf(x) + def futhark_to_bits32(x):-  s = struct.pack('>f', x)-  return np.int32(struct.unpack('>l', s)[0])+    s = struct.pack(">f", x)+    return np.int32(struct.unpack(">l", s)[0]) + def futhark_from_bits32(x):-  s = struct.pack('>l', x)-  return np.float32(struct.unpack('>f', s)[0])+    s = struct.pack(">l", x)+    return np.float32(struct.unpack(">f", s)[0]) + def futhark_log16(x):-  return np.float16(np.log(x))+    return np.float16(np.log(x)) + def futhark_log2_16(x):-  return np.float16(np.log2(x))+    return np.float16(np.log2(x)) + def futhark_log10_16(x):-  return np.float16(np.log10(x))+    return np.float16(np.log10(x)) + def futhark_log1p_16(x):-  return np.float16(np.log1p(x))+    return np.float16(np.log1p(x)) + def futhark_sqrt16(x):-  return np.float16(np.sqrt(x))+    return np.float16(np.sqrt(x)) + def futhark_cbrt16(x):-  return np.float16(np.cbrt(x))+    return np.float16(np.cbrt(x)) + def futhark_exp16(x):-  return np.exp(x)+    return np.exp(x) + def futhark_cos16(x):-  return np.cos(x)+    return np.cos(x) + def futhark_sin16(x):-  return np.sin(x)+    return np.sin(x) + def futhark_tan16(x):-  return np.tan(x)+    return np.tan(x) + def futhark_acos16(x):-  return np.arccos(x)+    return np.arccos(x) + def futhark_asin16(x):-  return np.arcsin(x)+    return np.arcsin(x) + def futhark_atan16(x):-  return np.arctan(x)+    return np.arctan(x) + def futhark_cosh16(x):-  return np.cosh(x)+    return np.cosh(x) + def futhark_sinh16(x):-  return np.sinh(x)+    return np.sinh(x) + def futhark_tanh16(x):-  return np.tanh(x)+    return np.tanh(x) + def futhark_acosh16(x):-  return np.arccosh(x)+    return np.arccosh(x) + def futhark_asinh16(x):-  return np.arcsinh(x)+    return np.arcsinh(x) + def futhark_atanh16(x):-  return np.arctanh(x)+    return np.arctanh(x) + def futhark_atan2_16(x, y):-  return np.arctan2(x, y)+    return np.arctan2(x, y) + def futhark_hypot16(x, y):-  return np.hypot(x, y)+    return np.hypot(x, y) + def futhark_gamma16(x):-  return np.float16(math.gamma(x))+    return np.float16(math.gamma(x)) + def futhark_lgamma16(x):-  return np.float16(math.lgamma(x))+    return np.float16(math.lgamma(x)) + def futhark_erf16(x):-  return np.float16(math.erf(x))+    return np.float16(math.erf(x)) + def futhark_erfc16(x):-  return np.float16(math.erfc(x))+    return np.float16(math.erfc(x)) + def futhark_round16(x):-  return np.round(x)+    return np.round(x) + def futhark_ceil16(x):-  return np.ceil(x)+    return np.ceil(x) + def futhark_floor16(x):-  return np.floor(x)+    return np.floor(x) + def futhark_nextafter16(x, y):-  return np.nextafter(x, y)+    return np.nextafter(x, y) + def futhark_isnan16(x):-  return np.isnan(x)+    return np.isnan(x) + def futhark_isinf16(x):-  return np.isinf(x)+    return np.isinf(x) + def futhark_to_bits16(x):-  s = struct.pack('>e', x)-  return np.int16(struct.unpack('>H', s)[0])+    s = struct.pack(">e", x)+    return np.int16(struct.unpack(">H", s)[0]) + def futhark_from_bits16(x):-  s = struct.pack('>H', np.uint16(x))-  return np.float16(struct.unpack('>e', s)[0])+    s = struct.pack(">H", np.uint16(x))+    return np.float16(struct.unpack(">e", s)[0]) + def futhark_lerp16(v0, v1, t):-  return v0 + (v1-v0)*t+    return v0 + (v1 - v0) * t + def futhark_lerp32(v0, v1, t):-  return v0 + (v1-v0)*t+    return v0 + (v1 - v0) * t + def futhark_lerp64(v0, v1, t):-  return v0 + (v1-v0)*t+    return v0 + (v1 - v0) * t + def futhark_mad16(a, b, c):-  return a * b + c+    return a * b + c + def futhark_mad32(a, b, c):-  return a * b + c+    return a * b + c + def futhark_mad64(a, b, c):-  return a * b + c+    return a * b + c + def futhark_fma16(a, b, c):-  return a * b + c+    return a * b + c + def futhark_fma32(a, b, c):-  return a * b + c+    return a * b + c + def futhark_fma64(a, b, c):-  return a * b + c+    return a * b + c+  # End of scalar.py.
rts/python/server.py view
@@ -2,8 +2,9 @@  import sys import time-import shlex # For string splitting+import shlex  # For string splitting + class Server:     def __init__(self, ctx):         self._ctx = ctx@@ -17,21 +18,21 @@         if i < len(args):             return args[i]         else:-            raise self.Failure('Insufficient command args')+            raise self.Failure("Insufficient command args")      def _get_entry_point(self, entry):         if entry in self._ctx.entry_points:             return self._ctx.entry_points[entry]         else:-            raise self.Failure('Unknown entry point: %s' % entry)+            raise self.Failure("Unknown entry point: %s" % entry)      def _check_var(self, vname):         if not vname in self._vars:-            raise self.Failure('Unknown variable: %s' % vname)+            raise self.Failure("Unknown variable: %s" % vname)      def _check_new_var(self, vname):         if vname in self._vars:-            raise self.Failure('Variable already exists: %s' % vname)+            raise self.Failure("Variable already exists: %s" % vname)      def _get_var(self, vname):         self._check_var(vname)@@ -71,27 +72,27 @@         exp_len = 1 + num_outs + num_ins          if len(args) != exp_len:-            raise self.Failure('Invalid argument count, expected %d' % exp_len)+            raise self.Failure("Invalid argument count, expected %d" % exp_len) -        out_vnames = args[1:num_outs+1]+        out_vnames = args[1 : num_outs + 1]          for out_vname in out_vnames:             self._check_new_var(out_vname) -        in_vnames = args[1+num_outs:]-        ins = [ self._get_var(in_vname) for in_vname in in_vnames ]+        in_vnames = args[1 + num_outs :]+        ins = [self._get_var(in_vname) for in_vname in in_vnames]          try:             (runtime, vals) = getattr(self._ctx, entry_fname)(*ins)         except Exception as e:             raise self.Failure(str(e)) -        print('runtime: %d' % runtime)+        print("runtime: %d" % runtime)          if num_outs == 1:             self._vars[out_vnames[0]] = vals         else:-            for (out_vname, val) in zip(out_vnames, vals):+            for out_vname, val in zip(out_vnames, vals):                 self._vars[out_vname] = val      def _store_val(self, f, value):@@ -101,7 +102,12 @@         if isinstance(value, opaque):             for component in value.data:                 self._store_val(f, component)-        elif isinstance(value, np.number) or isinstance(value, bool) or isinstance(value, np.bool_) or isinstance(value, np.ndarray):+        elif (+            isinstance(value, np.number)+            or isinstance(value, bool)+            or isinstance(value, np.bool_)+            or isinstance(value, np.ndarray)+        ):             # Ordinary NumPy value.             f.write(construct_binary_value(value))         else:@@ -111,7 +117,7 @@     def _cmd_store(self, args):         fname = self._get_arg(args, 0) -        with open(fname, 'wb') as f:+        with open(fname, "wb") as f:             for i in range(1, len(args)):                 self._store_val(f, self._get_var(args[i])) @@ -126,12 +132,12 @@      def _cmd_restore(self, args):         if len(args) % 2 == 0:-            raise self.Failure('Invalid argument count')+            raise self.Failure("Invalid argument count")          fname = args[0]         args = args[1:] -        with open(fname, 'rb') as f:+        with open(fname, "rb") as f:             reader = ReaderInput(f)             while args != []:                 vname = args[0]@@ -139,18 +145,19 @@                 args = args[2:]                  if vname in self._vars:-                    raise self.Failure('Variable already exists: %s' % vname)+                    raise self.Failure("Variable already exists: %s" % vname)                  try:                     self._vars[vname] = self._restore_val(reader, typename)                 except ValueError:-                    raise self.Failure('Failed to restore variable %s.\n'-                                       'Possibly malformed data in %s.\n'-                                       % (vname, fname))+                    raise self.Failure(+                        "Failed to restore variable %s.\n"+                        "Possibly malformed data in %s.\n" % (vname, fname)+                    )              skip_spaces(reader)-            if reader.get_char() != b'':-                raise self.Failure('Expected EOF after reading values')+            if reader.get_char() != b"":+                raise self.Failure("Expected EOF after reading values")      def _cmd_types(self, args):         for k in self._ctx.opaques.keys():@@ -160,47 +167,49 @@         for k in self._ctx.entry_points.keys():             print(k) -    _commands = { 'inputs': _cmd_inputs,-                  'outputs': _cmd_outputs,-                  'call': _cmd_call,-                  'restore': _cmd_restore,-                  'store': _cmd_store,-                  'free': _cmd_free,-                  'rename': _cmd_rename,-                  'clear': _cmd_dummy,-                  'pause_profiling': _cmd_dummy,-                  'unpause_profiling': _cmd_dummy,-                  'report': _cmd_dummy,-                  'types': _cmd_types,-                  'entry_points': _cmd_entry_points,-                 }+    _commands = {+        "inputs": _cmd_inputs,+        "outputs": _cmd_outputs,+        "call": _cmd_call,+        "restore": _cmd_restore,+        "store": _cmd_store,+        "free": _cmd_free,+        "rename": _cmd_rename,+        "clear": _cmd_dummy,+        "pause_profiling": _cmd_dummy,+        "unpause_profiling": _cmd_dummy,+        "report": _cmd_dummy,+        "types": _cmd_types,+        "entry_points": _cmd_entry_points,+    }      def _process_line(self, line):         lex = shlex.shlex(line)         lex.quotes = '"'         lex.whitespace_split = True-        lex.commenters = ''+        lex.commenters = ""         words = list(lex)         if words == []:-            raise self.Failure('Empty line')+            raise self.Failure("Empty line")         else:             cmd = words[0]             args = words[1:]             if cmd in self._commands:                 self._commands[cmd](self, args)             else:-                raise self.Failure('Unknown command: %s' % cmd)+                raise self.Failure("Unknown command: %s" % cmd)      def run(self):         while True:-            print('%%% OK', flush=True)+            print("%%% OK", flush=True)             line = sys.stdin.readline()-            if line == '':+            if line == "":                 return             try:                 self._process_line(line)             except self.Failure as e:-                print('%%% FAILURE')+                print("%%% FAILURE")                 print(e.msg)+  # End of server.py
rts/python/tuning.py view
@@ -1,9 +1,11 @@ # Start of tuning.py + def read_tuning_file(kvs, f):     for line in f.read().splitlines():-        size, value = line.split('=')+        size, value = line.split("=")         kvs[size] = int(value)     return kvs+  # End of tuning.py.
rts/python/values.py view
@@ -9,6 +9,7 @@ import struct import sys + class ReaderInput:     def __init__(self, f):         self.f = f@@ -27,7 +28,7 @@      def get_chars(self, n):         n1 = min(n, len(self.lookahead_buffer))-        s = b''.join(self.lookahead_buffer[:n1])+        s = b"".join(self.lookahead_buffer[:n1])         self.lookahead_buffer = self.lookahead_buffer[n1:]         n2 = n - n1         if n2 > 0:@@ -40,24 +41,26 @@             self.unget_char(c)         return c + def skip_spaces(f):     c = f.get_char()     while c != None:         if c.isspace():             c = f.get_char()-        elif c == b'-':-          # May be line comment.-          if f.peek_char() == b'-':-            # Yes, line comment. Skip to end of line.-            while (c != b'\n' and c != None):-              c = f.get_char()-          else:-            break+        elif c == b"-":+            # May be line comment.+            if f.peek_char() == b"-":+                # Yes, line comment. Skip to end of line.+                while c != b"\n" and c != None:+                    c = f.get_char()+            else:+                break         else:-          break+            break     if c:         f.unget_char(c) + def parse_specific_char(f, expected):     got = f.get_char()     if got != expected:@@ -65,12 +68,13 @@         raise ValueError     return True + def parse_specific_string(f, s):     # This funky mess is intended, and is caused by the fact that if `type(b) ==     # bytes` then `type(b[0]) == int`, but we need to match each element with a     # `bytes`, so therefore we make each character an array element-    b = s.encode('utf8')-    bs = [b[i:i+1] for i in range(len(b))]+    b = s.encode("utf8")+    bs = [b[i : i + 1] for i in range(len(b))]     read = []     try:         for c in bs:@@ -82,24 +86,27 @@             f.unget_char(c)         raise + def optional(p, *args):     try:         return p(*args)     except ValueError:         return None + def optional_specific_string(f, s):     c = f.peek_char()     # This funky mess is intended, and is caused by the fact that if `type(b) ==     # bytes` then `type(b[0]) == int`, but we need to match each element with a     # `bytes`, so therefore we make each character an array element-    b = s.encode('utf8')-    bs = [b[i:i+1] for i in range(len(b))]+    b = s.encode("utf8")+    bs = [b[i : i + 1] for i in range(len(b))]     if c == bs[0]:         return parse_specific_string(f, s)     else:         return False + def sepBy(p, sep, *args):     elems = []     x = optional(p, *args)@@ -110,34 +117,36 @@             elems += [x]     return elems + # Assumes '0x' has already been read def parse_hex_int(f):-    s = b''+    s = b""     c = f.get_char()     while c != None:-        if c in b'01234556789ABCDEFabcdef':+        if c in b"01234556789ABCDEFabcdef":             s += c             c = f.get_char()-        elif c == b'_':-            c = f.get_char() # skip _+        elif c == b"_":+            c = f.get_char()  # skip _         else:             f.unget_char(c)             break-    return str(int(s, 16)).encode('utf8') # ugh+    return str(int(s, 16)).encode("utf8")  # ugh + def parse_int(f):-    s = b''+    s = b""     c = f.get_char()-    if c == b'0' and f.peek_char() in b'xX':-        c = f.get_char() # skip X+    if c == b"0" and f.peek_char() in b"xX":+        c = f.get_char()  # skip X         return parse_hex_int(f)     else:         while c != None:             if c.isdigit():                 s += c                 c = f.get_char()-            elif c == b'_':-                c = f.get_char() # skip _+            elif c == b"_":+                c = f.get_char()  # skip _             else:                 f.unget_char(c)                 break@@ -145,72 +154,92 @@             raise ValueError         return s + def parse_int_signed(f):-    s = b''+    s = b""     c = f.get_char() -    if c == b'-' and f.peek_char().isdigit():-      return c + parse_int(f)+    if c == b"-" and f.peek_char().isdigit():+        return c + parse_int(f)     else:-      if c != b'+':-          f.unget_char(c)-      return parse_int(f)+        if c != b"+":+            f.unget_char(c)+        return parse_int(f) + def read_str_comma(f):     skip_spaces(f)-    parse_specific_char(f, b',')-    return b','+    parse_specific_char(f, b",")+    return b"," + def read_str_int(f, s):     skip_spaces(f)     x = int(parse_int_signed(f))     optional_specific_string(f, s)     return x + def read_str_uint(f, s):     skip_spaces(f)     x = int(parse_int(f))     optional_specific_string(f, s)     return x + def read_str_i8(f):-    return np.int8(read_str_int(f, 'i8'))+    return np.int8(read_str_int(f, "i8"))++ def read_str_i16(f):-    return np.int16(read_str_int(f, 'i16'))+    return np.int16(read_str_int(f, "i16"))++ def read_str_i32(f):-    return np.int32(read_str_int(f, 'i32'))+    return np.int32(read_str_int(f, "i32"))++ def read_str_i64(f):-    return np.int64(read_str_int(f, 'i64'))+    return np.int64(read_str_int(f, "i64")) + def read_str_u8(f):-    return np.uint8(read_str_int(f, 'u8'))+    return np.uint8(read_str_int(f, "u8"))++ def read_str_u16(f):-    return np.uint16(read_str_int(f, 'u16'))+    return np.uint16(read_str_int(f, "u16"))++ def read_str_u32(f):-    return np.uint32(read_str_int(f, 'u32'))+    return np.uint32(read_str_int(f, "u32"))++ def read_str_u64(f):-    return np.uint64(read_str_int(f, 'u64'))+    return np.uint64(read_str_int(f, "u64")) + def read_char(f):     skip_spaces(f)-    parse_specific_char(f, b'\'')+    parse_specific_char(f, b"'")     c = f.get_char()-    parse_specific_char(f, b'\'')+    parse_specific_char(f, b"'")     return c + def read_str_hex_float(f, sign):     int_part = parse_hex_int(f)-    parse_specific_char(f, b'.')+    parse_specific_char(f, b".")     frac_part = parse_hex_int(f)-    parse_specific_char(f, b'p')+    parse_specific_char(f, b"p")     exponent = parse_int(f)      int_val = int(int_part, 16)     frac_val = float(int(frac_part, 16)) / (16 ** len(frac_part))     exp_val = int(exponent) -    total_val = (int_val + frac_val) * (2.0 ** exp_val)-    if sign == b'-':+    total_val = (int_val + frac_val) * (2.0**exp_val)+    if sign == b"-":         total_val = -1 * total_val      return float(total_val)@@ -219,15 +248,15 @@ def read_str_decimal(f):     skip_spaces(f)     c = f.get_char()-    if (c == b'-'):-      sign = b'-'+    if c == b"-":+        sign = b"-"     else:-      f.unget_char(c)-      sign = b''+        f.unget_char(c)+        sign = b""      # Check for hexadecimal float     c = f.get_char()-    if (c == '0' and (f.peek_char() in ['x', 'X'])):+    if c == "0" and (f.peek_char() in ["x", "X"]):         f.get_char()         return read_str_hex_float(f, sign)     else:@@ -235,132 +264,143 @@      bef = optional(parse_int, f)     if bef == None:-        bef = b'0'-        parse_specific_char(f, b'.')+        bef = b"0"+        parse_specific_char(f, b".")         aft = parse_int(f)-    elif optional(parse_specific_char, f, b'.'):+    elif optional(parse_specific_char, f, b"."):         aft = parse_int(f)     else:-        aft = b'0'-    if (optional(parse_specific_char, f, b'E') or-        optional(parse_specific_char, f, b'e')):+        aft = b"0"+    if optional(parse_specific_char, f, b"E") or optional(+        parse_specific_char, f, b"e"+    ):         expt = parse_int_signed(f)     else:-        expt = b'0'-    return float(sign + bef + b'.' + aft + b'E' + expt)+        expt = b"0"+    return float(sign + bef + b"." + aft + b"E" + expt) + def read_str_f16(f):     skip_spaces(f)     try:-        parse_specific_string(f, 'f16.nan')+        parse_specific_string(f, "f16.nan")         return np.float32(np.nan)     except ValueError:         try:-            parse_specific_string(f, 'f16.inf')+            parse_specific_string(f, "f16.inf")             return np.float32(np.inf)         except ValueError:             try:-               parse_specific_string(f, '-f16.inf')-               return np.float32(-np.inf)+                parse_specific_string(f, "-f16.inf")+                return np.float32(-np.inf)             except ValueError:-               x = read_str_decimal(f)-               optional_specific_string(f, 'f16')-               return x+                x = read_str_decimal(f)+                optional_specific_string(f, "f16")+                return x + def read_str_f32(f):     skip_spaces(f)     try:-        parse_specific_string(f, 'f32.nan')+        parse_specific_string(f, "f32.nan")         return np.float32(np.nan)     except ValueError:         try:-            parse_specific_string(f, 'f32.inf')+            parse_specific_string(f, "f32.inf")             return np.float32(np.inf)         except ValueError:             try:-               parse_specific_string(f, '-f32.inf')-               return np.float32(-np.inf)+                parse_specific_string(f, "-f32.inf")+                return np.float32(-np.inf)             except ValueError:-               x = read_str_decimal(f)-               optional_specific_string(f, 'f32')-               return x+                x = read_str_decimal(f)+                optional_specific_string(f, "f32")+                return x + def read_str_f64(f):     skip_spaces(f)     try:-        parse_specific_string(f, 'f64.nan')+        parse_specific_string(f, "f64.nan")         return np.float64(np.nan)     except ValueError:         try:-            parse_specific_string(f, 'f64.inf')+            parse_specific_string(f, "f64.inf")             return np.float64(np.inf)         except ValueError:             try:-               parse_specific_string(f, '-f64.inf')-               return np.float64(-np.inf)+                parse_specific_string(f, "-f64.inf")+                return np.float64(-np.inf)             except ValueError:-               x = read_str_decimal(f)-               optional_specific_string(f, 'f64')-               return x+                x = read_str_decimal(f)+                optional_specific_string(f, "f64")+                return x + def read_str_bool(f):     skip_spaces(f)-    if f.peek_char() == b't':-        parse_specific_string(f, 'true')+    if f.peek_char() == b"t":+        parse_specific_string(f, "true")         return True-    elif f.peek_char() == b'f':-        parse_specific_string(f, 'false')+    elif f.peek_char() == b"f":+        parse_specific_string(f, "false")         return False     else:         raise ValueError + def read_str_empty_array(f, type_name, rank):-    parse_specific_string(f, 'empty')-    parse_specific_char(f, b'(')+    parse_specific_string(f, "empty")+    parse_specific_char(f, b"(")     dims = []     for i in range(rank):-        parse_specific_string(f, '[')+        parse_specific_string(f, "[")         dims += [int(parse_int(f))]-        parse_specific_string(f, ']')+        parse_specific_string(f, "]")     if np.product(dims) != 0:         raise ValueError     parse_specific_string(f, type_name)-    parse_specific_char(f, b')')+    parse_specific_char(f, b")")      return tuple(dims) + def read_str_array_elems(f, elem_reader, type_name, rank):     skip_spaces(f)     try:-        parse_specific_char(f, b'[')+        parse_specific_char(f, b"[")     except ValueError:         return read_str_empty_array(f, type_name, rank)     else:         xs = sepBy(elem_reader, read_str_comma, f)         skip_spaces(f)-        parse_specific_char(f, b']')+        parse_specific_char(f, b"]")         return xs + def read_str_array_helper(f, elem_reader, type_name, rank):     def nested_row_reader(_):-        return read_str_array_helper(f, elem_reader, type_name, rank-1)+        return read_str_array_helper(f, elem_reader, type_name, rank - 1)+     if rank == 1:         row_reader = elem_reader     else:         row_reader = nested_row_reader     return read_str_array_elems(f, row_reader, type_name, rank) + def expected_array_dims(l, rank):-  if rank > 1:-      n = len(l)-      if n == 0:-          elem = []-      else:-          elem = l[0]-      return [n] + expected_array_dims(elem, rank-1)-  else:-      return [len(l)]+    if rank > 1:+        n = len(l)+        if n == 0:+            elem = []+        else:+            elem = l[0]+        return [n] + expected_array_dims(elem, rank - 1)+    else:+        return [len(l)] + def verify_array_dims(l, dims):     if dims[0] != len(l):         raise ValueError@@ -368,6 +408,7 @@         for x in l:             verify_array_dims(x, dims[1:]) + def read_str_array(f, elem_reader, type_name, rank, bt):     elems = read_str_array_helper(f, elem_reader, type_name, rank)     if type(elems) == tuple:@@ -378,6 +419,7 @@         verify_array_dims(elems, dims)         return np.array(elems, dtype=bt) + ################################################################################  READ_BINARY_VERSION = 2@@ -385,180 +427,231 @@ # struct format specified at # https://docs.python.org/2/library/struct.html#format-characters + def mk_bin_scalar_reader(t):     def bin_reader(f):-        fmt = FUTHARK_PRIMTYPES[t]['bin_format']-        size = FUTHARK_PRIMTYPES[t]['size']-        tf = FUTHARK_PRIMTYPES[t]['numpy_type']-        return tf(struct.unpack('<' + fmt, f.get_chars(size))[0])+        fmt = FUTHARK_PRIMTYPES[t]["bin_format"]+        size = FUTHARK_PRIMTYPES[t]["size"]+        tf = FUTHARK_PRIMTYPES[t]["numpy_type"]+        return tf(struct.unpack("<" + fmt, f.get_chars(size))[0])+     return bin_reader -read_bin_i8 = mk_bin_scalar_reader('i8')-read_bin_i16 = mk_bin_scalar_reader('i16')-read_bin_i32 = mk_bin_scalar_reader('i32')-read_bin_i64 = mk_bin_scalar_reader('i64') -read_bin_u8 = mk_bin_scalar_reader('u8')-read_bin_u16 = mk_bin_scalar_reader('u16')-read_bin_u32 = mk_bin_scalar_reader('u32')-read_bin_u64 = mk_bin_scalar_reader('u64')+read_bin_i8 = mk_bin_scalar_reader("i8")+read_bin_i16 = mk_bin_scalar_reader("i16")+read_bin_i32 = mk_bin_scalar_reader("i32")+read_bin_i64 = mk_bin_scalar_reader("i64") -read_bin_f16 = mk_bin_scalar_reader('f16')-read_bin_f32 = mk_bin_scalar_reader('f32')-read_bin_f64 = mk_bin_scalar_reader('f64')+read_bin_u8 = mk_bin_scalar_reader("u8")+read_bin_u16 = mk_bin_scalar_reader("u16")+read_bin_u32 = mk_bin_scalar_reader("u32")+read_bin_u64 = mk_bin_scalar_reader("u64") -read_bin_bool = mk_bin_scalar_reader('bool')+read_bin_f16 = mk_bin_scalar_reader("f16")+read_bin_f32 = mk_bin_scalar_reader("f32")+read_bin_f64 = mk_bin_scalar_reader("f64") +read_bin_bool = mk_bin_scalar_reader("bool")++ def read_is_binary(f):     skip_spaces(f)     c = f.get_char()-    if c == b'b':+    if c == b"b":         bin_version = read_bin_u8(f)         if bin_version != READ_BINARY_VERSION:-            panic(1, "binary-input: File uses version %i, but I only understand version %i.\n",-                  bin_version, READ_BINARY_VERSION)+            panic(+                1,+                "binary-input: File uses version %i, but I only understand version %i.\n",+                bin_version,+                READ_BINARY_VERSION,+            )         return True     else:         f.unget_char(c)         return False -FUTHARK_PRIMTYPES = {-    'i8':  {'binname' : b"  i8",-            'size' : 1,-            'bin_reader': read_bin_i8,-            'str_reader': read_str_i8,-            'bin_format': 'b',-            'numpy_type': np.int8 }, -    'i16': {'binname' : b" i16",-            'size' : 2,-            'bin_reader': read_bin_i16,-            'str_reader': read_str_i16,-            'bin_format': 'h',-            'numpy_type': np.int16 },--    'i32': {'binname' : b" i32",-            'size' : 4,-            'bin_reader': read_bin_i32,-            'str_reader': read_str_i32,-            'bin_format': 'i',-            'numpy_type': np.int32 },--    'i64': {'binname' : b" i64",-            'size' : 8,-            'bin_reader': read_bin_i64,-            'str_reader': read_str_i64,-            'bin_format': 'q',-            'numpy_type': np.int64},--    'u8':  {'binname' : b"  u8",-            'size' : 1,-            'bin_reader': read_bin_u8,-            'str_reader': read_str_u8,-            'bin_format': 'B',-            'numpy_type': np.uint8 },--    'u16': {'binname' : b" u16",-            'size' : 2,-            'bin_reader': read_bin_u16,-            'str_reader': read_str_u16,-            'bin_format': 'H',-            'numpy_type': np.uint16 },--    'u32': {'binname' : b" u32",-            'size' : 4,-            'bin_reader': read_bin_u32,-            'str_reader': read_str_u32,-            'bin_format': 'I',-            'numpy_type': np.uint32 },--    'u64': {'binname' : b" u64",-            'size' : 8,-            'bin_reader': read_bin_u64,-            'str_reader': read_str_u64,-            'bin_format': 'Q',-            'numpy_type': np.uint64 },--    'f16': {'binname' : b" f16",-            'size' : 2,-            'bin_reader': read_bin_f16,-            'str_reader': read_str_f16,-            'bin_format': 'e',-            'numpy_type': np.float16 },--    'f32': {'binname' : b" f32",-            'size' : 4,-            'bin_reader': read_bin_f32,-            'str_reader': read_str_f32,-            'bin_format': 'f',-            'numpy_type': np.float32 },--    'f64': {'binname' : b" f64",-            'size' : 8,-            'bin_reader': read_bin_f64,-            'str_reader': read_str_f64,-            'bin_format': 'd',-            'numpy_type': np.float64 },--    'bool': {'binname' : b"bool",-             'size' : 1,-             'bin_reader': read_bin_bool,-             'str_reader': read_str_bool,-             'bin_format': 'b',-             'numpy_type': bool }+FUTHARK_PRIMTYPES = {+    "i8": {+        "binname": b"  i8",+        "size": 1,+        "bin_reader": read_bin_i8,+        "str_reader": read_str_i8,+        "bin_format": "b",+        "numpy_type": np.int8,+    },+    "i16": {+        "binname": b" i16",+        "size": 2,+        "bin_reader": read_bin_i16,+        "str_reader": read_str_i16,+        "bin_format": "h",+        "numpy_type": np.int16,+    },+    "i32": {+        "binname": b" i32",+        "size": 4,+        "bin_reader": read_bin_i32,+        "str_reader": read_str_i32,+        "bin_format": "i",+        "numpy_type": np.int32,+    },+    "i64": {+        "binname": b" i64",+        "size": 8,+        "bin_reader": read_bin_i64,+        "str_reader": read_str_i64,+        "bin_format": "q",+        "numpy_type": np.int64,+    },+    "u8": {+        "binname": b"  u8",+        "size": 1,+        "bin_reader": read_bin_u8,+        "str_reader": read_str_u8,+        "bin_format": "B",+        "numpy_type": np.uint8,+    },+    "u16": {+        "binname": b" u16",+        "size": 2,+        "bin_reader": read_bin_u16,+        "str_reader": read_str_u16,+        "bin_format": "H",+        "numpy_type": np.uint16,+    },+    "u32": {+        "binname": b" u32",+        "size": 4,+        "bin_reader": read_bin_u32,+        "str_reader": read_str_u32,+        "bin_format": "I",+        "numpy_type": np.uint32,+    },+    "u64": {+        "binname": b" u64",+        "size": 8,+        "bin_reader": read_bin_u64,+        "str_reader": read_str_u64,+        "bin_format": "Q",+        "numpy_type": np.uint64,+    },+    "f16": {+        "binname": b" f16",+        "size": 2,+        "bin_reader": read_bin_f16,+        "str_reader": read_str_f16,+        "bin_format": "e",+        "numpy_type": np.float16,+    },+    "f32": {+        "binname": b" f32",+        "size": 4,+        "bin_reader": read_bin_f32,+        "str_reader": read_str_f32,+        "bin_format": "f",+        "numpy_type": np.float32,+    },+    "f64": {+        "binname": b" f64",+        "size": 8,+        "bin_reader": read_bin_f64,+        "str_reader": read_str_f64,+        "bin_format": "d",+        "numpy_type": np.float64,+    },+    "bool": {+        "binname": b"bool",+        "size": 1,+        "bin_reader": read_bin_bool,+        "str_reader": read_str_bool,+        "bin_format": "b",+        "numpy_type": bool,+    }, } + def read_bin_read_type(f):     read_binname = f.get_chars(4) -    for (k,v) in FUTHARK_PRIMTYPES.items():-        if v['binname'] == read_binname:+    for k, v in FUTHARK_PRIMTYPES.items():+        if v["binname"] == read_binname:             return k     panic(1, "binary-input: Did not recognize the type '%s'.\n", read_binname) + def numpy_type_to_type_name(t):-    for (k,v) in FUTHARK_PRIMTYPES.items():-        if v['numpy_type'] == t:+    for k, v in FUTHARK_PRIMTYPES.items():+        if v["numpy_type"] == t:             return k-    raise Exception('Unknown Numpy type: {}'.format(t))+    raise Exception("Unknown Numpy type: {}".format(t)) + def read_bin_ensure_scalar(f, expected_type):-  dims = read_bin_i8(f)+    dims = read_bin_i8(f) -  if dims != 0:-      panic(1, "binary-input: Expected scalar (0 dimensions), but got array with %i dimensions.\n", dims)+    if dims != 0:+        panic(+            1,+            "binary-input: Expected scalar (0 dimensions), but got array with %i dimensions.\n",+            dims,+        ) -  bin_type = read_bin_read_type(f)-  if bin_type != expected_type:-      panic(1, "binary-input: Expected scalar of type %s but got scalar of type %s.\n",-            expected_type, bin_type)+    bin_type = read_bin_read_type(f)+    if bin_type != expected_type:+        panic(+            1,+            "binary-input: Expected scalar of type %s but got scalar of type %s.\n",+            expected_type,+            bin_type,+        ) + # ------------------------------------------------------------------------------ # General interface for reading Primitive Futhark Values # ------------------------------------------------------------------------------ + def read_scalar(f, ty):     if read_is_binary(f):         read_bin_ensure_scalar(f, ty)-        return FUTHARK_PRIMTYPES[ty]['bin_reader'](f)-    return FUTHARK_PRIMTYPES[ty]['str_reader'](f)+        return FUTHARK_PRIMTYPES[ty]["bin_reader"](f)+    return FUTHARK_PRIMTYPES[ty]["str_reader"](f) + def read_array(f, expected_type, rank):     if not read_is_binary(f):-        str_reader = FUTHARK_PRIMTYPES[expected_type]['str_reader']-        return read_str_array(f, str_reader, expected_type, rank,-                              FUTHARK_PRIMTYPES[expected_type]['numpy_type'])+        str_reader = FUTHARK_PRIMTYPES[expected_type]["str_reader"]+        return read_str_array(+            f,+            str_reader,+            expected_type,+            rank,+            FUTHARK_PRIMTYPES[expected_type]["numpy_type"],+        )      bin_rank = read_bin_u8(f)      if bin_rank != rank:-        panic(1, "binary-input: Expected %i dimensions, but got array with %i dimensions.\n",-              rank, bin_rank)+        panic(+            1,+            "binary-input: Expected %i dimensions, but got array with %i dimensions.\n",+            rank,+            bin_rank,+        )      bin_type_enum = read_bin_read_type(f)     if expected_type != bin_type_enum:-        panic(1, "binary-input: Expected %iD-array with element type '%s' but got %iD-array with element type '%s'.\n",-              rank, expected_type, bin_rank, bin_type_enum)+        panic(+            1,+            "binary-input: Expected %iD-array with element type '%s' but got %iD-array with element type '%s'.\n",+            rank,+            expected_type,+            bin_rank,+            bin_type_enum,+        )      shape = []     elem_count = 1@@ -567,43 +660,51 @@         elem_count *= bin_size         shape.append(bin_size) -    bin_fmt = FUTHARK_PRIMTYPES[bin_type_enum]['bin_format']+    bin_fmt = FUTHARK_PRIMTYPES[bin_type_enum]["bin_format"]      # We first read the expected number of types into a bytestring,     # then use np.frombuffer.  This is because np.fromfile does not     # work on things that are insufficiently file-like, like a network     # stream.-    bytes = f.get_chars(elem_count * FUTHARK_PRIMTYPES[expected_type]['size'])-    arr = np.frombuffer(bytes, dtype=FUTHARK_PRIMTYPES[bin_type_enum]['numpy_type'])+    bytes = f.get_chars(elem_count * FUTHARK_PRIMTYPES[expected_type]["size"])+    arr = np.frombuffer(+        bytes, dtype=FUTHARK_PRIMTYPES[bin_type_enum]["numpy_type"]+    )     arr.shape = shape      return arr -if sys.version_info >= (3,0):++if sys.version_info >= (3, 0):     input_reader = ReaderInput(sys.stdin.buffer) else:     input_reader = ReaderInput(sys.stdin)  import re + def read_value(type_desc, reader=input_reader):     """Read a value of the given type.  The type is a string-representation of the Futhark type."""-    m = re.match(r'((?:\[\])*)([a-z0-9]+)$', type_desc)+    representation of the Futhark type."""+    m = re.match(r"((?:\[\])*)([a-z0-9]+)$", type_desc)     if m:-        dims = int(len(m.group(1))/2)+        dims = int(len(m.group(1)) / 2)         basetype = m.group(2)-    assert m and basetype in FUTHARK_PRIMTYPES, "Unknown type: {}".format(type_desc)+    assert m and basetype in FUTHARK_PRIMTYPES, "Unknown type: {}".format(+        type_desc+    )     if dims > 0:         return read_array(reader, basetype, dims)     else:         return read_scalar(reader, basetype) + def end_of_input(entry, f=input_reader):     skip_spaces(f)-    if f.get_char() != b'':-        panic(1, "Expected EOF on stdin after reading input for \"%s\".", entry)+    if f.get_char() != b"":+        panic(1, 'Expected EOF on stdin after reading input for "%s".', entry) + def write_value_text(v, out=sys.stdout):     if type(v) == np.uint8:         out.write("%uu8" % v)@@ -628,63 +729,71 @@             out.write("false")     elif type(v) == np.float16:         if np.isnan(v):-            out.write('f16.nan')+            out.write("f16.nan")         elif np.isinf(v):             if v >= 0:-                out.write('f16.inf')+                out.write("f16.inf")             else:-                out.write('-f16.inf')+                out.write("-f16.inf")         else:             out.write("%.6ff16" % v)     elif type(v) == np.float32:         if np.isnan(v):-            out.write('f32.nan')+            out.write("f32.nan")         elif np.isinf(v):             if v >= 0:-                out.write('f32.inf')+                out.write("f32.inf")             else:-                out.write('-f32.inf')+                out.write("-f32.inf")         else:             out.write("%.6ff32" % v)     elif type(v) == np.float64:         if np.isnan(v):-            out.write('f64.nan')+            out.write("f64.nan")         elif np.isinf(v):             if v >= 0:-                out.write('f64.inf')+                out.write("f64.inf")             else:-                out.write('-f64.inf')+                out.write("-f64.inf")         else:             out.write("%.6ff64" % v)     elif type(v) == np.ndarray:         if np.product(v.shape) == 0:             tname = numpy_type_to_type_name(v.dtype)-            out.write('empty({}{})'.format(''.join(['[{}]'.format(d)-                                                    for d in v.shape]), tname))+            out.write(+                "empty({}{})".format(+                    "".join(["[{}]".format(d) for d in v.shape]), tname+                )+            )         else:             first = True-            out.write('[')+            out.write("[")             for x in v:-                if not first: out.write(', ')+                if not first:+                    out.write(", ")                 first = False                 write_value(x, out=out)-            out.write(']')+            out.write("]")     else:         raise Exception("Cannot print value of type {}: {}".format(type(v), v)) -type_strs = { np.dtype('int8'): b'  i8',-              np.dtype('int16'): b' i16',-              np.dtype('int32'): b' i32',-              np.dtype('int64'): b' i64',-              np.dtype('uint8'): b'  u8',-              np.dtype('uint16'): b' u16',-              np.dtype('uint32'): b' u32',-              np.dtype('uint64'): b' u64',-              np.dtype('float16'): b' f16',-              np.dtype('float32'): b' f32',-              np.dtype('float64'): b' f64',-              np.dtype('bool'): b'bool'} +type_strs = {+    np.dtype("int8"): b"  i8",+    np.dtype("int16"): b" i16",+    np.dtype("int32"): b" i32",+    np.dtype("int64"): b" i64",+    np.dtype("uint8"): b"  u8",+    np.dtype("uint16"): b" u16",+    np.dtype("uint32"): b" u32",+    np.dtype("uint64"): b" u64",+    np.dtype("float16"): b" f16",+    np.dtype("float32"): b" f32",+    np.dtype("float64"): b" f64",+    np.dtype("bool"): b"bool",+}++ def construct_binary_value(v):     t = v.dtype     shape = v.shape@@ -695,27 +804,30 @@      num_bytes = 1 + 1 + 1 + 4 + len(shape) * 8 + elems * t.itemsize     bytes = bytearray(num_bytes)-    bytes[0] = np.int8(ord('b'))+    bytes[0] = np.int8(ord("b"))     bytes[1] = 2     bytes[2] = np.int8(len(shape))     bytes[3:7] = type_strs[t]      for i in range(len(shape)):-        bytes[7+i*8:7+(i+1)*8] = np.int64(shape[i]).tobytes()+        bytes[7 + i * 8 : 7 + (i + 1) * 8] = np.int64(shape[i]).tobytes() -    bytes[7+len(shape)*8:] = np.ascontiguousarray(v).tobytes()+    bytes[7 + len(shape) * 8 :] = np.ascontiguousarray(v).tobytes()      return bytes + def write_value_binary(v, out=sys.stdout):-    if sys.version_info >= (3,0):+    if sys.version_info >= (3, 0):         out = out.buffer     out.write(construct_binary_value(v)) + def write_value(v, out=sys.stdout, binary=False):     if binary:         return write_value_binary(v, out=out)     else:         return write_value_text(v, out=out)+  # End of values.py.
src/Futhark/AD/Rev/Loop.hs view
@@ -4,7 +4,7 @@  import Control.Monad import Data.Foldable (toList)-import Data.List (nub, (\\))+import Data.List ((\\)) import Data.Map qualified as M import Data.Maybe import Futhark.AD.Rev.Monad@@ -16,7 +16,7 @@ import Futhark.Tools import Futhark.Transform.Rename import Futhark.Transform.Substitute-import Futhark.Util (traverseFold)+import Futhark.Util (nubOrd, traverseFold)  -- | A convenience function to bring the components of a for-loop into -- scope and throw an error if the passed 'Exp' is not a for-loop.@@ -353,7 +353,7 @@                   loopFree =                     (namesToList (freeIn loop') \\ loop_var_arrays') \\ mapMaybe getVName loop_vals',                   loopVars = loop_var_arrays',-                  loopVals = nub $ mapMaybe getVName loop_vals'+                  loopVals = nubOrd $ mapMaybe getVName loop_vals'                 }          renameLoopTape $ M.fromList $ zip (map paramName loop_params) (map paramName loop_params')
src/Futhark/Analysis/Interference.hs view
@@ -3,6 +3,7 @@ -- | Interference analysis for Futhark programs. module Futhark.Analysis.Interference (Graph, analyseProgGPU) where +import Control.Monad import Control.Monad.Reader import Data.Foldable (toList) import Data.Function ((&))
src/Futhark/Analysis/LastUse.hs view
@@ -18,6 +18,7 @@   ) where +import Control.Monad import Control.Monad.Reader import Control.Monad.State.Strict import Data.Bifunctor (bimap)
src/Futhark/Analysis/MemAlias.hs view
@@ -8,6 +8,7 @@   ) where +import Control.Monad import Control.Monad.Reader import Data.Bifunctor import Data.Function ((&))
src/Futhark/Analysis/Metrics.hs view
@@ -15,6 +15,7 @@   ) where +import Control.Monad import Control.Monad.Writer import Data.List (tails) import Data.Map.Strict qualified as M
src/Futhark/Bench.hs view
@@ -16,7 +16,9 @@ where  import Control.Applicative-import Control.Monad.Except+import Control.Monad+import Control.Monad.Except (ExceptT, MonadError (..), liftEither, runExceptT)+import Control.Monad.IO.Class (MonadIO, liftIO) import Data.Aeson qualified as JSON import Data.Aeson.Key qualified as JSON import Data.Aeson.KeyMap qualified as JSON
src/Futhark/CLI/Bench.hs view
@@ -4,7 +4,7 @@ import Control.Arrow (first) import Control.Exception import Control.Monad-import Control.Monad.Except hiding (throwError)+import Control.Monad.IO.Class (liftIO) import Data.ByteString.Char8 qualified as SBS import Data.ByteString.Lazy.Char8 qualified as LBS import Data.Either@@ -404,11 +404,12 @@       g <- create       resampled <- liftIO $ resample g [Mean] 70000 vec_runtimes       let bootstrapCI =-            ( estPoint boot - confIntLDX (estError boot),-              estPoint boot + confIntUDX (estError boot)-            )-            where-              boot = head $ bootstrapBCA cl95 vec_runtimes resampled+            case bootstrapBCA cl95 vec_runtimes resampled of+              boot : _ ->+                ( estPoint boot - confIntLDX (estError boot),+                  estPoint boot + confIntUDX (estError boot)+                )+              _ -> (0, 0)        reportResult runtimes bootstrapCI       -- We throw away the 'errout' because it is almost always
src/Futhark/CLI/Doc.hs view
@@ -4,6 +4,7 @@ -- | @futhark doc@ module Futhark.CLI.Doc (main) where +import Control.Monad import Control.Monad.State import Data.FileEmbed import Data.List (nubBy)
src/Futhark/CLI/Eval.hs view
@@ -2,8 +2,9 @@  import Control.Exception import Control.Monad-import Control.Monad.Except+import Control.Monad.Except (ExceptT, runExceptT, throwError) import Control.Monad.Free.Church+import Control.Monad.IO.Class (MonadIO, liftIO) import Data.Map qualified as M import Data.Maybe import Data.Text qualified as T
src/Futhark/CLI/Literate.hs view
@@ -2,6 +2,7 @@ module Futhark.CLI.Literate (main) where  import Codec.BMP qualified as BMP+import Control.Monad import Control.Monad.Except import Control.Monad.State hiding (State) import Data.Bifunctor (first, second)@@ -530,10 +531,10 @@     line = T.unwords . map prettyText  imgBlock :: FilePath -> T.Text-imgBlock f = "\n\n![](" <> T.pack f <> ")\n\n"+imgBlock f = "![](" <> T.pack f <> ")\n"  videoBlock :: VideoParams -> FilePath -> T.Text-videoBlock opts f = "\n\n![](" <> T.pack f <> ")" <> opts' <> "\n\n"+videoBlock opts f = "![](" <> T.pack f <> ")" <> opts' <> "\n"   where     opts'       | all T.null [loop, autoplay] =@@ -718,14 +719,7 @@     newFileContents env (Nothing, "eval.txt") $ \resultf -> do       v <- either nope pure =<< evalExpToGround literateBuiltin (envServer env) e       liftIO $ T.writeFile resultf $ prettyText v-  pure $-    T.unlines-      [ "",-        "```",-        result,-        "```",-        ""-      ]+  pure $ T.unlines ["```", result, "```"]   where     nope t =       throwError $ "Cannot show value of type " <> prettyText t@@ -1021,8 +1015,8 @@  processBlock :: Env -> Block -> IO (Failure, T.Text, Files) processBlock _ (BlockCode code)-  | T.null code = pure (Success, "\n", mempty)-  | otherwise = pure (Success, "\n```futhark\n" <> code <> "```\n\n", mempty)+  | T.null code = pure (Success, mempty, mempty)+  | otherwise = pure (Success, "```futhark\n" <> code <> "```\n", mempty) processBlock _ (BlockComment pretty) =   pure (Success, pretty, mempty) processBlock env (BlockDirective directive text) = do@@ -1039,7 +1033,7 @@   (r, files) <- runScriptM $ processDirective env' directive   case r of     Left err -> failed prompt err files-    Right t -> pure (Success, prompt <> t, files)+    Right t -> pure (Success, prompt <> "\n" <> t, files)   where     failed prompt err files = do       let message = prettyTextOneLine directive <> " failed:\n" <> err <> "\n"@@ -1072,7 +1066,7 @@   (failures, outputs, files) <-     unzip3 <$> mapM (processBlock env) script   cleanupImgDir env $ mconcat files-  pure (foldl' min Success failures, mconcat outputs)+  pure (foldl' min Success failures, T.intercalate "\n" outputs)  commandLineOptions :: [FunOptDescr Options] commandLineOptions =
src/Futhark/CLI/Misc.hs view
@@ -9,6 +9,7 @@   ) where +import Control.Monad import Control.Monad.State import Data.ByteString.Lazy qualified as BS import Data.Function (on)
src/Futhark/CLI/Pkg.hs view
@@ -1,6 +1,7 @@ -- | @futhark pkg@ module Futhark.CLI.Pkg (main) where +import Control.Monad import Control.Monad.IO.Class import Control.Monad.Reader import Control.Monad.State
src/Futhark/CLI/REPL.hs view
@@ -20,7 +20,7 @@ import Futhark.MonadFreshNames import Futhark.Util (fancyTerminal) import Futhark.Util.Options-import Futhark.Util.Pretty (AnsiStyle, Color (..), Doc, align, annotate, bgColorDull, bold, brackets, color, docText, docTextForHandle, hardline, pretty, putDoc, putDocLn, unAnnotate, (<+>))+import Futhark.Util.Pretty (AnsiStyle, Color (..), Doc, align, annotate, bgColorDull, bold, brackets, color, docText, docTextForHandle, hardline, oneLine, pretty, putDoc, putDocLn, unAnnotate, (<+>)) import Futhark.Version import Language.Futhark import Language.Futhark.Interpreter qualified as I@@ -288,7 +288,7 @@             Left err -> liftIO $ print err             Right v -> liftIO $ putDoc $ I.prettyValue v <> hardline       | otherwise -> liftIO $ do-          T.putStrLn $ "Inferred type of expression: " <> prettyText (typeOf e')+          putDocLn $ "Inferred type of expression: " <> align (pretty (typeOf e'))           T.putStrLn $             "The following types are ambiguous: "               <> T.intercalate ", " (map (nameToText . toName . typeParamName) tparams)@@ -382,7 +382,7 @@ genTypeCommand ::   (String -> T.Text -> Either SyntaxError a) ->   (Imports -> VNameSource -> T.Env -> a -> (Warnings, Either T.TypeError b)) ->-  (b -> String) ->+  (b -> Doc AnsiStyle) ->   Command genTypeCommand f g h e = do   prompt <- getPrompt@@ -392,17 +392,17 @@       (imports, src, tenv, _) <- getIt       case snd $ g imports src tenv e' of         Left err -> liftIO $ putDoc $ T.prettyTypeErrorNoLoc err-        Right x -> liftIO $ putStrLn $ h x+        Right x -> liftIO $ putDocLn $ h x  typeCommand :: Command typeCommand = genTypeCommand parseExp T.checkExp $ \(ps, e) ->-  prettyString e-    <> concatMap ((" " <>) . prettyString) ps+  oneLine (pretty e)+    <> foldMap ((" " <>) . pretty) ps     <> " : "-    <> prettyString (typeOf e)+    <> oneLine (pretty (typeOf e))  mtypeCommand :: Command-mtypeCommand = genTypeCommand parseModExp T.checkModExp $ prettyString . fst+mtypeCommand = genTypeCommand parseModExp T.checkModExp $ pretty . fst  unbreakCommand :: Command unbreakCommand _ = do
src/Futhark/CLI/Run.hs view
@@ -3,8 +3,9 @@  import Control.Exception import Control.Monad-import Control.Monad.Except+import Control.Monad.Except (ExceptT, runExceptT, throwError) import Control.Monad.Free.Church+import Control.Monad.IO.Class (MonadIO, liftIO) import Data.ByteString.Lazy qualified as BS import Data.Map qualified as M import Data.Maybe
src/Futhark/CLI/Test.hs view
@@ -7,8 +7,10 @@ import Control.Concurrent import Control.Exception import Control.Monad-import Control.Monad.Except hiding (throwError)+import Control.Monad.Except (ExceptT (..), MonadError, runExceptT, withExceptT) import Control.Monad.Except qualified as E+import Control.Monad.IO.Class (MonadIO, liftIO)+import Control.Monad.Trans.Class (lift) import Data.ByteString qualified as SBS import Data.ByteString.Lazy qualified as LBS import Data.List (delete, partition)
src/Futhark/CodeGen/Backends/COpenCL/Boilerplate.hs view
@@ -17,6 +17,7 @@   ) where +import Control.Monad import Control.Monad.State import Data.Map qualified as M import Data.Text qualified as T
src/Futhark/CodeGen/Backends/GenericC.hs view
@@ -17,6 +17,7 @@   ) where +import Control.Monad import Control.Monad.Reader import Control.Monad.State import Data.Bifunctor (second)
src/Futhark/CodeGen/Backends/GenericC/Code.hs view
@@ -11,7 +11,8 @@   ) where -import Control.Monad.Reader+import Control.Monad+import Control.Monad.Reader (asks) import Data.Maybe import Data.Text qualified as T import Futhark.CodeGen.Backends.GenericC.Monad
src/Futhark/CodeGen/Backends/GenericC/EntryPoints.hs view
@@ -6,7 +6,8 @@   ) where -import Control.Monad.Reader+import Control.Monad+import Control.Monad.Reader (asks) import Data.Maybe import Data.Text qualified as T import Futhark.CodeGen.Backends.GenericC.Monad@@ -133,9 +134,6 @@ entryName :: Name -> T.Text entryName = ("entry_" <>) . escapeName . nameToText -tuningParamsName :: Name -> T.Text-tuningParamsName = ("tuning_params_for_" <>) . escapeName . nameToText- onEntryPoint ::   [C.BlockItem] ->   [Name] ->@@ -152,7 +150,6 @@   decl_mem <- declAllocatedMem    entry_point_function_name <- publicName $ entryName ename-  tuning_params_name <- publicName $ tuningParamsName ename    (inputs', unpack_entry_inputs) <- prepareEntryInputs $ map snd args   let (entry_point_input_params, entry_point_input_checks) = unzip inputs'@@ -168,10 +165,6 @@                                      ($ty:ctx_ty *ctx,                                       $params:entry_point_output_params,                                       $params:entry_point_input_params);|]--  headerDecl-    MiscDecl-    [C.cedecl|const int* $id:tuning_params_name(void);|]    let checks = catMaybes entry_point_input_checks       check_input =
src/Futhark/CodeGen/Backends/GenericC/Fun.hs view
@@ -9,7 +9,7 @@   ) where -import Control.Monad.Reader+import Control.Monad import Futhark.CodeGen.Backends.GenericC.Code import Futhark.CodeGen.Backends.GenericC.Monad import Futhark.CodeGen.ImpCode
src/Futhark/CodeGen/Backends/GenericC/Monad.hs view
@@ -77,7 +77,7 @@   ) where -import Control.Monad.Identity+import Control.Monad import Control.Monad.Reader import Control.Monad.State import Data.Bifunctor (first)
src/Futhark/CodeGen/Backends/GenericC/Types.hs view
@@ -8,8 +8,9 @@   ) where -import Control.Monad.Reader-import Control.Monad.State+import Control.Monad+import Control.Monad.Reader (asks)+import Control.Monad.State (gets, modify) import Data.Char (isDigit) import Data.Map.Strict qualified as M import Data.Maybe
src/Futhark/CodeGen/Backends/GenericPython.hs view
@@ -41,7 +41,7 @@   ) where -import Control.Monad.Identity+import Control.Monad import Control.Monad.RWS import Data.Char (isAlpha, isAlphaNum) import Data.Map qualified as M
src/Futhark/CodeGen/Backends/GenericWASM.hs view
@@ -15,13 +15,13 @@   ) where -import Data.List (intercalate, nub)+import Data.List (intercalate) import Data.Text qualified as T import Futhark.CodeGen.Backends.GenericC qualified as GC import Futhark.CodeGen.Backends.SimpleRep (opaqueName) import Futhark.CodeGen.ImpCode.Sequential qualified as Imp import Futhark.CodeGen.RTS.JavaScript-import Futhark.Util (showText)+import Futhark.Util (nubOrd, showText) import Language.Futhark.Primitive import NeatInterpolation (text) @@ -69,7 +69,7 @@   where     arrays = filter isArray typs     opaques = filter isOpaque typs-    typs = nub $ concatMap (\jse -> parameters jse ++ ret jse) jses+    typs = nubOrd $ concatMap (\jse -> parameters jse ++ ret jse) jses     gfn typ str = "_futhark_" ++ typ ++ "_" ++ baseType str ++ "_" ++ show (dim str) ++ "d"  javascriptWrapper :: [JSEntryPoint] -> T.Text@@ -101,7 +101,7 @@     ]   where     arrays = filter isArray typs-    typs = nub $ concatMap (\jse -> parameters jse ++ ret jse) entryPoints+    typs = nubOrd $ concatMap (\jse -> parameters jse ++ ret jse) entryPoints  constructor :: [JSEntryPoint] -> T.Text constructor jses =
src/Futhark/CodeGen/ImpGen.hs view
@@ -120,9 +120,9 @@   ) where +import Control.Monad import Control.Monad.Reader import Control.Monad.State-import Control.Monad.Writer import Control.Parallel.Strategies import Data.Bifunctor (first) import Data.DList qualified as DL
src/Futhark/CodeGen/ImpGen/GPU.hs view
@@ -11,7 +11,7 @@   ) where -import Control.Monad.Except+import Control.Monad import Data.List (foldl') import Data.Map qualified as M import Data.Maybe
src/Futhark/CodeGen/ImpGen/GPU/Base.hs view
@@ -46,7 +46,7 @@   ) where -import Control.Monad.Except+import Control.Monad import Data.List (foldl') import Data.Map.Strict qualified as M import Data.Maybe@@ -1061,7 +1061,7 @@         (tvExp phys_group_id + i * sExt32 (kernelNumGroups constants))     -- Make sure the virtual group is actually done before we let     -- another virtual group have its way with it.-    sOp $ Imp.Barrier Imp.FenceGlobal+    sOp $ Imp.ErrorSync Imp.FenceGlobal virtualiseGroups _ _ m = do   gid <- kernelGroupIdVar . kernelConstants <$> askEnv   m $ Imp.le32 gid
src/Futhark/CodeGen/ImpGen/GPU/Group.hs view
@@ -14,7 +14,7 @@   ) where -import Control.Monad.Except+import Control.Monad import Data.Bifunctor import Data.List (partition, zip4) import Data.Map.Strict qualified as M@@ -282,8 +282,10 @@ compileGroupExp (Pat [dest]) (BasicOp (ArrayLit es _)) =   forM_ (zip [0 ..] es) $ \(i, e) ->     copyDWIMFix (patElemName dest) [fromIntegral (i :: Int64)] e []-compileGroupExp _ (BasicOp (UpdateAcc acc is vs)) =-  updateAcc acc is vs+compileGroupExp _ (BasicOp (UpdateAcc acc is vs)) = do+  ltid <- kernelLocalThreadId . kernelConstants <$> askEnv+  sWhen (ltid .==. 0) $ updateAcc acc is vs+  sOp $ Imp.Barrier Imp.FenceLocal compileGroupExp (Pat [dest]) (BasicOp (Replicate ds se)) = do   flat <- newVName "rep_flat"   is <- replicateM (arrayRank dest_t) (newVName "rep_i")
src/Futhark/CodeGen/ImpGen/GPU/SegHist.hs view
@@ -37,7 +37,7 @@ --   use global memory module Futhark.CodeGen.ImpGen.GPU.SegHist (compileSegHist) where -import Control.Monad.Except+import Control.Monad import Data.List (foldl', genericLength, zip5) import Data.Map qualified as M import Data.Maybe
src/Futhark/CodeGen/ImpGen/GPU/SegMap.hs view
@@ -6,7 +6,7 @@ -- by having actual workgroups run a loop to imitate multiple workgroups. module Futhark.CodeGen.ImpGen.GPU.SegMap (compileSegMap) where -import Control.Monad.Except+import Control.Monad import Futhark.CodeGen.ImpCode.GPU qualified as Imp import Futhark.CodeGen.ImpGen import Futhark.CodeGen.ImpGen.GPU.Base
src/Futhark/CodeGen/ImpGen/GPU/SegRed.hs view
@@ -48,7 +48,7 @@   ) where -import Control.Monad.Except+import Control.Monad import Data.List (genericLength, zip7) import Data.Maybe import Futhark.CodeGen.ImpCode.GPU qualified as Imp
src/Futhark/CodeGen/ImpGen/GPU/SegScan/SinglePass.hs view
@@ -5,7 +5,7 @@ -- with some constraints on the operator.  We use this when we can. module Futhark.CodeGen.ImpGen.GPU.SegScan.SinglePass (compileSegScan) where -import Control.Monad.Except+import Control.Monad import Data.List (zip4) import Data.Maybe import Futhark.CodeGen.ImpCode.GPU qualified as Imp
src/Futhark/CodeGen/ImpGen/GPU/SegScan/TwoPass.hs view
@@ -4,7 +4,7 @@ -- fairly inefficient two-pass algorithm, but can handle anything. module Futhark.CodeGen.ImpGen.GPU.SegScan.TwoPass (compileSegScan) where -import Control.Monad.Except+import Control.Monad import Control.Monad.State import Data.List (delete, find, foldl', zip4) import Data.Maybe
src/Futhark/CodeGen/ImpGen/GPU/ToOpenCL.hs view
@@ -8,6 +8,7 @@   ) where +import Control.Monad import Control.Monad.Identity import Control.Monad.Reader import Control.Monad.State
src/Futhark/CodeGen/ImpGen/Multicore/SegHist.hs view
@@ -5,6 +5,7 @@  import Control.Monad import Data.List (zip4)+import Data.Maybe (listToMaybe) import Futhark.CodeGen.ImpCode.Multicore qualified as Imp import Futhark.CodeGen.ImpGen import Futhark.CodeGen.ImpGen.Multicore.Base@@ -58,7 +59,7 @@   let ns = map snd $ unSegSpace space       ns_64 = map pe64 ns       num_histos' = tvExp num_histos-      hist_width = histSize $ head histops+      hist_width = maybe 0 histSize $ listToMaybe histops       use_subhistogram = sExt64 num_histos' * hist_width .<=. product ns_64    histops' <- renameHistOpLambda histops
src/Futhark/Compiler.hs view
@@ -18,7 +18,8 @@ where  import Control.Monad-import Control.Monad.Except+import Control.Monad.Except (MonadError)+import Control.Monad.IO.Class (MonadIO, liftIO) import Data.Bifunctor (first) import Data.List (sortOn) import Data.List.NonEmpty qualified as NE
src/Futhark/Compiler/Program.hs view
@@ -31,7 +31,7 @@     readMVar,   ) import Control.Monad-import Control.Monad.Except+import Control.Monad.IO.Class (MonadIO, liftIO) import Control.Monad.State (execStateT, gets, modify) import Data.Bifunctor (first) import Data.List (intercalate, sort)
src/Futhark/Construct.hs view
@@ -120,6 +120,7 @@   ) where +import Control.Monad import Control.Monad.Identity import Control.Monad.State import Data.List (foldl', sortOn, transpose)
src/Futhark/Doc/Generator.hs view
@@ -5,7 +5,7 @@ import Control.Arrow ((***)) import Control.Monad import Control.Monad.Reader-import Control.Monad.Writer hiding (Sum)+import Control.Monad.Writer (Writer, WriterT, runWriter, runWriterT, tell) import Data.Char (isAlpha, isSpace, toUpper) import Data.List (find, groupBy, inits, intersperse, isPrefixOf, partition, sort, sortOn, tails) import Data.Map qualified as M
src/Futhark/IR/Aliases.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-}+{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}  -- | A representation where all patterns are annotated with aliasing -- information.  It also records consumption of variables in bodies.@@ -129,7 +130,13 @@   scope <- asksScope removeScopeAliases   runReaderT m scope -instance (ASTRep rep, AliasedOp (OpC rep (Aliases rep))) => ASTRep (Aliases rep) where+instance+  ( ASTRep rep,+    AliasedOp (OpC rep (Aliases rep)),+    IsOp (OpC rep (Aliases rep))+  ) =>+  ASTRep (Aliases rep)+  where   expTypesFromPat =     withoutAliases . expTypesFromPat . removePatAliases @@ -137,7 +144,13 @@   bodyAliases = map unAliases . fst . fst . bodyDec   consumedInBody = unAliases . snd . fst . bodyDec -instance (ASTRep rep, AliasedOp (OpC rep (Aliases rep))) => PrettyRep (Aliases rep) where+instance+  ( ASTRep rep,+    AliasedOp (OpC rep (Aliases rep)),+    Pretty (OpC rep (Aliases rep))+  ) =>+  PrettyRep (Aliases rep)+  where   ppExpDec (consumed, inner) e =     maybeComment . catMaybes $       [exp_dec, merge_dec, ppExpDec inner $ removeExpAliases e]
src/Futhark/IR/Mem.hs view
@@ -100,6 +100,7 @@ where  import Control.Category+import Control.Monad import Control.Monad.Except import Control.Monad.Reader import Control.Monad.State
src/Futhark/IR/Mem/IxFun.hs view
@@ -41,9 +41,8 @@ where  import Control.Category-import Control.Monad.Identity+import Control.Monad import Control.Monad.State-import Control.Monad.Writer import Data.Function (on, (&)) import Data.List (elemIndex, partition, sort, sortBy, zip4, zipWith4) import Data.List.NonEmpty (NonEmpty (..))
src/Futhark/IR/Prop/Aliases.hs view
@@ -221,11 +221,19 @@  -- | Also includes the name itself. lookupAliases :: AliasesOf (LetDec rep) => VName -> Scope rep -> Names-lookupAliases v scope =-  case M.lookup v scope of-    Just (LetName dec) ->-      oneName v <> foldMap (`lookupAliases` scope) (namesToList (aliasesOf dec))-    _ -> oneName v+lookupAliases root scope =+  -- We must be careful to handle circular aliasing properly (this+  -- can happen due to Match and Loop).+  expand mempty root+  where+    expand prev v =+      case M.lookup v scope of+        Just (LetName dec) ->+          oneName v+            <> foldMap+              (expand (oneName v <> prev))+              (filter (`notNameIn` prev) (namesToList (aliasesOf dec)))+        _ -> oneName v  -- | The class of operations that can produce aliasing and consumption -- information.
src/Futhark/IR/Prop/Types.hs view
@@ -66,6 +66,7 @@   ) where +import Control.Monad import Control.Monad.State import Data.List (elemIndex, foldl') import Data.Map.Strict qualified as M
src/Futhark/IR/SOACS/SOAC.hs view
@@ -49,6 +49,7 @@ where  import Control.Category+import Control.Monad import Control.Monad.Identity import Control.Monad.State.Strict import Control.Monad.Writer@@ -371,7 +372,7 @@   }  -- | A mapper that simply returns the SOAC verbatim.-identitySOACMapper :: Monad m => SOACMapper rep rep m+identitySOACMapper :: forall rep m. Monad m => SOACMapper rep rep m identitySOACMapper =   SOACMapper     { mapOnSOACSubExp = pure,@@ -670,12 +671,14 @@   accargs <- mapM TC.checkArg accexps   arrargs <- mapM lookupType arrexps   _ <- TC.checkSOACArrayArgs size arrexps-  let chunk = head $ lambdaParams lam+  chunk <- case lambdaParams lam of+    chunk : _ -> pure chunk+    [] -> TC.bad $ TC.TypeError "Stream lambda without parameters."   let asArg t = (t, mempty)       inttp = Prim int64       lamarrs' = map (`setOuterSize` Var (paramName chunk)) arrargs-  let acc_len = length accexps-  let lamrtp = take acc_len $ lambdaReturnType lam+      acc_len = length accexps+      lamrtp = take acc_len $ lambdaReturnType lam   unless (map TC.argType accargs == lamrtp) $     TC.bad . TC.TypeError $       "Stream with inconsistent accumulator type in lambda."
src/Futhark/IR/SOACS/Simplify.hs view
@@ -770,7 +770,7 @@       tell $ arrayOps (cs <> more_cs) $ lambdaBody lam       pure lam     walker more_cs =-      identityWalker+      (identityWalker @rep)         { walkOnBody = const $ modify . (<>) . arrayOps (cs <> more_cs),           walkOnOp = modify . (<>) . onOp more_cs         }@@ -780,22 +780,18 @@ replaceArrayOps ::   forall rep.   (Buildable rep, BuilderOps rep, HasSOAC rep) =>-  M.Map (Pat (LetDec rep), ArrayOp) ArrayOp ->+  M.Map (Pat (LetDec rep)) ArrayOp ->   Body rep ->   Body rep replaceArrayOps substs (Body _ stms res) =   mkBody (fmap onStm stms) res   where     onStm (Let pat aux e) =-      let (cs', e') = onExp pat (stmAuxCerts aux) e+      let (cs', e') =+            maybe (mempty, mapExp mapper e) fromArrayOp $ M.lookup pat substs        in certify cs' $ mkLet' (patIdents pat) aux e'-    onExp pat cs e-      | Just op <- isArrayOp cs e,-        Just op' <- M.lookup (pat, op) substs =-          fromArrayOp op'-    onExp _ cs e = (cs, mapExp mapper e)     mapper =-      identityMapper+      (identityMapper @rep)         { mapOnBody = const $ pure . replaceArrayOps substs,           mapOnOp = pure . onOp         }@@ -887,7 +883,7 @@         Just           ( arr'',             arr_elem_param,-            ( (pat, ArrayIndexing cs arr slice),+            ( pat,               ArrayIndexing cs (paramName arr_elem_param) (Slice (drop (length js + 1) (unSlice slice)))             )           )@@ -913,10 +909,8 @@                 lambdaBody = replaceArrayOps (M.fromList replacements) $ lambdaBody map_lam               } -      auxing aux $-        letBind screma_pat $-          Op $-            Screma w (arrs <> more_arrs) (ScremaForm scan reduce map_lam')+      auxing aux . letBind screma_pat . Op $+        Screma w (arrs <> more_arrs) (ScremaForm scan reduce map_lam')   where     -- It is not safe to move the transform if the root array is being     -- consumed by the Screma.  This is a bit too conservative - it's@@ -979,7 +973,7 @@             Just               ( arr_transformed,                 Param mempty arr_transformed_row (rowType arr_transformed_t),-                ((pat, op), ArrayVar mempty arr_transformed_row)+                (pat, ArrayVar mempty arr_transformed_row)               )     mapOverArr _ = pure Nothing moveTransformToInput _ _ _ _ =
src/Futhark/IR/SegOp.hs view
@@ -46,10 +46,11 @@ where  import Control.Category-import Control.Monad.Identity hiding (mapM_)-import Control.Monad.Reader hiding (mapM_)+import Control.Monad+import Control.Monad.Identity+import Control.Monad.Reader import Control.Monad.State.Strict-import Control.Monad.Writer hiding (mapM_)+import Control.Monad.Writer import Data.Bifunctor (first) import Data.Bitraversable import Data.Foldable (traverse_)
src/Futhark/IR/Syntax/Core.hs view
@@ -75,6 +75,7 @@ where  import Control.Category+import Control.Monad import Control.Monad.State import Data.Bifoldable import Data.Bifunctor@@ -246,6 +247,9 @@   bitraverse _ g (Acc arrs ispace ts u) = Acc arrs ispace ts <$> g u   bitraverse _ _ (Mem s) = pure $ Mem s +instance Functor (TypeBase shape) where+  fmap = second+ instance Bifunctor TypeBase where   bimap = bimapDefault @@ -304,7 +308,7 @@   deriving (Eq, Ord, Show)  instance Semigroup Certs where-  Certs x <> Certs y = Certs (x <> y)+  Certs x <> Certs y = Certs (x <> filter (`notElem` x) y)  instance Monoid Certs where   mempty = Certs mempty
src/Futhark/IR/Traversals.hs view
@@ -66,7 +66,7 @@   }  -- | A mapper that simply returns the tree verbatim.-identityMapper :: Monad m => Mapper rep rep m+identityMapper :: forall rep m. Monad m => Mapper rep rep m identityMapper =   Mapper     { mapOnSubExp = pure,@@ -247,7 +247,7 @@   }  -- | A no-op traversal.-identityWalker :: Monad m => Walker rep m+identityWalker :: forall rep m. Monad m => Walker rep m identityWalker =   Walker     { walkOnSubExp = const $ pure (),
src/Futhark/IR/TypeCheck.hs view
@@ -42,6 +42,7 @@   ) where +import Control.Monad import Control.Monad.Reader import Control.Monad.State.Strict import Control.Parallel.Strategies
src/Futhark/Internalise/Bindings.hs view
@@ -11,7 +11,8 @@   ) where -import Control.Monad.Reader hiding (mapM)+import Control.Monad+import Control.Monad.Reader import Data.Bifunctor import Data.Map.Strict qualified as M import Data.Maybe
src/Futhark/Internalise/Defunctionalise.hs view
@@ -1,6 +1,7 @@ -- | Defunctionalization of typed, monomorphic Futhark programs without modules. module Futhark.Internalise.Defunctionalise (transformProg) where +import Control.Monad import Control.Monad.Identity import Control.Monad.Reader import Control.Monad.State@@ -571,6 +572,7 @@       Just sv -> pure (Project vn e0' (Info $ typeFromSV sv) loc, sv)       Nothing -> error "Invalid record projection."     Dynamic _ -> pure (Project vn e0' tp loc, Dynamic tp')+    HoleSV _ hloc -> pure (Project vn e0' tp loc, HoleSV tp' hloc)     _ -> error $ "Projection of an expression with static value " ++ show sv0 defuncExp (AppExp (LetWith id1 id2 idxs e1 body loc) res) = do   e1' <- defuncExp' e1
src/Futhark/Internalise/Entry.hs view
@@ -6,6 +6,7 @@   ) where +import Control.Monad import Control.Monad.State import Data.List (find) import Data.Map qualified as M
src/Futhark/Internalise/Exps.hs view
@@ -5,6 +5,7 @@ -- program to a core Futhark program. module Futhark.Internalise.Exps (transformProg) where +import Control.Monad import Control.Monad.Reader import Data.List (elemIndex, find, intercalate, intersperse, transpose) import Data.List.NonEmpty (NonEmpty (..))
src/Futhark/Internalise/Lambdas.hs view
@@ -5,6 +5,7 @@   ) where +import Data.Maybe (listToMaybe) import Futhark.IR.SOACS as I import Futhark.Internalise.AccurateSizes import Futhark.Internalise.Monad@@ -77,5 +78,6 @@      lambdaWithIncrement :: I.Body SOACS -> InternaliseM (I.Body SOACS)     lambdaWithIncrement lam_body = runBodyBuilder $ do-      eq_class <- resSubExp . head <$> bodyBind lam_body+      eq_class <-+        maybe (intConst Int64 0) resSubExp . listToMaybe <$> bodyBind lam_body       resultBody <$> mkResult eq_class 0
src/Futhark/Internalise/Monad.hs view
@@ -23,6 +23,7 @@   ) where +import Control.Monad import Control.Monad.Except import Control.Monad.Reader import Control.Monad.State
src/Futhark/Internalise/Monomorphise.hs view
@@ -24,10 +24,10 @@ -- representation. module Futhark.Internalise.Monomorphise (transformProg) where -import Control.Monad.Identity-import Control.Monad.RWS hiding (Sum)+import Control.Monad+import Control.Monad.RWS (MonadReader (..), MonadWriter (..), RWST, asks, runRWST) import Control.Monad.State-import Control.Monad.Writer hiding (Sum)+import Control.Monad.Writer (runWriterT) import Data.Bifunctor import Data.Bitraversable import Data.Foldable@@ -653,9 +653,8 @@ transformPat (Wildcard (Info t) loc) = do   t' <- transformType t   pure (wildcard t' loc, mempty)-transformPat (PatAscription pat td loc) = do-  (pat', rr) <- transformPat pat-  pure (PatAscription pat' td loc, rr)+transformPat (PatAscription pat _ _) =+  transformPat pat transformPat (PatLit e t loc) = pure (PatLit e t loc, mempty) transformPat (PatConstr name t all_ps loc) = do   (all_ps', rrs) <- mapAndUnzipM transformPat all_ps
src/Futhark/Optimise/ArrayShortCircuiting.hs view
@@ -10,6 +10,7 @@   ) where +import Control.Monad import Control.Monad.Reader import Data.Function ((&)) import Data.Map qualified as M
src/Futhark/Optimise/ArrayShortCircuiting/ArrayCoalescing.hs view
@@ -11,6 +11,7 @@ where  import Control.Exception.Base qualified as Exc+import Control.Monad import Control.Monad.Reader import Control.Monad.State.Strict import Data.Function ((&))
src/Futhark/Optimise/BlkRegTiling.hs view
@@ -18,9 +18,9 @@ --          the kernel produces one scalar result module Futhark.Optimise.BlkRegTiling (mmBlkRegTiling, doRegTiling3D) where -import Control.Monad.Reader+import Control.Monad import Data.List qualified as L-import Data.List.NonEmpty (NonEmpty (..))+import Data.List.NonEmpty qualified as NE import Data.Map.Strict qualified as M import Data.Maybe import Data.Sequence qualified as Seq@@ -143,14 +143,16 @@         | [slc_X'] <- patNames pat,           slc_X == slc_X',           Just ixf_fn <- M.lookup x ixfn_env,-          (IxFun.IxFun (lmad :| []) _ _) <- ixf_fn =-            let lmad_dims = IxFun.lmadDims lmad-                q = length lmad_dims-                last_perm = IxFun.ldPerm $ last lmad_dims-                stride = IxFun.ldStride $ last lmad_dims-                res = last_perm == q - 1 && (stride == pe64 (intConst Int64 1))-             in res-      isInnerCoal _ _ _ = error "TileLoops/Shared.hs: not an error, but I would like to know why!"+          (IxFun.IxFun lmads _ _) <- ixf_fn =+            all innerHasStride1 $ NE.toList lmads+      isInnerCoal _ _ _ =+        error "kkLoopBody.isInnerCoal: not an error, but I would like to know why!"+      innerHasStride1 lmad =+        let lmad_dims = IxFun.lmadDims lmad+            q = length lmad_dims+            last_perm = IxFun.ldPerm $ last lmad_dims+            stride = IxFun.ldStride $ last lmad_dims+         in (last_perm == q - 1) && (stride == pe64 (intConst Int64 1))       --       mkRedomapOneTileBody acc_merge asss bsss fits_ij = do         -- the actual redomap.
src/Futhark/Optimise/CSE.hs view
@@ -167,6 +167,7 @@   pure lam {lambdaBody = body'}  cseInStms ::+  forall rep a.   (Aliased rep, CSEInOp (Op rep)) =>   Names ->   [Stm rep] ->@@ -190,7 +191,7 @@       pure stm' {stmExp = e}      cse ds =-      identityMapper+      (identityMapper @rep)         { mapOnBody = const $ cseInBody ds,           mapOnOp = cseInOp         }
src/Futhark/Optimise/DoubleBuffer.hs view
@@ -71,6 +71,7 @@ -- per iteration (and an initial one, elided above). module Futhark.Optimise.DoubleBuffer (doubleBufferGPU, doubleBufferMC) where +import Control.Monad import Control.Monad.Reader import Control.Monad.State import Control.Monad.Writer@@ -170,7 +171,7 @@   oneStm . Let pat aux <$> mapExpM (optimise onOp) e   where     optimise onOp =-      identityMapper+      (identityMapper @rep)         { mapOnBody = \_ x ->             optimiseBody x :: DoubleBufferM rep (Body rep),           mapOnOp = onOp
src/Futhark/Optimise/Fusion.hs view
@@ -6,6 +6,7 @@ -- Redomap Construct/). module Futhark.Optimise.Fusion (fuseSOACs) where +import Control.Monad import Control.Monad.Reader import Control.Monad.State import Data.Graph.Inductive.Graph qualified as G
src/Futhark/Optimise/GenRedOpt.hs view
@@ -16,6 +16,7 @@ --     map-reduce, as to potentially enable tiling oportunities. module Futhark.Optimise.GenRedOpt (optimiseGenRed) where +import Control.Monad import Control.Monad.Reader import Control.Monad.State import Data.List qualified as L
src/Futhark/Optimise/HistAccs.hs view
@@ -3,6 +3,7 @@ -- | Turn certain uses of accumulators into SegHists. module Futhark.Optimise.HistAccs (histAccsGPU) where +import Control.Monad import Control.Monad.Reader import Control.Monad.State import Data.Map.Strict qualified as M
src/Futhark/Optimise/InPlaceLowering.hs view
@@ -65,6 +65,7 @@   ) where +import Control.Monad import Control.Monad.RWS import Data.Map.Strict qualified as M import Data.Ord (comparing)@@ -377,14 +378,14 @@           ++ prettyString name           ++ " not found." -seenVar :: VName -> ForwardingM rep ()+seenVar :: forall rep. VName -> ForwardingM rep () seenVar name = do   aliases <-     asks $       maybe mempty entryAliases         . M.lookup name         . topDownTable-  tell $ mempty {bottomUpSeen = oneName name <> aliases}+  tell $ (mempty :: BottomUp rep) {bottomUpSeen = oneName name <> aliases}  tapBottomUp :: ForwardingM rep a -> ForwardingM rep (a, BottomUp rep) tapBottomUp m = do
src/Futhark/Optimise/InliningDeadFun.hs view
@@ -7,6 +7,7 @@   ) where +import Control.Monad import Control.Monad.Identity import Control.Monad.State import Control.Parallel.Strategies@@ -210,7 +211,7 @@     onStm (Let pat aux e) = Let pat aux <$> mapExpM inliner e      inliner =-      identityMapper+      (identityMapper @SOACS)         { mapOnBody = const onBody,           mapOnOp = onSOAC         }
src/Futhark/Optimise/Simplify/Engine.hs view
@@ -63,6 +63,7 @@   ) where +import Control.Monad import Control.Monad.Reader import Control.Monad.State.Strict import Data.Either
src/Futhark/Optimise/Simplify/Rep.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-}+{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}  -- | Representation used by the simplification engine.  It contains -- aliasing information and a bit of caching for various information@@ -116,7 +117,16 @@ instance FreeDec BodyWisdom where   precomputed = const . fvNames . unAliases . bodyWisdomFree -instance Informing rep => RepTypes (Wise rep) where+instance+  ( Informing rep,+    Ord (OpC rep (Wise rep)),+    Eq (OpC rep (Wise rep)),+    Show (OpC rep (Wise rep)),+    IsOp (OpC rep (Wise rep)),+    Pretty (OpC rep (Wise rep))+  ) =>+  RepTypes (Wise rep)+  where   type LetDec (Wise rep) = (VarWisdom, LetDec rep)   type ExpDec (Wise rep) = (ExpWisdom, ExpDec rep)   type BodyDec (Wise rep) = (BodyWisdom, BodyDec rep)@@ -134,14 +144,14 @@   scope <- asksScope removeScopeWisdom   runReaderT m scope -instance Informing rep => ASTRep (Wise rep) where+instance (Informing rep, IsOp (OpC rep (Wise rep))) => ASTRep (Wise rep) where   expTypesFromPat =     withoutWisdom . expTypesFromPat . removePatWisdom  instance Pretty VarWisdom where   pretty _ = pretty () -instance Informing rep => PrettyRep (Wise rep) where+instance (Informing rep, Pretty (OpC rep (Wise rep))) => PrettyRep (Wise rep) where   ppExpDec (_, dec) = ppExpDec dec . removeExpWisdom  instance AliasesOf (VarWisdom, dec) where
src/Futhark/Optimise/Simplify/Rules.hs view
@@ -203,7 +203,7 @@       pure $ Just x withAccTopDown _ _ = Skip -elimUpdates :: (ASTRep rep, TraverseOpStms rep) => [VName] -> Body rep -> (Body rep, [VName])+elimUpdates :: forall rep. (ASTRep rep, TraverseOpStms rep) => [VName] -> Body rep -> (Body rep, [VName]) elimUpdates get_rid_of = flip runState mempty . onBody   where     onBody body = do@@ -219,7 +219,7 @@     onExp = mapExpM mapper       where         mapper =-          identityMapper+          (identityMapper :: forall m. Monad m => Mapper rep rep m)             { mapOnOp = traverseOpStms (\_ stms -> onStms stms),               mapOnBody = \_ body -> onBody body             }
src/Futhark/Optimise/Simplify/Rules/Loop.hs view
@@ -95,22 +95,22 @@     ([], _, _, _) ->       -- Nothing is invariant.       Skip-    (invariant, explpat', merge', res') -> Simplify $ do+    (invariant, explpat', merge', res') -> Simplify . auxing aux $ do       -- We have moved something invariant out of the loop.       let loopbody' = loopbody {bodyResult = res'}           explpat'' = map fst explpat'-      forM_ invariant $ \(v1, v2) ->-        letBindNames [identName v1] $ BasicOp $ SubExp v2-      auxing aux $ letBind (Pat explpat'') $ DoLoop merge' form loopbody'+      forM_ invariant $ \(v1, (v2, cs)) ->+        certifying cs $ letBindNames [identName v1] $ BasicOp $ SubExp v2+      letBind (Pat explpat'') $ DoLoop merge' form loopbody'   where     res = bodyResult loopbody      namesOfMergeParams = namesFromList $ map (paramName . fst) merge -    removeFromResult (mergeParam, mergeInit) explpat' =+    removeFromResult cs (mergeParam, mergeInit) explpat' =       case partition ((== paramName mergeParam) . snd) explpat' of         ([(patelem, _)], rest) ->-          (Just (patElemIdent patelem, mergeInit), rest)+          (Just (patElemIdent patelem, (mergeInit, cs)), rest)         (_, _) ->           (Nothing, explpat') @@ -119,10 +119,16 @@       (invariant, explpat', merge', resExps)         | isInvariant,           -- Also do not remove the condition in a while-loop.-          paramName mergeParam `notNameIn` freeIn form =+          paramName mergeParam `notNameIn` freeIn form,+          -- Certificates must be available.+          all (`ST.elem` vtable) $ unCerts $ resCerts resExp =             let (stm, explpat'') =-                  removeFromResult (mergeParam, mergeInit) explpat'-             in ( maybe id (:) stm $ (paramIdent mergeParam, mergeInit) : invariant,+                  removeFromResult+                    (resCerts resExp)+                    (mergeParam, mergeInit)+                    explpat'+             in ( maybe id (:) stm $+                    (paramIdent mergeParam, (mergeInit, resCerts resExp)) : invariant,                   explpat'',                   merge',                   resExps
src/Futhark/Optimise/Simplify/Rules/Simple.hs view
@@ -344,16 +344,18 @@ copyScratchToScratch :: SimpleRule rep copyScratchToScratch defOf seType (Copy src) = do   t <- seType $ Var src-  if isActuallyScratch src-    then Just (Scratch (elemType t) (arrayDims t), mempty)-    else Nothing+  cs <- isActuallyScratch src+  pure (Scratch (elemType t) (arrayDims t), cs)   where     isActuallyScratch v =-      case asBasicOp . fst =<< defOf v of-        Just Scratch {} -> True-        Just (Rearrange _ v') -> isActuallyScratch v'-        Just (Reshape _ _ v') -> isActuallyScratch v'-        _ -> False+      case defOf v of+        Just (BasicOp Scratch {}, cs) ->+          Just cs+        Just (BasicOp (Rearrange _ v'), cs) ->+          (cs <>) <$> isActuallyScratch v'+        Just (BasicOp (Reshape _ _ v'), cs) ->+          (cs <>) <$> isActuallyScratch v'+        _ -> Nothing copyScratchToScratch _ _ _ =   Nothing 
src/Futhark/Optimise/TileLoops.hs view
@@ -5,6 +5,7 @@ -- tile primitive types, to avoid excessive local memory use. module Futhark.Optimise.TileLoops (tileLoops) where +import Control.Monad import Control.Monad.Reader import Control.Monad.State import Data.Map.Strict qualified as M
src/Futhark/Optimise/TileLoops/Shared.hs view
@@ -17,6 +17,7 @@   ) where +import Control.Monad import Control.Monad.Reader import Control.Monad.State import Data.List (foldl', zip4)
src/Futhark/Optimise/Unstream.hs view
@@ -19,6 +19,7 @@ -- kept together. module Futhark.Optimise.Unstream (unstreamGPU, unstreamMC) where +import Control.Monad import Control.Monad.Reader import Control.Monad.State import Futhark.IR.GPU
src/Futhark/Pass/AD.hs view
@@ -53,7 +53,7 @@ onStm mode scope (Let pat aux e) = oneStm . Let pat aux <$> mapExpM mapper e   where     mapper =-      identityMapper+      (identityMapper @SOACS)         { mapOnBody = \bscope -> onBody mode (bscope <> scope),           mapOnOp = mapSOACM soac_mapper         }
src/Futhark/Pass/ExpandAllocations.hs view
@@ -3,6 +3,7 @@ -- | Expand allocations inside of maps when possible. module Futhark.Pass.ExpandAllocations (expandAllocations) where +import Control.Monad import Control.Monad.Except import Control.Monad.Reader import Control.Monad.State@@ -412,7 +413,7 @@   pure $ Just $ stm {stmExp = e}   where     expMapper user' =-      identityMapper+      (identityMapper @GPUMem)         { mapOnBody = const $ onBody user',           mapOnOp = onOp user'         }@@ -722,7 +723,7 @@ offsetMemoryInExp e = mapExpM recurse e   where     recurse =-      identityMapper+      (identityMapper @GPUMem)         { mapOnBody = \bscope -> localScope bscope . offsetMemoryInBody,           mapOnBranchType = offsetMemoryInBodyReturns,           mapOnOp = onOp
src/Futhark/Pass/ExplicitAllocations.hs view
@@ -34,6 +34,7 @@   ) where +import Control.Monad import Control.Monad.RWS.Strict import Control.Monad.Reader import Control.Monad.State
src/Futhark/Pass/ExplicitAllocations/GPU.hs view
@@ -8,6 +8,7 @@   ) where +import Control.Monad import Data.Set qualified as S import Futhark.IR.GPU import Futhark.IR.GPUMem
src/Futhark/Pass/ExplicitAllocations/SegOp.hs view
@@ -7,6 +7,7 @@   ) where +import Control.Monad import Futhark.IR.GPUMem import Futhark.IR.Mem.IxFun qualified as IxFun import Futhark.Pass.ExplicitAllocations
src/Futhark/Pass/ExtractKernels.hs view
@@ -153,7 +153,7 @@ -- single kernel. module Futhark.Pass.ExtractKernels (extractKernels) where -import Control.Monad.Identity+import Control.Monad import Control.Monad.RWS.Strict import Control.Monad.Reader import Data.Bifunctor (first)
src/Futhark/Pass/ExtractKernels/BlockedKernel.hs view
@@ -18,7 +18,6 @@ where  import Control.Monad-import Control.Monad.Writer import Futhark.Analysis.PrimExp import Futhark.IR import Futhark.IR.Aliases (AliasableRep)
src/Futhark/Pass/ExtractKernels/DistributeNests.hs view
@@ -28,7 +28,7 @@ where  import Control.Arrow (first)-import Control.Monad.Identity+import Control.Monad import Control.Monad.RWS.Strict import Control.Monad.Reader import Control.Monad.Trans.Maybe
src/Futhark/Pass/ExtractKernels/Distribution.hs view
@@ -38,6 +38,7 @@   ) where +import Control.Monad import Control.Monad.RWS.Strict import Control.Monad.Trans.Maybe import Data.Bifunctor (second)
src/Futhark/Pass/ExtractKernels/ISRWIM.hs view
@@ -9,7 +9,7 @@ where  import Control.Arrow (first)-import Control.Monad.State+import Control.Monad import Futhark.IR.SOACS import Futhark.MonadFreshNames import Futhark.Tools
src/Futhark/Pass/ExtractKernels/Interchange.hs view
@@ -16,7 +16,7 @@   ) where -import Control.Monad.Identity+import Control.Monad import Data.List (find) import Data.Maybe import Futhark.IR.SOACS
src/Futhark/Pass/ExtractKernels/Intragroup.hs view
@@ -4,7 +4,7 @@ -- individual kernel workgroups. module Futhark.Pass.ExtractKernels.Intragroup (intraGroupParallelise) where -import Control.Monad.Identity+import Control.Monad import Control.Monad.RWS import Control.Monad.Trans.Maybe import Data.Map.Strict qualified as M
src/Futhark/Pass/ExtractMulticore.hs view
@@ -5,6 +5,7 @@ -- involve ad-hoc irregular nested parallelism. module Futhark.Pass.ExtractMulticore (extractMulticore) where +import Control.Monad import Control.Monad.Identity import Control.Monad.Reader import Control.Monad.State
src/Futhark/Pass/KernelBabysitting.hs view
@@ -4,6 +4,7 @@ module Futhark.Pass.KernelBabysitting (babysitKernels) where  import Control.Arrow (first)+import Control.Monad import Control.Monad.State.Strict import Data.Foldable import Data.List (elemIndex, isPrefixOf, sort)@@ -139,6 +140,7 @@   m (Maybe (VName, Slice SubExp))  traverseKernelBodyArrayIndexes ::+  forall f.   Monad f =>   Names ->   Names ->@@ -157,6 +159,7 @@       (stmsToList kstms)     <*> pure kres   where+    onLambda :: (VarianceTable, Scope GPU) -> Lambda GPU -> f (Lambda GPU)     onLambda (variance, scope) lam =       (\body' -> lam {lambdaBody = body'})         <$> onBody (variance, scope') (lambdaBody lam)@@ -188,12 +191,18 @@     onStm (variance, scope) (Let pat dec e) =       Let pat dec <$> mapExpM (mapper (variance, scope)) e +    onOp :: (VarianceTable, Scope GPU) -> Op GPU -> f (Op GPU)     onOp ctx (OtherOp soac) =-      OtherOp <$> mapSOACM identitySOACMapper {mapOnSOACLambda = onLambda ctx} soac+      OtherOp <$> mapSOACM (soacMapper ctx) soac     onOp _ op = pure op +    soacMapper ctx =+      (identitySOACMapper @GPU)+        { mapOnSOACLambda = onLambda ctx+        }+     mapper ctx =-      identityMapper+      (identityMapper @GPU)         { mapOnBody = const (onBody ctx),           mapOnOp = onOp ctx         }
src/Futhark/Pipeline.hs view
@@ -28,7 +28,6 @@ import Control.Monad.Except import Control.Monad.Reader import Control.Monad.State-import Control.Monad.Writer.Strict hiding (pass) import Control.Parallel import Data.Text qualified as T import Data.Text.IO qualified as T
src/Futhark/Pkg/Solve.hs view
@@ -10,6 +10,7 @@   ) where +import Control.Monad import Control.Monad.Free.Church import Control.Monad.State import Data.Map qualified as M
src/Futhark/Script.hs view
@@ -31,7 +31,9 @@   ) where -import Control.Monad.Except+import Control.Monad+import Control.Monad.Except (MonadError (..))+import Control.Monad.IO.Class (MonadIO, liftIO) import Data.Bifunctor (bimap) import Data.ByteString.Lazy qualified as LBS import Data.Char@@ -43,6 +45,7 @@ import Data.Set qualified as S import Data.Text qualified as T import Data.Traversable+import Data.Vector.Storable qualified as SVec import Data.Void import Data.Word (Word8) import Futhark.Data.Parser qualified as V@@ -291,6 +294,50 @@ valueToExp (V.ValueTuple fs) =   Tuple $ map valueToExp fs +-- Decompose a type name into a rank and an element type.+parseTypeName :: TypeName -> Maybe (Int, V.PrimType)+parseTypeName s+  | Just pt <- lookup s m =+      Just (0, pt)+  | "[]" `T.isPrefixOf` s = do+      (d, pt) <- parseTypeName (T.drop 2 s)+      pure (d + 1, pt)+  | otherwise = Nothing+  where+    prims = [minBound .. maxBound]+    primtexts = map (V.valueTypeText . V.ValueType []) prims+    m = zip primtexts prims++coerceValue :: TypeName -> V.Value -> Maybe V.Value+coerceValue t v = do+  (_, pt) <- parseTypeName t+  case v of+    V.I8Value shape vs ->+      coerceInts pt shape $ map toInteger $ SVec.toList vs+    V.I16Value shape vs ->+      coerceInts pt shape $ map toInteger $ SVec.toList vs+    V.I32Value shape vs ->+      coerceInts pt shape $ map toInteger $ SVec.toList vs+    V.I64Value shape vs ->+      coerceInts pt shape $ map toInteger $ SVec.toList vs+    _ ->+      Nothing+  where+    coerceInts V.I8 shape =+      Just . V.I8Value shape . SVec.fromList . map fromInteger+    coerceInts V.I16 shape =+      Just . V.I16Value shape . SVec.fromList . map fromInteger+    coerceInts V.I32 shape =+      Just . V.I32Value shape . SVec.fromList . map fromInteger+    coerceInts V.I64 shape =+      Just . V.I64Value shape . SVec.fromList . map fromInteger+    coerceInts V.F32 shape =+      Just . V.F32Value shape . SVec.fromList . map fromInteger+    coerceInts V.F64 shape =+      Just . V.F64Value shape . SVec.fromList . map fromInteger+    coerceInts _ _ =+      const Nothing+ -- | How to evaluate a builtin function. type EvalBuiltin m = T.Text -> [V.CompoundValue] -> m V.CompoundValue @@ -391,6 +438,8 @@       -- FutharkScript tuples/records to Futhark-level tuples/records,       -- as well as maps between different names for the same       -- tuple/record.+      --+      -- We also implicitly convert the types of constants.       interValToVar :: m VarName -> TypeName -> ExpValue -> m VarName       interValToVar _ t (V.ValueAtom v)         | STValue t == scriptValueType v = scriptValueToVar v@@ -407,6 +456,9 @@           Just vt_fs <- isRecord vt types,           vt_fs == t_fs =             mkRecord t =<< mapM (getField v) vt_fs+      interValToVar _ t (V.ValueAtom (SValue _ (VVal v)))+        | Just v' <- coerceValue t v =+            scriptValueToVar $ SValue t $ VVal v'       interValToVar bad _ _ = bad        valToInterVal :: V.CompoundValue -> ExpValue
src/Futhark/Test.hs view
@@ -32,7 +32,8 @@ import Control.Exception (catch) import Control.Exception.Base qualified as E import Control.Monad-import Control.Monad.Except+import Control.Monad.Except (MonadError (..))+import Control.Monad.IO.Class (MonadIO, liftIO) import Data.Binary qualified as Bin import Data.ByteString qualified as SBS import Data.ByteString.Lazy qualified as BS
src/Futhark/Tools.hs view
@@ -15,7 +15,7 @@   ) where -import Control.Monad.Identity+import Control.Monad import Futhark.Analysis.PrimExp.Convert import Futhark.Construct import Futhark.IR
src/Futhark/Transform/FirstOrderTransform.hs view
@@ -16,7 +16,7 @@   ) where -import Control.Monad.Except+import Control.Monad import Control.Monad.State import Data.List (find, zip4) import Data.Map.Strict qualified as M
src/Futhark/Util.hs view
@@ -13,8 +13,6 @@     maxinum,     chunk,     chunks,-    pairs,-    unpairs,     dropAt,     takeLast,     dropLast,@@ -133,18 +131,6 @@   let (bef, aft) = splitAt n xs    in bef : chunks ns aft --- | @pairs l@ chunks the list into pairs of consecutive elements,--- ignoring any excess element.  Example: @pairs [a,b,c,d] ==--- [(a,b),(c,d)]@.-pairs :: [a] -> [(a, a)]-pairs (a : b : l) = (a, b) : pairs l-pairs _ = []---- | The opposite of 'pairs': @unpairs [(a,b),(c,d)] = [a,b,c,d]@.-unpairs :: [(a, a)] -> [a]-unpairs [] = []-unpairs ((a, b) : l) = a : b : unpairs l- -- | Like 'maximum', but returns zero for an empty list. maxinum :: (Num a, Ord a, Foldable f) => f a -> a maxinum = foldl' max 0@@ -435,7 +421,7 @@ encodeAsUnicodeCharar :: Char -> EncodedString encodeAsUnicodeCharar c =   'z'-    : if isDigit (head hex_str)+    : if maybe False isDigit $ maybeHead hex_str       then hex_str       else '0' : hex_str   where
src/Futhark/Util/Pretty.hs view
@@ -31,7 +31,6 @@     commastack,     commasep,     semistack,-    semisep,     stack,     parensIf,     ppTuple',@@ -168,17 +167,13 @@ commastack :: [Doc a] -> Doc a commastack = align . vsep . punctuate comma --- | Like 'semisep', but a newline after every semicolon.+-- | Separate with semicolons and newlines. semistack :: [Doc a] -> Doc a semistack = align . vsep . punctuate semi  -- | Separate with commas. commasep :: [Doc a] -> Doc a commasep = hsep . punctuate comma---- | Separate with semicolons.-semisep :: [Doc a] -> Doc a-semisep = hsep . punctuate semi  -- | Separate with linebreaks. stack :: [Doc a] -> Doc a
src/Language/Futhark/Interpreter.hs view
@@ -26,7 +26,7 @@   ) where -import Control.Monad.Except+import Control.Monad import Control.Monad.Free.Church import Control.Monad.Identity import Control.Monad.Reader@@ -132,6 +132,16 @@ getSizes :: EvalM Sizes getSizes = get +-- | Disregard any existential sizes computed during this action.+-- This is used so that existentials computed during one iteration of+-- a loop or a function call are not remembered the next time around.+localExts :: EvalM a -> EvalM a+localExts m = do+  s <- get+  x <- m+  put s+  pure x+ extSizeEnv :: EvalM Env extSizeEnv = i64Env <$> getSizes @@ -265,18 +275,14 @@ -- | The actual type- and value environment. data Env = Env   { envTerm :: M.Map VName TermBinding,-    envType :: M.Map VName T.TypeBinding,-    -- | A mapping from type parameters to the shapes of-    -- the value to which they were initially bound.-    envShapes :: M.Map VName ValueShape+    envType :: M.Map VName T.TypeBinding   }  instance Monoid Env where-  mempty = Env mempty mempty mempty+  mempty = Env mempty mempty  instance Semigroup Env where-  Env vm1 tm1 sm1 <> Env vm2 tm2 sm2 =-    Env (vm1 <> vm2) (tm1 <> tm2) (sm1 <> sm2)+  Env vm1 tm1 <> Env vm2 tm2 = Env (vm1 <> vm2) (tm1 <> tm2)  -- | An error occurred during interpretation due to an error in the -- user program.  Actual interpreter errors will be signaled with an@@ -291,24 +297,21 @@ valEnv m =   Env     { envTerm = M.map (uncurry TermValue) m,-      envType = mempty,-      envShapes = mempty+      envType = mempty     }  modEnv :: M.Map VName Module -> Env modEnv m =   Env     { envTerm = M.map TermModule m,-      envType = mempty,-      envShapes = mempty+      envType = mempty     }  typeEnv :: M.Map VName StructType -> Env typeEnv m =   Env     { envTerm = mempty,-      envType = M.map tbind m,-      envShapes = mempty+      envType = M.map tbind m     }   where     tbind = T.TypeAbbr Unlifted [] . RetType []@@ -544,23 +547,16 @@  -- | Expand type based on information that was not available at -- type-checking time (the structure of abstract types).-evalType :: Env -> StructType -> StructType-evalType _ (Scalar (Prim pt)) = Scalar $ Prim pt-evalType env (Scalar (Record fs)) = Scalar $ Record $ fmap (evalType env) fs-evalType env (Scalar (Arrow () p d t1 (RetType dims t2))) =-  Scalar $ Arrow () p d (evalType env t1) (RetType dims (evalType env t2))-evalType env t@(Array _ u shape _) =+expandType :: Env -> StructType -> StructType+expandType _ (Scalar (Prim pt)) = Scalar $ Prim pt+expandType env (Scalar (Record fs)) = Scalar $ Record $ fmap (expandType env) fs+expandType env (Scalar (Arrow () p d t1 (RetType dims t2))) =+  Scalar $ Arrow () p d (expandType env t1) (RetType dims (expandType env t2))+expandType env t@(Array _ u shape _) =   let et = stripArray (shapeRank shape) t-      et' = evalType env et-      shape' = fmap evalDim shape-   in arrayOf u shape' et'-  where-    evalDim (NamedSize qn)-      | Just (TermValue _ (ValuePrim (SignedValue (Int64Value x)))) <--          lookupVar qn env =-          ConstSize $ fromIntegral x-    evalDim d = d-evalType env t@(Scalar (TypeVar () _ tn args)) =+      et' = expandType env et+   in arrayOf u shape et'+expandType env t@(Scalar (TypeVar () _ tn args)) =   case lookupType tn env of     Just (T.TypeAbbr _ ps (RetType _ t')) ->       let (substs, types) = mconcat $ zipWith matchPtoA ps args@@ -568,7 +564,7 @@           onDim d = d        in if null ps             then first onDim t'-            else evalType (Env mempty types mempty <> env) $ first onDim t'+            else expandType (Env mempty types <> env) $ first onDim t'     Nothing -> t   where     matchPtoA (TypeParamDim p _) (TypeArgDim (NamedSize qv) _) =@@ -576,25 +572,35 @@     matchPtoA (TypeParamDim p _) (TypeArgDim (ConstSize k) _) =       (M.singleton p $ ConstSize k, mempty)     matchPtoA (TypeParamType l p _) (TypeArgType t' _) =-      let t'' = evalType env t'+      let t'' = expandType env t'        in (mempty, M.singleton p $ T.TypeAbbr l [] $ RetType [] t'')     matchPtoA _ _ = mempty-evalType env (Scalar (Sum cs)) = Scalar $ Sum $ (fmap . fmap) (evalType env) cs+expandType env (Scalar (Sum cs)) = Scalar $ Sum $ (fmap . fmap) (expandType env) cs +-- | First expand type abbreviations, then evaluate all possible+-- sizes.+evalType :: Env -> StructType -> EvalM StructType+evalType outer_env t = do+  size_env <- extSizeEnv+  let env = size_env <> outer_env+      evalDim (NamedSize qn)+        | Just (TermValue _ (ValuePrim (SignedValue (Int64Value x)))) <-+            lookupVar qn env =+            ConstSize $ fromIntegral x+      evalDim d = d+  pure $ first evalDim $ expandType env t+ evalTermVar :: Env -> QualName VName -> StructType -> EvalM Value evalTermVar env qv t =   case lookupVar qv env of-    Just (TermPoly _ v) -> do-      size_env <- extSizeEnv-      v $ evalType (size_env <> env) t+    Just (TermPoly _ v) -> v =<< evalType env t     Just (TermValue _ v) -> pure v     _ -> error $ "\"" <> prettyString qv <> "\" is not bound to a value."  typeValueShape :: Env -> StructType -> EvalM ValueShape typeValueShape env t = do-  size_env <- extSizeEnv-  let t' = evalType (size_env <> env) t-  case traverse dim $ typeShape mempty t' of+  t' <- evalType env t+  case traverse dim $ typeShape t' of     Nothing -> error $ "typeValueShape: failed to fully evaluate type " <> prettyString t'     Just shape -> pure shape   where@@ -612,24 +618,23 @@   etaExpand [] env rettype   where     etaExpand vs env' (Scalar (Arrow _ _ _ pt (RetType _ rt))) =-      pure $-        ValueFun $ \v -> do-          env'' <- matchPat env' (Wildcard (Info $ fromStruct pt) noLoc) v-          etaExpand (v : vs) env'' rt+      pure . ValueFun $ \v -> do+        env'' <- matchPat env' (Wildcard (Info $ fromStruct pt) noLoc) v+        etaExpand (v : vs) env'' rt     etaExpand vs env' _ = do-      f <- eval env' body+      f <- localExts $ eval env' body       foldM (apply noLoc mempty) f $ reverse vs evalFunction env missing_sizes (p : ps) body rettype =-  pure $-    ValueFun $ \v -> do-      env' <- matchPat env p v-      -- Fix up the last sizes, if any.-      let p_t = evalType env $ patternStructType p-          env''-            | null missing_sizes = env'-            | otherwise =-                env' <> i64Env (resolveExistentials missing_sizes p_t (valueShape v))-      evalFunction env'' missing_sizes ps body rettype+  pure . ValueFun $ \v -> do+    env' <- matchPat env p v+    -- Fix up the last sizes, if any.+    let p_t = expandType env $ patternStructType p+        env''+          | null missing_sizes =+              env'+          | otherwise =+              env' <> i64Env (resolveExistentials missing_sizes p_t (valueShape v))+    evalFunction env'' missing_sizes ps body rettype  evalFunctionBinding ::   Env ->@@ -639,9 +644,8 @@   Exp ->   EvalM TermBinding evalFunctionBinding env tparams ps ret fbody = do-  let ret' = evalType env $ retType ret-      arrow (xp, d, xt) yt = Scalar $ Arrow () xp d xt $ RetType [] yt-      ftype = foldr (arrow . patternParam) ret' ps+  let arrow (xp, d, xt) yt = Scalar $ Arrow () xp d xt $ RetType [] yt+      ftype = foldr (arrow . patternParam) (retType ret) ps       retext = case ps of         [] -> retDims ret         _ -> []@@ -649,21 +653,22 @@   -- Distinguish polymorphic and non-polymorphic bindings here.   if null tparams     then-      TermValue (Just $ T.BoundV [] ftype)-        <$> (returned env (retType ret) retext =<< evalFunction env [] ps fbody ret')-    else pure $-      TermPoly (Just $ T.BoundV [] ftype) $ \ftype' -> do-        let tparam_names = map typeParamName tparams-            env' = resolveTypeParams tparam_names ftype ftype' <> env+      fmap (TermValue (Just $ T.BoundV [] ftype))+        . returned env (retType ret) retext+        =<< evalFunction env [] ps fbody (retType ret)+    else pure . TermPoly (Just $ T.BoundV [] ftype) $ \ftype' -> do+      let tparam_names = map typeParamName tparams+          env' = resolveTypeParams tparam_names ftype ftype' <> env -            -- In some cases (abstract lifted types) there may be-            -- missing sizes that were not fixed by the type-            -- instantiation.  These will have to be set by looking-            -- at the actual function arguments.-            missing_sizes =-              filter (`M.notMember` envTerm env') $-                map typeParamName (filter isSizeParam tparams)-        returned env (retType ret) retext =<< evalFunction env' missing_sizes ps fbody ret'+          -- In some cases (abstract lifted types) there may be+          -- missing sizes that were not fixed by the type+          -- instantiation.  These will have to be set by looking+          -- at the actual function arguments.+          missing_sizes =+            filter (`M.notMember` envTerm env') $+              map typeParamName (filter isSizeParam tparams)+      returned env (retType ret) retext+        =<< evalFunction env' missing_sizes ps fbody (retType ret)  evalArg :: Env -> Exp -> Maybe VName -> EvalM Value evalArg env e ext = do@@ -676,10 +681,9 @@ returned :: Env -> TypeBase Size als -> [VName] -> Value -> EvalM Value returned _ _ [] v = pure v returned env ret retext v = do-  mapM_ (uncurry putExtSize) $-    M.toList $-      resolveExistentials retext (evalType env $ toStruct ret) $-        valueShape v+  mapM_ (uncurry putExtSize) . M.toList $+    resolveExistentials retext (expandType env $ toStruct ret) $+      valueShape v   pure v  evalAppExp :: Env -> StructType -> AppExp -> EvalM Value@@ -733,7 +737,7 @@         <> " is invalid." evalAppExp env t (Coerce e te loc) = do   v <- eval env e-  case checkShape (structTypeShape (envShapes env) t) (valueShape v) of+  case checkShape (structTypeShape t) (valueShape v) of     Just _ -> pure v     Nothing ->       bad loc env . docText $@@ -749,7 +753,7 @@ evalAppExp env _ (LetPat sizes p e body _) = do   v <- eval env e   env' <- matchPat env p v-  let p_t = evalType env $ patternStructType p+  let p_t = expandType env $ patternStructType p       v_s = valueShape v       env'' = env' <> i64Env (resolveExistentials (map sizeName sizes) p_t v_s)   eval env'' body@@ -826,34 +830,34 @@     inc = (`P.doAdd` Int64Value 1)     zero = (`P.doMul` Int64Value 0) +    evalBody env' = localExts $ eval env' body++    forLoopEnv iv i =+      valEnv+        ( M.singleton+            iv+            ( Just $ T.BoundV [] $ Scalar $ Prim $ Signed Int64,+              ValuePrim (SignedValue i)+            )+        )+     forLoop iv bound i v       | i >= bound = pure v       | otherwise = do           env' <- withLoopParams v-          forLoop iv bound (inc i)-            =<< eval-              ( valEnv-                  ( M.singleton-                      iv-                      ( Just $ T.BoundV [] $ Scalar $ Prim $ Signed Int64,-                        ValuePrim (SignedValue i)-                      )-                  )-                  <> env'-              )-              body+          forLoop iv bound (inc i) =<< evalBody (forLoopEnv iv i <> env')      whileLoop cond v = do       env' <- withLoopParams v       continue <- asBool <$> eval env' cond       if continue-        then whileLoop cond =<< eval env' body+        then whileLoop cond =<< evalBody env'         else pure v      forInLoop in_pat v in_v = do       env' <- withLoopParams v       env'' <- matchPat env' in_pat in_v-      eval env'' body+      evalBody env'' evalAppExp env _ (Match e cs _) = do   v <- eval env e   match v (NE.toList cs)@@ -897,10 +901,9 @@   v' <- eval env v   vs' <- mapM (eval env) vs   pure $ toArray' (valueShape v') (v' : vs')-eval env (AppExp e (Info (AppRes t retext))) =+eval env (AppExp e (Info (AppRes t retext))) = do+  t' <- evalType env $ toStruct t   returned env t' retext =<< evalAppExp env t' e-  where-    t' = evalType env $ toStruct t eval env (Var qv (Info t) _) = evalTermVar env qv (toStruct t) eval env (Ascript e _ _) = eval env e eval _ (IntLit v (Info t) _) =@@ -959,7 +962,8 @@ -- convenient in the interpreter. eval env (Lambda ps body _ (Info (_, RetType _ rt)) _) =   evalFunction env [] ps body rt-eval env (OpSection qv (Info t) _) = evalTermVar env qv $ toStruct t+eval env (OpSection qv (Info t) _) =+  evalTermVar env qv $ toStruct t eval env (OpSectionLeft qv _ e (Info (_, _, argext), _) (Info (RetType _ t), _) loc) = do   v <- evalArg env e argext   f <- evalTermVar env qv (toStruct t)@@ -1032,8 +1036,8 @@       (k, v) <- M.toList m       k' <- replace k       pure (k', f v)-    onModule (Module (Env terms types _)) =-      Module $ Env (replaceM onTerm terms) (replaceM onType types) mempty+    onModule (Module (Env terms types)) =+      Module $ Env (replaceM onTerm terms) (replaceM onType types)     onModule (ModuleFun f) =       ModuleFun $ \m -> onModule <$> f (substituteInModule substs m)     onTerm (TermValue t v) = TermValue t v@@ -1063,14 +1067,13 @@           ]     Just m -> pure $ Module m evalModExp env (ModDecs ds _) = do-  Env terms types _ <- foldM evalDec env ds+  Env terms types <- foldM evalDec env ds   -- Remove everything that was present in the original Env.   pure $     Module $       Env         (terms `M.difference` envTerm env)         (types `M.difference` envType env)-        mempty evalModExp env (ModVar qv _) =   evalModuleVar env qv evalModExp env (ModAscript me _ (Info substs) _) =@@ -1105,7 +1108,7 @@ evalDec env (LocalDec d _) = evalDec env d evalDec env SigDec {} = pure env evalDec env (TypeDec (TypeBind v l ps _ (Info (RetType dims t)) _ _)) = do-  let abbr = T.TypeAbbr l ps . RetType dims $ evalType env t+  let abbr = T.TypeAbbr l ps . RetType dims $ expandType env t   pure env {envType = M.insert v abbr $ envType env} evalDec env (ModDec (ModBind v ps ret body _ loc)) = do   mod <- evalModExp env $ wrapInLambda ps@@ -1152,11 +1155,10 @@     ( Env         ( M.insert             (VName (nameFromString "intrinsics") 0)-            (TermModule (Module $ Env terms types mempty))+            (TermModule (Module $ Env terms types))             terms         )         types-        mempty     )     mempty   where@@ -1477,13 +1479,13 @@               | Just rowshape <- typeRowShape ret_t ->                   toArray' rowshape <$> mapM (apply noLoc mempty f) (snd $ fromArray xs)               | otherwise ->-                  error $ "Bad pure type: " <> prettyString ret_t+                  error $ "Bad return type: " <> prettyString ret_t             _ ->               error $                 "Invalid arguments to map intrinsic:\n"                   ++ unlines [prettyString t, show f, show xs]       where-        typeRowShape = sequenceA . structTypeShape mempty . stripArray 1+        typeRowShape = sequenceA . structTypeShape . stripArray 1     def s | "reduce" `isPrefixOf` s = Just $       fun3 $ \f ne xs ->         foldM (apply2 noLoc mempty f) ne $ snd $ fromArray xs
src/Language/Futhark/Interpreter/Values.hs view
@@ -76,27 +76,21 @@ emptyShape (ShapeDim d s) = d == 0 || emptyShape s emptyShape _ = False -typeShape :: M.Map VName (Shape d) -> TypeBase d () -> Shape d-typeShape shapes = go-  where-    go (Array _ _ shape et) =-      foldr ShapeDim (go (Scalar et)) $ shapeDims shape-    go (Scalar (Record fs)) =-      ShapeRecord $ M.map go fs-    go (Scalar (Sum cs)) =-      ShapeSum $ M.map (map go) cs-    go (Scalar (TypeVar _ _ (QualName [] v) []))-      | Just shape <- M.lookup v shapes =-          shape-    go _ =-      ShapeLeaf+typeShape :: TypeBase d () -> Shape d+typeShape (Array _ _ shape et) =+  foldr ShapeDim (typeShape (Scalar et)) $ shapeDims shape+typeShape (Scalar (Record fs)) =+  ShapeRecord $ M.map typeShape fs+typeShape (Scalar (Sum cs)) =+  ShapeSum $ M.map (map typeShape) cs+typeShape _ =+  ShapeLeaf -structTypeShape :: M.Map VName ValueShape -> StructType -> Shape (Maybe Int64)-structTypeShape shapes = fmap dim . typeShape shapes'+structTypeShape :: StructType -> Shape (Maybe Int64)+structTypeShape = fmap dim . typeShape   where     dim (ConstSize d) = Just $ fromIntegral d     dim _ = Nothing-    shapes' = M.map (fmap $ ConstSize . fromIntegral) shapes  -- | A fully evaluated Futhark value. data Value m
src/Language/Futhark/Parser/Monad.hs view
@@ -38,9 +38,11 @@  import Control.Applicative (liftA) import Control.Monad-import Control.Monad.Except+import Control.Monad.Except (ExceptT, MonadError (..), runExceptT)+import Control.Monad.Trans.Class (lift) import Control.Monad.Trans.State import Data.Array hiding (index)+import Data.List.NonEmpty qualified as NE import Data.Monoid import Data.Text qualified as T import Futhark.Util.Loc@@ -127,11 +129,11 @@ arrayFromList :: [a] -> Array Int a arrayFromList l = listArray (0, length l - 1) l -applyExp :: [UncheckedExp] -> ParserMonad UncheckedExp-applyExp all_es@((Constr n [] _ loc1) : es) =-  pure $ Constr n es NoInfo (srcspan loc1 (last all_es))+applyExp :: NE.NonEmpty UncheckedExp -> ParserMonad UncheckedExp+applyExp all_es@((Constr n [] _ loc1) NE.:| es) =+  pure $ Constr n es NoInfo (srcspan loc1 (NE.last all_es)) applyExp es =-  foldM op (head es) (tail es)+  foldM op (NE.head es) (NE.tail es)   where     op (AppExp (Index e is floc) _) (ArrayLit xs _ xloc) =       parseErrorAt (srcspan floc xloc) . Just . docText $
src/Language/Futhark/Parser/Parser.y view
@@ -581,11 +581,11 @@       | ApplyList {% applyExp $1 } -ApplyList :: { [UncheckedExp] }-          : ApplyList Atom %prec juxtprec-            { $1 ++ [$2] }+ApplyList :: { NE.NonEmpty UncheckedExp }+          : Atom ApplyList %prec juxtprec+            { NE.cons $1 $2 }           | Atom %prec juxtprec-            { [$1] }+            { NE.singleton $1 }  Atom :: { UncheckedExp } Atom : PrimLit        { Literal (fst $1) (srclocOf (snd $1)) }
src/Language/Futhark/Prop.hs view
@@ -97,6 +97,7 @@   ) where +import Control.Monad import Control.Monad.State import Data.Bifoldable import Data.Bifunctor
src/Language/Futhark/Query.hs view
@@ -88,7 +88,7 @@         Lambda params _ _ _ _ ->           mconcat (map patternDefs params)         AppExp (LetFun name (tparams, params, _, Info ret, _) _ loc) _ ->-          let name_t = foldFunType (map (undefined . patternStructType) params) ret+          let name_t = foldFunTypeFromParams params ret            in M.singleton name (DefBound $ BoundTerm name_t (locOf loc))                 <> mconcat (map typeParamDefs tparams)                 <> mconcat (map patternDefs params)@@ -111,7 +111,7 @@       <> expDefs (valBindBody vbind)   where     vbind_t =-      foldFunType (map (undefined . patternStructType) (valBindParams vbind)) $+      foldFunTypeFromParams (valBindParams vbind) $         unInfo $           valBindRetType vbind 
src/Language/Futhark/Syntax.hs view
@@ -286,6 +286,9 @@ instance Bitraversable RetTypeBase where   bitraverse f g (RetType dims t) = RetType dims <$> bitraverse f g t +instance Functor (RetTypeBase dim) where+  fmap = second+ instance Bifunctor RetTypeBase where   bimap = bimapDefault @@ -314,6 +317,9 @@     Arrow <$> g als <*> pure v <*> pure d <*> bitraverse f pure t1 <*> bitraverse f g t2   bitraverse f g (Sum cs) = Sum <$> (traverse . traverse) (bitraverse f g) cs +instance Functor (ScalarTypeBase dim) where+  fmap = second+ instance Bifunctor ScalarTypeBase where   bimap = bimapDefault @@ -334,6 +340,9 @@   bitraverse f g (Scalar t) = Scalar <$> bitraverse f g t   bitraverse f g (Array a u shape t) =     Array <$> g a <*> pure u <*> traverse f shape <*> bitraverse f pure t++instance Functor (TypeBase dim) where+  fmap = second  instance Bifunctor TypeBase where   bimap = bimapDefault
src/Language/Futhark/TypeChecker.hs view
@@ -18,10 +18,11 @@   ) where +import Control.Monad import Control.Monad.Except-import Control.Monad.Writer hiding (Sum) import Data.Bifunctor (first, second) import Data.Either+import Data.List qualified as L import Data.Map.Strict qualified as M import Data.Maybe import Data.Ord@@ -552,6 +553,15 @@ checkTypeBind (TypeBind name l tps te NoInfo doc loc) =   checkTypeParams tps $ \tps' -> do     (te', svars, RetType dims t, l') <- bindingTypeParams tps' $ checkTypeExp te++    let (witnessed, _) = determineSizeWitnesses t+    case L.find (`S.notMember` witnessed) svars of+      Just _ ->+        typeError (locOf te) mempty . withIndexLink "anonymous-nonconstructive" $+          "Type abbreviation contains an anonymous size not used constructively as an array size."+      Nothing ->+        pure ()+     let elab_t = RetType (svars ++ dims) t      let used_dims = freeInType t
src/Language/Futhark/TypeChecker/Modules.hs view
@@ -8,8 +8,7 @@   ) where -import Control.Monad.Except-import Control.Monad.Writer hiding (Sum)+import Control.Monad import Data.Either import Data.List (intersect) import Data.Map.Strict qualified as M
src/Language/Futhark/TypeChecker/Monad.hs view
@@ -49,6 +49,7 @@   ) where +import Control.Monad import Control.Monad.Except import Control.Monad.Reader import Control.Monad.State.Strict
src/Language/Futhark/TypeChecker/Terms.hs view
@@ -12,6 +12,7 @@   ) where +import Control.Monad import Control.Monad.Except import Control.Monad.Reader import Control.Monad.State
src/Language/Futhark/TypeChecker/Terms/DoLoop.hs view
@@ -8,7 +8,7 @@   ) where -import Control.Monad.Except+import Control.Monad import Control.Monad.Reader import Control.Monad.State import Data.Bifunctor
src/Language/Futhark/TypeChecker/Terms/Monad.hs view
@@ -75,6 +75,7 @@   ) where +import Control.Monad import Control.Monad.Except import Control.Monad.Reader import Control.Monad.State
src/Language/Futhark/TypeChecker/Terms/Pat.hs view
@@ -10,7 +10,7 @@   ) where -import Control.Monad.Except+import Control.Monad import Control.Monad.State import Data.Bitraversable import Data.Either
src/Language/Futhark/TypeChecker/Types.hs view
@@ -22,6 +22,7 @@   ) where +import Control.Monad import Control.Monad.Identity import Control.Monad.Reader import Control.Monad.State
src/Language/Futhark/TypeChecker/Unify.hs view
@@ -30,6 +30,7 @@   ) where +import Control.Monad import Control.Monad.Except import Control.Monad.State import Data.Bifunctor@@ -925,7 +926,7 @@ equalityType usage t = do   unless (orderZero t) $     unifyError usage mempty noBreadCrumbs $-      "Type " <+> dquotes (pretty t) <+> "does not support equality (is higher-order)."+      "Type " <+> dquotes (pretty t) <+> "does not support equality (may contain function)."   mapM_ mustBeEquality $ typeVars t   where     mustBeEquality vn = do