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 +9/−4
- docs/conf.py +317/−153
- docs/error-index.rst +21/−0
- docs/glossary.rst +242/−0
- docs/index.rst +1/−0
- docs/language-reference.rst +2/−0
- docs/versus-other-languages.rst +1/−1
- futhark.cabal +2/−2
- rts/python/memory.py +33/−20
- rts/python/opencl.py +171/−100
- rts/python/panic.py +4/−2
- rts/python/scalar.py +584/−327
- rts/python/server.py +50/−41
- rts/python/tuning.py +3/−1
- rts/python/values.py +376/−264
- src/Futhark/AD/Rev/Loop.hs +3/−3
- src/Futhark/Analysis/Interference.hs +1/−0
- src/Futhark/Analysis/LastUse.hs +1/−0
- src/Futhark/Analysis/MemAlias.hs +1/−0
- src/Futhark/Analysis/Metrics.hs +1/−0
- src/Futhark/Bench.hs +3/−1
- src/Futhark/CLI/Bench.hs +7/−6
- src/Futhark/CLI/Doc.hs +1/−0
- src/Futhark/CLI/Eval.hs +2/−1
- src/Futhark/CLI/Literate.hs +8/−14
- src/Futhark/CLI/Misc.hs +1/−0
- src/Futhark/CLI/Pkg.hs +1/−0
- src/Futhark/CLI/REPL.hs +8/−8
- src/Futhark/CLI/Run.hs +2/−1
- src/Futhark/CLI/Test.hs +3/−1
- src/Futhark/CodeGen/Backends/COpenCL/Boilerplate.hs +1/−0
- src/Futhark/CodeGen/Backends/GenericC.hs +1/−0
- src/Futhark/CodeGen/Backends/GenericC/Code.hs +2/−1
- src/Futhark/CodeGen/Backends/GenericC/EntryPoints.hs +2/−9
- src/Futhark/CodeGen/Backends/GenericC/Fun.hs +1/−1
- src/Futhark/CodeGen/Backends/GenericC/Monad.hs +1/−1
- src/Futhark/CodeGen/Backends/GenericC/Types.hs +3/−2
- src/Futhark/CodeGen/Backends/GenericPython.hs +1/−1
- src/Futhark/CodeGen/Backends/GenericWASM.hs +4/−4
- src/Futhark/CodeGen/ImpGen.hs +1/−1
- src/Futhark/CodeGen/ImpGen/GPU.hs +1/−1
- src/Futhark/CodeGen/ImpGen/GPU/Base.hs +2/−2
- src/Futhark/CodeGen/ImpGen/GPU/Group.hs +5/−3
- src/Futhark/CodeGen/ImpGen/GPU/SegHist.hs +1/−1
- src/Futhark/CodeGen/ImpGen/GPU/SegMap.hs +1/−1
- src/Futhark/CodeGen/ImpGen/GPU/SegRed.hs +1/−1
- src/Futhark/CodeGen/ImpGen/GPU/SegScan/SinglePass.hs +1/−1
- src/Futhark/CodeGen/ImpGen/GPU/SegScan/TwoPass.hs +1/−1
- src/Futhark/CodeGen/ImpGen/GPU/ToOpenCL.hs +1/−0
- src/Futhark/CodeGen/ImpGen/Multicore/SegHist.hs +2/−1
- src/Futhark/Compiler.hs +2/−1
- src/Futhark/Compiler/Program.hs +1/−1
- src/Futhark/Construct.hs +1/−0
- src/Futhark/Doc/Generator.hs +1/−1
- src/Futhark/IR/Aliases.hs +15/−2
- src/Futhark/IR/Mem.hs +1/−0
- src/Futhark/IR/Mem/IxFun.hs +1/−2
- src/Futhark/IR/Prop/Aliases.hs +13/−5
- src/Futhark/IR/Prop/Types.hs +1/−0
- src/Futhark/IR/SOACS/SOAC.hs +7/−4
- src/Futhark/IR/SOACS/Simplify.hs +9/−15
- src/Futhark/IR/SegOp.hs +4/−3
- src/Futhark/IR/Syntax/Core.hs +5/−1
- src/Futhark/IR/Traversals.hs +2/−2
- src/Futhark/IR/TypeCheck.hs +1/−0
- src/Futhark/Internalise/Bindings.hs +2/−1
- src/Futhark/Internalise/Defunctionalise.hs +2/−0
- src/Futhark/Internalise/Entry.hs +1/−0
- src/Futhark/Internalise/Exps.hs +1/−0
- src/Futhark/Internalise/Lambdas.hs +3/−1
- src/Futhark/Internalise/Monad.hs +1/−0
- src/Futhark/Internalise/Monomorphise.hs +5/−6
- src/Futhark/Optimise/ArrayShortCircuiting.hs +1/−0
- src/Futhark/Optimise/ArrayShortCircuiting/ArrayCoalescing.hs +1/−0
- src/Futhark/Optimise/BlkRegTiling.hs +12/−10
- src/Futhark/Optimise/CSE.hs +2/−1
- src/Futhark/Optimise/DoubleBuffer.hs +2/−1
- src/Futhark/Optimise/Fusion.hs +1/−0
- src/Futhark/Optimise/GenRedOpt.hs +1/−0
- src/Futhark/Optimise/HistAccs.hs +1/−0
- src/Futhark/Optimise/InPlaceLowering.hs +3/−2
- src/Futhark/Optimise/InliningDeadFun.hs +2/−1
- src/Futhark/Optimise/Simplify/Engine.hs +1/−0
- src/Futhark/Optimise/Simplify/Rep.hs +13/−3
- src/Futhark/Optimise/Simplify/Rules.hs +2/−2
- src/Futhark/Optimise/Simplify/Rules/Loop.hs +15/−9
- src/Futhark/Optimise/Simplify/Rules/Simple.hs +10/−8
- src/Futhark/Optimise/TileLoops.hs +1/−0
- src/Futhark/Optimise/TileLoops/Shared.hs +1/−0
- src/Futhark/Optimise/Unstream.hs +1/−0
- src/Futhark/Pass/AD.hs +1/−1
- src/Futhark/Pass/ExpandAllocations.hs +3/−2
- src/Futhark/Pass/ExplicitAllocations.hs +1/−0
- src/Futhark/Pass/ExplicitAllocations/GPU.hs +1/−0
- src/Futhark/Pass/ExplicitAllocations/SegOp.hs +1/−0
- src/Futhark/Pass/ExtractKernels.hs +1/−1
- src/Futhark/Pass/ExtractKernels/BlockedKernel.hs +0/−1
- src/Futhark/Pass/ExtractKernels/DistributeNests.hs +1/−1
- src/Futhark/Pass/ExtractKernels/Distribution.hs +1/−0
- src/Futhark/Pass/ExtractKernels/ISRWIM.hs +1/−1
- src/Futhark/Pass/ExtractKernels/Interchange.hs +1/−1
- src/Futhark/Pass/ExtractKernels/Intragroup.hs +1/−1
- src/Futhark/Pass/ExtractMulticore.hs +1/−0
- src/Futhark/Pass/KernelBabysitting.hs +11/−2
- src/Futhark/Pipeline.hs +0/−1
- src/Futhark/Pkg/Solve.hs +1/−0
- src/Futhark/Script.hs +53/−1
- src/Futhark/Test.hs +2/−1
- src/Futhark/Tools.hs +1/−1
- src/Futhark/Transform/FirstOrderTransform.hs +1/−1
- src/Futhark/Util.hs +1/−15
- src/Futhark/Util/Pretty.hs +1/−6
- src/Language/Futhark/Interpreter.hs +106/−104
- src/Language/Futhark/Interpreter/Values.hs +11/−17
- src/Language/Futhark/Parser/Monad.hs +7/−5
- src/Language/Futhark/Parser/Parser.y +4/−4
- src/Language/Futhark/Prop.hs +1/−0
- src/Language/Futhark/Query.hs +2/−2
- src/Language/Futhark/Syntax.hs +9/−0
- src/Language/Futhark/TypeChecker.hs +11/−1
- src/Language/Futhark/TypeChecker/Modules.hs +1/−2
- src/Language/Futhark/TypeChecker/Monad.hs +1/−0
- src/Language/Futhark/TypeChecker/Terms.hs +1/−0
- src/Language/Futhark/TypeChecker/Terms/DoLoop.hs +1/−1
- src/Language/Futhark/TypeChecker/Terms/Monad.hs +1/−0
- src/Language/Futhark/TypeChecker/Terms/Pat.hs +1/−1
- src/Language/Futhark/TypeChecker/Types.hs +1/−0
- src/Language/Futhark/TypeChecker/Unify.hs +2/−1
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\n\n"+imgBlock f = "\n" videoBlock :: VideoParams -> FilePath -> T.Text-videoBlock opts f = "\n\n" <> opts' <> "\n\n"+videoBlock opts 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
@@ -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