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 +146/−0
- LICENSE +30/−0
- Setup.hs +3/−0
- abstract-par-accelerate.cabal +49/−0
+ 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