packages feed

abstract-par-accelerate (empty) → 0.3.1

raw patch · 4 files changed

+228/−0 lines, 4 filesdep +abstract-pardep +acceleratedep +accelerate-iosetup-changed

Dependencies added: abstract-par, accelerate, accelerate-io, array, base, vector

Files

+ Control/Monad/Par/Accelerate.hs view
@@ -0,0 +1,146 @@+{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, TypeFamilies #-}+{-# LANGUAGE CPP #-}+{-# OPTIONS_GHC -Wall #-}++module Control.Monad.Par.Accelerate +       (+         -- * The Class+         ParAccelerate(..),+       +         -- * Example applications of `unsafeHybrid`+         unsafeHybridVector,+         unsafeHybridIArray+       ) where ++import Control.Monad.Par.Class+import Data.Array.IArray (IArray)+import Foreign (Ptr, Storable)+import qualified Data.Array.IArray as IArray    +import qualified Data.Vector.Storable as Vector++-- From 'accelerate':+import Data.Array.Accelerate (Acc, Arrays, Shape)+import Data.Array.Accelerate.Array.Sugar (EltRepr,Elt,Array,DIM1,toIArray)++-- From 'accelerate-io', or 'accelerate" <= 0.10+import qualified Data.Array.Accelerate.IO as IO ++--------------------------------------------------------------------------------++-- | A class containing Accelerate-specific `Par` operations.+-- +-- A minimal complete instance contains:+--  * one of `runAccWith` or `spawnAccWith`+--  * `getDefaultAccImpl`+--  * `compileAcc`.+class ParFuture iv p => ParAccelerate iv p where +  +  -- | Run an Accelerate computation and wait for its result.  In the+  -- context of a `Par` computation this can result in better+  -- performance than using an Accelerate-provided `run` function+  -- directly, because this version enables the CPU work scheduler to do+  -- other work while waiting for the GPU computation to complete.+  -- +  -- Moreover, when configured with a high-performance /CPU/ Accelerate backend+  -- in the future this routine can enable automatic CPU/GPU work partitioning.+  -- +  -- The specific Accelerate implementation is NOT specified when+  -- calling `runAcc`.  That choice is deferred to the point where+  -- `runPar` is invoked for the scheduler in question.+  runAcc   :: (Arrays a) => Acc a -> p a+  runAcc comp = do runner <- getDefaultAccImpl+                   runAccWith runner comp++  -- | Like `runAcc` but runs the Accelerate computation asynchronously.+  spawnAcc :: (Arrays a) => Acc a -> p (iv a)+  spawnAcc comp = do runner <- getDefaultAccImpl+                     spawnAccWith runner comp++  +-- | Spawn an computation which may execute /either/ on the CPU or GPU+  -- based on runtime load.  The CPU and GPU implementations may employ+  -- completely different algorithms; this is an UNSAFE operation which+  -- will not guarantee determinism unless the user ensures that the+  -- result of both computations is always equivalent.+  -- +  --     +  -- A common application of `unsafeHybrid` is the following:+  --+  -- > unsafeHybrid Data.Array.Accelerate.IO.toVector+  --+  unsafeHybrid :: Arrays b => (b -> a) -> (p a, Acc b) -> p (iv a)+  unsafeHybrid cvrt pr = do runner <- getDefaultAccImpl +                            unsafeHybridWith runner cvrt pr+                                           +  ------------------------------------------------------------+  -- * Control over selecting the Accelerate implementation.++  -- Retrieve the Accelerate @run@ function that is the default for+  -- this execution, i.e. the one used for `runAcc` or `spawnAcc`.+  getDefaultAccImpl :: Arrays a => p (Acc a -> a)++  -- | Like `runAcc` but specify a specific Accelerate implementation, e.g. @CUDA.run@.+  runAccWith   :: (Arrays a) => (Acc a -> a) -> Acc a -> p a+  runAccWith runner comp = spawnAccWith runner comp >>= get  +  +  -- | Analogous to `runAccWith`.+  spawnAccWith :: (Arrays a) => (Acc a -> a) -> Acc a -> p (iv a)+  -- This default implementation is actually QUITE BAD.  It's an+  -- anti-pattern.  We don't want to wait until the spawned+  -- computation is executed to enqueue the GPU computation.  This is+  -- a problem with child-stealing Par implemenations, but not so much+  -- with parent-stealing ones.+  spawnAccWith runner acc = spawn_ $ runAccWith runner  acc++  -- | Analogous to other @*With@ functions.+  unsafeHybridWith :: Arrays b => (Acc b -> b) -> (b -> a) -> (p a, Acc b) -> p (iv a)+  -- This default implementation simply /always/ runs the GPU version:+  unsafeHybridWith runner cvrt (_, acc) = +    spawn_ $ do x <- runAccWith runner acc+                return (cvrt x)++  -- TODO: to be fully consistent we should perhaps have+  -- compileAccWith, but that gets complicated.++  ------------------------------------------------------------+  -- TODO: We would really like to add this, but it requires more than+  -- getDefaultAccImpl can provide right now.+#if 0+  -- | Prepare a GPU computation for repeated execution.  +  -- +  -- Typically, this is applied to its first argument once in an outer+  -- scope then applied to its second argument repeatedly inside a loop.+  -- +  -- Whereas the normal `runAcc` will /attempt/ to cache compiled+  -- programs and avoid recompilation, this function guarantees no+  -- recompilation and further avoids some overhead from re-executing+  -- the Accelerate front-end.+  -- +  -- See "Data.Array.Accelerate.CUDA.run1" for more explanation.+  compileAcc :: (Arrays a, Arrays b) => (Acc a -> Acc b) -> a -> p b+#endif++++--------------------------------------------------------------------------------++-- | An example application of `unsafeHybrid` for vectors.+unsafeHybridVector :: (Vector.Storable a, Elt a, +                       IO.BlockPtrs (EltRepr a) ~ ((), Ptr a), +                       ParAccelerate iv p)+                  => (p (Vector.Vector a), Acc (Array DIM1 a))+                  -> p (iv (Vector.Vector a))+-- /TODO/: make a variant with unrestricted 'Shape' that, e.g., yields+-- a vector in row-major order.+unsafeHybridVector = unsafeHybrid IO.toVector+++-- | An example application of `unsafeHybrid` for any IArray type.+unsafeHybridIArray :: ( EltRepr ix ~ EltRepr sh+                     , IArray a e, IArray.Ix ix+                     , Shape sh, Elt ix, Elt e +                     , ParAccelerate iv p)+                  => (p (a ix e), Acc (Array sh e))+                  ->  p (iv (a ix e))               +unsafeHybridIArray = unsafeHybrid toIArray+                     --IO.toArray 
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Simon Marlow 2011++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Simon Marlow nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,3 @@+#!/usr/bin/env runhaskell+import Distribution.Simple+main = defaultMain
+ abstract-par-accelerate.cabal view
@@ -0,0 +1,49 @@+Name:                abstract-par-accelerate+Version:             0.3.1+Synopsis:            Provides the class ParAccelerate, nothing more.++Description:         Following the convention the @abstract-par@ package,+                     this package simply defines an interface, in the form of a+		     type class, and does not contain any implementation.++                     Importing this module gives the user an API to+                     access @Accelerate@ computations from within+                     @Par@ computations, with the added benefit that+                     the @Par@ can do integrated CPU/GPU scheduling.++-- Version history:+-- +-- 0.3: Initial release.+-- 0.3.1: Tweak Accelerate dependencies.++Homepage:            https://github.com/simonmar/monad-par+License:             BSD3+License-file:        LICENSE+Author:              Adam Foltzer 2011-2012+Maintainer:          Ryan Newton <rrnewton@gmail.com>+Copyright:           (c) Adam Foltzer 2011-2012+Stability:           Experimental+Category:            Parallelism+Build-type:          Simple+Cabal-version:       >=1.8++Library+  Exposed-modules: +                 -- Provides the class ParAccelerate:+                 Control.Monad.Par.Accelerate+  ghc-options:    -Wall+  Build-depends:  +                  base >= 4 && < 5+                , abstract-par >= 0.3+                , vector >= 0.9+                , array ++  if flag(newAccelerate) {+    Build-depends: accelerate >= 0.12+                 , accelerate-io >= 0.12+  } else {+    Build-depends: accelerate >= 0.10 && < 0.12+  }++flag newAccelerate+  default:        False