cufft 0.1.0.3 → 0.1.1.0
raw patch · 9 files changed
+420/−25 lines, 9 filesbuild-type:Customsetup-changed
Files
- Foreign/CUDA/FFT/Error.chs +6/−0
- Foreign/CUDA/FFT/Internal/C2HS.hs +1/−1
- Foreign/CUDA/FFT/Plan.chs +36/−0
- Setup.hs +160/−1
- cbits/wrap.h +1/−0
- configure +137/−10
- configure.ac +72/−9
- cufft.buildinfo.in +5/−2
- cufft.cabal +2/−2
Foreign/CUDA/FFT/Error.chs view
@@ -32,6 +32,12 @@ describe SetupFailed = "the CUFFT library failed to initialize" describe InvalidSize = "invalid transform size" describe UnalignedData = "no longer used"+#if CUDA_VERSION >= 6000+describe IncompleteParameterList = "missing parameters in call"+describe InvalidDevice = "execution of a plan was on different GPU than plan creation"+describe ParseError = "internal plan database error"+describe NoWorkspace = "no workspace has been provided prior to plan execution"+#endif -- Exceptions ------------------------------------------------------------------
Foreign/CUDA/FFT/Internal/C2HS.hs view
@@ -21,7 +21,7 @@ -- | Floating conversion ---{-# INLINE cFloatConv #-}+{-# INLINE[1] cFloatConv #-} cFloatConv :: (RealFloat a, RealFloat b) => a -> b cFloatConv = realToFrac -- As this conversion by default goes via `Rational', it can be very slow...
Foreign/CUDA/FFT/Plan.chs view
@@ -9,6 +9,7 @@ plan1D, plan2D, plan3D,+ planMany, destroy, ) where@@ -21,6 +22,7 @@ import Foreign import Foreign.C import Control.Monad ( liftM )+import Data.Maybe #include <cbits/wrap.h> {# context lib="cufft" #}@@ -77,6 +79,40 @@ , cFromEnum `Type' } -> `Result' cToEnum #} 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.+--+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)+ -> 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 #}+ where+ 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
Setup.hs view
@@ -1,2 +1,161 @@+import Distribution.PackageDescription+import Distribution.PackageDescription.Parse+import Distribution.Verbosity+import Distribution.System import Distribution.Simple-main = defaultMain+import Distribution.Simple.Utils+import Distribution.Simple.Setup+import Distribution.Simple.Command+import Distribution.Simple.Program+import Distribution.Simple.LocalBuildInfo+import Distribution.Simple.PreProcess hiding (ppC2hs)++import Control.Exception+import Control.Monad+import System.Exit+import System.FilePath+import System.Directory+import System.Environment+import System.IO.Error hiding (catch)+import Prelude hiding (catch)+++-- Replicate the invocation of the postConf script, so that we can insert the+-- arguments of --extra-include-dirs and --extra-lib-dirs as paths in CPPFLAGS+-- and LDFLAGS into the environment+--+main :: IO ()+main = defaultMainWithHooks customHooks+ where+ preprocessors = hookedPreProcessors autoconfUserHooks+ customHooks = autoconfUserHooks {+ preConf = preConfHook,+ postConf = postConfHook,+ hookedPreProcessors = ("chs",ppC2hs) : filter (\x -> fst x /= "chs") preprocessors+ }++ preConfHook :: Args -> ConfigFlags -> IO HookedBuildInfo+ preConfHook args flags = do+ let verbosity = fromFlag (configVerbosity flags)++ confExists <- doesFileExist "configure"+ unless confExists $ do+ code <- rawSystemExitCode verbosity "autoconf" []+ case code of+ ExitSuccess -> return ()+ ExitFailure c -> die $ "autoconf exited with code " ++ show c++ preConf autoconfUserHooks args flags++ postConfHook :: Args -> ConfigFlags -> PackageDescription -> LocalBuildInfo -> IO ()+ postConfHook args flags pkg_descr lbi+ = let verbosity = fromFlag (configVerbosity flags)+ in do+ noExtraFlags args+ confExists <- doesFileExist "configure"+ if confExists+ then runConfigureScript verbosity False flags lbi+ else die "configure script not found."++ pbi <- getHookedBuildInfo verbosity+ let pkg_descr' = updatePackageDescription pbi pkg_descr+ postConf simpleUserHooks args flags pkg_descr' lbi+++runConfigureScript :: Verbosity -> Bool -> ConfigFlags -> LocalBuildInfo -> IO ()+runConfigureScript verbosity backwardsCompatHack flags lbi = do+ env <- getEnvironment+ (ccProg, ccFlags) <- configureCCompiler verbosity (withPrograms lbi)++ let env' = foldr appendToEnvironment env+ [("CC", ccProg)+ ,("CFLAGS", unwords ccFlags)+ ,("CPPFLAGS", unwords $ map ("-I"++) (configExtraIncludeDirs flags))+ ,("LDFLAGS", unwords $ map ("-L"++) (configExtraLibDirs flags))+ ]++ handleNoWindowsSH $ rawSystemExitWithEnv verbosity "sh" args env'++ where+ args = "configure" : configureArgs backwardsCompatHack flags++ appendToEnvironment (key, val) [] = [(key, val)]+ appendToEnvironment (key, val) (kv@(k, v) : rest)+ | key == k = (key, v ++ " " ++ val) : rest+ | otherwise = kv : appendToEnvironment (key, val) rest++ handleNoWindowsSH action+ | buildOS /= Windows+ = action++ | otherwise+ = action+ `catch` \ioe -> if isDoesNotExistError ioe+ then die notFoundMsg+ else throwIO ioe++ notFoundMsg = "The package has a './configure' script. This requires a "+ ++ "Unix compatibility toolchain such as MinGW+MSYS or Cygwin."+++getHookedBuildInfo :: Verbosity -> IO HookedBuildInfo+getHookedBuildInfo verbosity = do+ maybe_infoFile <- defaultHookedPackageDesc+ case maybe_infoFile of+ Nothing -> return emptyHookedBuildInfo+ Just infoFile -> do+ info verbosity $ "Reading parameters from " ++ infoFile+ readHookedBuildInfo verbosity infoFile+++-- 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+--+ppC2hs :: BuildInfo -> LocalBuildInfo -> PreProcessor+ppC2hs 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]+ ++ ["--cppopts=" ++ opt | opt <- getCppOptions bi lbi]+ ++ ["--output-dir=" ++ outBaseDir,+ "--output=" ++ outRelativeFile,+ inBaseDir </> inRelativeFile]+ }++getCppOptions :: BuildInfo -> LocalBuildInfo -> [String]+getCppOptions bi lbi+ = hcDefines (compiler lbi)+ ++ ["-I" ++ dir | dir <- includeDirs bi]+ ++ [opt | opt@('-':c:_) <- ccOptions bi, c `elem` "DIU"]++hcDefines :: Compiler -> [String]+hcDefines comp =+ case compilerFlavor comp of+ GHC -> ["-D__GLASGOW_HASKELL__=" ++ versionInt version]+ JHC -> ["-D__JHC__=" ++ versionInt version]+ NHC -> ["-D__NHC__=" ++ versionInt version]+ Hugs -> ["-D__HUGS__"]+ _ -> []+ where version = compilerVersion comp++-- TODO: move this into the compiler abstraction+-- FIXME: this forces GHC's crazy 4.8.2 -> 408 convention on all the other+-- compilers. Check if that's really what they want.+versionInt :: Version -> String+versionInt (Version { versionBranch = [] }) = "1"+versionInt (Version { versionBranch = [n] }) = show n+versionInt (Version { versionBranch = n1:n2:_ })+ = -- 6.8.x -> 608+ -- 6.10.x -> 610+ let s1 = show n1+ s2 = show n2+ middle = case s2 of+ _ : _ : _ -> ""+ _ -> "0"+ in s1 ++ middle ++ s2
cbits/wrap.h view
@@ -15,6 +15,7 @@ #define __OSX_AVAILABLE_BUT_DEPRECATED(_macIntro, _macDep, _iphoneIntro, _iphoneDep) #endif +#include <cuda.h> #include <cufft.h> #endif
configure view
@@ -624,9 +624,14 @@ ac_subst_vars='LTLIBOBJS LIBOBJS+cuda_ghci_libs+cuda_frameworks+cuda_libraries+cuda_lib_path cuda_c2hsflags cuda_ldflags-cuda_cppflags+cuda_ccflags+cuda_ghcflags EGREP GREP CPP@@ -1318,9 +1323,9 @@ Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)-Haskell compiler-CUDA compiler-C compiler+ --with-compiler=HC use HC as the Haskell compiler+ --with-nvcc=NVCC use NVCC as the CUDA compiler+ --with-gcc=CC use CC as the C compiler Some influential environment variables: CC C compiler command@@ -1651,6 +1656,52 @@ } # ac_fn_c_check_header_compile +# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES+# ---------------------------------------------+# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR+# accordingly.+ac_fn_c_check_decl ()+{+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack+ as_decl_name=`echo $2|sed 's/ *(.*//'`+ as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5+$as_echo_n "checking whether $as_decl_name is declared... " >&6; }+if eval \${$3+:} false; then :+ $as_echo_n "(cached) " >&6+else+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h. */+$4+int+main ()+{+#ifndef $as_decl_name+#ifdef __cplusplus+ (void) $as_decl_use;+#else+ (void) $as_decl_name;+#endif+#endif++ ;+ return 0;+}+_ACEOF+if ac_fn_c_try_compile "$LINENO"; then :+ eval "$3=yes"+else+ eval "$3=no"+fi+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext+fi+eval ac_res=\$$3+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5+$as_echo "$ac_res" >&6; }+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno++} # ac_fn_c_check_decl+ # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded.@@ -3052,7 +3103,8 @@ ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR-for as_dir in $PATH+as_dummy="$PATH:/usr/local/cuda/bin"+for as_dir in $as_dummy do IFS=$as_save_IFS test -z "$as_dir" && as_dir=.@@ -3092,9 +3144,26 @@ # that, otherwise choose the default # if test "$NVCC" != ""; then+ case $target in+ *mingw* )+ # We need a Windows-style path, but mingw doesn't include cygpath,+ # thus this hack.+ NVCC=`cd $(dirname $NVCC) && pwd -W`/$(basename nvcc)+ ;;+ esac+ cuda_prefix="$(dirname "$(dirname "$NVCC")")"- cuda_c2hsflags="--cpp="$NVCC" --cppopts=-E "++ case $target in+ *mingw* )+ cuda_c2hsflags="--cppopts=-E --cppopts=-arch=sm_20 --cppopts="-D${target_os}_TARGET_OS=1" "+ ;;+ * )+ cuda_c2hsflags="--cpp="$NVCC" --cppopts=-E --cppopts=-arch=sm_20 "+ ;;+ esac else+ echo "WARNING: Cannot find the CUDA compiler 'nvcc'. This is likely to cause problems." cuda_prefix="/usr/local/cuda" fi @@ -3106,9 +3175,19 @@ case $target_os in darwin*) cuda_lib_path="${cuda_prefix}/lib"- LDFLAGS+=" -Xlinker -rpath ${cuda_lib_path} "+ #LDFLAGS+=" -Xlinker -rpath ${cuda_lib_path} " #CPPFLAGS+=" -arch ${target_cpu} " ;;+ mingw*)+ case $target_cpu in+ x86_64*)+ cuda_lib_path="${cuda_prefix}/lib/x64"+ ;;+ *)+ cuda_lib_path="${cuda_prefix}/lib/Win32"+ ;;+ esac+ ;; *) case $target_cpu in x86_64*)@@ -3146,6 +3225,9 @@ # confuses the c2hs preprocessor. We disable this by undefining the __BLOCKS__ # macro. #+# NB: This test doesn't work with newer versions of Xcode/command lines tools anymore.+# However, other CPP magic keeps blocks at bay.+# { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Apple Blocks extension" >&5 $as_echo_n "checking for Apple Blocks extension... " >&6; } if test -r "/usr/include/stdlib.h"; then@@ -3591,7 +3673,33 @@ done -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing cufftPlan1d" >&5+case $target in+ *mingw32* )+ # AC_SEARCH_LIBS doesn't work on Win32 with functions that use the+ # stdcall calling convention, so we use AC_CHECK_DELCS instead.+ LIBS+="-lcufft"+ ac_fn_c_check_decl "$LINENO" "cufftPlan1d" "ac_cv_have_decl_cufftPlan1d" "#include <cufft.h>+"+if test "x$ac_cv_have_decl_cufftPlan1d" = xyes; then :+ ac_have_decl=1+else+ ac_have_decl=0+fi++cat >>confdefs.h <<_ACEOF+#define HAVE_DECL_CUFFTPLAN1D $ac_have_decl+_ACEOF+if test $ac_have_decl = 1; then :++else+ as_fn_error $? "could not find CUFFT library${longerror}" "$LINENO" 5+fi+++ cuda_ghci_libs+="`nm ${cuda_lib_path}/cufft.lib | head -2 | tail -1 | sed -e 's/://' -e 's/.dll//'` "+ ;;+ *)+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing cufftPlan1d" >&5 $as_echo_n "checking for library containing cufftPlan1d... " >&6; } if ${ac_cv_search_cufftPlan1d+:} false; then : $as_echo_n "(cached) " >&6@@ -3649,15 +3757,32 @@ as_fn_error $? "could not find CUFFT library${longerror}" "$LINENO" 5 fi + ;;+esac # Populate the buildinfo, with the search paths and any target specific options #-cuda_cppflags="$CPPFLAGS "-cuda_ldflags="$LDFLAGS $LIBS "+cuda_ccflags="$CPPFLAGS "+cuda_ldflags="$LDFLAGS " +for x in $cuda_ccflags; do+ cuda_ghcflags+="-optc${x} "+done+for x in $cuda_ldflags; do+ cuda_ghcflags+="-optl${x} "+done+for x in $LIBS; do+ cuda_libraries+="${x#-l} "+done ++++++ cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure@@ -4812,3 +4937,5 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi++
configure.ac view
@@ -11,17 +11,37 @@ # prefix to the include and library search directories. Additionally, set nvcc # as the C preprocessor for c2hs (only, or it won't try to link cudart) #-AC_ARG_WITH([compiler], [Haskell compiler], [GHC=$withval], [AC_PATH_PROG(GHC, ghc)])-AC_ARG_WITH([nvcc], [CUDA compiler], [NVCC=$withval], [AC_PATH_PROG(NVCC, nvcc)])-AC_ARG_WITH([gcc], [C compiler], [CC=$withval])+AC_ARG_WITH([compiler], [ --with-compiler=HC use HC as the Haskell compiler],+ [GHC=$withval], [AC_PATH_PROG(GHC, ghc)])+AC_ARG_WITH([nvcc], [ --with-nvcc=NVCC use NVCC as the CUDA compiler],+ [NVCC=$withval], [AC_PATH_PROG(NVCC, nvcc, [], [$PATH:/usr/local/cuda/bin])])+AC_ARG_WITH([gcc], [ --with-gcc=CC use CC as the C compiler],+ [CC=$withval]) # If NVCC is detected in the path, set the location of the toolkit relative to # that, otherwise choose the default # if test "$NVCC" != ""; then+ case $target in+ *mingw* )+ # We need a Windows-style path, but mingw doesn't include cygpath,+ # thus this hack.+ NVCC=`cd $(dirname $NVCC) && pwd -W`/$(basename nvcc)+ ;;+ esac+ cuda_prefix="$(dirname "$(dirname "$NVCC")")"- cuda_c2hsflags="--cpp="$NVCC" --cppopts=-E "+ + case $target in+ *mingw* )+ cuda_c2hsflags="--cppopts=-E --cppopts=-arch=sm_20 --cppopts="-D${target_os}_TARGET_OS=1" "+ ;;+ * )+ cuda_c2hsflags="--cpp="$NVCC" --cppopts=-E --cppopts=-arch=sm_20 "+ ;;+ esac else+ echo "WARNING: Cannot find the CUDA compiler 'nvcc'. This is likely to cause problems." cuda_prefix="/usr/local/cuda" fi @@ -33,9 +53,19 @@ case $target_os in darwin*) cuda_lib_path="${cuda_prefix}/lib"- LDFLAGS+=" -Xlinker -rpath ${cuda_lib_path} "+ #LDFLAGS+=" -Xlinker -rpath ${cuda_lib_path} " #CPPFLAGS+=" -arch ${target_cpu} " ;;+ mingw*)+ case $target_cpu in+ x86_64*)+ cuda_lib_path="${cuda_prefix}/lib/x64"+ ;;+ *)+ cuda_lib_path="${cuda_prefix}/lib/Win32"+ ;;+ esac+ ;; *) case $target_cpu in x86_64*)@@ -71,6 +101,9 @@ # confuses the c2hs preprocessor. We disable this by undefining the __BLOCKS__ # macro. #+# NB: This test doesn't work with newer versions of Xcode/command lines tools anymore.+# However, other CPP magic keeps blocks at bay.+# AC_MSG_CHECKING(for Apple Blocks extension) if test -r "/usr/include/stdlib.h"; then BLOCKS=`grep __BLOCKS__ /usr/include/stdlib.h`@@ -102,15 +135,45 @@ ********************************************************************************' AC_CHECK_HEADERS([cufft.h], [], [AC_MSG_ERROR(could not find CUFFT headers${longerror})])-AC_SEARCH_LIBS(cufftPlan1d, cufft, [], [AC_MSG_ERROR(could not find CUFFT library${longerror})])+case $target in+ *mingw32* )+ # AC_SEARCH_LIBS doesn't work on Win32 with functions that use the+ # stdcall calling convention, so we use AC_CHECK_DELCS instead.+ LIBS+="-lcufft"+ AC_CHECK_DECLS([cufftPlan1d],+ [],+ [AC_MSG_ERROR(could not find CUFFT library${longerror})],+ [[#include <cufft.h>]])+ + cuda_ghci_libs+="`nm ${cuda_lib_path}/cufft.lib | head -2 | tail -1 | sed -e 's/://' -e 's/.dll//'` "+ ;;+ *)+ AC_SEARCH_LIBS(cufftPlan1d, cufft, [], [AC_MSG_ERROR(could not find CUFFT library${longerror})])+ ;;+esac # Populate the buildinfo, with the search paths and any target specific options #-cuda_cppflags="$CPPFLAGS "-cuda_ldflags="$LDFLAGS $LIBS "+cuda_ccflags="$CPPFLAGS "+cuda_ldflags="$LDFLAGS " -AC_SUBST([cuda_cppflags])+for x in $cuda_ccflags; do+ cuda_ghcflags+="-optc${x} "+done+for x in $cuda_ldflags; do+ cuda_ghcflags+="-optl${x} "+done+for x in $LIBS; do+ cuda_libraries+="${x#-l} "+done++AC_SUBST([cuda_ghcflags])+AC_SUBST([cuda_ccflags]) AC_SUBST([cuda_ldflags]) AC_SUBST([cuda_c2hsflags])+AC_SUBST([cuda_lib_path])+AC_SUBST([cuda_libraries])+AC_SUBST([cuda_frameworks])+AC_SUBST([cuda_ghci_libs]) AC_OUTPUT
cufft.buildinfo.in view
@@ -1,4 +1,7 @@-ghc-options: -optc@cuda_cppflags@-cc-options: @cuda_cppflags@+ghc-options: @cuda_ghcflags@+cc-options: @cuda_ccflags@ ld-options: @cuda_ldflags@ x-extra-c2hs-options: @cuda_c2hsflags@+extra-lib-dirs: @cuda_lib_path@+extra-libraries: @cuda_libraries@+frameworks: @cuda_frameworks@
cufft.cabal view
@@ -2,7 +2,7 @@ -- see http://haskell.org/cabal/users-guide/ name: cufft-version: 0.1.0.3+version: 0.1.1.0 synopsis: Haskell bindings for the CUFFT library description: The CUFFT library is part of the CUDA developer toolkit. .@@ -17,7 +17,7 @@ maintainer: Robert Clifton-Everest <robertce@cse.unsw.edu.au> category: Foreign-build-type: Configure+build-type: Custom cabal-version: >=1.8 Extra-tmp-files: cufft.buildinfo config.status config.log