packages feed

futhark 0.16.1 → 0.16.2

raw patch · 16 files changed

+138/−32 lines, 16 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Futhark.IR.Prop.Types: modifyArrayShape :: ArrayShape newshape => (oldshape -> newshape) -> TypeBase oldshape u -> TypeBase newshape u

Files

docs/c-api.rst view
@@ -81,6 +81,13 @@    you must not pass values between them.  They have the same C type,    so this is an easy mistake to make. +   After you have created a context object, you must immediately call+   :c:func:`futhark_context_get_error`, which will return non-``NULL``+   if initialisation failed.  If initialisation has failed, then you+   still need to call :c:func:`futhark_context_free` to release+   resources used for the context object, but you may not use the+   context object for anything else.+ .. c:function:: void futhark_context_free(struct futhark_context *ctx)     Free the context object.  It must not be used again.  The@@ -207,6 +214,17 @@    sure to call :c:func:`futhark_context_sync` before using the value    of ``out0``. +The exact behaviour of the exit code depends on the backend.  For the+sequential C backend, errors will always be available when the entry+point returns, and :c:func:`futhark_context_sync` will always return+success.  When using a GPU backend such as ``cuda`` or ``opencl``, the+entry point may still be running asynchronous operations when it+returns, in which case the entry point may return zero successfully,+even though execution has already (or will) fail.  These problems will+be reported when :c:func:`futhark_context_sync` is called.  When using+GPU backends, be careful to check the return code of *both* the entry+point itself, and :c:func:`futhark_context_sync`.+ GPU --- @@ -325,3 +343,30 @@     During :c:func:`futhark_context_new`, read PTX code from the given    file instead of using the embedded program.++General guarantees+------------------++Calling an entry point, or interacting with Futhark values through the+functions listed above, has no system-wide side effects, such as+writing to the file system, launching processes, or performing network+connections.  Defects in the program or Futhark compiler itself can+with high probability result only in the consumption of CPU or GPU+resources, or a process crash.++Using the ``#[unsafe]`` attribute with in-place updates can result in+writes to arbitrary memory locations.  A malicious program can likely+exploit this to obtain arbitrary code execution, just as with any+insecure C program.  If you must run untrusted code, consider using+the ``--safe`` command line option to instruct the compiler to disable+``#[unsafe]``.++Initialising a Futhark context likewise has no side effects, except if+explicitly configured differently, such as by using+:c:func:`futhark_context_config_dump_program_to`.  In its default+configuration, Futhark will not access the file system.++Note that for the GPU backends, the underlying API (such as CUDA or+OpenCL) may perform file system operations during startup, and perhaps+for caching GPU kernels in some cases.  This is beyond Futhark's+control.
docs/language-reference.rst view
@@ -728,12 +728,14 @@   ``^``, ``&``, ``|``, ``>>``, ``<<``      Bitwise operators, respectively bitwise xor, and, or, arithmetic-    shift right and left, and logical shift right.  Shift amounts-    must be non-negative and the operands must be integers.  Note-    that, unlike in C, bitwise operators have *higher* priority than-    arithmetic operators.  This means that ``x & y == z`` is-    understood as ``(x & y) == z``, rather than ``x & (y == z)`` as-    it would in C.  Note that the latter is a type error in Futhark+    shift right and left, and logical shift right.  **Shifting is+    undefined if the right operand is negative, or greater than or+    equal to the length in bits of the left operand.**++    Note that, unlike in C, bitwise operators have *higher* priority+    than arithmetic operators.  This means that ``x & y == z`` is+    understood as ``(x & y) == z``, rather than ``x & (y == z)`` as it+    would in C.  Note that the latter is a type error in Futhark     anyhow.    ``==``, ``!=``
docs/usage.rst view
@@ -19,6 +19,8 @@ useful mostly for testing and benchmarking.  Libraries can be called from non-Futhark code. +.. _executable:+ Compiling to Executable ----------------------- @@ -450,3 +452,18 @@ Futhark arrays are mapped to either the Numpy ``ndarray`` type or the `pyopencl.array <https://documen.tician.de/pyopencl/array.html>`_ type.  Scalars are mapped to Numpy scalar types.++Reproducibility+---------------++The Futhark compiler is deterministic by design, meaning that+repeatedly compiling the *same program* with the *same compilation+flags* and using the *same version* of the compiler will produce+identical output every time.++Note that this only applies to the code generated by the Futhark+compiler itself.  When compiling to an executable with one of the C+backends (see :ref:`executable`), Futhark will invoke a C compiler+that may not be perfectly reproducible.  In such cases the generated+``.c`` and ``.h`` files will be reproducible, but the final executable+may not.
futhark.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.4  name:           futhark-version:        0.16.1+version:        0.16.2 synopsis:       An optimising compiler for a functional, array-oriented language.  description:    Futhark is a small programming language designed to be compiled to
rts/c/util.h view
@@ -2,7 +2,7 @@ // // Various helper functions that are useful in all generated C code. -static const char *fut_progname = "(some Futhark code)";+static const char *fut_progname = "(embedded Futhark)";  static void futhark_panic(int eval, const char *fmt, ...) {   va_list ap;
rts/python/opencl.py view
@@ -204,7 +204,7 @@     if (len(program_src) >= 0):         return cl.Program(self.ctx, program_src).build(             ["-DLOCKSTEP_WIDTH={}".format(lockstep_width)]-            + ["-D{}={}".format(s.replace('z', 'zz').replace('.', 'zi'),v) for (s,v) in self.sizes.items()])+            + ["-D{}={}".format(s.replace('z', 'zz').replace('.', 'zi').replace('#', 'zh'),v) for (s,v) in self.sizes.items()])  def opencl_alloc(self, min_size, tag):     min_size = 1 if min_size == 0 else min_size@@ -219,6 +219,11 @@     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)++        # Read failure args.         failure_args = np.empty(self.global_failure_args_max+1, dtype=np.int32)         cl.enqueue_copy(self.queue, failure_args, self.global_failure_args, is_blocking=True)+         raise Exception(self.failure_msgs[failure[0]].format(*failure_args))
src/Futhark/CLI/Autotune.hs view
@@ -348,6 +348,12 @@     (ReqArg (\prog -> Right $ \config -> config { optFuthark = Just prog })      "PROGRAM")     "The binary used for operations (defaults to 'futhark')."+  , Option [] ["pass-option"]+    (ReqArg (\opt ->+               Right $ \config ->+               config { optExtraOptions = opt : optExtraOptions config })+     "OPT")+    "Pass this option to programs being run."   , Option [] ["tuning"]     (ReqArg (\s -> Right $ \config -> config { optTuning = Just s })     "EXTENSION")
src/Futhark/CLI/Bench.hs view
@@ -165,15 +165,19 @@ progressBar :: Int -> Int -> Int -> String progressBar cur bound steps =   "[" ++ map cell [1..steps] ++ "] " ++ show cur ++ "/" ++ show bound-  where step_size = bound `div` steps+  where step_size :: Double+        step_size = fromIntegral bound / fromIntegral steps+        cur' = fromIntegral cur         chars = " ▏▎▍▍▌▋▊▉█"         char i = fromMaybe ' ' $ maybeNth (i::Int) chars+        num_chars = fromIntegral $ length chars          cell :: Int -> Char         cell i-          | i * step_size <= cur = char 9-          | otherwise = char (((cur - (i-1) * step_size) * length chars)-                              `div` step_size)+          | i' * step_size <= cur' = char 9+          | otherwise = char (floor (((cur' - (i'-1) * step_size) * num_chars)+                                     / step_size))+          where i' = fromIntegral i  descString :: String -> Int -> String descString desc pad_to = desc ++ ": " ++ replicate (pad_to - length desc) ' '
src/Futhark/CodeGen/Backends/CCUDA/Boilerplate.hs view
@@ -386,6 +386,14 @@                    ctx->failure_is_an_option = 0;                     if (failure_idx >= 0) {+                     // We have to clear global_failure so that the next entry point+                     // is not considered a failure from the start.+                     typename int32_t no_failure = -1;+                     CUDA_SUCCEED(+                       cuMemcpyHtoD(ctx->global_failure,+                                    &no_failure,+                                    sizeof(int32_t)));+                      typename int32_t args[$int:max_failure_args+1];                      CUDA_SUCCEED(                        cuMemcpyDtoH(&args,
src/Futhark/CodeGen/Backends/COpenCL/Boilerplate.hs view
@@ -416,6 +416,14 @@                  OPENCL_SUCCEED_OR_RETURN(clFinish(ctx->opencl.queue));                   if (failure_idx >= 0) {+                   // We have to clear global_failure so that the next entry point+                   // is not considered a failure from the start.+                   typename cl_int no_failure = -1;+                   OPENCL_SUCCEED_OR_RETURN(+                    clEnqueueWriteBuffer(ctx->opencl.queue, ctx->global_failure, CL_TRUE,+                                         0, sizeof(cl_int), &no_failure,+                                         0, NULL, NULL));+                    typename cl_int args[$int:max_failure_args+1];                    OPENCL_SUCCEED_OR_RETURN(                      clEnqueueReadBuffer(ctx->opencl.queue,
src/Futhark/CodeGen/Backends/GenericC.hs view
@@ -1656,6 +1656,7 @@                     mapM_ resetMemConst ps                     compileCode init_consts   libDecl [C.cedecl|int init_constants($ty:ctx_ty *ctx) {+      (void)ctx;       int err = 0;       $items:defs       $items:init_consts'@@ -1666,6 +1667,7 @@    free_consts <- collect $ mapM_ freeConst ps   libDecl [C.cedecl|int free_constants($ty:ctx_ty *ctx) {+      (void)ctx;       $items:free_consts       return 0;     }|]@@ -1988,7 +1990,7 @@   cached <- cacheMem name   case cached of     Just cur_size ->-      stm [C.cstm|if ($exp:cur_size < $exp:size) {+      stm [C.cstm|if ($exp:cur_size < (size_t)$exp:size) {                     $exp:name = realloc($exp:name, $exp:size);                     $exp:cur_size = $exp:size;                   }|]
src/Futhark/CodeGen/Backends/GenericPython.hs view
@@ -294,7 +294,7 @@             -> [Option]             -> Imp.Definitions op             -> m String-compileProg module_name constructor imports defines ops userstate pre_timing options prog = do+compileProg module_name constructor imports defines ops userstate sync options prog = do   src <- getNameSource   let prog' = runCompilerM ops src userstate compileProg'       maybe_shebang =@@ -321,14 +321,14 @@           case module_name of             Just name -> do               (entry_points, entry_point_types) <--                unzip <$> mapM compileEntryFun (filter (Imp.functionEntry . snd) funs)+                unzip <$> mapM (compileEntryFun sync) (filter (Imp.functionEntry . snd) funs)               return [ClassDef $ Class name $                        Assign (Var "entry_points") (Dict entry_point_types) :                        map FunDef (constructor' : definitions ++ entry_points)]             Nothing -> do               let classinst = Assign (Var "self") $ simpleCall "internal" []               (entry_point_defs, entry_point_names, entry_points) <--                unzip3 <$> mapM (callEntryFun pre_timing)+                unzip3 <$> mapM (callEntryFun sync)                 (filter (Imp.functionEntry . snd) funs)               return (parse_options ++                       ClassDef (Class "internal" $ map FunDef $@@ -604,14 +604,14 @@                      [srcmem, srcidx, Var "ct.c_byte"]   stm $ Exp $ simpleCall "ct.memmove" [offset_call1, offset_call2, nbytes] -compileEntryFun :: (Name, Imp.Function op)+compileEntryFun :: [PyStmt] -> (Name, Imp.Function op)                 -> CompilerM op s (PyFunDef, (PyExp, PyExp))-compileEntryFun entry = do+compileEntryFun sync entry = do   (fname', params, prepareIn, body_lib, _, prepareOut, res, _) <- prepareEntry entry   let ret = Return $ tupleOrSingle $ map snd res       (pts, rts) = entryTypes $ snd entry   return (Def fname' ("self" : params) $-           prepareIn ++ body_lib ++ prepareOut ++ [ret],+           prepareIn ++ body_lib ++ prepareOut ++ sync ++ [ret],           (String fname', Tuple [List (map String pts), List (map String rts)]))  entryTypes :: Imp.Function op -> ([String], [String])
src/Futhark/CodeGen/ImpGen/Kernels/Base.hs view
@@ -1425,7 +1425,8 @@    -- Avoid loop for the common case where each thread is statically   -- known to write at most one element.-  if toExp' int32 per_group_elems == kernelGroupSize constants+  localOps threadOperations $+    if toExp' int32 per_group_elems == kernelGroupSize constants     then sWhen (offset + ltid .<. toExp' int32 w) $          copyDWIMFix (patElemName pe) [ltid + offset] (Var what) [ltid]     else@@ -1441,7 +1442,8 @@   local_is <- localThreadIDs $ map snd dims   is_for_thread <- mapM (dPrimV "thread_out_index") $ zipWith (+) group_is local_is -  sWhen (isActive $ zip is_for_thread $ map fst dims) $+  localOps threadOperations $+    sWhen (isActive $ zip is_for_thread $ map fst dims) $     copyDWIMFix (patElemName pe) (map Imp.vi32 is_for_thread) (Var what) local_is  compileGroupResult space pe (Returns _ what) = do
src/Futhark/IR/Mem/IxFun.hs view
@@ -421,8 +421,8 @@       mid_dims = take (length dims - num_coercions) $ drop hd_len dims'       num_rshps = length reshapes   guard (num_rshps == 0 || (num_rshps == 1 && length mid_dims == 1))-  let dims'' = map snd $ sortBy (compare `on` fst) $-               zipWith (\ld n -> (ldPerm ld, ld { ldShape = n }))+  let dims'' = permuteInv perm $+               zipWith (\ld n -> ld { ldShape = n })                dims' (newDims newshape)       lmad' = LMAD off dims''   return $ IxFun (lmad' :| lmads) (newDims newshape) cg
src/Futhark/IR/Prop/Types.hs view
@@ -5,7 +5,6 @@          rankShaped        , arrayRank        , arrayShape-       , modifyArrayShape        , setArrayShape        , existential        , uniqueness
src/Language/Futhark/TypeChecker/Terms.hs view
@@ -2193,7 +2193,6 @@   occur [observation as loc]    checkOccurences dflow-  occurs <- consumeArg argloc argtype' (diet tp1')    case anyConsumption dflow of     Just c ->@@ -2201,7 +2200,11 @@       in zeroOrderType (mkUsage argloc "potential consumption in expression") msg tp1     _ -> return () -  occur $ dflow `seqOccurences` occurs+  occurs <- (dflow `seqOccurences`) <$> consumeArg argloc argtype' (diet tp1')++  checkIfConsumable loc $ S.map AliasBound $ allConsumed occurs+  occur occurs+   (argext, parsubst) <-     case pname of       Named pname' -> do@@ -2928,9 +2931,8 @@   let als = AliasBound nm `S.insert` aliases t   in occur [observation als loc] --- | Proclaim that we have written to the given variable.-consume :: SrcLoc -> Aliasing -> TermTypeM ()-consume loc als = do+checkIfConsumable :: SrcLoc -> Aliasing -> TermTypeM ()+checkIfConsumable loc als = do   vtable <- asks $ scopeVtable . termScope   let consumable v = case M.lookup v vtable of                        Just (BoundV Local _ t)@@ -2940,9 +2942,15 @@                        _ -> False   case filter (not . consumable) $ map aliasVar $ S.toList als of     v:_ -> typeError loc mempty $-           "Attempt to consume variable" <+> pquote (pprName v)+           "Would consume variable" <+> pquote (pprName v)            <> ", which is not allowed."-    [] -> occur [consumption als loc]+    [] -> return ()++-- | Proclaim that we have written to the given variable.+consume :: SrcLoc -> Aliasing -> TermTypeM ()+consume loc als = do+  checkIfConsumable loc als+  occur [consumption als loc]  -- | Proclaim that we have written to the given variable, and mark -- accesses to it and all of its aliases as invalid inside the given