cufft 0.7.5.0 → 0.8.0.0
raw patch · 3 files changed
+125/−222 lines, 3 filessetup-changednew-uploader
Files
- Foreign/CUDA/FFT/Error.chs +3/−0
- Setup.hs +86/−199
- cufft.cabal +36/−23
Foreign/CUDA/FFT/Error.chs view
@@ -42,6 +42,9 @@ describe NotImplemented = "not implemented" describe LicenseError = "cufft license error" #endif+#if CUDA_VERSION >= 8000+describe NotSupported = "operation not supported for given parameters"+#endif -- Exceptions ------------------------------------------------------------------
Setup.hs view
@@ -1,6 +1,7 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE QuasiQuotes #-}-{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TemplateHaskell #-} -- The MIN_VERSION_Cabal macro was introduced with Cabal-1.24 (??) #ifndef MIN_VERSION_Cabal@@ -13,7 +14,7 @@ import Distribution.Simple.BuildPaths import Distribution.Simple.Command import Distribution.Simple.LocalBuildInfo-import Distribution.Simple.PreProcess hiding ( ppC2hs )+import Distribution.Simple.PreProcess import Distribution.Simple.Program import Distribution.Simple.Program.Db import Distribution.Simple.Program.Find@@ -30,14 +31,13 @@ import Control.Applicative import Control.Exception import Control.Monad+import Language.Haskell.TH+import Prelude import System.Directory-import System.Environment import System.FilePath-import System.IO.Error import Text.Printf-import Prelude -import Language.Haskell.TH+import Foreign.CUDA.Path -- Configuration@@ -46,13 +46,29 @@ customBuildInfoFilePath :: FilePath customBuildInfoFilePath = "cufft" <.> "buildinfo" -generatedBuldInfoFilePath :: FilePath-generatedBuldInfoFilePath = customBuildInfoFilePath <.> "generated"+generatedBuildInfoFilePath :: FilePath+generatedBuildInfoFilePath = customBuildInfoFilePath <.> "generated" -defaultCUDAInstallPath :: Platform -> FilePath-defaultCUDAInstallPath _ = "/usr/local/cuda" -- windows? +-- http://docs.nvidia.com/cuda/cufft/index.html#static-library+--+staticLibs :: Platform -> [String]+staticLibs platform@(Platform _arch os) =+ case os of+ _ -> dynamicLibs platform + -- TLM: I can't get this work at the moment. This package will build fine,+ -- but client packages (e.g. accelerate-fft) will fail with an error such as:+ --+ -- > dyld: lazy symbol binding failed: Symbol not found: ___cudaRegisterLinkedBinary_72_tmpxft_000005ef_00000000_15_fft_dimension_class_multi_compute_60_cpp1_ii_466e44ab+ --+ -- Windows -> dynamicLibs platform+ -- _ -> ["cufft_static", "cudart_static", "culibos", "pthread", "dl"]++dynamicLibs :: Platform -> [String]+dynamicLibs _ = ["cufft"]++ -- Build setup -- ----------- @@ -63,6 +79,8 @@ noExtraFlags args getHookedBuildInfo (fromFlag (get_verbosity flags)) + preprocessors = hookedPreProcessors simpleUserHooks+ -- Our readHook implementation uses our getHookedBuildInfo. We can't rely on -- cabal's autoconfUserHooks since they don't handle user overwrites to -- buildinfo like we do.@@ -78,8 +96,8 @@ , preReg = readHook regVerbosity , preUnreg = readHook regVerbosity , postConf = postConfHook- , postBuild = postBuildHook- , hookedPreProcessors = ("chs", ppC2hs) : filter (\x -> fst x /= "chs") (hookedPreProcessors simpleUserHooks)+ -- , postBuild = postBuildHook+ , hookedPreProcessors = ("chs", pp_c2hs) : filter (\x -> fst x /= "chs") preprocessors } -- The hook just loads the HookedBuildInfo generated by postConfHook, unless@@ -94,12 +112,13 @@ postConfHook :: Args -> ConfigFlags -> PackageDescription -> LocalBuildInfo -> IO () postConfHook args flags pkg_descr lbi = do let- verbosity = fromFlag (configVerbosity flags)+ verbosity = fromFlagOrDefault normal (configVerbosity flags)+ profile = fromFlagOrDefault False (configProfLib flags) currentPlatform = hostPlatform lbi compilerId_ = compilerId (compiler lbi) -- noExtraFlags args- generateAndStoreBuildInfo verbosity currentPlatform compilerId_ generatedBuldInfoFilePath+ generateAndStoreBuildInfo verbosity profile currentPlatform compilerId_ generatedBuildInfoFilePath validateLinker verbosity currentPlatform $ withPrograms lbi -- actualBuildInfoToUse <- getHookedBuildInfo verbosity@@ -137,7 +156,7 @@ -- dynamic linking works on OSX. Even though we have specified -- '-optl-Wl,-rpath,...' as part of the configuration, this (sometimes?) gets -- filtered out somewhere, and the resulting .dylib that is generated does not--- have this path embedded as an LC_RPATH. The result is that the NVVM library+-- have this path embedded as an LC_RPATH. The result is that the cuFFT library -- will not be found, resulting in a link-time error. -- -- On *nix (and versions of OSX previous to El Capitan 10.11), we could use@@ -163,6 +182,17 @@ runProgramInvocation verbosity $ simpleProgramInvocation install_name_tool ["-add_rpath", libDir, sharedLib] +-- Runs CUDA detection procedure and stores .buildinfo to a file.+--+generateAndStoreBuildInfo :: Verbosity -> Bool -> Platform -> CompilerId -> FilePath -> IO ()+generateAndStoreBuildInfo verbosity profile platform (CompilerId _ghcFlavor ghcVersion) path =+ storeHookedBuildInfo verbosity path =<< libraryBuildInfo profile platform ghcVersion++storeHookedBuildInfo :: Verbosity -> FilePath -> HookedBuildInfo -> IO ()+storeHookedBuildInfo verbosity path hbi = do+ notice verbosity $ "Storing parameters to " ++ path+ writeHookedBuildInfo path hbi+ -- Reads user-provided `cufft.buildinfo` if present, otherwise loads -- `cufft.buildinfo.generated` Outputs message informing about the other -- possibility. Calls die when neither of the files is available. (generated one@@ -176,170 +206,49 @@ notice verbosity $ printf "The user-provided buildinfo from file '%s' will be used. To use default settings, delete this file." customBuildInfoFilePath readHookedBuildInfo verbosity customBuildInfoFilePath else do- generatedBuildInfoExists <- doesFileExist generatedBuldInfoFilePath+ generatedBuildInfoExists <- doesFileExist generatedBuildInfoFilePath if generatedBuildInfoExists then do- notice verbosity $ printf "Using build information from '%s'" generatedBuldInfoFilePath+ notice verbosity $ printf "Using build information from '%s'" generatedBuildInfoFilePath notice verbosity $ printf "Provide a '%s' file to override this behaviour" customBuildInfoFilePath- readHookedBuildInfo verbosity generatedBuldInfoFilePath+ readHookedBuildInfo verbosity generatedBuildInfoFilePath else- die $ printf "Unexpected failure: neither the default '%s' nor custom '%s' exist" generatedBuldInfoFilePath customBuildInfoFilePath----- Runs CUDA detection procedure and stores .buildinfo to a file.----generateAndStoreBuildInfo :: Verbosity -> Platform -> CompilerId -> FilePath -> IO ()-generateAndStoreBuildInfo verbosity platform (CompilerId _ghcFlavor ghcVersion) path = do- installPath <- findCUDAInstallPath verbosity platform- hbi <- libraryBuildInfo installPath platform ghcVersion- storeHookedBuildInfo verbosity path hbi----- Try to locate CUDA installation by checking (in order):------ 1. CUDA_PATH environment variable--- 2. Looking for `nvcc` in `PATH`--- 3. Checking /usr/local/cuda------ In case of failure, calls die with the pretty long message from below.----findCUDAInstallPath :: Verbosity -> Platform -> IO FilePath-findCUDAInstallPath verbosity platform = do- result <- findFirstValidLocation verbosity platform (candidateCUDAInstallPaths verbosity platform)- case result of- Just installPath -> do- notice verbosity $ printf "Found CUDA toolkit at: %s" installPath- return installPath- Nothing -> die cudaNotFoundMsg----- Function iterates over action yielding possible locations, evaluating them--- and returning the first valid one. Returns Nothing if no location matches.----findFirstValidLocation :: Verbosity -> Platform -> [(IO FilePath, String)] -> IO (Maybe FilePath)-findFirstValidLocation verbosity platform = go- where- go :: [(IO FilePath, String)] -> IO (Maybe FilePath)- go [] = return Nothing- go (x:xs) = do- let (path,desc) = x- info verbosity $ printf "checking for %s" desc- found <- validateIOLocation verbosity platform path- if found- then Just `fmap` path- else go xs----- Evaluates IO to obtain the path, handling any possible exceptions.--- If path is evaluable and points to valid CUDA toolkit returns True.----validateIOLocation :: Verbosity -> Platform -> IO FilePath -> IO Bool-validateIOLocation verbosity platform iopath =- let handler :: IOError -> IO Bool- handler err = do- info verbosity (show err)- return False- in- (iopath >>= validateLocation verbosity platform) `catch` handler----- Checks whether given location looks like a valid CUDA toolkit directory by--- testing whether the 'cufft.h' file exists in the expected place.------ TODO: Ideally this should check also for 'libcufft' and whether the library--- exports relevant symbols. This should be achievable with some `nm` trickery.----validateLocation :: Verbosity -> Platform -> FilePath -> IO Bool-validateLocation verbosity platform path = do- let cufftHeader = cudaIncludePath platform path </> "cufft.h"- --- exists <- doesFileExist cufftHeader- info verbosity $- if exists- then printf "Path accepted: %s" path- else printf "Path rejected: %s\nDoes not exist: %s" path cufftHeader- return exists----- Returns pairs of (action yielding candidate path, String description of that location)----candidateCUDAInstallPaths :: Verbosity -> Platform -> [(IO FilePath, String)]-candidateCUDAInstallPaths verbosity platform =- [ (getEnv "CUDA_PATH", "environment variable CUDA_PATH")- , (findInPath, "nvcc compiler executable in PATH")- , (return defaultPath, printf "default install location (%s)" defaultPath)- ]- where- findInPath :: IO FilePath- findInPath = do- nvccPath <- findProgramLocationOrError verbosity "nvcc"- -- The obtained path is likely TOOLKIT/bin/nvcc. We want to extract the- -- TOOLKIT part- return (takeDirectory $ takeDirectory nvccPath)-- defaultPath :: FilePath- defaultPath = defaultCUDAInstallPath platform+ die $ printf "Unexpected failure: neither the default '%s' nor custom '%s' exist" generatedBuildInfoFilePath customBuildInfoFilePath --- NOTE: this function throws an exception when there is no `nvcc` in PATH.--- The exception contains a meaningful message.----findProgramLocationOrError :: Verbosity -> String -> IO FilePath-findProgramLocationOrError verbosity execName = do- location <- findProgram verbosity execName- case location of- Just path -> return path- Nothing -> ioError $ mkIOError doesNotExistErrorType ("not found: " ++ execName) Nothing Nothing- findProgram :: Verbosity -> FilePath -> IO (Maybe FilePath)-findProgram verbosity prog = do- result <- findProgramOnSearchPath verbosity defaultProgramSearchPath prog-#if MIN_VERSION_Cabal(1,25,0)- return (fmap fst result)-#else- $( case withinRange cabalVersion (orLaterVersion (Version [1,24] [])) of- True -> [| return (fmap fst result) |]- False -> [| return result |]- )-#endif+findProgram verbosity prog =+ findProgram_helper (findProgramOnSearchPath verbosity defaultProgramSearchPath prog) +class FindProgram f where+ findProgram_helper :: f -> IO (Maybe FilePath) -cudaNotFoundMsg :: String-cudaNotFoundMsg = unlines- [ "********************************************************************************"- , ""- , "The configuration process failed to locate your CUDA installation. Ensure that you have installed both the developer driver and toolkit, available from:"- , ""- , "> http://developer.nvidia.com/cuda-downloads"- , ""- , "and make sure that `nvcc` is available in your PATH, or set the CUDA_PATH environment variable appropriately. Check the above output log and run the command directly to ensure it can be located."- , ""- , "If you have a non-standard installation, you can add additional search paths using --extra-include-dirs and --extra-lib-dirs. Note that 64-bit Linux flavours often require both `lib64` and `lib` library paths, in that order."- , ""- , "********************************************************************************"- ]+instance FindProgram (IO (Maybe (FilePath, [FilePath]))) where+ findProgram_helper f = fmap fst `fmap` f +instance FindProgram (IO (Maybe FilePath)) where+ findProgram_helper f = f + -- Generates build info with flags needed for CUDA Toolkit to be properly -- visible to underlying build tools. ---libraryBuildInfo :: FilePath -> Platform -> Version -> IO HookedBuildInfo-libraryBuildInfo installPath platform@(Platform arch os) ghcVersion = do+libraryBuildInfo :: Bool -> Platform -> Version -> IO HookedBuildInfo+libraryBuildInfo profile platform@(Platform arch os) ghcVersion = do let- libraryPaths = [cudaLibraryPath platform installPath]- includePaths = [cudaIncludePath platform installPath]- -- options for GHC- extraLibDirs' = libraryPaths- ccOptions' = map ("-I"++) includePaths- ldOptions' = map ("-L"++) extraLibDirs'+ extraLibDirs' = [ cudaLibraryPath ]+ ccOptions' = [ "-I" ++ cudaIncludePath ]+ ldOptions' = [ "-L" ++ cudaLibraryPath ] ghcOptions = map ("-optc"++) ccOptions' ++ map ("-optl"++) ldOptions'- ++ if os /= Windows+ ++ if os /= Windows && not profile then map ("-optl-Wl,-rpath,"++) extraLibDirs' else []- extraLibs' = cufftLibrary platform + extraLibs' = staticLibs platform+ extraGHCiLibs' = dynamicLibs platform+ -- options for C2HS archFlag = case arch of I386 -> "-m32"@@ -356,14 +265,13 @@ -- In the CUDA package this is used to populate the extraGHCiLibs -- field with the mangled .dll names. I'm not sure what those are for -- this library, so left out for the time being.- Windows -> return bi- OSX -> return bi _ -> return bi buildInfo' <- addSystemSpecificOptions $ emptyBuildInfo { ccOptions = ccOptions' , ldOptions = ldOptions' , extraLibs = extraLibs'+ , extraGHCiLibs = extraGHCiLibs' , extraLibDirs = extraLibDirs' , options = [(GHC, ghcOptions) | os /= Windows] , customFieldsBI = [c2hsExtraOptions]@@ -372,31 +280,6 @@ return (Just buildInfo', []) --- Location of the CUFFT library relative to the base CUDA installation----cudaIncludePath :: Platform -> FilePath -> FilePath-cudaIncludePath _ base = base </> "include"--cudaLibraryPath :: Platform -> FilePath -> FilePath-cudaLibraryPath (Platform arch os) base = base </> libpath- where- libpath =- case (os, arch) of- (Windows, I386) -> "Win32"- (Windows, X86_64) -> "x64"- (OSX, _) -> "lib" -- MacOS does not distinguish 32- vs. 64-bit paths- (_, X86_64) -> "lib64" -- treat all others similarly- _ -> "lib"--cufftLibrary :: Platform -> [String]-cufftLibrary _ = ["cufft"]--storeHookedBuildInfo :: Verbosity -> FilePath -> HookedBuildInfo -> IO ()-storeHookedBuildInfo verbosity path hbi = do- notice verbosity $ "Storing parameters to " ++ path- writeHookedBuildInfo path hbi-- -- On Windows platform the binutils linker targeting x64 is bugged and cannot -- properly link with import libraries generated by MS compiler (like the CUDA ones). -- The programs would correctly compile and crash as soon as the first FFI call is made.@@ -507,18 +390,21 @@ -- Replicate the default C2HS preprocessor hook here, and inject a value for -- extra-c2hs-options, if it was present in the buildinfo file ----- Everything below copied from Distribution.Simple.PreProcess+-- This is largely copied from Distribution.Simple.PreProcess, with some hacks+-- to make it work with different versions of Cabal-the-library. ---#if MIN_VERSION_Cabal(1,25,0)-ppC2hs :: BuildInfo -> LocalBuildInfo -> ComponentLocalBuildInfo -> PreProcessor-ppC2hs bi lbi _clbi =-#else-ppC2hs :: BuildInfo -> LocalBuildInfo -> PreProcessor-ppC2hs bi lbi =-#endif- PreProcessor- { platformIndependent = False- , runPreProcessor = \(inBaseDir, inRelativeFile) (outBaseDir, outRelativeFile) verbosity ->+class PPC2HS f where+ pp_c2hs :: f++instance PPC2HS (BuildInfo -> LocalBuildInfo -> ComponentLocalBuildInfo -> PreProcessor) where+ pp_c2hs bi lbi _ = pp_c2hs bi lbi++instance PPC2HS (BuildInfo -> LocalBuildInfo -> PreProcessor) where+ pp_c2hs bi lbi =+ PreProcessor+ { platformIndependent = False+ , runPreProcessor = \(inBaseDir, inRelativeFile)+ (outBaseDir, outRelativeFile) verbosity -> rawSystemProgramConf verbosity c2hsProgram (withPrograms lbi) . filter (not . null) $ maybe [] words (lookup "x-extra-c2hs-options" (customFieldsBI bi)) ++ ["--include=" ++ outBaseDir]@@ -526,7 +412,8 @@ ++ ["--output-dir=" ++ outBaseDir, "--output=" ++ outRelativeFile, inBaseDir </> inRelativeFile]- }+ }+ getCppOptions :: BuildInfo -> LocalBuildInfo -> [String] getCppOptions bi lbi
cufft.cabal view
@@ -1,5 +1,5 @@ name: cufft-version: 0.7.5.0+version: 0.8.0.0 synopsis: Haskell bindings for the CUFFT library description: This library contains FFI bindings to the CUFFT library, which provides@@ -9,11 +9,8 @@ . <http://developer.nvidia.com/cuda-downloads> .- The configure script will look for your CUDA installation in the standard- places, and if the `nvcc` compiler is in your PATH, relative to that.- .- This release tested with versions 6.5, 7.0, and 7.5 of the CUDA toolkit.- .+ 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@@ -27,41 +24,57 @@ cabal-version: >= 1.22 tested-with: GHC >= 7.6 -Extra-tmp-files: cufft.buildinfo.generated+Extra-tmp-files:+ cufft.buildinfo.generated -Extra-source-files: cbits/wrap.h- README.md+Extra-source-files:+ cbits/wrap.h+ README.md custom-setup setup-depends: base >= 4.6 , Cabal >= 1.22+ , cuda >= 0.8 , directory >= 1.0 , filepath >= 1.0 , template-haskell library- exposed-modules: Foreign.CUDA.FFT+ hs-source-dirs: .+ include-dirs: .+ default-language: Haskell98 - other-modules: Foreign.CUDA.FFT.Error- Foreign.CUDA.FFT.Execute- Foreign.CUDA.FFT.Plan- Foreign.CUDA.FFT.Stream- Foreign.CUDA.FFT.Internal.C2HS+ exposed-modules:+ Foreign.CUDA.FFT + other-modules:+ Foreign.CUDA.FFT.Error+ Foreign.CUDA.FFT.Execute+ Foreign.CUDA.FFT.Plan+ Foreign.CUDA.FFT.Stream+ Foreign.CUDA.FFT.Internal.C2HS+ build-depends:- base == 4.*- , cuda >= 0.6.6+ base == 4.*+ , cuda >= 0.6.6 - build-tools: c2hs >= 0.21- ghc-options: -Wall -O2 -funbox-strict-fields -fwarn-tabs+ build-tools:+ c2hs >= 0.21 - include-dirs: .- default-language: Haskell98+ ghc-options:+ -Wall+ -O2+ -funbox-strict-fields+ -fwarn-tabs Source-repository head Type: git- Location: git://github.com/robeverest/cufft.git+ Location: https://github.com/robeverest/cufft --- vim: nospell+source-repository this+ type: git+ location: https://github.com/robeverest/cufft+ tag: 0.8.0.0 +-- vim: nospell