cufft 0.8.0.0 → 0.10.0.0
raw patch · 10 files changed
Files
- CHANGELOG.md +33/−0
- Foreign/CUDA/FFT.hs +43/−4
- Foreign/CUDA/FFT/Error.chs +25/−4
- Foreign/CUDA/FFT/Execute.chs +136/−66
- Foreign/CUDA/FFT/Internal/C2HS.hs +9/−0
- Foreign/CUDA/FFT/Plan.chs +113/−62
- Foreign/CUDA/FFT/Stream.chs +27/−11
- README.md +7/−6
- Setup.hs +23/−6
- cufft.cabal +10/−10
+ CHANGELOG.md view
@@ -0,0 +1,33 @@+# Revision history for cufft++Notable changes to the project will be documented in this file.++The format is based on [Keep a Changelog](http://keepachangelog.com/) and the+project adheres to the [Haskell Package Versioning+Policy (PVP)](https://pvp.haskell.org)+++## [0.10.0.0] - 2020-08-26+### Added+ * Support for Cabal-3+ * Support for CUDA-10.x++## [0.9.0.1] - 2018-10-02+### Fixed+ * Build fix for ghc-8.6++## [0.9.0.0] - 2018-03-12+### Changed+ * Updated API++### Fixed+ * Build fix for Cabal-2.2 (ghc-8.4)++## 0.8.0.0 - 2017-08-24+ * _No change log recorded at this point_+++[0.10.0.0]: https://github.com/tmcdonell/cufft/compare/release/v0.9.0.1...v0.10.0.0+[0.9.0.1]: https://github.com/tmcdonell/cufft/compare/release/0.9.0.0...v0.9.0.1+[0.9.0.0]: https://github.com/tmcdonell/cufft/compare/release/0.8.0.0...0.9.0.0+
Foreign/CUDA/FFT.hs view
@@ -1,15 +1,54 @@+-- |+-- Module : Foreign.CUDA.FFT+-- Copyright : [2013..2018] Robert Clifton-Everest, Trevor L. McDonell+-- License : BSD+--+-- Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-portable (GHC extensions)+--+-- The cuFFT library is an implementation of Fast Fourier Transform (FFT)+-- operations for NVIDIA GPUs.+--+-- The FFT is a divide-and-conquer algorithm for efficiently computing discrete+-- Fourier transforms of real- or complex-valued data sets. It is one of the+-- most important and widely used numerical algorithms in computational physics+-- and general signals processing. The cuFFT library provides a simple interface+-- for computing FFTs on a NVIDIA GPU.+--+-- To use operations from the cuFFT library, the user must allocate the required+-- arrays in the GPU memory space, fill them with data, call the desired+-- sequence of cuFFT library functions, then copy the results from the GPU+-- memory back to the host.+--+-- The <http://hackage.haskell.org/package/cuda cuda> package can be used for+-- writing to and retrieving data from the GPU.+--+-- [/Example/]+--+-- _TODO_+--+-- [/Additional information/]+--+-- For more information, see the NVIDIA cuFFT documentation:+--+-- <http://docs.nvidia.com/cuda/cufft/index.html>+-- module Foreign.CUDA.FFT ( + -- * Control+ module Foreign.CUDA.FFT.Plan,+ module Foreign.CUDA.FFT.Stream, module Foreign.CUDA.FFT.Error,++ -- * Operations module Foreign.CUDA.FFT.Execute,- module Foreign.CUDA.FFT.Plan,- module Foreign.CUDA.FFT.Stream ) where -import Foreign.CUDA.FFT.Error+import Foreign.CUDA.FFT.Error ( CUFFTException(..) ) import Foreign.CUDA.FFT.Execute-import Foreign.CUDA.FFT.Plan+import Foreign.CUDA.FFT.Plan hiding ( useHandle ) import Foreign.CUDA.FFT.Stream
Foreign/CUDA/FFT/Error.chs view
@@ -1,25 +1,40 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE ForeignFunctionInterface #-}+-- |+-- Module : Foreign.CUDA.FFT.Error+-- Copyright : [2013..2018] Robert Clifton-Everest, Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-portable (GHC extensions)+-- module Foreign.CUDA.FFT.Error where --- System-import Data.Typeable+-- friends+import Foreign.CUDA.FFT.Internal.C2HS++-- system import Control.Exception+import Data.Typeable+import Foreign.C.Types #include <cbits/wrap.h> {# context lib="cufft" #} --- Error codes -----------------------------------------------------------------+-- | Error codes used by cuFFT library functions --+-- <http://docs.nvidia.com/cuda/cufft/index.html#cufftresult>+-- {# enum cufftResult as Result { underscoreToCase } with prefix="CUFFT" deriving (Eq, Show) #} --- Describe each error code+-- | Describe an error code -- describe :: Result -> String describe Success = "success"@@ -70,6 +85,7 @@ -- | Return the results of a function on successful execution, otherwise throw -- an exception with an error string associated with the return code --+{-# INLINE resultIfOk #-} resultIfOk :: (Result, a) -> IO a resultIfOk (status,result) = case status of@@ -80,9 +96,14 @@ -- | Throw an exception with an error string associated with an unsuccessful -- return code, otherwise return unit. --+{-# INLINE nothingIfOk #-} nothingIfOk :: Result -> IO () nothingIfOk status = case status of Success -> return () _ -> throwIO (ExitCode status)++{-# INLINE checkStatus #-}+checkStatus :: CInt -> IO ()+checkStatus = nothingIfOk . cToEnum
Foreign/CUDA/FFT/Execute.chs view
@@ -1,102 +1,172 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE ForeignFunctionInterface #-}+-- |+-- Module : Foreign.CUDA.FFT.Execute+-- Copyright : [2013..2018] Robert Clifton-Everest, Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-portable (GHC extensions)+-- module Foreign.CUDA.FFT.Execute (- execC2C,execZ2Z,- execR2C,execD2Z,- execC2R,execZ2D,++ Mode(..),++ execC2C, execZ2Z,+ execR2C, execD2Z,+ execC2R, execZ2D,+ ) where --- Friends+-- friends import Foreign.CUDA.FFT.Error import Foreign.CUDA.FFT.Plan import Foreign.CUDA.FFT.Internal.C2HS import Foreign.CUDA.Ptr --- System+-- system import Foreign import Foreign.C+import Data.Complex #include <cbits/wrap.h> {# context lib="cufft" #} --- | Executes a single-precision complex-to-complex transform plan in the--- transform direction specified by the fourth argument+#c+typedef enum cufftMode_enum {+ CUFFT_MODE_FORWARD = CUFFT_FORWARD,+ CUFFT_MODE_INVERSE = CUFFT_INVERSE+} cufftMode;+#endc++-- | FFT transform direction ---execC2C :: Handle -> DevicePtr Float -> DevicePtr Float -> Int -> IO ()-execC2C ctx i o dir = nothingIfOk =<< cufftExecC2C ctx i o dir+{# enum cufftMode as Mode+ { underscoreToCase }+ with prefix="CUFFT_MODE" deriving (Eq, Show, Bounded) #} -{# fun unsafe cufftExecC2C- { useHandle `Handle'- , useDev `DevicePtr Float'- , useDev `DevicePtr Float'- , `Int' } -> `Result' cToEnum #}- where- useDev = useDevicePtr . castDevPtr --- | Executes a double-precision complex-to-complex transform plan in the--- transform direction specified by the fourth argument+-- | Executes a single-precision complex-to-complex transform. ---execZ2Z :: Handle -> DevicePtr Double -> DevicePtr Double -> Int -> IO ()-execZ2Z ctx i o dir = nothingIfOk =<< cufftExecZ2Z ctx i o dir+-- If the input and output device pointers are the same, an in-place transform+-- is executed.+--+-- <http://docs.nvidia.com/cuda/cufft/index.html#function-cufftexecc2c-cufftexecz2z>+--+{-# INLINEABLE execC2C #-}+execC2C+ :: Handle -- ^ plan handle, of type 'C2C'+ -> Mode -- ^ transform direction+ -> DevicePtr (Complex Float) -- ^ input data+ -> DevicePtr (Complex Float) -- ^ output data+ -> IO ()+execC2C hdl dir i o = cufftExecC2C hdl i o dir+ where+ {# fun unsafe cufftExecC2C+ { useHandle `Handle'+ , useDevicePtr' `DevicePtr (Complex Float)'+ , useDevicePtr' `DevicePtr (Complex Float)'+ , cFromEnum `Mode'+ }+ -> `()' checkStatus*- #} -{# fun unsafe cufftExecZ2Z- { useHandle `Handle'- , useDev `DevicePtr Double'- , useDev `DevicePtr Double'- , `Int' } -> `Result' cToEnum #}++-- | Executes a double-precision complex-to-complex transform.+--+-- If the input and output device pointers are the same, an in-place transform+-- is executed.+--+-- <http://docs.nvidia.com/cuda/cufft/index.html#function-cufftexecc2c-cufftexecz2z>+--+{-# INLINEABLE execZ2Z #-}+execZ2Z+ :: Handle -- ^ plan handle, of type 'Z2Z'+ -> Mode -- ^ transform direction+ -> DevicePtr (Complex Double) -- ^ input data+ -> DevicePtr (Complex Double) -- ^ output data+ -> IO ()+execZ2Z hdl dir i o = cufftExecZ2Z hdl i o dir where- useDev = useDevicePtr . castDevPtr+ {# fun unsafe cufftExecZ2Z+ { useHandle `Handle'+ , useDevicePtr' `DevicePtr (Complex Double)'+ , useDevicePtr' `DevicePtr (Complex Double)'+ , cFromEnum `Mode'+ }+ -> `()' checkStatus*- #} --- | Executes a single-precision real-to-complex (implicitly forward)--- transform plan++-- | Executes a single-precision real-to-complex, implicitly forward, transform. ---execR2C :: Handle -> DevicePtr Float -> DevicePtr Float -> IO ()-execR2C ctx i o = nothingIfOk =<< cufftExecR2C ctx i o+-- If the input and output device pointers refer to the same address, an+-- in-place transform is executed.+--+-- <http://docs.nvidia.com/cuda/cufft/index.html#function-cufftexecr2c-cufftexecd2z>+--+{-# INLINEABLE execR2C #-}+{# fun unsafe cufftExecR2C as execR2C+ { useHandle `Handle' -- ^ plan handle, of type 'R2C'+ , useDevicePtr' `DevicePtr Float' -- ^ input data+ , useDevicePtr' `DevicePtr (Complex Float)' -- ^ output data+ }+ -> `()' checkStatus*- #} -{# fun unsafe cufftExecR2C- { useHandle `Handle'- , useDev `DevicePtr Float'- , useDev `DevicePtr Float' } -> `Result' cToEnum #}- where- useDev = useDevicePtr . castDevPtr --- | Executes a double-precision real-to-complex (implicitly forward)--- transform plan+-- | Executes a double-precision real-to-complex, implicitly forward, transform. ---execD2Z :: Handle -> DevicePtr Double -> DevicePtr Double -> IO ()-execD2Z ctx i o = nothingIfOk =<< cufftExecD2Z ctx i o+-- If the input and output device pointers refer to the same address, an+-- in-place transform is executed.+--+-- <http://docs.nvidia.com/cuda/cufft/index.html#function-cufftexecr2c-cufftexecd2z>+--+{-# INLINEABLE execD2Z #-}+{# fun unsafe cufftExecD2Z as execD2Z+ { useHandle `Handle' -- ^ plan handle, of type 'D2Z'+ , useDevicePtr' `DevicePtr Double' -- ^ input data+ , useDevicePtr' `DevicePtr (Complex Double)' -- ^ output data+ }+ -> `()' checkStatus*- #} -{# fun unsafe cufftExecD2Z- { useHandle `Handle'- , useDev `DevicePtr Double'- , useDev `DevicePtr Double' } -> `Result' cToEnum #}- where- useDev = useDevicePtr . castDevPtr --- | Executes a single-precision complex-to-real (implicitly forward)--- transform plan+-- | Executes a single-precision complex-to-real, implicitly forward, transform. ---execC2R :: Handle -> DevicePtr Float -> DevicePtr Float -> IO ()-execC2R ctx i o = nothingIfOk =<< cufftExecC2R ctx i o+-- If the input and output device pointers refer to the same address, an+-- in-place transform is executed.+--+-- <http://docs.nvidia.com/cuda/cufft/index.html#function-cufftexecc2r-cufftexecz2d>+--+{-# INLINEABLE execC2R #-}+{# fun unsafe cufftExecC2R as execC2R+ { useHandle `Handle' -- ^ plan handle, of type 'C2R'+ , useDevicePtr' `DevicePtr (Complex Float)' -- ^ input data+ , useDevicePtr' `DevicePtr Float' -- ^ output data+ }+ -> `()' checkStatus*- #} -{# fun unsafe cufftExecC2R- { useHandle `Handle'- , useDev `DevicePtr Float'- , useDev `DevicePtr Float' } -> `Result' cToEnum #}- where- useDev = useDevicePtr . castDevPtr --- | Executes a double-precision complex-to-real (implicitly forward)--- transform plan+-- | Executes a double-precision complex-to-real, implicitly forward, transform. ---execZ2D :: Handle -> DevicePtr Double -> DevicePtr Double -> IO ()-execZ2D ctx i o = nothingIfOk =<< cufftExecZ2D ctx i o+-- If the input and output device pointers refer to the same address, an+-- in-place transform is executed.+--+-- <http://docs.nvidia.com/cuda/cufft/index.html#function-cufftexecc2r-cufftexecz2d>+--+{-# INLINEABLE execZ2D #-}+{# fun unsafe cufftExecZ2D as execZ2D+ { useHandle `Handle' -- ^ plan handle, of type 'Z2D'+ , useDevicePtr' `DevicePtr (Complex Double)' -- ^ input data+ , useDevicePtr' `DevicePtr Double' -- ^ output data+ }+ -> `()' checkStatus*- #} -{# fun unsafe cufftExecZ2D- { useHandle `Handle'- , useDev `DevicePtr Double'- , useDev `DevicePtr Double' } -> `Result' cToEnum #}- where- useDev = useDevicePtr . castDevPtr++-- c2hs treats pointers to complex values as 'Ptr ()' (they are structs on the+-- C side) and uses 'CFloat' instead of 'Float', etc.+--+{-# INLINE useDevicePtr' #-}+useDevicePtr' :: DevicePtr a -> Ptr b+useDevicePtr' = castPtr . useDevicePtr+
Foreign/CUDA/FFT/Internal/C2HS.hs view
@@ -1,3 +1,12 @@+-- |+-- Module : Foreign.CUDA.FFT.Internal.C2HS+-- Copyright : [2013..2018] Robert Clifton-Everest, Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-portable (GHC extensions)+-- module Foreign.CUDA.FFT.Internal.C2HS (
Foreign/CUDA/FFT/Plan.chs view
@@ -1,9 +1,17 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE ForeignFunctionInterface #-}+-- |+-- Module : Foreign.CUDA.FFT.Plan+-- Copyright : [2013..2018] Robert Clifton-Everest, Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-portable (GHC extensions)+-- module Foreign.CUDA.FFT.Plan ( - -- * Context Handle(..), Type(..), plan1D,@@ -28,10 +36,27 @@ {# context lib="cufft" #} --- | Operations handle+-- | A handle used to store and access cuFFT plans. --+-- A handle is created by the FFT planning functions (e.g. 'plan1D') and used+-- during execution of the transforms (e.g. 'Foreign.CUDA.FFT.Execute.execC2C').+--+-- The handle may be reused, but should be 'destroy'ed once it is no longer+-- required, in order to release associated GPU memory and other resources.+-- newtype Handle = Handle { useHandle :: {# type cufftHandle #}} ++-- | The cuFFT library supports complex- and real-valued transforms. This data+-- type enumerates the kind of transform a plan will execute.+--+-- Key:+--+-- * __R__: real (32-bit float)+-- * __D__: double (64-bit float)+-- * __C__: single-precision complex numbers (32-bit, interleaved)+-- * __Z__: double-precision complex numbers (64-bit, interleaved)+-- {# enum cufftType as Type {} with prefix="CUFFT" deriving (Eq, Show) #}@@ -39,89 +64,115 @@ -- Context management ---------------------------------------------------------- -- --- | Creates a 1D FFT plan configuration for a specified signal size and data type.--- The third argument tells CUFFT how many 1D transforms to configure.----plan1D :: Int -> Type -> Int -> IO Handle-plan1D nx t batch = resultIfOk =<< cufftPlan1d nx t batch+-- | -{# fun unsafe cufftPlan1d+-- | Creates a 1D FFT plan configured for a specified signal size and data type.+--+-- The third argument tells cuFFT how many 1D transforms, of size given by the+-- first argument, to configure. Consider using 'planMany' for multiple+-- transforms instead.+--+-- <http://docs.nvidia.com/cuda/cufft/index.html#function-cufftplan1d>+--+{-# INLINEABLE plan1D #-}+{# fun unsafe cufftPlan1d as plan1D { alloca- `Handle' peekHdl*- , `Int'- , cFromEnum `Type'- , `Int' } -> `Result' cToEnum #}+ , `Int' -- ^ Size of the transformation+ , cFromEnum `Type' -- ^ Transformation data type+ , `Int' -- ^ Number of one-dimensional transforms to configure+ }+ -> `()' checkStatus*- #} where peekHdl = liftM Handle . peek + -- | Creates a 2D FFT plan configuration for a specified signal size and data type. ---plan2D :: Int -> Int -> Type -> IO Handle-plan2D nx ny t = resultIfOk =<< cufftPlan2d nx ny t--{# fun unsafe cufftPlan2d+-- <http://docs.nvidia.com/cuda/cufft/index.html#function-cufftplan2d>+--+{-# INLINEABLE plan2D #-}+{# fun unsafe cufftPlan2d as plan2D { alloca- `Handle' peekHdl*- , `Int'- , `Int'- , cFromEnum `Type' } -> `Result' cToEnum #}+ , `Int' -- ^ The transform size in the /x/-dimension. This is the slowest changing dimension of a transform (strided in memory)+ , `Int' -- ^ The transform size in the /y/-dimension. This is the fastest changing dimension of a transform (contiguous in memory)+ , cFromEnum `Type' -- ^ Transformation data type+ }+ -> `()' checkStatus*- #} where peekHdl = liftM Handle . peek + -- | Creates a 3D FFT plan configuration for a specified signal size and data type. ---plan3D :: Int -> Int -> Int -> Type -> IO Handle-plan3D nx ny nz t = resultIfOk =<< cufftPlan3d nx ny nz t--{# fun unsafe cufftPlan3d+-- <http://docs.nvidia.com/cuda/cufft/index.html#function-cufftplan3d>+--+{-# INLINEABLE plan3D #-}+{# fun unsafe cufftPlan3d as plan3D { alloca- `Handle' peekHdl*- , `Int'- , `Int'- , `Int'- , cFromEnum `Type' } -> `Result' cToEnum #}+ , `Int' -- ^ The transform size in the /x/-dimension. This is the slowest changing dimension of the transform (strided in memory)+ , `Int' -- ^ The transform size in the /y/-dimension.+ , `Int' -- ^ The transform size in the /z/-dimension. This is the fastest changing dimension of the transform (contiguous in memory)+ , cFromEnum `Type' -- ^ Transformation data type+ }+ -> `()' checkStatus*- #} where peekHdl = liftM Handle . peek --- | Creates a batched plan configuration for many signals of a specified size in--- either 1, 2 or 3 dimensions, and of the specified data type.++-- | Creates a batched plan configuration for many signals of a specified size+-- and data type in either 1, 2 or 3 dimensions. ---planMany :: [Int] -- ^ The size of each dimension- -> Maybe ([Int], Int, Int) -- ^ Storage dimensions of the output data,- -- the stride, and the distance between- -- signals for the input data- -> Maybe ([Int], Int, Int) -- ^ As above but for the output data- -> Type -- ^ The type of the transformation.- -> Int -- ^ The batch size (either 1, 2 or 3)+-- This function supports more complicated input and output data layouts. If not+-- specified (that is, 'Nothing' is passed for either of the second or third+-- parameters), contiguous data arrays are assumed.+--+-- Data layout configuration consists of three fields, respectively:+--+-- * storage dimensions of the input data in memory+-- * the distance between two successive input elements in the innermost (least significant) dimension+-- * the distance between the first element of two consecutive signals in a batch of the input data+--+-- <http://docs.nvidia.com/cuda/cufft/index.html#function-cufftplanmany>+--+planMany :: [Int] -- ^ The size of the transform in each dimension, where @(n !! 0)@ is the size of the outermost dimension, and @(n !! rank-1)@ the size of the innermost (contiguous) dimension of the transform.+ -> Maybe ([Int], Int, Int) -- ^ Input data layout. If 'Nothing', the data is assumed to be contiguous.+ -> Maybe ([Int], Int, Int) -- ^ Output data layout. If 'Nothing', the data is stored contiguously.+ -> Type -- ^ Transformation type+ -> Int -- ^ Batch size for this transform -> IO Handle-planMany n ilayout olayout t batch- = do- let (inembed, istride, idist) = fromMaybe ([], 0, 0) ilayout- let (onembed, ostride, odist) = fromMaybe ([], 0, 0) olayout- resultIfOk =<< cufftPlanMany (length n) n inembed istride idist onembed ostride odist t batch--{# fun unsafe cufftPlanMany- { alloca- `Handle' peekHdl*- , `Int'- , asArray * `[Int]'- , asArray * `[Int]'- , `Int'- , `Int'- , asArray * `[Int]'- , `Int'- , `Int'- , cFromEnum `Type'- , `Int'} -> `Result' cToEnum #}+planMany n ilayout olayout t batch =+ cufftPlanMany (length n) n inembed istride idist onembed ostride odist t batch where+ (inembed, istride, idist) = fromMaybe ([], 0, 0) ilayout+ (onembed, ostride, odist) = fromMaybe ([], 0, 0) olayout+ peekHdl = liftM Handle . peek+ asArray [] f = f nullPtr asArray xs f = withArray (map fromIntegral xs) f --- | This function releases hardware resources used by the CUFFT plan. The--- release of GPU resources may be deferred until the application exits. This--- function is usually the last call with a particular handle to the CUFFT--- plan.----destroy :: Handle -> IO ()-destroy ctx = nothingIfOk =<< cufftDestroy ctx+ {# fun unsafe cufftPlanMany+ { alloca- `Handle' peekHdl*+ , `Int'+ , asArray* `[Int]'+ , asArray* `[Int]'+ , `Int'+ , `Int'+ , asArray* `[Int]'+ , `Int'+ , `Int'+ , cFromEnum `Type'+ , `Int'+ }+ -> `()' checkStatus*- #} -{# fun unsafe cufftDestroy- { useHandle `Handle' } -> `Result' cToEnum #}++-- | Release resources associated with the given plan. This function should be+-- called once a plan is no longer needed, to avoid wasting GPU memory.+--+-- <http://docs.nvidia.com/cuda/cufft/index.html#function-cufftdestroy>+--+{-# INLINEABLE destroy #-}+{# fun unsafe cufftDestroy as destroy+ { useHandle `Handle' } -> `()' checkStatus*- #}
Foreign/CUDA/FFT/Stream.chs view
@@ -1,15 +1,24 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE ForeignFunctionInterface #-}+-- |+-- Module : Foreign.CUDA.FFT.Stream+-- Copyright : [2013..2018] Robert Clifton-Everest, Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-portable (GHC extensions)+-- module Foreign.CUDA.FFT.Stream ( - -- * Streamed transforms+ Stream, setStream, ) where -- friends-import Foreign.CUDA.Types+import Foreign.CUDA.Driver.Stream ( Stream(..) ) import Foreign.CUDA.FFT.Plan import Foreign.CUDA.FFT.Error import Foreign.CUDA.FFT.Internal.C2HS@@ -21,15 +30,22 @@ #include <cbits/wrap.h> {# context lib="cufft" #} --- | Associates a CUDA stream with a CUFFT plan. All kernel launches made during--- plan execution are now done through the associated stream, enabling overlap--- with activity in other streams (e.g. data copying). The association remains--- until the plan is destroyed or the stream is changed.----setStream :: Handle -> Stream -> IO ()-setStream ctx st = nothingIfOk =<< cufftSetStream ctx st -{# fun unsafe cufftSetStream+-- | Set the execution stream which all subsequent cuFFT library functions will+-- execute with. This enables the activity in this execution stream (e.g. kernel+-- launches and data transfer) to overlap with activity in other execution+-- streams. The association remains until the plan is destroyed or the stream is+-- changed.+--+-- If not set, functions execute in the default stream, which never overlaps+-- with any other operation.+--+-- <http://docs.nvidia.com/cuda/cufft/index.html#function-cufftsetstream>+--+{-# INLINEABLE setStream #-}+{# fun unsafe cufftSetStream as setStream { useHandle `Handle'- , useStream `Stream' } -> `Result' cToEnum #}+ , useStream `Stream'+ }+ -> `()' checkStatus*- #}
README.md view
@@ -1,18 +1,19 @@ Haskell FFI Bindings to CUDA FFT ================================ -[](https://travis-ci.org/robeverest/cufft)+[](https://travis-ci.org/tmcdonell/cufft)+[](https://ci.appveyor.com/project/tmcdonell/cufft)+[](https://stackage.org/lts/package/cufft)+[](https://stackage.org/nightly/package/cufft)+[](https://hackage.haskell.org/package/cufft) -The CUFFT library provides high performance implementations of Fast Fourier+The cuFFT library provides high performance implementations of Fast Fourier Transform (FFT) operations on NVIDIA GPUs. This is a collection of bindings to allow you to call those functions from Haskell. You will need to install the CUDA driver and developer toolkit. -[http://developer.nvidia.com/cuda-downloads][cuda]+ <https://developer.nvidia.com/cuda-toolkit> The configure script will look for your CUDA installation in the standard places, and if the `nvcc` compiler is found in your `PATH`, relative to that.--[cuda]: http://developer.nvidia.com/object/cuda.html-
Setup.hs view
@@ -9,7 +9,6 @@ #endif import Distribution.PackageDescription-import Distribution.PackageDescription.Parse import Distribution.Simple import Distribution.Simple.BuildPaths import Distribution.Simple.Command@@ -27,6 +26,11 @@ import Distribution.PackageDescription.PrettyPrint import Distribution.Version #endif+#if MIN_VERSION_Cabal(2,2,0)+import Distribution.PackageDescription.Parsec+#else+import Distribution.PackageDescription.Parse+#endif import Control.Applicative import Control.Exception@@ -146,7 +150,11 @@ -- False -> [| head (componentLibraries (getComponentLocalBuildInfo lbi CLibName)) |] ) #endif- sharedLib = buildDir lbi </> mkSharedLibName cid uid+#if MIN_VERSION_Cabal(2,3,0)+ sharedLib = buildDir lbi </> mkSharedLibName platform cid uid+#else+ sharedLib = buildDir lbi </> mkSharedLibName cid uid+#endif Just extraLibDirs' = extraLibDirs . libBuildInfo <$> library pkg_descr -- updateLibraryRPATHs verbosity platform sharedLib extraLibDirs'@@ -172,7 +180,7 @@ updateLibraryRPATHs verbosity (Platform _ os) sharedLib extraLibDirs' = when (os == OSX) $ do exists <- doesFileExist sharedLib- unless exists $ die $ printf "Unexpected failure: library does not exist: %s" sharedLib+ unless exists $ die' verbosity $ printf "Unexpected failure: library does not exist: %s" sharedLib -- mint <- findProgram verbosity "install_name_tool" case mint of@@ -213,7 +221,7 @@ notice verbosity $ printf "Provide a '%s' file to override this behaviour" customBuildInfoFilePath readHookedBuildInfo verbosity generatedBuildInfoFilePath else- die $ printf "Unexpected failure: neither the default '%s' nor custom '%s' exist" generatedBuildInfoFilePath customBuildInfoFilePath+ die' verbosity $ printf "Unexpected failure: neither the default '%s' nor custom '%s' exist" generatedBuildInfoFilePath customBuildInfoFilePath findProgram :: Verbosity -> FilePath -> IO (Maybe FilePath)@@ -273,7 +281,11 @@ , extraLibs = extraLibs' , extraGHCiLibs = extraGHCiLibs' , extraLibDirs = extraLibDirs'+#if MIN_VERSION_Cabal(3,0,0)+ , options = PerCompilerFlavor (if os /= Windows then ghcOptions else []) []+#else , options = [(GHC, ghcOptions) | os /= Windows]+#endif , customFieldsBI = [c2hsExtraOptions] } @@ -301,7 +313,7 @@ Nothing -> warn verbosity $ say "Unknown ld.exe version" Just ldVersion -> do debug verbosity $ "Found ld.exe version: " ++ show ldVersion- when (ldVersion < [2,25,1]) $ die (windowsLinkerBugMsg ldPath)+ when (ldVersion < [2,25,1]) $ die' verbosity (windowsLinkerBugMsg ldPath) validateLinker _ _ _ = return () -- The linker bug is present only on Win64 platform @@ -405,7 +417,7 @@ { platformIndependent = False , runPreProcessor = \(inBaseDir, inRelativeFile) (outBaseDir, outRelativeFile) verbosity ->- rawSystemProgramConf verbosity c2hsProgram (withPrograms lbi) . filter (not . null) $+ runDbProgram verbosity c2hsProgram (withPrograms lbi) . filter (not . null) $ maybe [] words (lookup "x-extra-c2hs-options" (customFieldsBI bi)) ++ ["--include=" ++ outBaseDir] ++ ["--cppopts=" ++ opt | opt <- getCppOptions bi lbi]@@ -444,5 +456,10 @@ #if MIN_VERSION_Cabal(1,25,0) versionBranch :: Version -> [Int] versionBranch = versionNumbers+#endif++#if !MIN_VERSION_Cabal(2,0,0)+die' :: Verbosity -> String -> IO a+die' _ = die #endif
cufft.cabal view
@@ -1,10 +1,10 @@ name: cufft-version: 0.8.0.0+version: 0.10.0.0 synopsis: Haskell bindings for the CUFFT library description: This library contains FFI bindings to the CUFFT library, which provides highly optimised, FFTW compatible, Fast-Fourier Transform (FFT)- implementations for NVIDIA GPUs. The CUFFT library is part of the CUDA+ implementations for NVIDIA GPUs. The cuFFT library is part of the CUDA developer toolkit. . <http://developer.nvidia.com/cuda-downloads>@@ -12,16 +12,15 @@ See the <https://travis-ci.org/tmcdonell/cublas travis-ci.org> build matrix for tested CUDA library versions. -homepage: http://github.com/robeverest/cufft license: BSD3 license-file: LICENSE author: Robert Clifton-Everest, Trevor L. McDonell-maintainer: Robert Clifton-Everest <robertce@cse.unsw.edu.au>+maintainer: Trevor L. McDonell <trevor.mcdonell@gmail.com> homepage: https://github.com/robeverest/cufft bug-reports: https://github.com/robeverest/cufft/issues category: Foreign build-type: Custom-cabal-version: >= 1.22+cabal-version: >= 1.24 tested-with: GHC >= 7.6 Extra-tmp-files:@@ -29,12 +28,13 @@ Extra-source-files: cbits/wrap.h+ CHANGELOG.md README.md custom-setup setup-depends: base >= 4.6- , Cabal >= 1.22+ , Cabal >= 1.24 , cuda >= 0.8 , directory >= 1.0 , filepath >= 1.0@@ -47,17 +47,17 @@ exposed-modules: Foreign.CUDA.FFT-- other-modules: Foreign.CUDA.FFT.Error Foreign.CUDA.FFT.Execute Foreign.CUDA.FFT.Plan Foreign.CUDA.FFT.Stream++ other-modules: Foreign.CUDA.FFT.Internal.C2HS build-depends: base == 4.*- , cuda >= 0.6.6+ , cuda >= 0.8 build-tools: c2hs >= 0.21@@ -75,6 +75,6 @@ source-repository this type: git location: https://github.com/robeverest/cufft- tag: 0.8.0.0+ tag: v0.10.0.0 -- vim: nospell