 --
 --------------------------------------------------------------------------------
 
+#include "cbits/stubs.h"
+#include <cuda_runtime_api.h>
+{# context lib="cudart" #}
+
 module Foreign.CUDA.Runtime.Exec
   (
     FunAttributes(..), FunParam(..),
-    attributes, setConfig, setParams, launch
+#if CUDART_VERSION >= 3000
+    CacheConfig(..),
+#endif
+    attributes, setConfig, setParams,
+#if CUDART_VERSION >= 3000
+    setCacheConfig,
+#endif
+    launch
   )
   where
-
-#include "cbits/stubs.h"
-#include <cuda_runtime_api.h>
-{# context lib="cudart" #}
 
 -- Friends
 import Foreign.CUDA.Runtime.Stream

        numRegs                  = nr
      }

-- |
-- Kernel function parameters. Doubles will be converted to an internal float
-- representation on devices that do not support doubles natively.

    peek'     = peek . castPtr


#if CUDART_VERSION >= 3000
-- |
-- On devices where the L1 cache and shared memory use the same hardware
-- resources, this sets the preferred cache configuration for the given device
-- function. This is only a preference; the driver is free to choose a different
-- configuration as required to execute the function.
--
-- Switching between configuration modes may insert a device-side
-- synchronisation point for streamed kernel launches
--
setCacheConfig :: String -> CacheConfig -> IO ()
setCacheConfig fn pref = nothingIfOk =<< cudaFuncSetCacheConfig fn pref

{# fun unsafe cudaFuncSetCacheConfig
  { withCString* `String'
  , cFromEnum    `CacheConfig' } -> `Status' cToEnum #}
#endif


-- |
-- Invoke the named kernel on the device, which must have been declared
-- @__global__@. This must be preceded by a call to 'setConfig' and (if
