packages feed

accelerate-cufft 0.0.1 → 1.0

raw patch · 8 files changed

+199/−104 lines, 8 filesdep +accelerate-llvm-ptxdep −accelerate-cudadep ~acceleratedep ~accelerate-fourierdep ~accelerate-utilityPVP ok

version bump matches the API change (PVP)

Dependencies added: accelerate-llvm-ptx

Dependencies removed: accelerate-cuda

Dependency ranges changed: accelerate, accelerate-fourier, accelerate-utility, base, cuda, cufft

API changes (from Hackage documentation)

+ Data.Array.Accelerate.CUFFT.Batched: getBestTarget :: IO PTX
+ Data.Array.Accelerate.CUFFT.Single: getBestTarget :: IO PTX
- Data.Array.Accelerate.CUFFT.Batched: class (RealFloat e, IsFloating e) => Real e
+ Data.Array.Accelerate.CUFFT.Batched: class (RealFloat e, RealFloat e, FromIntegral Int e) => Real e
- Data.Array.Accelerate.CUFFT.Batched: plan1D :: (Shape sh, Slice sh, Elt e, Real e) => Mode (Batch1 sh) e a b -> Batch1 sh -> IO (Handle (Batch1 sh) e a b)
+ Data.Array.Accelerate.CUFFT.Batched: plan1D :: (Shape sh, Slice sh, Elt e, Real e) => PTX -> Mode (Batch1 sh) e a b -> Batch1 sh -> IO (Handle (Batch1 sh) e a b)
- Data.Array.Accelerate.CUFFT.Batched: plan2D :: (Shape sh, Slice sh, Elt e, Real e) => Mode (Batch2 sh) e a b -> Batch2 sh -> IO (Handle (Batch2 sh) e a b)
+ Data.Array.Accelerate.CUFFT.Batched: plan2D :: (Shape sh, Slice sh, Elt e, Real e) => PTX -> Mode (Batch2 sh) e a b -> Batch2 sh -> IO (Handle (Batch2 sh) e a b)
- Data.Array.Accelerate.CUFFT.Batched: plan3D :: (Shape sh, Slice sh, Elt e, Real e) => Mode (Batch3 sh) e a b -> Batch3 sh -> IO (Handle (Batch3 sh) e a b)
+ Data.Array.Accelerate.CUFFT.Batched: plan3D :: (Shape sh, Slice sh, Elt e, Real e) => PTX -> Mode (Batch3 sh) e a b -> Batch3 sh -> IO (Handle (Batch3 sh) e a b)
- Data.Array.Accelerate.CUFFT.Batched: transform :: (Shape sh, Slice sh, Elt e, Real e) => Handle (sh :. Int) e a b -> Transform (sh :. Int) a b
+ Data.Array.Accelerate.CUFFT.Batched: transform :: (Shape sh, Slice sh, Real e) => Handle (sh :. Int) e a b -> Transform (sh :. Int) a b
- Data.Array.Accelerate.CUFFT.Single: class (RealFloat e, IsFloating e) => Real e
+ Data.Array.Accelerate.CUFFT.Single: class (RealFloat e, RealFloat e, FromIntegral Int e) => Real e
- Data.Array.Accelerate.CUFFT.Single: plan1D :: (Elt e, Real e) => Mode DIM1 e a b -> DIM1 -> IO (Handle DIM1 e a b)
+ Data.Array.Accelerate.CUFFT.Single: plan1D :: (Elt e, Real e) => PTX -> Mode DIM1 e a b -> DIM1 -> IO (Handle DIM1 e a b)
- Data.Array.Accelerate.CUFFT.Single: plan2D :: (Elt e, Real e) => Mode DIM2 e a b -> DIM2 -> IO (Handle DIM2 e a b)
+ Data.Array.Accelerate.CUFFT.Single: plan2D :: (Elt e, Real e) => PTX -> Mode DIM2 e a b -> DIM2 -> IO (Handle DIM2 e a b)
- Data.Array.Accelerate.CUFFT.Single: plan3D :: (Elt e, Real e) => Mode DIM3 e a b -> DIM3 -> IO (Handle DIM3 e a b)
+ Data.Array.Accelerate.CUFFT.Single: plan3D :: (Elt e, Real e) => PTX -> Mode DIM3 e a b -> DIM3 -> IO (Handle DIM3 e a b)
- Data.Array.Accelerate.CUFFT.Single: transform :: (Shape sh, Slice sh, Elt e, Real e) => Handle (sh :. Int) e a b -> Transform (sh :. Int) a b
+ Data.Array.Accelerate.CUFFT.Single: transform :: (Shape sh, Slice sh, Real e) => Handle (sh :. Int) e a b -> Transform (sh :. Int) a b

Files

accelerate-cufft.cabal view
@@ -1,5 +1,5 @@ Name:             accelerate-cufft-Version:          0.0.1+Version:          1.0 License:          BSD3 License-File:     LICENSE Author:           Henning Thielemann <haskell@henning-thielemann.de>@@ -20,7 +20,7 @@   default:     False  Source-Repository this-  Tag:         0.0.1+  Tag:         1.0   Type:        darcs   Location:    http://hub.darcs.net/thielema/accelerate-cufft/ @@ -30,13 +30,13 @@  Library   Build-Depends:-    cufft >=0.1.1 && <0.8,-    cuda >= 0.5 && <0.8,-    accelerate-fourier >=0.0 && <0.1,-    accelerate-utility >=0.1 && <0.2,-    accelerate-cuda >=0.16 && <0.17,-    accelerate >=0.15 && <0.16,-    base >=4.5 && <4.10+    cufft >=0.1.1 && <0.9,+    cuda >= 0.5 && <0.10,+    accelerate-fourier >=1.0 && <1.1,+    accelerate-utility >=1.0 && <1.1,+    accelerate-llvm-ptx >=1.1 && <1.2,+    accelerate >=1.1 && <1.2,+    base >=4.5 && <4.11    GHC-Options:      -Wall -fwarn-missing-import-lists   Hs-Source-Dirs:   src@@ -56,7 +56,7 @@   If flag(buildExamples)     Build-Depends:       accelerate-cufft,-      accelerate-cuda,+      accelerate-llvm-ptx,       accelerate,       base   Else@@ -69,7 +69,7 @@   Default-Language: Haskell98   If flag(buildExamples)     Build-Depends:-      accelerate-cuda,+      accelerate-llvm-ptx,       accelerate,       cufft,       cuda,@@ -84,7 +84,7 @@   Default-Language: Haskell98   If flag(buildExamples)     Build-Depends:-      accelerate-cuda,+      accelerate-llvm-ptx,       accelerate,       cufft,       cuda,
example/Main.hs view
@@ -2,23 +2,23 @@  import qualified Data.Array.Accelerate.CUFFT.Batched as Batched import qualified Data.Array.Accelerate.CUFFT.Single as Single-import qualified Data.Array.Accelerate.CUDA.Foreign as AF-import qualified Data.Array.Accelerate.CUDA as CUDA+import qualified Data.Array.Accelerate.LLVM.PTX as CUDA import qualified Data.Array.Accelerate as A import Data.Array.Accelerate (Z(Z), (:.)((:.)))   mainSingle :: IO () mainSingle = do+   target <- Batched.getBestTarget    let dim = Z:.7-   hf <- AF.inDefaultContext $ Single.plan1D Single.forwardReal dim+   hf <- Single.plan1D target Single.forwardReal dim    let spec =-          CUDA.run1 (Single.transform hf) $+          CUDA.run1With target (Single.transform hf) $           A.fromList dim $ 0 : 1 : repeat (0 :: Float)    print spec -   hb <- AF.inDefaultContext $ Single.plan1D Single.inverseReal dim-   print $ CUDA.run1 (Single.transform hb) spec+   hb <- Single.plan1D target Single.inverseReal dim+   print $ CUDA.run1With target (Single.transform hb) spec   mainBatched :: IO ()@@ -28,16 +28,17 @@        dim :: A.DIM2        dim = Z:.count:.width -   hf <- AF.inDefaultContext $ Batched.plan1D Batched.forwardReal dim+   target <- Batched.getBestTarget+   hf <- Batched.plan1D target Batched.forwardReal dim    let spec =-          CUDA.run1 (Batched.transform hf) $+          CUDA.run1With target (Batched.transform hf) $           A.fromList dim $ concat $           take count $ map (take width) $           iterate (0:) $ 1 : repeat (0 :: Float)    print spec -   hb <- AF.inDefaultContext $ Batched.plan1D Batched.inverseReal dim-   print $ CUDA.run1 (Batched.transform hb) spec+   hb <- Batched.plan1D target Batched.inverseReal dim+   print $ CUDA.run1With target (Batched.transform hb) spec   main :: IO ()
example/Merged.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE TypeFamilies #-} {- | Simple manual implementation of embedding cufft functionality in the @accelerate@ framework.@@ -6,34 +7,50 @@ -} module Main where -import qualified Data.Array.Accelerate.CUDA.Foreign as AF-import qualified Data.Array.Accelerate.CUDA as CUDA+import qualified Data.Array.Accelerate.LLVM.PTX.Foreign as AF+import qualified Data.Array.Accelerate.LLVM.PTX as PTX+import qualified Data.Array.Accelerate.Array.Sugar as Sugar  import qualified Foreign.CUDA.FFT as CUFFT+import qualified Foreign.CUDA.Driver as CUDA+import Foreign.Storable (Storable)+import Foreign.Ptr (Ptr)  import qualified Data.Array.Accelerate as A import Data.Array.Accelerate (Acc, Vector, Z(Z), (:.)((:.)), )  -transformForeign :: Vector Float -> AF.CIO (Vector Float)-transformForeign input =+transformForeign :: AF.Stream -> Vector Float -> AF.LLVM AF.PTX (Vector Float)+transformForeign stream input =    let (Z:.inlen) = A.arrayShape input        outlen = (div inlen 2 + 1) * 2    in  do-       output <- AF.allocateArray (Z:.outlen)-       ((), iptr) <- AF.devicePtrsOfArray input-       ((), optr) <- AF.devicePtrsOfArray output-       AF.liftIO $ do-          h <- CUFFT.plan1D inlen CUFFT.R2C 1-          CUFFT.execR2C h iptr optr+       output <- AF.allocateRemote (Z:.outlen)+       withArray input stream $ \iptr ->+          withArray output stream $ \optr -> AF.liftIO $ do+             h <- CUFFT.plan1D inlen CUFFT.R2C 1+             CUFFT.execR2C h iptr optr        return output +withArray ::+   (Sugar.EltRepr e ~ er, AF.ArrayPtrs er ~ Ptr er, Storable er) =>+   A.Array sh e ->+   AF.Stream ->+   (CUDA.DevicePtr er -> AF.LLVM AF.PTX r) ->+   AF.LLVM AF.PTX r+withArray (Sugar.Array _ adata) s k =+   AF.withDevicePtr adata $ \p -> do+      r <- k p+      e <- AF.checkpoint s+      return (Just e, r)++ transform :: Acc (Vector Float) -> Acc (Vector Float) transform =    A.foreignAcc-      (AF.CUDAForeignAcc "transformForeign" $ const transformForeign)+      (AF.ForeignAcc "transformForeign" transformForeign)       (error "no fft fallback implemented")  main :: IO () main =-   print $ CUDA.run1 transform $ A.fromList (Z:.5) [1,0,0,0,0]+   print $ PTX.run1 transform $ A.fromList (Z:.5) [1,0,0,0,0]
example/Separate.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE TypeFamilies #-} {- | Simple manual implementation of embedding cufft functionality in the @accelerate@ framework.@@ -6,34 +7,69 @@ -} module Main where -import qualified Data.Array.Accelerate.CUDA.Foreign as AF-import qualified Data.Array.Accelerate.CUDA as CUDA+import qualified Data.Array.Accelerate.LLVM.PTX.Foreign as AF+import qualified Data.Array.Accelerate.LLVM.PTX as PTX+import qualified Data.Array.Accelerate.Array.Sugar as Sugar  import qualified Foreign.CUDA.FFT as CUFFT+import qualified Foreign.CUDA.Driver as CUDA+import Foreign.Storable (Storable)+import Foreign.Ptr (Ptr)  import qualified Data.Array.Accelerate as A+import Data.Array.Accelerate.Lifetime (withLifetime) import Data.Array.Accelerate (Acc, Vector, Z(Z), (:.)((:.)), ) +import Control.Exception (bracket_) -transformForeign :: CUFFT.Handle -> Vector Float -> AF.CIO (Vector Float)-transformForeign h input =++transformForeign ::+   CUFFT.Handle -> AF.Stream -> Vector Float -> AF.LLVM AF.PTX (Vector Float)+transformForeign h stream input =    let (Z:.inlen) = A.arrayShape input        outlen = (div inlen 2 + 1) * 2    in  do-       output <- AF.allocateArray (Z:.outlen)-       ((), iptr) <- AF.devicePtrsOfArray input-       ((), optr) <- AF.devicePtrsOfArray output-       AF.liftIO $ CUFFT.execR2C h iptr optr+       output <- AF.allocateRemote (Z:.outlen)+       withArray input stream $ \iptr ->+          withArray output stream $ \optr ->+             AF.liftIO $ CUFFT.execR2C h iptr optr        return output +withArray ::+   (Sugar.EltRepr e ~ er, AF.ArrayPtrs er ~ Ptr er, Storable er) =>+   A.Array sh e ->+   AF.Stream ->+   (CUDA.DevicePtr er -> AF.LLVM AF.PTX r) ->+   AF.LLVM AF.PTX r+withArray (Sugar.Array _ adata) s k =+   AF.withDevicePtr adata $ \p -> do+      r <- k p+      e <- AF.checkpoint s+      return (Just e, r)++ transform :: CUFFT.Handle -> Acc (Vector Float) -> Acc (Vector Float) transform h =    A.foreignAcc-      (AF.CUDAForeignAcc "transformForeign" $ const $ transformForeign h)+      (AF.ForeignAcc "transformForeign" $ transformForeign h)       (error "no fft fallback implemented") ++getBestTarget :: IO PTX.PTX+getBestTarget = do+   CUDA.initialise []+   dev <- CUDA.device 0+   prop <- CUDA.props dev+   PTX.createTargetForDevice dev prop [CUDA.SchedAuto]++atTarget :: PTX.PTX -> IO a -> IO a+atTarget target act =+   withLifetime (AF.deviceContext $ AF.ptxContext target) $ \ctx ->+      bracket_ (CUDA.push ctx) CUDA.pop act+ main :: IO () main = do    let inlen = 5-   h <- AF.inDefaultContext $ CUFFT.plan1D inlen CUFFT.R2C 1-   print $ CUDA.run1 (transform h) $ A.fromList (Z:.inlen) [1,0,0,0,0]+   target <- getBestTarget+   h <- atTarget target $ CUFFT.plan1D inlen CUFFT.R2C 1+   print $ PTX.run1With target (transform h) $ A.fromList (Z:.inlen) [1,0,0,0,0]
src/Data/Array/Accelerate/CUFFT/Batched.hs view
@@ -17,14 +17,17 @@    Priv.forwardComplex, Priv.inverseComplex,    Priv.forwardReal, Priv.inverseReal,    Batch0, Batch1, Batch2, Batch3,++   Priv.getBestTarget,    ) where  import qualified Data.Array.Accelerate.CUFFT.Private as Priv import Data.Array.Accelerate.CUFFT.Private           (Batch0, Batch1, Batch2, Batch3,-           Mode, wrapFallback, Handle, makeHandle, )+           Mode, wrapFallback, Handle, makeHandle, atTarget)  import qualified Data.Array.Accelerate.CUFFT.RealClass as RC+import Data.Array.Accelerate.LLVM.PTX (PTX)  import qualified Data.Array.Accelerate.Fourier.Planned as Fourier @@ -35,24 +38,24 @@   {- |-The plan must be created in the 'Data.Array.Accelerate.CUDA.Context'+The plan must be created in the 'Data.Array.Accelerate.LLVM.PTX.PTX' target where 'Priv.transform' is executed.-E.g. if you run 'Priv.transform' in 'Data.Array.Accelerate.CUDA.run1',-then you must call 'plan1D'-within 'Data.Array.Accelerate.CUDA.Foreign.inDefaultContext'.+That is, if using cuFFT you always have to use a @run*With@ function. -} plan1D ::    (Shape sh, Slice sh, Elt e, RC.Real e) =>-   Mode (Batch1 sh) e a b -> Batch1 sh -> IO (Handle (Batch1 sh) e a b)-plan1D mode (batch:.width) =+   PTX -> Mode (Batch1 sh) e a b -> Batch1 sh -> IO (Handle (Batch1 sh) e a b)+plan1D target mode (batch:.width) =+   atTarget target $    makeHandle mode width       (\sign -> wrapFallback mode $ Fourier.transform sign width)       (\typ -> CUFFT.planMany [width] Nothing Nothing typ (A.arraySize batch))  plan2D ::    (Shape sh, Slice sh, Elt e, RC.Real e) =>-   Mode (Batch2 sh) e a b -> Batch2 sh -> IO (Handle (Batch2 sh) e a b)-plan2D mode sh@(batch:.height:.width) =+   PTX -> Mode (Batch2 sh) e a b -> Batch2 sh -> IO (Handle (Batch2 sh) e a b)+plan2D target mode sh@(batch:.height:.width) =+   atTarget target $    makeHandle mode width       (wrapFallback mode . Priv.transform2D sh)       (\typ ->@@ -60,9 +63,9 @@  plan3D ::    (Shape sh, Slice sh, Elt e, RC.Real e) =>-   Mode (Batch3 sh) e a b ->-   Batch3 sh -> IO (Handle (Batch3 sh) e a b)-plan3D mode sh@(batch:.depth:.height:.width) =+   PTX -> Mode (Batch3 sh) e a b -> Batch3 sh -> IO (Handle (Batch3 sh) e a b)+plan3D target mode sh@(batch:.depth:.height:.width) =+   atTarget target $    makeHandle mode width       (wrapFallback mode . Priv.transform3D sh)       (\typ ->
src/Data/Array/Accelerate/CUFFT/Private.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-}+{-# LANGUAGE FlexibleContexts #-} {- | Accelerate interface to the native CUDA implementation of the Fourier Transform provided by the CUFFT library.@@ -15,20 +16,24 @@ import qualified Data.Array.Accelerate.Utility.Sliced as Sliced import Data.Array.Accelerate.Utility.Lift.Exp (expr) -import qualified Data.Array.Accelerate.CUDA.Foreign as AF+import qualified Data.Array.Accelerate.LLVM.PTX.Foreign as AF+import qualified Data.Array.Accelerate.LLVM.PTX as PTX+import qualified Data.Array.Accelerate.Array.Sugar as Sugar import qualified Data.Array.Accelerate as A import Data.Array.Accelerate.Data.Complex (Complex((:+)), real, imag, conjugate)+import Data.Array.Accelerate.Lifetime (withLifetime) import Data.Array.Accelerate-          (Acc, Array, Elt, Shape, Slice, (:.)((:.)),-           Exp, (!), (?), (==*), (<*),)+         (Acc, Array, Elt, Shape, Slice, (:.)((:.)), Exp, (!), (?))  import qualified Foreign.CUDA.FFT as CUFFT import qualified Foreign.CUDA.Driver as CUDA-import Foreign.CUDA.Ptr (DevicePtr, )+import Foreign.CUDA.Ptr (DevicePtr)  import qualified System.Mem.Weak as Weak +import Control.Exception (bracket_) + type Transform sh a b = Acc (Array sh a) -> Acc (Array sh b)  @@ -55,13 +60,29 @@    return $ Handle (fallback $ fsign mode) mode width plan  ++getBestTarget :: IO AF.PTX+getBestTarget = do+   CUDA.initialise []+   -- (dev,prop) <- PTX.selectBestDevice+   dev <- CUDA.device 0+   prop <- CUDA.props dev+   PTX.createTargetForDevice dev prop [CUDA.SchedAuto]++atTarget :: AF.PTX -> IO a -> IO a+atTarget target act =+   withLifetime (AF.deviceContext $ AF.ptxContext target) $ \ctx ->+      bracket_ (CUDA.push ctx) CUDA.pop act+++ type Batch0 sh = sh type Batch1 sh = Batch0 sh :. Int type Batch2 sh = Batch1 sh :. Int type Batch3 sh = Batch2 sh :. Int  transform2D ::-   (Shape sh, Slice sh, Elt a, RC.Real a) =>+   (Shape sh, Slice sh, RC.Real a) =>    Batch2 sh -> Fourier.Sign a ->    Fourier.Transform (Batch2 sh) (Complex a) transform2D (_shape:.height:.width) sign =@@ -72,7 +93,7 @@   transform3D ::-   (Shape sh, Slice sh, Elt a, RC.Real a) =>+   (Shape sh, Slice sh, RC.Real a) =>    Batch3 sh -> Fourier.Sign a ->    Fourier.Transform (Batch3 sh) (Complex a) transform3D (_shape:.depth:.height:.width) sign =@@ -88,7 +109,7 @@ The result is un-normalised. -} transform ::-   (Shape sh, Slice sh, Elt e, RC.Real e) =>+   (Shape sh, Slice sh, RC.Real e) =>    Handle (sh:.Int) e a b ->    Transform (sh:.Int) a b transform hndl@(Handle fallback mode width _) =@@ -103,7 +124,7 @@    -}    wrap mode (A.constant width) $    A.foreignAcc-      (AF.CUDAForeignAcc "transformForeign" $ const $ transformForeign hndl)+      (AF.ForeignAcc "transformForeign" $ transformForeign hndl)       (unwrap mode (A.constant width) fallback)  @@ -150,7 +171,11 @@    Mode {       types :: CUFFT.Type,       plainTypes :: Types,-      execute :: CUFFT.Handle -> CUDA.DevicePtr e -> CUDA.DevicePtr e -> IO (),+      execute ::+         CUFFT.Handle ->+         CUDA.DevicePtr (Sugar.EltRepr e) ->+         CUDA.DevicePtr (Sugar.EltRepr e) ->+         IO (),       wrap :: Exp Int -> Fourier.Transform (sh:.Int) e -> Transform sh a b,       unwrap :: Exp Int -> Transform sh a b -> Fourier.Transform (sh:.Int) e,       wrapFallback :: Fourier.Transform sh (Complex e) -> Transform sh a b,@@ -175,8 +200,8 @@   modeC2C ::-   (Shape sh, Slice sh, RC.Real e, Elt e) =>-   CUFFT.Type -> ExecuteSign e -> Sign e -> ModeC2C sh e+   (Shape sh, Slice sh, RC.Real e) =>+   CUFFT.Type -> ExecuteSign (Sugar.EltRepr e) -> Sign e -> ModeC2C sh e modeC2C typ exec (isign,fsign0) =    ModeC2C $    Mode {@@ -203,8 +228,8 @@ and also for odd data set sizes. -} modeR2C ::-   (Shape sh, Slice sh, RC.Real e, Elt e) =>-   CUFFT.Type -> Execute e -> ModeR2C (sh:.Int) e+   (Shape sh, Slice sh, RC.Real e) =>+   CUFFT.Type -> Execute (Sugar.EltRepr e) -> ModeR2C (sh:.Int) e modeR2C typ exec =    ModeR2C $    Mode {@@ -218,8 +243,8 @@    }  modeC2R ::-   (Shape sh, Slice sh, RC.Real e, Elt e) =>-   CUFFT.Type -> Execute e -> ModeC2R (sh:.Int) e+   (Shape sh, Slice sh, RC.Real e) =>+   CUFFT.Type -> Execute (Sugar.EltRepr e) -> ModeC2R (sh:.Int) e modeC2R typ exec =    ModeC2R $    Mode {@@ -234,38 +259,44 @@   transformForeign ::-   (Shape sh, Elt e, RC.Real e) =>-   Handle (sh:.Int) e a b ->-   Array (sh:.Int:.Int) e -> AF.CIO (Array (sh:.Int:.Int) e)-transformForeign (Handle _ mode width hndl) input = do+   (Shape sh, RC.Real e) =>+   Handle (sh:.Int) e a b -> AF.Stream ->+   Array (sh:.Int:.Int) e -> AF.LLVM AF.PTX (Array (sh:.Int:.Int) e)+transformForeign (Handle _ mode width hndl) stream input = do    let (shape :. _width :. _tupleSize) = A.arrayShape input        outputSh =           case plainTypes mode of-             R2C -> shape :. div width 2 + 1 :. 2+             R2C -> shape :. div width 2 + 1 :. (2::Int)              C2R -> shape :. width :. 1              C2C -> shape :. width :. 2-   output <- AF.allocateArray outputSh-   iptr   <- getDevicePtr input-   optr   <- getDevicePtr output-   AF.liftIO $ execute mode hndl iptr optr-   return output+   output <- AF.allocateRemote outputSh+   withDevicePtr input $ \iptr ->+      withDevicePtr output $ \optr -> do+         AF.liftIO $ execute mode hndl iptr optr+         ev <- AF.checkpoint stream+         return (Just ev, (Just ev, output))   newtype-   GetDevicePtr sh e =-      GetDevicePtr {-         runGetDevicePtr :: Array sh e -> AF.CIO ((), CUDA.DevicePtr e)+   WithDevicePtr target r sh e =+      WithDevicePtr {+         runWithDevicePtr ::+            Array sh e ->+            (CUDA.DevicePtr (Sugar.EltRepr e) ->+             AF.LLVM target (Maybe AF.Event, r)) ->+            AF.LLVM target r       } -getDevicePtr ::+withDevicePtr ::    (RC.Real e) =>-   Array sh e -> AF.CIO (CUDA.DevicePtr e)-getDevicePtr =-   fmap snd .-   runGetDevicePtr+   Array sh e ->+   (CUDA.DevicePtr (Sugar.EltRepr e) -> AF.LLVM AF.PTX (Maybe AF.Event, r)) ->+   AF.LLVM AF.PTX r+withDevicePtr =+   runWithDevicePtr       (RC.switch-         (GetDevicePtr AF.devicePtrsOfArray)-         (GetDevicePtr AF.devicePtrsOfArray))+         (WithDevicePtr $ \(Sugar.Array _ dat) -> AF.withDevicePtr dat)+         (WithDevicePtr $ \(Sugar.Array _ dat) -> AF.withDevicePtr dat))   {-@@ -293,7 +324,7 @@       (A.lift $ A.shape arr :. (2::Int))       (\ix ->          let x = arr ! A.indexTail ix-         in  A.indexHead ix ==* 0 ? (real x, imag x))+         in  A.indexHead ix A.== 0 ? (real x, imag x))  {-# NOINLINE[1] deinterleave #-} deinterleave ::@@ -324,12 +355,12 @@ takeHalf width = Sliced.take (div width 2 + 1)  mirror ::-   (Shape sh, Slice sh, Elt a, A.IsNum a) =>+   (Shape sh, Slice sh, A.Num a) =>    Exp Int -> Fourier.Transform (sh:.Int) (Complex a) mirror newWidth arr =    let (sh:.width) = Exp.unlift (expr:.expr) $ A.shape arr    in  A.generate (A.lift $ sh :. newWidth) $        Exp.modify (expr:.expr) $ \(ix:.k) ->-          k <* width ?+          k A.< width ?              (arr ! Exp.indexCons ix k,               conjugate (arr ! Exp.indexCons ix (newWidth - k)))
src/Data/Array/Accelerate/CUFFT/RealClass.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE FlexibleContexts #-} module Data.Array.Accelerate.CUFFT.RealClass where  import qualified Data.Array.Accelerate as A@@ -6,7 +7,7 @@ import Prelude (Float, Double)  -class (P.RealFloat e, A.IsFloating e) => Real e where+class (P.RealFloat e, A.RealFloat e, A.FromIntegral P.Int e) => Real e where    switch :: f Float -> f Double -> f e  instance Real Float  where switch f _ = f
src/Data/Array/Accelerate/CUFFT/Single.hs view
@@ -16,44 +16,50 @@    Mode,    Priv.forwardComplex, Priv.inverseComplex,    Priv.forwardReal, Priv.inverseReal,++   Priv.getBestTarget,    ) where  import qualified Data.Array.Accelerate.CUFFT.RealClass as RC import qualified Data.Array.Accelerate.CUFFT.Private as Priv import Data.Array.Accelerate.CUFFT.Private-          (Mode, wrapFallback, Handle, makeHandle, )+          (Mode, wrapFallback, Handle, makeHandle, atTarget)  import qualified Data.Array.Accelerate.Fourier.Planned as Fourier +import Data.Array.Accelerate.LLVM.PTX (PTX) import Data.Array.Accelerate (Elt, DIM1, DIM2, DIM3, Z(Z), (:.)((:.)), )  import qualified Foreign.CUDA.FFT as CUFFT   {- |-The plan must be created in the context where the transform is executed.+The plan must be created for the target where the transform is executed. See 'Data.Array.Accelerate.CUFFT.Batched.plan1D' for details. -} plan1D ::    (Elt e, RC.Real e) =>-   Mode DIM1 e a b -> DIM1 -> IO (Handle DIM1 e a b)-plan1D mode (Z:.width) =+   PTX -> Mode DIM1 e a b -> DIM1 -> IO (Handle DIM1 e a b)+plan1D target mode (Z:.width) =+   atTarget target $    makeHandle mode width       (\sign -> wrapFallback mode $ Fourier.transform sign width)       (\typ -> CUFFT.plan1D width typ 1)  plan2D ::    (Elt e, RC.Real e) =>-   Mode DIM2 e a b -> DIM2 -> IO (Handle DIM2 e a b)-plan2D mode sh@(Z:.height:.width) =+   PTX -> Mode DIM2 e a b -> DIM2 -> IO (Handle DIM2 e a b)+plan2D target mode sh@(Z:.height:.width) =+   atTarget target $    makeHandle mode width       (wrapFallback mode . Priv.transform2D sh)       (CUFFT.plan2D height width)  plan3D ::    (Elt e, RC.Real e) =>-   Mode DIM3 e a b -> DIM3 -> IO (Handle DIM3 e a b)-plan3D mode sh@(Z:.depth:.height:.width) =+   PTX -> Mode DIM3 e a b -> DIM3 -> IO (Handle DIM3 e a b)+plan3D target mode sh@(Z:.depth:.height:.width) =+   atTarget target $    makeHandle mode width       (wrapFallback mode . Priv.transform3D sh)       (CUFFT.plan3D depth height width)