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 +12/−12
- example/Main.hs +11/−10
- example/Merged.hs +29/−12
- example/Separate.hs +47/−11
- src/Data/Array/Accelerate/CUFFT/Batched.hs +15/−12
- src/Data/Array/Accelerate/CUFFT/Private.hs +69/−38
- src/Data/Array/Accelerate/CUFFT/RealClass.hs +2/−1
- src/Data/Array/Accelerate/CUFFT/Single.hs +14/−8
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)