diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,10 @@
+# Revision history for cusparse
+
+Notable changes to the project will be documented in this file.
+
+The format is based on [Keep a Changelog](http://keepachangelog.com/).
+
+## 0.1.0.0 - 2017-08-24
+
+* First version; split off from [bmsherman/cublas](https://github.com/bmsherman/cublas). Released on an unsuspecting world.
+
diff --git a/Foreign/CUDA/BLAS/Sparse.hs b/Foreign/CUDA/BLAS/Sparse.hs
new file mode 100644
--- /dev/null
+++ b/Foreign/CUDA/BLAS/Sparse.hs
@@ -0,0 +1,146 @@
+-- |
+-- Module      : Foreign.CUDA.BLAS.Sparse
+-- Copyright   : [2017] Trevor L. McDonell
+-- License     : BSD3
+--
+-- Maintainer  : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+--
+-- The cuSPARSE library is an implementation of Sparse BLAS (Basic Linear
+-- Algebra Subprograms) for NVIDIA GPUs. Sparse matrices are those where the
+-- majority of elements are zero. Sparse BLAS routines are specifically
+-- implemented to take advantage of this sparsity.
+--
+-- To use operations from the cuSPARSE library, the user must allocate the
+-- required matrices and vectors in the GPU memory space, fill them with data,
+-- call the desired sequence of cuSPARSE functions, then copy the results from
+-- the GPU memory space 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/]
+--
+-- The following is based on the following example:
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#appendix-b-cusparse-library-c---example>
+--
+-- It assumes basic familiarity with the <http://hackage.haskell.org/package/cuda cuda>
+-- package, as described in the "Foreign.CUDA.Driver" module.
+--
+-- >>> import Foreign.CUDA.Driver      as CUDA
+-- >>> import Foreign.CUDA.BLAS.Sparse as Sparse
+-- >>> CUDA.initialise []
+-- >>> dev <- CUDA.device 0
+-- >>> ctx <- CUDA.create dev []
+--
+-- We begin by creating the following matrix in COO format and transferring to
+-- the GPU:
+--
+-- \[
+-- \left(\begin{matrix}
+--   1.0 &     & 2.0 & 3.0 \\
+--       & 4.0 &     &     \\
+--   5.0 &     & 6.0 & 7.0 \\
+--       & 8.0 &     & 9.0
+-- \end{matrix}\right)
+-- \]
+--
+-- >>> let n = 4
+-- >>> let nnz = 9
+-- >>> d_cooRowIdx <- newListArray [ 0,0,0, 1, 2,2,2, 3,3 ]  :: IO (DevicePtr Int32)
+-- >>> d_cooColIdx <- newListArray [ 0,2,3, 1, 0,2,3, 1,3 ]  :: IO (DevicePtr Int32)
+-- >>> d_vals      <- newListArray [ 1..9 ]                  :: IO (DevicePtr Double)
+--
+-- Create a sparse and dense vector:
+--
+-- >>> let nnz_vector = 3
+-- >>> d_xVal <- newListArray [ 100, 200, 400 ] :: IO (DevicePtr Double)
+-- >>> d_xIdx <- newListArray [ 0,   1,   3 ]   :: IO (DevicePtr Int32)
+-- >>> d_y    <- newListArray [ 10, 20 .. 80 ]  :: IO (DevicePtr Double)
+--
+-- Initialise the cuSPARSE library and set up the matrix descriptor:
+--
+-- >>> hdl <- Sparse.create
+-- >>> mat <- Sparse.createMatDescr
+-- >>> Sparse.setMatrixType mat General
+-- >>> Sparse.setIndexBase mat Zero
+--
+-- Exercise the conversion routines to convert from COO to CSR format:
+--
+-- >>> d_csrRowPtr <- CUDA.mallocArray (n+1) :: IO (DevicePtr Int32)
+-- >>> xcoo2csr hdl d_cooRowIdx nnz n d_csrRowPtr Zero
+-- >>> peekListArray (n+1) d_csrRowPtr
+-- [0,3,4,7,9]
+--
+-- Scatter elements from the sparse vector into the dense vector:
+--
+-- >>> dsctr hdl nnz_vector d_xVal d_xIdx (d_y `plusDevPtr` (n * sizeOf (undefined::Double))) Zero
+-- >>> peekListArray 8 d_y
+-- [10.0,20.0,30.0,40.0,100.0,200.0,70.0,400.0]
+--
+-- Multiply the matrix in CSR format with the dense vector:
+--
+-- >>> with 2.0 $ \alpha ->
+-- >>> with 3.0 $ \beta  ->
+-- >>>   dcsrmv hdl N n n nnz alpha mat d_vals d_csrRowPtr d_cooColIdx d_y beta (d_y `plusDevPtr` (n * sizeOf (undefined::Double)))
+-- >>> peekListArray 8 d_y
+-- [10.0,20.0,30.0,40.0,680.0,760.0,1230.0,2240.0]
+--
+-- Multiply the matrix in CSR format with a dense matrix:
+--
+-- >>> d_z <- CUDA.mallocArray (2*(n+1)) :: IO (DevicePtr Double)
+-- >>> memset (castDevPtr d_z :: DevicePtr Word8) (2*(n+1)*sizeOf (undefined::Double)) 0
+-- >>> with 5.0 $ \alpha ->
+-- >>> with 0.0 $ \beta  ->
+-- >>>   dcsrmm hdl N n 2 n nnz alpha mat d_vals d_csrRowPtr d_cooColIdx d_y n beta d_z (n+1)
+-- >> peekListArray (2*(n+1)) d_z
+-- [950.0,400.0,2550.0,2600.0,0.0,49300.0,15200.0,132300.0,131200.0,0.0]
+--
+-- Finally, we should 'Foreign.CUDA.Driver.free' the device memory we allocated,
+-- and release the Sparse BLAS context handle:
+--
+-- >>> Sparse.destroy hdl
+--
+-- [/Additional information/]
+--
+-- For more information, see the NVIDIA cuSPARSE documentation:
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html>
+--
+
+module Foreign.CUDA.BLAS.Sparse (
+
+  -- * Control
+  module Foreign.CUDA.BLAS.Sparse.Context,
+  module Foreign.CUDA.BLAS.Sparse.Analysis,
+  module Foreign.CUDA.BLAS.Sparse.Error,
+  module Foreign.CUDA.BLAS.Sparse.Matrix.Descriptor,
+  module Foreign.CUDA.BLAS.Sparse.Matrix.Hybrid,
+  module Foreign.CUDA.BLAS.Sparse.Stream,
+
+  -- * Operations
+  module Foreign.CUDA.BLAS.Sparse.Level1,
+  module Foreign.CUDA.BLAS.Sparse.Level2,
+  module Foreign.CUDA.BLAS.Sparse.Level3,
+  module Foreign.CUDA.BLAS.Sparse.Precondition,
+  module Foreign.CUDA.BLAS.Sparse.Reorder,
+  module Foreign.CUDA.BLAS.Sparse.Convert,
+
+) where
+
+import Foreign.CUDA.BLAS.Sparse.Analysis                  hiding ( useInfo, useInfo_bsrsv2, useInfo_csrsv2, useInfo_bsrsm2, useInfo_csrgemm2 )
+import Foreign.CUDA.BLAS.Sparse.Context                   hiding ( useHandle )
+import Foreign.CUDA.BLAS.Sparse.Error                     hiding ( resultIfOk, nothingIfOk )
+import Foreign.CUDA.BLAS.Sparse.Matrix.Descriptor         hiding ( useMatDescr )
+import Foreign.CUDA.BLAS.Sparse.Matrix.Hybrid             hiding ( useHYB )
+import Foreign.CUDA.BLAS.Sparse.Stream
+
+import Foreign.CUDA.BLAS.Sparse.Level1
+import Foreign.CUDA.BLAS.Sparse.Level2
+import Foreign.CUDA.BLAS.Sparse.Level3
+import Foreign.CUDA.BLAS.Sparse.Precondition
+import Foreign.CUDA.BLAS.Sparse.Reorder
+import Foreign.CUDA.BLAS.Sparse.Convert
+
diff --git a/Foreign/CUDA/BLAS/Sparse/Analysis.chs b/Foreign/CUDA/BLAS/Sparse/Analysis.chs
new file mode 100644
--- /dev/null
+++ b/Foreign/CUDA/BLAS/Sparse/Analysis.chs
@@ -0,0 +1,253 @@
+{-# LANGUAGE CPP                      #-}
+{-# LANGUAGE EmptyDataDecls           #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+-- |
+-- Module      : Foreign.CUDA.BLAS.Sparse.Analysis
+-- Copyright   : [2017] Trevor L. McDonell
+-- License     : BSD3
+--
+-- Maintainer  : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+--
+
+module Foreign.CUDA.BLAS.Sparse.Analysis (
+
+  Info(..), createInfo, destroyInfo,
+  Info_csrsv2(..), createInfo_csrsv2, destroyInfo_csrsv2,
+  Info_csric02(..), createInfo_csric02, destroyInfo_csric02,
+  Info_csrilu02(..), createInfo_csrilu02, destroyInfo_csrilu02,
+  Info_bsrsv2(..), createInfo_bsrsv2, destroyInfo_bsrsv2,
+  Info_bsrsm2(..), createInfo_bsrsm2, destroyInfo_bsrsm2,
+  Info_bsric02(..), createInfo_bsric02, destroyInfo_bsric02,
+  Info_bsrilu02(..), createInfo_bsrilu02, destroyInfo_bsrilu02,
+  Info_csrgemm2(..), createInfo_csrgemm2, destroyInfo_csrgemm2,
+  Info_color(..), createInfo_color, destroyInfo_color,
+  Info_csru2csr(..), createInfo_csru2csr, destroyInfo_csru2csr,
+
+) where
+
+-- Friends
+import Foreign.CUDA.BLAS.Sparse.Error
+import Foreign.CUDA.BLAS.Sparse.Internal.C2HS
+
+-- System
+import Foreign
+import Foreign.C
+import Control.Monad                                      ( liftM )
+
+#include "cbits/stubs.h"
+{# context lib="cusparse" #}
+
+
+-- | An opaque structure holding the information collected in the analysis phase
+-- of the solution of the sparse triangular linear system.
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparsesolveanalysisinfot>
+--
+newtype Info = Info { useInfo :: {# type cusparseSolveAnalysisInfo_t #}}
+
+-- | Create and initialise the solve and analysis structure to default values.
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparsecreatesolveanalysisinfo>
+--
+{-# INLINEABLE createInfo #-}
+{# fun unsafe cusparseCreateSolveAnalysisInfo as createInfo
+  { alloca- `Info' peekI* } -> `()' checkStatus*- #}
+  where
+    peekI = liftM Info . peek
+
+-- | Release memory associated with a matrix solver structure.
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparsedestroysolveanalysisinfo>
+--
+{-# INLINEABLE destroyInfo #-}
+{# fun unsafe cusparseDestroySolveAnalysisInfo as destroyInfo
+  { useInfo `Info' } -> `()' checkStatus* #}
+
+
+-- | <http://docs.nvidia.com/cuda/cusparse/index.html#csrsv2infot>
+--
+newtype Info_csrsv2 = Info_csrsv2 { useInfo_csrsv2 :: {# type csrsv2Info_t #}}
+
+{-# INLINEABLE createInfo_csrsv2 #-}
+{# fun unsafe cusparseCreateCsrsv2Info as createInfo_csrsv2
+  { alloca- `Info_csrsv2' peekI* } -> `()' checkStatus*- #}
+  where
+    peekI = liftM Info_csrsv2 . peek
+
+{-# INLINEABLE destroyInfo_csrsv2 #-}
+{# fun unsafe cusparseDestroyCsrsv2Info as destroyInfo_csrsv2
+  { useInfo_csrsv2 `Info_csrsv2' } -> `()' checkStatus* #}
+
+
+-- | <http://docs.nvidia.com/cuda/cusparse/index.html#csric02infot>
+--
+newtype Info_csric02 = Info_csric02 { useInfo_csric02 :: {# type csric02Info_t #}}
+
+{-# INLINEABLE createInfo_csric02 #-}
+{# fun unsafe cusparseCreateCsric02Info as createInfo_csric02
+  { alloca- `Info_csric02' peekI* } -> `()' checkStatus*- #}
+  where
+    peekI = liftM Info_csric02 . peek
+
+{-# INLINEABLE destroyInfo_csric02 #-}
+{# fun unsafe cusparseDestroyCsric02Info as destroyInfo_csric02
+  { useInfo_csric02 `Info_csric02' } -> `()' checkStatus* #}
+
+
+-- | <http://docs.nvidia.com/cuda/cusparse/index.html#csrilu02infot>
+--
+newtype Info_csrilu02 = Info_csrilu02 { useInfo_csrilu02 :: {# type csrilu02Info_t #}}
+
+{-# INLINEABLE createInfo_csrilu02 #-}
+{# fun unsafe cusparseCreateCsrilu02Info as createInfo_csrilu02
+  { alloca- `Info_csrilu02' peekI* } -> `()' checkStatus*- #}
+  where
+    peekI = liftM Info_csrilu02 . peek
+
+{-# INLINEABLE destroyInfo_csrilu02 #-}
+{# fun unsafe cusparseDestroyCsrilu02Info as destroyInfo_csrilu02
+  { useInfo_csrilu02 `Info_csrilu02' } -> `()' checkStatus* #}
+
+
+-- | <http://docs.nvidia.com/cuda/cusparse/index.html#bsrsv2infot>
+--
+newtype Info_bsrsv2 = Info_bsrsv2 { useInfo_bsrsv2 :: {# type bsrsv2Info_t #}}
+
+{-# INLINEABLE createInfo_bsrsv2 #-}
+{# fun unsafe cusparseCreateBsrsv2Info as createInfo_bsrsv2
+  { alloca- `Info_bsrsv2' peekI* } -> `()' checkStatus*- #}
+  where
+    peekI = liftM Info_bsrsv2 . peek
+
+{-# INLINEABLE destroyInfo_bsrsv2 #-}
+{# fun unsafe cusparseDestroyBsrsv2Info as destroyInfo_bsrsv2
+  { useInfo_bsrsv2 `Info_bsrsv2' } -> `()' checkStatus* #}
+
+
+-- | <http://docs.nvidia.com/cuda/cusparse/index.html#bsrsvminfot>
+--
+newtype Info_bsrsm2 = Info_bsrsm2 { useInfo_bsrsm2 :: {# type bsrsm2Info_t #}}
+
+{-# INLINEABLE createInfo_bsrsm2 #-}
+{# fun unsafe cusparseCreateBsrsm2Info as createInfo_bsrsm2
+  { alloca- `Info_bsrsm2' peekI* } -> `()' checkStatus*- #}
+  where
+    peekI = liftM Info_bsrsm2 . peek
+
+{-# INLINEABLE destroyInfo_bsrsm2 #-}
+{# fun unsafe cusparseDestroyBsrsm2Info as destroyInfo_bsrsm2
+  { useInfo_bsrsm2 `Info_bsrsm2' } -> `()' checkStatus* #}
+
+
+-- | <http://docs.nvidia.com/cuda/cusparse/index.html#bsric02infot>
+--
+newtype Info_bsric02 = Info_bsric02 { useInfo_bsric02 :: {# type bsric02Info_t #}}
+
+{-# INLINEABLE createInfo_bsric02 #-}
+{# fun unsafe cusparseCreateBsric02Info as createInfo_bsric02
+  { alloca- `Info_bsric02' peekI* } -> `()' checkStatus*- #}
+  where
+    peekI = liftM Info_bsric02 . peek
+
+{-# INLINEABLE destroyInfo_bsric02 #-}
+{# fun unsafe cusparseDestroyBsric02Info as destroyInfo_bsric02
+  { useInfo_bsric02 `Info_bsric02' } -> `()' checkStatus* #}
+
+
+-- | <http://docs.nvidia.com/cuda/cusparse/index.html#bsrilu02infot>
+--
+newtype Info_bsrilu02 = Info_bsrilu02 { useInfo_bsrilu02 :: {# type bsrilu02Info_t #}}
+
+{-# INLINEABLE createInfo_bsrilu02 #-}
+{# fun unsafe cusparseCreateBsrilu02Info as createInfo_bsrilu02
+  { alloca- `Info_bsrilu02' peekI* } -> `()' checkStatus*- #}
+  where
+    peekI = liftM Info_bsrilu02 . peek
+
+{-# INLINEABLE destroyInfo_bsrilu02 #-}
+{# fun unsafe cusparseDestroyBsrilu02Info as destroyInfo_bsrilu02
+  { useInfo_bsrilu02 `Info_bsrilu02' } -> `()' checkStatus* #}
+
+
+-- | <http://docs.nvidia.com/cuda/cusparse/index.html#csrgemm2infot>
+--
+#if CUDA_VERSION >= 7000
+newtype Info_csrgemm2 = Info_csrgemm2 { useInfo_csrgemm2 :: {# type csrgemm2Info_t #}}
+
+{-# INLINEABLE createInfo_csrgemm2 #-}
+{# fun unsafe cusparseCreateCsrgemm2Info as createInfo_csrgemm2
+  { alloca- `Info_csrgemm2' peekI* } -> `()' checkStatus*- #}
+  where
+    peekI = liftM Info_csrgemm2 . peek
+
+{-# INLINEABLE destroyInfo_csrgemm2 #-}
+{# fun unsafe cusparseDestroyCsrgemm2Info as destroyInfo_csrgemm2
+  { useInfo_csrgemm2 `Info_csrgemm2' } -> `()' checkStatus* #}
+
+#else
+data Info_csrgemm2
+
+createInfo_csrgemm2 :: IO Info_csrgemm2
+createInfo_csrgemm2 = cusparseError "'createInfo_csrgemm2' requires at least cuda-7.0"
+
+destroyInfo_csrgemm2 :: Info_csrgemm2 -> IO ()
+destroyInfo_csrgemm2 _ = cusparseError "'destroyInfo_csrgemm2' requires at least cuda-7.0"
+
+#endif
+
+
+-- /undocumented/
+--
+#if CUDA_VERSION >= 7000
+newtype Info_color = Info_color { useInfo_color :: {# type cusparseColorInfo_t #}}
+
+{-# INLINEABLE createInfo_color #-}
+{# fun unsafe cusparseCreateColorInfo as createInfo_color
+  { alloca- `Info_color' peekI* } -> `()' checkStatus*- #}
+  where
+    peekI = liftM Info_color . peek
+
+{-# INLINEABLE destroyInfo_color #-}
+{# fun unsafe cusparseDestroyColorInfo as destroyInfo_color
+  { useInfo_color `Info_color' } -> `()' checkStatus* #}
+
+#else
+data Info_color
+
+createInfo_color :: IO Info_color
+createInfo_color = cusparseError "'createInfo_color' requires at least cuda-7.0"
+
+destroyInfo_color :: Info_color -> IO ()
+destroyInfo_color _ = cusparseError "'destroyInfo_color' requires at least cuda-7.0"
+
+#endif
+
+
+-- /undocumented/
+--
+#if CUDA_VERSION >= 7000
+newtype Info_csru2csr = Info_csru2csr { useInfo_csru2csr :: {# type csru2csrInfo_t #}}
+
+{-# INLINEABLE createInfo_csru2csr #-}
+{# fun unsafe cusparseCreateCsru2csrInfo as createInfo_csru2csr
+  { alloca- `Info_csru2csr' peekI* } -> `()' checkStatus*- #}
+  where
+    peekI = liftM Info_csru2csr . peek
+
+{-# INLINEABLE destroyInfo_csru2csr #-}
+{# fun unsafe cusparseDestroyCsru2csrInfo as destroyInfo_csru2csr
+  { useInfo_csru2csr `Info_csru2csr' } -> `()' checkStatus* #}
+
+#else
+data Info_csru2csr
+
+createInfo_csru2csr :: IO Info_csru2csr
+createInfo_csru2csr = cusparseError "'createInfo_csru2csr' requires at least cuda-7.0"
+
+destroyInfo_csru2csr :: Info_csru2csr -> IO ()
+destroyInfo_csru2csr _ = cusparseError "'destroyInfo_csru2csr' requires at least cuda-7.0"
+
+#endif
+
diff --git a/Foreign/CUDA/BLAS/Sparse/Context.chs b/Foreign/CUDA/BLAS/Sparse/Context.chs
new file mode 100644
--- /dev/null
+++ b/Foreign/CUDA/BLAS/Sparse/Context.chs
@@ -0,0 +1,106 @@
+{-# LANGUAGE CPP                      #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+-- |
+-- Module      : Foreign.CUDA.BLAS.Sparse.Context
+-- Copyright   : [2017] Trevor L. McDonell
+-- License     : BSD3
+--
+-- Maintainer  : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+--
+
+module Foreign.CUDA.BLAS.Sparse.Context (
+
+  -- * Context management
+  Handle(..),
+  create, destroy,
+
+  -- ** Utilities
+  PointerMode(..),
+  setPointerMode,
+  getPointerMode,
+
+) where
+
+-- Friends
+import Foreign.CUDA.BLAS.Sparse.Error
+import Foreign.CUDA.BLAS.Sparse.Internal.C2HS
+
+-- System
+import Foreign
+import Foreign.C
+import Control.Monad                                      ( liftM )
+
+#include "cbits/stubs.h"
+{# context lib="cusparse" #}
+
+
+-- | An opaque handle to the cuSPARSE library context, which is passed to all
+-- library function calls.
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparsehandlet>
+--
+newtype Handle = Handle { useHandle :: {# type cusparseHandle_t #}}
+
+-- | This function initializes the cuSPARSE library and creates a handle on the
+-- cuSPARSE context. It must be called before any other cuSPARSE API function is
+-- invoked. It allocates hardware resources necessary for accessing the GPU.
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparsecreate>
+--
+{-# INLINEABLE create #-}
+{# fun unsafe cusparseCreate as create
+  { alloca- `Handle' peekHdl* } -> `()' checkStatus*- #}
+  where
+    peekHdl = liftM Handle . peek
+
+
+-- | This function releases CPU-side resources used by the cuSPARSE library. The
+-- release of GPU-side resources may be deferred until the application shuts
+-- down.
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparsedestroy>
+--
+{-# INLINEABLE destroy #-}
+{# fun unsafe cusparseDestroy as destroy
+  { useHandle `Handle' } -> `()' checkStatus* #}
+
+
+-- | For functions which take scalar value arguments, determines whether those
+-- values are passed by reference on the host or device.
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparsepointermode_t>
+--
+{# enum cusparsePointerMode_t as PointerMode
+  { underscoreToCase }
+  with prefix="CUSPARSE_POINTER_MODE" deriving (Eq, Show) #}
+
+
+-- | Set the pointer mode used by cuSPARSE library functions.
+--
+-- The default mode is for values to be passed by reference from the host.
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparsesetpointermode>
+--
+{-# INLINEABLE setPointerMode #-}
+{# fun unsafe cusparseSetPointerMode as setPointerMode
+  { useHandle `Handle'
+  , cFromEnum `PointerMode'
+  }
+  -> `()' checkStatus* #}
+
+-- | Get the pointer mode used by cuSPARSE library functions to pass scalar
+-- arguments.
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparsegetpointermode>
+--
+{-# INLINEABLE getPointerMode #-}
+{# fun unsafe cusparseGetPointerMode as getPointerMode
+  { useHandle `Handle'
+  , alloca-   `PointerMode' peekPM*
+  }
+  -> `()' checkStatus*- #}
+  where
+    peekPM = liftM cToEnum . peek
+
diff --git a/Foreign/CUDA/BLAS/Sparse/Convert.chs b/Foreign/CUDA/BLAS/Sparse/Convert.chs
new file mode 100644
--- /dev/null
+++ b/Foreign/CUDA/BLAS/Sparse/Convert.chs
@@ -0,0 +1,594 @@
+--
+-- This module is auto-generated. Do not edit directly.
+--
+
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds #-}
+-- |
+-- Module      : Foreign.CUDA.BLAS.Sparse.Convert
+-- Copyright   : [2017] Trevor L. McDonell
+-- License     : BSD3
+--
+-- Maintainer  : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+--
+-- For more information see the cuSPARSE function reference:
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparse-format-conversion-reference>
+--
+
+module Foreign.CUDA.BLAS.Sparse.Convert (
+
+  Direction(..),
+  Action(..),
+  Hybrid,
+  HybridPartition(..),
+  Info_csru2csr,
+  sbsr2csr,
+  dbsr2csr,
+  cbsr2csr,
+  zbsr2csr,
+  sgebsr2gebsc_bufferSize,
+  dgebsr2gebsc_bufferSize,
+  cgebsr2gebsc_bufferSize,
+  zgebsr2gebsc_bufferSize,
+  sgebsr2gebsc,
+  dgebsr2gebsc,
+  cgebsr2gebsc,
+  zgebsr2gebsc,
+  sgebsr2gebsr_bufferSize,
+  dgebsr2gebsr_bufferSize,
+  cgebsr2gebsr_bufferSize,
+  zgebsr2gebsr_bufferSize,
+  sgebsr2gebsr,
+  dgebsr2gebsr,
+  cgebsr2gebsr,
+  zgebsr2gebsr,
+  xgebsr2gebsrNnz,
+  sgebsr2csr,
+  dgebsr2csr,
+  cgebsr2csr,
+  zgebsr2csr,
+  scsr2gebsr_bufferSize,
+  dcsr2gebsr_bufferSize,
+  ccsr2gebsr_bufferSize,
+  zcsr2gebsr_bufferSize,
+  scsr2gebsr,
+  dcsr2gebsr,
+  ccsr2gebsr,
+  zcsr2gebsr,
+  xcsr2gebsrNnz,
+  xcoo2csr,
+  scsc2dense,
+  dcsc2dense,
+  ccsc2dense,
+  zcsc2dense,
+  scsc2hyb,
+  dcsc2hyb,
+  ccsc2hyb,
+  zcsc2hyb,
+  scsr2bsr,
+  dcsr2bsr,
+  ccsr2bsr,
+  zcsr2bsr,
+  xcsr2bsrNnz,
+  xcsr2coo,
+  scsr2csc,
+  dcsr2csc,
+  ccsr2csc,
+  zcsr2csc,
+  scsr2dense,
+  dcsr2dense,
+  ccsr2dense,
+  zcsr2dense,
+  scsr2hyb,
+  dcsr2hyb,
+  ccsr2hyb,
+  zcsr2hyb,
+  sdense2csc,
+  ddense2csc,
+  cdense2csc,
+  zdense2csc,
+  sdense2csr,
+  ddense2csr,
+  cdense2csr,
+  zdense2csr,
+  sdense2hyb,
+  ddense2hyb,
+  cdense2hyb,
+  zdense2hyb,
+  shyb2csc,
+  dhyb2csc,
+  chyb2csc,
+  zhyb2csc,
+  shyb2csr,
+  dhyb2csr,
+  chyb2csr,
+  zhyb2csr,
+  shyb2dense,
+  dhyb2dense,
+  chyb2dense,
+  zhyb2dense,
+  snnz,
+  dnnz,
+  cnnz,
+  znnz,
+  createIdentityPermutation,
+  xcoosort_bufferSizeExt,
+  xcoosortByRow,
+  xcoosortByColumn,
+  xcsrsort_bufferSizeExt,
+  xcsrsort,
+  xcscsort_bufferSizeExt,
+  xcscsort,
+  scsru2csr_bufferSizeExt,
+  dcsru2csr_bufferSizeExt,
+  ccsru2csr_bufferSizeExt,
+  zcsru2csr_bufferSizeExt,
+  scsru2csr,
+  dcsru2csr,
+  ccsru2csr,
+  zcsru2csr,
+  scsr2csru,
+  dcsr2csru,
+  ccsr2csru,
+  zcsr2csru,
+  csr2cscEx,
+  scsr2csr_compress,
+  dcsr2csr_compress,
+  ccsr2csr_compress,
+  zcsr2csr_compress,
+
+) where
+
+import Data.Complex
+import Numeric.Half
+import Foreign
+import Foreign.C
+import Foreign.Storable.Complex ()
+import Foreign.CUDA.Ptr
+import Foreign.CUDA.BLAS.Sparse.Analysis
+import Foreign.CUDA.BLAS.Sparse.Context
+import Foreign.CUDA.BLAS.Sparse.Error
+import Foreign.CUDA.BLAS.Sparse.Internal.C2HS
+import Foreign.CUDA.BLAS.Sparse.Internal.Types
+import Foreign.CUDA.BLAS.Sparse.Matrix.Descriptor
+import Foreign.CUDA.BLAS.Sparse.Matrix.Hybrid
+
+#include "cbits/stubs.h"
+{# context lib="cusparse" #}
+
+{-# INLINE useDevP #-}
+useDevP :: DevicePtr a -> Ptr b
+useDevP = useDevicePtr . castDevPtr
+
+{-# INLINE useHostP #-}
+useHostP :: HostPtr a -> Ptr b
+useHostP = useHostPtr . castHostPtr
+
+
+{-# INLINEABLE sbsr2csr #-}
+{# fun unsafe cusparseSbsr2csr as sbsr2csr { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dbsr2csr #-}
+{# fun unsafe cusparseDbsr2csr as dbsr2csr { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cbsr2csr #-}
+{# fun unsafe cusparseCbsr2csr as cbsr2csr { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zbsr2csr #-}
+{# fun unsafe cusparseZbsr2csr as zbsr2csr { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sgebsr2gebsc_bufferSize #-}
+{# fun unsafe cusparseSgebsr2gebsc_bufferSize as sgebsr2gebsc_bufferSize { useHandle `Handle', `Int', `Int', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dgebsr2gebsc_bufferSize #-}
+{# fun unsafe cusparseDgebsr2gebsc_bufferSize as dgebsr2gebsc_bufferSize { useHandle `Handle', `Int', `Int', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cgebsr2gebsc_bufferSize #-}
+{# fun unsafe cusparseCgebsr2gebsc_bufferSize as cgebsr2gebsc_bufferSize { useHandle `Handle', `Int', `Int', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zgebsr2gebsc_bufferSize #-}
+{# fun unsafe cusparseZgebsr2gebsc_bufferSize as zgebsr2gebsc_bufferSize { useHandle `Handle', `Int', `Int', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sgebsr2gebsc #-}
+{# fun unsafe cusparseSgebsr2gebsc as sgebsr2gebsc { useHandle `Handle', `Int', `Int', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', cFromEnum `Action', cFromEnum `IndexBase', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dgebsr2gebsc #-}
+{# fun unsafe cusparseDgebsr2gebsc as dgebsr2gebsc { useHandle `Handle', `Int', `Int', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', cFromEnum `Action', cFromEnum `IndexBase', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cgebsr2gebsc #-}
+{# fun unsafe cusparseCgebsr2gebsc as cgebsr2gebsc { useHandle `Handle', `Int', `Int', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', cFromEnum `Action', cFromEnum `IndexBase', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zgebsr2gebsc #-}
+{# fun unsafe cusparseZgebsr2gebsc as zgebsr2gebsc { useHandle `Handle', `Int', `Int', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', cFromEnum `Action', cFromEnum `IndexBase', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sgebsr2gebsr_bufferSize #-}
+{# fun unsafe cusparseSgebsr2gebsr_bufferSize as sgebsr2gebsr_bufferSize { useHandle `Handle', cFromEnum `Direction', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', `Int', `Int', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dgebsr2gebsr_bufferSize #-}
+{# fun unsafe cusparseDgebsr2gebsr_bufferSize as dgebsr2gebsr_bufferSize { useHandle `Handle', cFromEnum `Direction', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', `Int', `Int', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cgebsr2gebsr_bufferSize #-}
+{# fun unsafe cusparseCgebsr2gebsr_bufferSize as cgebsr2gebsr_bufferSize { useHandle `Handle', cFromEnum `Direction', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', `Int', `Int', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zgebsr2gebsr_bufferSize #-}
+{# fun unsafe cusparseZgebsr2gebsr_bufferSize as zgebsr2gebsr_bufferSize { useHandle `Handle', cFromEnum `Direction', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', `Int', `Int', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sgebsr2gebsr #-}
+{# fun unsafe cusparseSgebsr2gebsr as sgebsr2gebsr { useHandle `Handle', cFromEnum `Direction', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', `Int', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dgebsr2gebsr #-}
+{# fun unsafe cusparseDgebsr2gebsr as dgebsr2gebsr { useHandle `Handle', cFromEnum `Direction', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', `Int', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cgebsr2gebsr #-}
+{# fun unsafe cusparseCgebsr2gebsr as cgebsr2gebsr { useHandle `Handle', cFromEnum `Direction', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', `Int', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zgebsr2gebsr #-}
+{# fun unsafe cusparseZgebsr2gebsr as zgebsr2gebsr { useHandle `Handle', cFromEnum `Direction', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', `Int', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE xgebsr2gebsrNnz #-}
+{# fun unsafe cusparseXgebsr2gebsrNnz as xgebsr2gebsrNnz { useHandle `Handle', cFromEnum `Direction', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Int32', `Int', `Int', castPtr `Ptr Int32', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sgebsr2csr #-}
+{# fun unsafe cusparseSgebsr2csr as sgebsr2csr { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dgebsr2csr #-}
+{# fun unsafe cusparseDgebsr2csr as dgebsr2csr { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cgebsr2csr #-}
+{# fun unsafe cusparseCgebsr2csr as cgebsr2csr { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zgebsr2csr #-}
+{# fun unsafe cusparseZgebsr2csr as zgebsr2csr { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsr2gebsr_bufferSize #-}
+{# fun unsafe cusparseScsr2gebsr_bufferSize as scsr2gebsr_bufferSize { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsr2gebsr_bufferSize #-}
+{# fun unsafe cusparseDcsr2gebsr_bufferSize as dcsr2gebsr_bufferSize { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsr2gebsr_bufferSize #-}
+{# fun unsafe cusparseCcsr2gebsr_bufferSize as ccsr2gebsr_bufferSize { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsr2gebsr_bufferSize #-}
+{# fun unsafe cusparseZcsr2gebsr_bufferSize as zcsr2gebsr_bufferSize { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsr2gebsr #-}
+{# fun unsafe cusparseScsr2gebsr as scsr2gebsr { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', `Int', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsr2gebsr #-}
+{# fun unsafe cusparseDcsr2gebsr as dcsr2gebsr { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', `Int', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsr2gebsr #-}
+{# fun unsafe cusparseCcsr2gebsr as ccsr2gebsr { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', `Int', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsr2gebsr #-}
+{# fun unsafe cusparseZcsr2gebsr as zcsr2gebsr { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', `Int', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE xcsr2gebsrNnz #-}
+{# fun unsafe cusparseXcsr2gebsrNnz as xcsr2gebsrNnz { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Int32', `Int', `Int', castPtr `Ptr Int32', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE xcoo2csr #-}
+{# fun unsafe cusparseXcoo2csr as xcoo2csr { useHandle `Handle', useDevP `DevicePtr Int32', `Int', `Int', useDevP `DevicePtr Int32', cFromEnum `IndexBase' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsc2dense #-}
+{# fun unsafe cusparseScsc2dense as scsc2dense { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Float', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsc2dense #-}
+{# fun unsafe cusparseDcsc2dense as dcsc2dense { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Double', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsc2dense #-}
+{# fun unsafe cusparseCcsc2dense as ccsc2dense { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Float)', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsc2dense #-}
+{# fun unsafe cusparseZcsc2dense as zcsc2dense { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Double)', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsc2hyb #-}
+{# fun unsafe cusparseScsc2hyb as scsc2hyb { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useHYB `Hybrid', `Int', cFromEnum `HybridPartition' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsc2hyb #-}
+{# fun unsafe cusparseDcsc2hyb as dcsc2hyb { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useHYB `Hybrid', `Int', cFromEnum `HybridPartition' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsc2hyb #-}
+{# fun unsafe cusparseCcsc2hyb as ccsc2hyb { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useHYB `Hybrid', `Int', cFromEnum `HybridPartition' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsc2hyb #-}
+{# fun unsafe cusparseZcsc2hyb as zcsc2hyb { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useHYB `Hybrid', `Int', cFromEnum `HybridPartition' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsr2bsr #-}
+{# fun unsafe cusparseScsr2bsr as scsr2bsr { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsr2bsr #-}
+{# fun unsafe cusparseDcsr2bsr as dcsr2bsr { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsr2bsr #-}
+{# fun unsafe cusparseCcsr2bsr as ccsr2bsr { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsr2bsr #-}
+{# fun unsafe cusparseZcsr2bsr as zcsr2bsr { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE xcsr2bsrNnz #-}
+{# fun unsafe cusparseXcsr2bsrNnz as xcsr2bsrNnz { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Int32', castPtr `Ptr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE xcsr2coo #-}
+{# fun unsafe cusparseXcsr2coo as xcsr2coo { useHandle `Handle', useDevP `DevicePtr Int32', `Int', `Int', useDevP `DevicePtr Int32', cFromEnum `IndexBase' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsr2csc #-}
+{# fun unsafe cusparseScsr2csc as scsr2csc { useHandle `Handle', `Int', `Int', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', cFromEnum `Action', cFromEnum `IndexBase' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsr2csc #-}
+{# fun unsafe cusparseDcsr2csc as dcsr2csc { useHandle `Handle', `Int', `Int', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', cFromEnum `Action', cFromEnum `IndexBase' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsr2csc #-}
+{# fun unsafe cusparseCcsr2csc as ccsr2csc { useHandle `Handle', `Int', `Int', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', cFromEnum `Action', cFromEnum `IndexBase' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsr2csc #-}
+{# fun unsafe cusparseZcsr2csc as zcsr2csc { useHandle `Handle', `Int', `Int', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', cFromEnum `Action', cFromEnum `IndexBase' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsr2dense #-}
+{# fun unsafe cusparseScsr2dense as scsr2dense { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Float', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsr2dense #-}
+{# fun unsafe cusparseDcsr2dense as dcsr2dense { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Double', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsr2dense #-}
+{# fun unsafe cusparseCcsr2dense as ccsr2dense { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Float)', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsr2dense #-}
+{# fun unsafe cusparseZcsr2dense as zcsr2dense { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Double)', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsr2hyb #-}
+{# fun unsafe cusparseScsr2hyb as scsr2hyb { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useHYB `Hybrid', `Int', cFromEnum `HybridPartition' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsr2hyb #-}
+{# fun unsafe cusparseDcsr2hyb as dcsr2hyb { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useHYB `Hybrid', `Int', cFromEnum `HybridPartition' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsr2hyb #-}
+{# fun unsafe cusparseCcsr2hyb as ccsr2hyb { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useHYB `Hybrid', `Int', cFromEnum `HybridPartition' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsr2hyb #-}
+{# fun unsafe cusparseZcsr2hyb as zcsr2hyb { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useHYB `Hybrid', `Int', cFromEnum `HybridPartition' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sdense2csc #-}
+{# fun unsafe cusparseSdense2csc as sdense2csc { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ddense2csc #-}
+{# fun unsafe cusparseDdense2csc as ddense2csc { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cdense2csc #-}
+{# fun unsafe cusparseCdense2csc as cdense2csc { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zdense2csc #-}
+{# fun unsafe cusparseZdense2csc as zdense2csc { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sdense2csr #-}
+{# fun unsafe cusparseSdense2csr as sdense2csr { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ddense2csr #-}
+{# fun unsafe cusparseDdense2csr as ddense2csr { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cdense2csr #-}
+{# fun unsafe cusparseCdense2csr as cdense2csr { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zdense2csr #-}
+{# fun unsafe cusparseZdense2csr as zdense2csr { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sdense2hyb #-}
+{# fun unsafe cusparseSdense2hyb as sdense2hyb { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Int32', useHYB `Hybrid', `Int', cFromEnum `HybridPartition' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ddense2hyb #-}
+{# fun unsafe cusparseDdense2hyb as ddense2hyb { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Int32', useHYB `Hybrid', `Int', cFromEnum `HybridPartition' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cdense2hyb #-}
+{# fun unsafe cusparseCdense2hyb as cdense2hyb { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr Int32', useHYB `Hybrid', `Int', cFromEnum `HybridPartition' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zdense2hyb #-}
+{# fun unsafe cusparseZdense2hyb as zdense2hyb { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr Int32', useHYB `Hybrid', `Int', cFromEnum `HybridPartition' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE shyb2csc #-}
+{# fun unsafe cusparseShyb2csc as shyb2csc { useHandle `Handle', useMatDescr `MatrixDescriptor', useHYB `Hybrid', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dhyb2csc #-}
+{# fun unsafe cusparseDhyb2csc as dhyb2csc { useHandle `Handle', useMatDescr `MatrixDescriptor', useHYB `Hybrid', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE chyb2csc #-}
+{# fun unsafe cusparseChyb2csc as chyb2csc { useHandle `Handle', useMatDescr `MatrixDescriptor', useHYB `Hybrid', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zhyb2csc #-}
+{# fun unsafe cusparseZhyb2csc as zhyb2csc { useHandle `Handle', useMatDescr `MatrixDescriptor', useHYB `Hybrid', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE shyb2csr #-}
+{# fun unsafe cusparseShyb2csr as shyb2csr { useHandle `Handle', useMatDescr `MatrixDescriptor', useHYB `Hybrid', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dhyb2csr #-}
+{# fun unsafe cusparseDhyb2csr as dhyb2csr { useHandle `Handle', useMatDescr `MatrixDescriptor', useHYB `Hybrid', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE chyb2csr #-}
+{# fun unsafe cusparseChyb2csr as chyb2csr { useHandle `Handle', useMatDescr `MatrixDescriptor', useHYB `Hybrid', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zhyb2csr #-}
+{# fun unsafe cusparseZhyb2csr as zhyb2csr { useHandle `Handle', useMatDescr `MatrixDescriptor', useHYB `Hybrid', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE shyb2dense #-}
+{# fun unsafe cusparseShyb2dense as shyb2dense { useHandle `Handle', useMatDescr `MatrixDescriptor', useHYB `Hybrid', useDevP `DevicePtr Float', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dhyb2dense #-}
+{# fun unsafe cusparseDhyb2dense as dhyb2dense { useHandle `Handle', useMatDescr `MatrixDescriptor', useHYB `Hybrid', useDevP `DevicePtr Double', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE chyb2dense #-}
+{# fun unsafe cusparseChyb2dense as chyb2dense { useHandle `Handle', useMatDescr `MatrixDescriptor', useHYB `Hybrid', useDevP `DevicePtr (Complex Float)', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zhyb2dense #-}
+{# fun unsafe cusparseZhyb2dense as zhyb2dense { useHandle `Handle', useMatDescr `MatrixDescriptor', useHYB `Hybrid', useDevP `DevicePtr (Complex Double)', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE snnz #-}
+{# fun unsafe cusparseSnnz as snnz { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Int32', castPtr `Ptr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dnnz #-}
+{# fun unsafe cusparseDnnz as dnnz { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Int32', castPtr `Ptr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cnnz #-}
+{# fun unsafe cusparseCnnz as cnnz { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr Int32', castPtr `Ptr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE znnz #-}
+{# fun unsafe cusparseZnnz as znnz { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr Int32', castPtr `Ptr Int32' } -> `()' checkStatus*- #}
+#if CUDA_VERSION >= 7000
+
+{-# INLINEABLE createIdentityPermutation #-}
+{# fun unsafe cusparseCreateIdentityPermutation as createIdentityPermutation { useHandle `Handle', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE xcoosort_bufferSizeExt #-}
+{# fun unsafe cusparseXcoosort_bufferSizeExt as xcoosort_bufferSizeExt { useHandle `Handle', `Int', `Int', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE xcoosortByRow #-}
+{# fun unsafe cusparseXcoosortByRow as xcoosortByRow { useHandle `Handle', `Int', `Int', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE xcoosortByColumn #-}
+{# fun unsafe cusparseXcoosortByColumn as xcoosortByColumn { useHandle `Handle', `Int', `Int', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE xcsrsort_bufferSizeExt #-}
+{# fun unsafe cusparseXcsrsort_bufferSizeExt as xcsrsort_bufferSizeExt { useHandle `Handle', `Int', `Int', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE xcsrsort #-}
+{# fun unsafe cusparseXcsrsort as xcsrsort { useHandle `Handle', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE xcscsort_bufferSizeExt #-}
+{# fun unsafe cusparseXcscsort_bufferSizeExt as xcscsort_bufferSizeExt { useHandle `Handle', `Int', `Int', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE xcscsort #-}
+{# fun unsafe cusparseXcscsort as xcscsort { useHandle `Handle', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsru2csr_bufferSizeExt #-}
+{# fun unsafe cusparseScsru2csr_bufferSizeExt as scsru2csr_bufferSizeExt { useHandle `Handle', `Int', `Int', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csru2csr `Info_csru2csr', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsru2csr_bufferSizeExt #-}
+{# fun unsafe cusparseDcsru2csr_bufferSizeExt as dcsru2csr_bufferSizeExt { useHandle `Handle', `Int', `Int', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csru2csr `Info_csru2csr', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsru2csr_bufferSizeExt #-}
+{# fun unsafe cusparseCcsru2csr_bufferSizeExt as ccsru2csr_bufferSizeExt { useHandle `Handle', `Int', `Int', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csru2csr `Info_csru2csr', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsru2csr_bufferSizeExt #-}
+{# fun unsafe cusparseZcsru2csr_bufferSizeExt as zcsru2csr_bufferSizeExt { useHandle `Handle', `Int', `Int', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csru2csr `Info_csru2csr', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsru2csr #-}
+{# fun unsafe cusparseScsru2csr as scsru2csr { useHandle `Handle', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csru2csr `Info_csru2csr', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsru2csr #-}
+{# fun unsafe cusparseDcsru2csr as dcsru2csr { useHandle `Handle', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csru2csr `Info_csru2csr', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsru2csr #-}
+{# fun unsafe cusparseCcsru2csr as ccsru2csr { useHandle `Handle', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csru2csr `Info_csru2csr', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsru2csr #-}
+{# fun unsafe cusparseZcsru2csr as zcsru2csr { useHandle `Handle', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csru2csr `Info_csru2csr', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsr2csru #-}
+{# fun unsafe cusparseScsr2csru as scsr2csru { useHandle `Handle', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csru2csr `Info_csru2csr', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsr2csru #-}
+{# fun unsafe cusparseDcsr2csru as dcsr2csru { useHandle `Handle', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csru2csr `Info_csru2csr', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsr2csru #-}
+{# fun unsafe cusparseCcsr2csru as ccsr2csru { useHandle `Handle', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csru2csr `Info_csru2csr', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsr2csru #-}
+{# fun unsafe cusparseZcsr2csru as zcsr2csru { useHandle `Handle', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csru2csr `Info_csru2csr', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+#else
+
+createIdentityPermutation :: Handle -> Int -> DevicePtr Int32 -> IO ()
+createIdentityPermutation _ _ _ = cusparseError "'createIdentityPermutation' requires at least cuda-7.0"
+
+xcoosort_bufferSizeExt :: Handle -> Int -> Int -> Int -> DevicePtr Int32 -> DevicePtr Int32 -> Int -> IO ()
+xcoosort_bufferSizeExt _ _ _ _ _ _ _ = cusparseError "'xcoosort_bufferSizeExt' requires at least cuda-7.0"
+
+xcoosortByRow :: Handle -> Int -> Int -> Int -> DevicePtr Int32 -> DevicePtr Int32 -> DevicePtr Int32 -> DevicePtr () -> IO ()
+xcoosortByRow _ _ _ _ _ _ _ _ = cusparseError "'xcoosortByRow' requires at least cuda-7.0"
+
+xcoosortByColumn :: Handle -> Int -> Int -> Int -> DevicePtr Int32 -> DevicePtr Int32 -> DevicePtr Int32 -> DevicePtr () -> IO ()
+xcoosortByColumn _ _ _ _ _ _ _ _ = cusparseError "'xcoosortByColumn' requires at least cuda-7.0"
+
+xcsrsort_bufferSizeExt :: Handle -> Int -> Int -> Int -> DevicePtr Int32 -> DevicePtr Int32 -> Int -> IO ()
+xcsrsort_bufferSizeExt _ _ _ _ _ _ _ = cusparseError "'xcsrsort_bufferSizeExt' requires at least cuda-7.0"
+
+xcsrsort :: Handle -> Int -> Int -> Int -> MatrixDescriptor -> DevicePtr Int32 -> DevicePtr Int32 -> DevicePtr Int32 -> DevicePtr () -> IO ()
+xcsrsort _ _ _ _ _ _ _ _ _ = cusparseError "'xcsrsort' requires at least cuda-7.0"
+
+xcscsort_bufferSizeExt :: Handle -> Int -> Int -> Int -> DevicePtr Int32 -> DevicePtr Int32 -> Int -> IO ()
+xcscsort_bufferSizeExt _ _ _ _ _ _ _ = cusparseError "'xcscsort_bufferSizeExt' requires at least cuda-7.0"
+
+xcscsort :: Handle -> Int -> Int -> Int -> MatrixDescriptor -> DevicePtr Int32 -> DevicePtr Int32 -> DevicePtr Int32 -> DevicePtr () -> IO ()
+xcscsort _ _ _ _ _ _ _ _ _ = cusparseError "'xcscsort' requires at least cuda-7.0"
+
+scsru2csr_bufferSizeExt :: Handle -> Int -> Int -> Int -> DevicePtr Float -> DevicePtr Int32 -> DevicePtr Int32 -> Info_csru2csr -> Int -> IO ()
+scsru2csr_bufferSizeExt _ _ _ _ _ _ _ _ _ = cusparseError "'scsru2csr_bufferSizeExt' requires at least cuda-7.0"
+
+dcsru2csr_bufferSizeExt :: Handle -> Int -> Int -> Int -> DevicePtr Double -> DevicePtr Int32 -> DevicePtr Int32 -> Info_csru2csr -> Int -> IO ()
+dcsru2csr_bufferSizeExt _ _ _ _ _ _ _ _ _ = cusparseError "'dcsru2csr_bufferSizeExt' requires at least cuda-7.0"
+
+ccsru2csr_bufferSizeExt :: Handle -> Int -> Int -> Int -> DevicePtr (Complex Float) -> DevicePtr Int32 -> DevicePtr Int32 -> Info_csru2csr -> Int -> IO ()
+ccsru2csr_bufferSizeExt _ _ _ _ _ _ _ _ _ = cusparseError "'ccsru2csr_bufferSizeExt' requires at least cuda-7.0"
+
+zcsru2csr_bufferSizeExt :: Handle -> Int -> Int -> Int -> DevicePtr (Complex Double) -> DevicePtr Int32 -> DevicePtr Int32 -> Info_csru2csr -> Int -> IO ()
+zcsru2csr_bufferSizeExt _ _ _ _ _ _ _ _ _ = cusparseError "'zcsru2csr_bufferSizeExt' requires at least cuda-7.0"
+
+scsru2csr :: Handle -> Int -> Int -> Int -> MatrixDescriptor -> DevicePtr Float -> DevicePtr Int32 -> DevicePtr Int32 -> Info_csru2csr -> DevicePtr () -> IO ()
+scsru2csr _ _ _ _ _ _ _ _ _ _ = cusparseError "'scsru2csr' requires at least cuda-7.0"
+
+dcsru2csr :: Handle -> Int -> Int -> Int -> MatrixDescriptor -> DevicePtr Double -> DevicePtr Int32 -> DevicePtr Int32 -> Info_csru2csr -> DevicePtr () -> IO ()
+dcsru2csr _ _ _ _ _ _ _ _ _ _ = cusparseError "'dcsru2csr' requires at least cuda-7.0"
+
+ccsru2csr :: Handle -> Int -> Int -> Int -> MatrixDescriptor -> DevicePtr (Complex Float) -> DevicePtr Int32 -> DevicePtr Int32 -> Info_csru2csr -> DevicePtr () -> IO ()
+ccsru2csr _ _ _ _ _ _ _ _ _ _ = cusparseError "'ccsru2csr' requires at least cuda-7.0"
+
+zcsru2csr :: Handle -> Int -> Int -> Int -> MatrixDescriptor -> DevicePtr (Complex Double) -> DevicePtr Int32 -> DevicePtr Int32 -> Info_csru2csr -> DevicePtr () -> IO ()
+zcsru2csr _ _ _ _ _ _ _ _ _ _ = cusparseError "'zcsru2csr' requires at least cuda-7.0"
+
+scsr2csru :: Handle -> Int -> Int -> Int -> MatrixDescriptor -> DevicePtr Float -> DevicePtr Int32 -> DevicePtr Int32 -> Info_csru2csr -> DevicePtr () -> IO ()
+scsr2csru _ _ _ _ _ _ _ _ _ _ = cusparseError "'scsr2csru' requires at least cuda-7.0"
+
+dcsr2csru :: Handle -> Int -> Int -> Int -> MatrixDescriptor -> DevicePtr Double -> DevicePtr Int32 -> DevicePtr Int32 -> Info_csru2csr -> DevicePtr () -> IO ()
+dcsr2csru _ _ _ _ _ _ _ _ _ _ = cusparseError "'dcsr2csru' requires at least cuda-7.0"
+
+ccsr2csru :: Handle -> Int -> Int -> Int -> MatrixDescriptor -> DevicePtr (Complex Float) -> DevicePtr Int32 -> DevicePtr Int32 -> Info_csru2csr -> DevicePtr () -> IO ()
+ccsr2csru _ _ _ _ _ _ _ _ _ _ = cusparseError "'ccsr2csru' requires at least cuda-7.0"
+
+zcsr2csru :: Handle -> Int -> Int -> Int -> MatrixDescriptor -> DevicePtr (Complex Double) -> DevicePtr Int32 -> DevicePtr Int32 -> Info_csru2csr -> DevicePtr () -> IO ()
+zcsr2csru _ _ _ _ _ _ _ _ _ _ = cusparseError "'zcsr2csru' requires at least cuda-7.0"
+#endif
+#if CUDA_VERSION >= 8000
+
+{-# INLINEABLE csr2cscEx #-}
+{# fun unsafe cusparseCsr2cscEx as csr2cscEx { useHandle `Handle', `Int', `Int', `Int', useDevP `DevicePtr ()', cFromEnum `Type', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr ()', cFromEnum `Type', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', cFromEnum `Action', cFromEnum `IndexBase', cFromEnum `Type' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsr2csr_compress #-}
+{# fun unsafe cusparseScsr2csr_compress as scsr2csr_compress { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', CFloat `Float' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsr2csr_compress #-}
+{# fun unsafe cusparseDcsr2csr_compress as dcsr2csr_compress { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', CDouble `Double' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsr2csr_compress #-}
+{# fun unsafe cusparseCcsr2csr_compress as ccsr2csr_compress { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', withComplex* `(Complex Float)' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsr2csr_compress #-}
+{# fun unsafe cusparseZcsr2csr_compress as zcsr2csr_compress { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', withComplex* `(Complex Double)' } -> `()' checkStatus*- #}
+#else
+
+csr2cscEx :: Handle -> Int -> Int -> Int -> DevicePtr () -> Type -> DevicePtr Int32 -> DevicePtr Int32 -> DevicePtr () -> Type -> DevicePtr Int32 -> DevicePtr Int32 -> Action -> IndexBase -> Type -> IO ()
+csr2cscEx _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ = cusparseError "'csr2cscEx' requires at least cuda-8.0"
+
+scsr2csr_compress :: Handle -> Int -> Int -> MatrixDescriptor -> DevicePtr Float -> DevicePtr Int32 -> DevicePtr Int32 -> Int -> DevicePtr Int32 -> DevicePtr Float -> DevicePtr Int32 -> DevicePtr Int32 -> Float -> IO ()
+scsr2csr_compress _ _ _ _ _ _ _ _ _ _ _ _ _ = cusparseError "'scsr2csr_compress' requires at least cuda-8.0"
+
+dcsr2csr_compress :: Handle -> Int -> Int -> MatrixDescriptor -> DevicePtr Double -> DevicePtr Int32 -> DevicePtr Int32 -> Int -> DevicePtr Int32 -> DevicePtr Double -> DevicePtr Int32 -> DevicePtr Int32 -> Double -> IO ()
+dcsr2csr_compress _ _ _ _ _ _ _ _ _ _ _ _ _ = cusparseError "'dcsr2csr_compress' requires at least cuda-8.0"
+
+ccsr2csr_compress :: Handle -> Int -> Int -> MatrixDescriptor -> DevicePtr (Complex Float) -> DevicePtr Int32 -> DevicePtr Int32 -> Int -> DevicePtr Int32 -> DevicePtr (Complex Float) -> DevicePtr Int32 -> DevicePtr Int32 -> (Complex Float) -> IO ()
+ccsr2csr_compress _ _ _ _ _ _ _ _ _ _ _ _ _ = cusparseError "'ccsr2csr_compress' requires at least cuda-8.0"
+
+zcsr2csr_compress :: Handle -> Int -> Int -> MatrixDescriptor -> DevicePtr (Complex Double) -> DevicePtr Int32 -> DevicePtr Int32 -> Int -> DevicePtr Int32 -> DevicePtr (Complex Double) -> DevicePtr Int32 -> DevicePtr Int32 -> (Complex Double) -> IO ()
+zcsr2csr_compress _ _ _ _ _ _ _ _ _ _ _ _ _ = cusparseError "'zcsr2csr_compress' requires at least cuda-8.0"
+#endif
diff --git a/Foreign/CUDA/BLAS/Sparse/Error.chs b/Foreign/CUDA/BLAS/Sparse/Error.chs
new file mode 100644
--- /dev/null
+++ b/Foreign/CUDA/BLAS/Sparse/Error.chs
@@ -0,0 +1,98 @@
+{-# LANGUAGE CPP                      #-}
+{-# LANGUAGE DeriveDataTypeable       #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+-- |
+-- Module      : Foreign.CUDA.BLAS.Sparse.Error
+-- Copyright   : [2017] Trevor L. McDonell
+-- License     : BSD3
+--
+-- Maintainer  : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+--
+
+module Foreign.CUDA.BLAS.Sparse.Error
+  where
+
+-- friends
+import Foreign.CUDA.BLAS.Sparse.Internal.C2HS
+
+-- system
+import Control.Exception
+import Data.Typeable
+import Foreign.C.Types
+
+#include "cbits/stubs.h"
+{# context lib="cusparse" #}
+
+
+-- | Error codes used by cuSPARSE library functions
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparsestatust>
+--
+{# enum cusparseStatus_t as Status
+  { underscoreToCase }
+  with prefix="CUSPARSE_STATUS" deriving (Eq, Show) #}
+
+-- Describe each error code
+--
+describe :: Status -> String
+describe Success                = "success"
+describe NotInitialized         = "library not initialised"
+describe AllocFailed            = "resource allocation failed"
+describe InvalidValue           = "unsupported value or parameter passed to a function"
+describe ArchMismatch           = "unsupported on current architecture"
+describe MappingError           = "access to GPU memory failed"
+describe ExecutionFailed        = "execution failed"
+describe InternalError          = "internal error"
+describe MatrixTypeNotSupported = "matrix type not supported for this function"
+describe ZeroPivot              = "zero pivot"
+
+
+-- Exceptions ------------------------------------------------------------------
+--
+data CUSparseException
+  = ExitCode  Status
+  | UserError String
+  deriving Typeable
+
+instance Exception CUSparseException
+
+instance Show CUSparseException where
+  showsPrec _ (ExitCode  s) = showString ("CUSparse Exception: " ++ describe s)
+  showsPrec _ (UserError s) = showString ("CUSparse Exception: " ++ s)
+
+
+-- | Raise a CUSparseException in the IO Monad
+--
+cusparseError :: String -> IO a
+cusparseError s = throwIO (UserError s)
+
+
+-- | 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 :: (Status, a) -> IO a
+resultIfOk (status,result) =
+    case status of
+        Success -> return  result
+        _       -> throwIO (ExitCode status)
+
+
+-- | Throw an exception with an error string associated with an unsuccessful
+-- return code, otherwise return unit.
+--
+{-# INLINE nothingIfOk #-}
+nothingIfOk :: Status -> IO ()
+nothingIfOk status =
+    case status of
+        Success -> return  ()
+        _       -> throwIO (ExitCode status)
+
+-- | Throw an error if given error code is not CUSPARSE_STATUS_SUCCESS
+--
+{-# INLINE checkStatus #-}
+checkStatus :: CInt -> IO ()
+checkStatus = nothingIfOk . cToEnum
+
diff --git a/Foreign/CUDA/BLAS/Sparse/Internal/C2HS.hs b/Foreign/CUDA/BLAS/Sparse/Internal/C2HS.hs
new file mode 100644
--- /dev/null
+++ b/Foreign/CUDA/BLAS/Sparse/Internal/C2HS.hs
@@ -0,0 +1,93 @@
+-- |
+-- Module      : Foreign.CUDA.BLAS.Sparse.Internal.C2HS
+-- Copyright   : [2017] Trevor L. McDonell
+-- License     : BSD3
+--
+-- Maintainer  : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+--
+
+module Foreign.CUDA.BLAS.Sparse.Internal.C2HS (
+
+  -- * Conversion between C and Haskell types
+  cIntConv, cFloatConv, cToBool, cFromBool, cToEnum, cFromEnum,
+
+  -- * Composite marshalling functions
+  withComplex,
+  peekIntConv, peekFloatConv,
+
+) where
+
+-- system
+import Control.Monad                                      ( liftM )
+import Data.Complex
+import Foreign
+import Foreign.C
+import Foreign.Storable.Complex ()
+
+
+-- Conversions -----------------------------------------------------------------
+--
+
+-- | Integral conversion
+--
+{-# INLINE cIntConv #-}
+cIntConv :: (Integral a, Integral b) => a -> b
+cIntConv  = fromIntegral
+
+-- | Floating conversion
+--
+{-# 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...
+{-# RULES
+  "cFloatConv/Float->Float"    forall (x::Float).  cFloatConv x = x;
+  "cFloatConv/Double->Double"  forall (x::Double). cFloatConv x = x;
+  "cFloatConv/Float->CFloat"   forall (x::Float).  cFloatConv x = CFloat x;
+  "cFloatConv/CFloat->Float"   forall (x::Float).  cFloatConv CFloat x = x;
+  "cFloatConv/Double->CDouble" forall (x::Double). cFloatConv x = CDouble x;
+  "cFloatConv/CDouble->Double" forall (x::Double). cFloatConv CDouble x = x
+ #-}
+
+-- | Obtain C value from Haskell 'Bool'.
+--
+{-# INLINE cFromBool #-}
+cFromBool :: Num a => Bool -> a
+cFromBool  = fromBool
+
+-- | Obtain Haskell 'Bool' from C value.
+--
+{-# INLINE cToBool #-}
+cToBool :: (Eq a, Num a) => a -> Bool
+cToBool  = toBool
+
+-- | Convert a C enumeration to Haskell.
+--
+{-# INLINE cToEnum #-}
+cToEnum :: (Integral i, Enum e) => i -> e
+cToEnum  = toEnum . cIntConv
+
+-- | Convert a Haskell enumeration to C.
+--
+{-# INLINE cFromEnum #-}
+cFromEnum :: (Enum e, Integral i) => e -> i
+cFromEnum  = cIntConv . fromEnum
+
+-- | Marshalling of complex numbers
+--
+{-# INLINE withComplex #-}
+withComplex :: Storable a => Complex a -> (Ptr () -> IO b) -> IO b
+withComplex c f = with c (f . castPtr)
+
+-- | Marshalling of numerals
+--
+{-# INLINE peekIntConv #-}
+peekIntConv :: (Storable a, Integral a, Integral b) => Ptr a -> IO b
+peekIntConv = liftM cIntConv . peek
+
+{-# INLINE peekFloatConv #-}
+peekFloatConv :: (Storable a, RealFloat a, RealFloat b) => Ptr a -> IO b
+peekFloatConv = liftM cFloatConv . peek
+
diff --git a/Foreign/CUDA/BLAS/Sparse/Internal/Types.chs b/Foreign/CUDA/BLAS/Sparse/Internal/Types.chs
new file mode 100644
--- /dev/null
+++ b/Foreign/CUDA/BLAS/Sparse/Internal/Types.chs
@@ -0,0 +1,87 @@
+{-# LANGUAGE CPP                      #-}
+{-# LANGUAGE EmptyDataDecls           #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+-- |
+-- Module      : Foreign.CUDA.BLAS.Sparse.Internal.Types
+-- Copyright   : [2017] Trevor L. McDonell
+-- License     : BSD3
+--
+-- Maintainer  : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+--
+
+module Foreign.CUDA.BLAS.Sparse.Internal.Types
+  where
+
+-- other
+import Prelude                                            hiding ( Either(..) )
+import Foreign.Ptr
+
+#include "cbits/stubs.h"
+{# context lib="cusparse" #}
+
+
+-- | This type indicates whether the operation is performed only on indices
+-- ('Symbolic') or on data and indices ('Numeric').
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparseactiont>
+--
+{# enum cusparseAction_t as Action
+  { underscoreToCase }
+  with prefix="CUSPARSE_ACTION" deriving (Eq, Show) #}
+
+-- | Indicates the underlying storage model for elements of matrices.
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparsedirectiont>
+--
+{# enum cusparseDirection_t as Direction
+  { underscoreToCase }
+  with prefix="CUSPARSE_DIRECTION" deriving (Eq, Show) #}
+
+-- | Indicates which operations need to be performed with the sparse matrix.
+--
+--   * @N@: no transpose selected
+--   * @T@: transpose operation
+--   * @C@: conjugate transpose
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparseoperationt>
+--
+{# enum cusparseOperation_t as Operation
+  { CUSPARSE_OPERATION_NON_TRANSPOSE       as N
+  , CUSPARSE_OPERATION_TRANSPOSE           as T
+  , CUSPARSE_OPERATION_CONJUGATE_TRANSPOSE as C
+  }
+  deriving (Eq, Show) #}
+
+-- | Used to specify the type of data underlying a @void*@ pointer. For example,
+-- it is used in the routine <http://docs.nvidia.com/cuda/cusparse/index.html#cusparse-csrmvEx csrmvEx>.
+--
+#if CUDA_VERSION < 8000
+data Type
+#else
+{# enum cudaDataType_t as Type
+  { underscoreToCase }
+  with prefix="CUDA" deriving (Eq, Show) #}
+#endif
+
+
+-- | Specify the algorithm to use, for example used in the routine
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparse-csrmvEx csrmvEx>.
+--
+#if CUDA_VERSION < 8000
+data Algorithm
+#else
+{# enum cusparseAlgMode_t as Algorithm
+  { underscoreToCase }
+  with prefix="CUSPARSE" deriving (Eq, Show) #}
+#endif
+
+-- | Indicates whether level information is used by some solver algorithms.
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparsesolvepolicy_t>
+--
+{# enum cusparseSolvePolicy_t as Policy
+  { underscoreToCase }
+  with prefix="CUSPARSE_SOLVE_POLICY" deriving (Eq, Show) #}
+
diff --git a/Foreign/CUDA/BLAS/Sparse/Level1.chs b/Foreign/CUDA/BLAS/Sparse/Level1.chs
new file mode 100644
--- /dev/null
+++ b/Foreign/CUDA/BLAS/Sparse/Level1.chs
@@ -0,0 +1,149 @@
+--
+-- This module is auto-generated. Do not edit directly.
+--
+
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds #-}
+-- |
+-- Module      : Foreign.CUDA.BLAS.Sparse.Level1
+-- Copyright   : [2017] Trevor L. McDonell
+-- License     : BSD3
+--
+-- Maintainer  : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+--
+-- For more information see the cuSPARSE Level-1 function reference:
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparse-level-1-function-reference>
+--
+
+module Foreign.CUDA.BLAS.Sparse.Level1 (
+
+  IndexBase(..),
+  saxpyi,
+  daxpyi,
+  caxpyi,
+  zaxpyi,
+  sdoti,
+  ddoti,
+  cdoti,
+  zdoti,
+  cdotci,
+  zdotci,
+  sgthr,
+  dgthr,
+  cgthr,
+  zgthr,
+  sgthrz,
+  dgthrz,
+  cgthrz,
+  zgthrz,
+  sroti,
+  droti,
+  ssctr,
+  dsctr,
+  csctr,
+  zsctr,
+
+) where
+
+import Data.Complex
+import Numeric.Half
+import Foreign
+import Foreign.C
+import Foreign.Storable.Complex ()
+import Foreign.CUDA.Ptr
+import Foreign.CUDA.BLAS.Sparse.Analysis
+import Foreign.CUDA.BLAS.Sparse.Context
+import Foreign.CUDA.BLAS.Sparse.Error
+import Foreign.CUDA.BLAS.Sparse.Internal.C2HS
+import Foreign.CUDA.BLAS.Sparse.Internal.Types
+import Foreign.CUDA.BLAS.Sparse.Matrix.Descriptor
+import Foreign.CUDA.BLAS.Sparse.Matrix.Hybrid
+
+#include "cbits/stubs.h"
+{# context lib="cusparse" #}
+
+{-# INLINE useDevP #-}
+useDevP :: DevicePtr a -> Ptr b
+useDevP = useDevicePtr . castDevPtr
+
+{-# INLINE useHostP #-}
+useHostP :: HostPtr a -> Ptr b
+useHostP = useHostPtr . castHostPtr
+
+
+{-# INLINEABLE saxpyi #-}
+{# fun unsafe cusparseSaxpyi as saxpyi { useHandle `Handle', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', castPtr `Ptr Float', cFromEnum `IndexBase' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE daxpyi #-}
+{# fun unsafe cusparseDaxpyi as daxpyi { useHandle `Handle', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', castPtr `Ptr Double', cFromEnum `IndexBase' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE caxpyi #-}
+{# fun unsafe cusparseCaxpyi as caxpyi { useHandle `Handle', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', castPtr `Ptr (Complex Float)', cFromEnum `IndexBase' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zaxpyi #-}
+{# fun unsafe cusparseZaxpyi as zaxpyi { useHandle `Handle', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', castPtr `Ptr (Complex Double)', cFromEnum `IndexBase' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sdoti #-}
+{# fun unsafe cusparseSdoti as sdoti { useHandle `Handle', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Float', castPtr `Ptr Float', cFromEnum `IndexBase' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ddoti #-}
+{# fun unsafe cusparseDdoti as ddoti { useHandle `Handle', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Double', castPtr `Ptr Double', cFromEnum `IndexBase' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cdoti #-}
+{# fun unsafe cusparseCdoti as cdoti { useHandle `Handle', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Float)', castPtr `Ptr (Complex Float)', cFromEnum `IndexBase' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zdoti #-}
+{# fun unsafe cusparseZdoti as zdoti { useHandle `Handle', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Double)', castPtr `Ptr (Complex Double)', cFromEnum `IndexBase' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cdotci #-}
+{# fun unsafe cusparseCdotci as cdotci { useHandle `Handle', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Float)', castPtr `Ptr (Complex Float)', cFromEnum `IndexBase' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zdotci #-}
+{# fun unsafe cusparseZdotci as zdotci { useHandle `Handle', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Double)', castPtr `Ptr (Complex Double)', cFromEnum `IndexBase' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sgthr #-}
+{# fun unsafe cusparseSgthr as sgthr { useHandle `Handle', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', cFromEnum `IndexBase' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dgthr #-}
+{# fun unsafe cusparseDgthr as dgthr { useHandle `Handle', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', cFromEnum `IndexBase' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cgthr #-}
+{# fun unsafe cusparseCgthr as cgthr { useHandle `Handle', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', cFromEnum `IndexBase' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zgthr #-}
+{# fun unsafe cusparseZgthr as zgthr { useHandle `Handle', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', cFromEnum `IndexBase' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sgthrz #-}
+{# fun unsafe cusparseSgthrz as sgthrz { useHandle `Handle', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', cFromEnum `IndexBase' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dgthrz #-}
+{# fun unsafe cusparseDgthrz as dgthrz { useHandle `Handle', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', cFromEnum `IndexBase' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cgthrz #-}
+{# fun unsafe cusparseCgthrz as cgthrz { useHandle `Handle', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', cFromEnum `IndexBase' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zgthrz #-}
+{# fun unsafe cusparseZgthrz as zgthrz { useHandle `Handle', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', cFromEnum `IndexBase' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sroti #-}
+{# fun unsafe cusparseSroti as sroti { useHandle `Handle', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Float', castPtr `Ptr Float', castPtr `Ptr Float', cFromEnum `IndexBase' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE droti #-}
+{# fun unsafe cusparseDroti as droti { useHandle `Handle', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Double', castPtr `Ptr Double', castPtr `Ptr Double', cFromEnum `IndexBase' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ssctr #-}
+{# fun unsafe cusparseSsctr as ssctr { useHandle `Handle', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Float', cFromEnum `IndexBase' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dsctr #-}
+{# fun unsafe cusparseDsctr as dsctr { useHandle `Handle', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Double', cFromEnum `IndexBase' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE csctr #-}
+{# fun unsafe cusparseCsctr as csctr { useHandle `Handle', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Float)', cFromEnum `IndexBase' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zsctr #-}
+{# fun unsafe cusparseZsctr as zsctr { useHandle `Handle', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Double)', cFromEnum `IndexBase' } -> `()' checkStatus*- #}
diff --git a/Foreign/CUDA/BLAS/Sparse/Level2.chs b/Foreign/CUDA/BLAS/Sparse/Level2.chs
new file mode 100644
--- /dev/null
+++ b/Foreign/CUDA/BLAS/Sparse/Level2.chs
@@ -0,0 +1,412 @@
+--
+-- This module is auto-generated. Do not edit directly.
+--
+
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds #-}
+-- |
+-- Module      : Foreign.CUDA.BLAS.Sparse.Level2
+-- Copyright   : [2017] Trevor L. McDonell
+-- License     : BSD3
+--
+-- Maintainer  : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+--
+-- For more information see the cuSPARSE Level-2 function reference:
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparse-level-2-function-reference>
+--
+
+module Foreign.CUDA.BLAS.Sparse.Level2 (
+
+  Operation(..),
+  Direction(..),
+  Type(..),
+  Algorithm(..),
+  Policy(..),
+  MatrixDescriptor,
+  Hybrid,
+  Info,
+  Info_bsrsv2,
+  Info_csrsv2,
+  sbsrmv,
+  dbsrmv,
+  cbsrmv,
+  zbsrmv,
+  sbsrxmv,
+  dbsrxmv,
+  cbsrxmv,
+  zbsrxmv,
+  scsrmv,
+  dcsrmv,
+  ccsrmv,
+  zcsrmv,
+  sbsrsv2_bufferSize,
+  dbsrsv2_bufferSize,
+  cbsrsv2_bufferSize,
+  zbsrsv2_bufferSize,
+  sbsrsv2_analysis,
+  dbsrsv2_analysis,
+  cbsrsv2_analysis,
+  zbsrsv2_analysis,
+  sbsrsv2_solve,
+  dbsrsv2_solve,
+  cbsrsv2_solve,
+  zbsrsv2_solve,
+  xbsrsv2_zeroPivot,
+  scsrsv_analysis,
+  dcsrsv_analysis,
+  ccsrsv_analysis,
+  zcsrsv_analysis,
+  scsrsv_solve,
+  dcsrsv_solve,
+  ccsrsv_solve,
+  zcsrsv_solve,
+  scsrsv2_bufferSize,
+  dcsrsv2_bufferSize,
+  ccsrsv2_bufferSize,
+  zcsrsv2_bufferSize,
+  scsrsv2_analysis,
+  dcsrsv2_analysis,
+  ccsrsv2_analysis,
+  zcsrsv2_analysis,
+  scsrsv2_solve,
+  dcsrsv2_solve,
+  ccsrsv2_solve,
+  zcsrsv2_solve,
+  xcsrsv2_zeroPivot,
+  shybmv,
+  dhybmv,
+  chybmv,
+  zhybmv,
+  shybsv_analysis,
+  dhybsv_analysis,
+  chybsv_analysis,
+  zhybsv_analysis,
+  shybsv_solve,
+  dhybsv_solve,
+  chybsv_solve,
+  zhybsv_solve,
+  sgemvi,
+  dgemvi,
+  cgemvi,
+  zgemvi,
+  sgemvi_bufferSize,
+  dgemvi_bufferSize,
+  cgemvi_bufferSize,
+  zgemvi_bufferSize,
+  csrmvEx,
+  csrmvEx_bufferSize,
+  scsrmv_mp,
+  dcsrmv_mp,
+  ccsrmv_mp,
+  zcsrmv_mp,
+  csrsv_analysisEx,
+  csrsv_solveEx,
+
+) where
+
+import Data.Complex
+import Numeric.Half
+import Foreign
+import Foreign.C
+import Foreign.Storable.Complex ()
+import Foreign.CUDA.Ptr
+import Foreign.CUDA.BLAS.Sparse.Analysis
+import Foreign.CUDA.BLAS.Sparse.Context
+import Foreign.CUDA.BLAS.Sparse.Error
+import Foreign.CUDA.BLAS.Sparse.Internal.C2HS
+import Foreign.CUDA.BLAS.Sparse.Internal.Types
+import Foreign.CUDA.BLAS.Sparse.Matrix.Descriptor
+import Foreign.CUDA.BLAS.Sparse.Matrix.Hybrid
+
+#include "cbits/stubs.h"
+{# context lib="cusparse" #}
+
+{-# INLINE useDevP #-}
+useDevP :: DevicePtr a -> Ptr b
+useDevP = useDevicePtr . castDevPtr
+
+{-# INLINE useHostP #-}
+useHostP :: HostPtr a -> Ptr b
+useHostP = useHostPtr . castHostPtr
+
+
+{-# INLINEABLE sbsrmv #-}
+{# fun unsafe cusparseSbsrmv as sbsrmv { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', `Int', `Int', `Int', castPtr `Ptr Float', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useDevP `DevicePtr Float', castPtr `Ptr Float', useDevP `DevicePtr Float' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dbsrmv #-}
+{# fun unsafe cusparseDbsrmv as dbsrmv { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', `Int', `Int', `Int', castPtr `Ptr Double', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useDevP `DevicePtr Double', castPtr `Ptr Double', useDevP `DevicePtr Double' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cbsrmv #-}
+{# fun unsafe cusparseCbsrmv as cbsrmv { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', `Int', `Int', `Int', castPtr `Ptr (Complex Float)', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useDevP `DevicePtr (Complex Float)', castPtr `Ptr (Complex Float)', useDevP `DevicePtr (Complex Float)' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zbsrmv #-}
+{# fun unsafe cusparseZbsrmv as zbsrmv { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', `Int', `Int', `Int', castPtr `Ptr (Complex Double)', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useDevP `DevicePtr (Complex Double)', castPtr `Ptr (Complex Double)', useDevP `DevicePtr (Complex Double)' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sbsrxmv #-}
+{# fun unsafe cusparseSbsrxmv as sbsrxmv { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', `Int', `Int', `Int', `Int', castPtr `Ptr Float', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useDevP `DevicePtr Float', castPtr `Ptr Float', useDevP `DevicePtr Float' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dbsrxmv #-}
+{# fun unsafe cusparseDbsrxmv as dbsrxmv { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', `Int', `Int', `Int', `Int', castPtr `Ptr Double', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useDevP `DevicePtr Double', castPtr `Ptr Double', useDevP `DevicePtr Double' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cbsrxmv #-}
+{# fun unsafe cusparseCbsrxmv as cbsrxmv { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', `Int', `Int', `Int', `Int', castPtr `Ptr (Complex Float)', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useDevP `DevicePtr (Complex Float)', castPtr `Ptr (Complex Float)', useDevP `DevicePtr (Complex Float)' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zbsrxmv #-}
+{# fun unsafe cusparseZbsrxmv as zbsrxmv { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', `Int', `Int', `Int', `Int', castPtr `Ptr (Complex Double)', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useDevP `DevicePtr (Complex Double)', castPtr `Ptr (Complex Double)', useDevP `DevicePtr (Complex Double)' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsrmv #-}
+{# fun unsafe cusparseScsrmv as scsrmv { useHandle `Handle', cFromEnum `Operation', `Int', `Int', `Int', castPtr `Ptr Float', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Float', castPtr `Ptr Float', useDevP `DevicePtr Float' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsrmv #-}
+{# fun unsafe cusparseDcsrmv as dcsrmv { useHandle `Handle', cFromEnum `Operation', `Int', `Int', `Int', castPtr `Ptr Double', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Double', castPtr `Ptr Double', useDevP `DevicePtr Double' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsrmv #-}
+{# fun unsafe cusparseCcsrmv as ccsrmv { useHandle `Handle', cFromEnum `Operation', `Int', `Int', `Int', castPtr `Ptr (Complex Float)', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Float)', castPtr `Ptr (Complex Float)', useDevP `DevicePtr (Complex Float)' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsrmv #-}
+{# fun unsafe cusparseZcsrmv as zcsrmv { useHandle `Handle', cFromEnum `Operation', `Int', `Int', `Int', castPtr `Ptr (Complex Double)', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Double)', castPtr `Ptr (Complex Double)', useDevP `DevicePtr (Complex Double)' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sbsrsv2_bufferSize #-}
+{# fun unsafe cusparseSbsrsv2_bufferSize as sbsrsv2_bufferSize { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrsv2 `Info_bsrsv2', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dbsrsv2_bufferSize #-}
+{# fun unsafe cusparseDbsrsv2_bufferSize as dbsrsv2_bufferSize { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrsv2 `Info_bsrsv2', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cbsrsv2_bufferSize #-}
+{# fun unsafe cusparseCbsrsv2_bufferSize as cbsrsv2_bufferSize { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrsv2 `Info_bsrsv2', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zbsrsv2_bufferSize #-}
+{# fun unsafe cusparseZbsrsv2_bufferSize as zbsrsv2_bufferSize { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrsv2 `Info_bsrsv2', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sbsrsv2_analysis #-}
+{# fun unsafe cusparseSbsrsv2_analysis as sbsrsv2_analysis { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrsv2 `Info_bsrsv2', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dbsrsv2_analysis #-}
+{# fun unsafe cusparseDbsrsv2_analysis as dbsrsv2_analysis { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrsv2 `Info_bsrsv2', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cbsrsv2_analysis #-}
+{# fun unsafe cusparseCbsrsv2_analysis as cbsrsv2_analysis { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrsv2 `Info_bsrsv2', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zbsrsv2_analysis #-}
+{# fun unsafe cusparseZbsrsv2_analysis as zbsrsv2_analysis { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrsv2 `Info_bsrsv2', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sbsrsv2_solve #-}
+{# fun unsafe cusparseSbsrsv2_solve as sbsrsv2_solve { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', `Int', `Int', castPtr `Ptr Float', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrsv2 `Info_bsrsv2', useDevP `DevicePtr Float', useDevP `DevicePtr Float', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dbsrsv2_solve #-}
+{# fun unsafe cusparseDbsrsv2_solve as dbsrsv2_solve { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', `Int', `Int', castPtr `Ptr Double', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrsv2 `Info_bsrsv2', useDevP `DevicePtr Double', useDevP `DevicePtr Double', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cbsrsv2_solve #-}
+{# fun unsafe cusparseCbsrsv2_solve as cbsrsv2_solve { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', `Int', `Int', castPtr `Ptr (Complex Float)', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrsv2 `Info_bsrsv2', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zbsrsv2_solve #-}
+{# fun unsafe cusparseZbsrsv2_solve as zbsrsv2_solve { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', `Int', `Int', castPtr `Ptr (Complex Double)', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrsv2 `Info_bsrsv2', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE xbsrsv2_zeroPivot #-}
+{# fun unsafe cusparseXbsrsv2_zeroPivot as xbsrsv2_zeroPivot { useHandle `Handle', useInfo_bsrsv2 `Info_bsrsv2', castPtr `Ptr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsrsv_analysis #-}
+{# fun unsafe cusparseScsrsv_analysis as scsrsv_analysis { useHandle `Handle', cFromEnum `Operation', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo `Info' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsrsv_analysis #-}
+{# fun unsafe cusparseDcsrsv_analysis as dcsrsv_analysis { useHandle `Handle', cFromEnum `Operation', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo `Info' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsrsv_analysis #-}
+{# fun unsafe cusparseCcsrsv_analysis as ccsrsv_analysis { useHandle `Handle', cFromEnum `Operation', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo `Info' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsrsv_analysis #-}
+{# fun unsafe cusparseZcsrsv_analysis as zcsrsv_analysis { useHandle `Handle', cFromEnum `Operation', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo `Info' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsrsv_solve #-}
+{# fun unsafe cusparseScsrsv_solve as scsrsv_solve { useHandle `Handle', cFromEnum `Operation', `Int', castPtr `Ptr Float', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo `Info', useDevP `DevicePtr Float', useDevP `DevicePtr Float' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsrsv_solve #-}
+{# fun unsafe cusparseDcsrsv_solve as dcsrsv_solve { useHandle `Handle', cFromEnum `Operation', `Int', castPtr `Ptr Double', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo `Info', useDevP `DevicePtr Double', useDevP `DevicePtr Double' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsrsv_solve #-}
+{# fun unsafe cusparseCcsrsv_solve as ccsrsv_solve { useHandle `Handle', cFromEnum `Operation', `Int', castPtr `Ptr (Complex Float)', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo `Info', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsrsv_solve #-}
+{# fun unsafe cusparseZcsrsv_solve as zcsrsv_solve { useHandle `Handle', cFromEnum `Operation', `Int', castPtr `Ptr (Complex Double)', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo `Info', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsrsv2_bufferSize #-}
+{# fun unsafe cusparseScsrsv2_bufferSize as scsrsv2_bufferSize { useHandle `Handle', cFromEnum `Operation', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrsv2 `Info_csrsv2', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsrsv2_bufferSize #-}
+{# fun unsafe cusparseDcsrsv2_bufferSize as dcsrsv2_bufferSize { useHandle `Handle', cFromEnum `Operation', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrsv2 `Info_csrsv2', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsrsv2_bufferSize #-}
+{# fun unsafe cusparseCcsrsv2_bufferSize as ccsrsv2_bufferSize { useHandle `Handle', cFromEnum `Operation', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrsv2 `Info_csrsv2', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsrsv2_bufferSize #-}
+{# fun unsafe cusparseZcsrsv2_bufferSize as zcsrsv2_bufferSize { useHandle `Handle', cFromEnum `Operation', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrsv2 `Info_csrsv2', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsrsv2_analysis #-}
+{# fun unsafe cusparseScsrsv2_analysis as scsrsv2_analysis { useHandle `Handle', cFromEnum `Operation', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrsv2 `Info_csrsv2', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsrsv2_analysis #-}
+{# fun unsafe cusparseDcsrsv2_analysis as dcsrsv2_analysis { useHandle `Handle', cFromEnum `Operation', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrsv2 `Info_csrsv2', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsrsv2_analysis #-}
+{# fun unsafe cusparseCcsrsv2_analysis as ccsrsv2_analysis { useHandle `Handle', cFromEnum `Operation', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrsv2 `Info_csrsv2', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsrsv2_analysis #-}
+{# fun unsafe cusparseZcsrsv2_analysis as zcsrsv2_analysis { useHandle `Handle', cFromEnum `Operation', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrsv2 `Info_csrsv2', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsrsv2_solve #-}
+{# fun unsafe cusparseScsrsv2_solve as scsrsv2_solve { useHandle `Handle', cFromEnum `Operation', `Int', `Int', castPtr `Ptr Float', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrsv2 `Info_csrsv2', useDevP `DevicePtr Float', useDevP `DevicePtr Float', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsrsv2_solve #-}
+{# fun unsafe cusparseDcsrsv2_solve as dcsrsv2_solve { useHandle `Handle', cFromEnum `Operation', `Int', `Int', castPtr `Ptr Double', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrsv2 `Info_csrsv2', useDevP `DevicePtr Double', useDevP `DevicePtr Double', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsrsv2_solve #-}
+{# fun unsafe cusparseCcsrsv2_solve as ccsrsv2_solve { useHandle `Handle', cFromEnum `Operation', `Int', `Int', castPtr `Ptr (Complex Float)', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrsv2 `Info_csrsv2', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsrsv2_solve #-}
+{# fun unsafe cusparseZcsrsv2_solve as zcsrsv2_solve { useHandle `Handle', cFromEnum `Operation', `Int', `Int', castPtr `Ptr (Complex Double)', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrsv2 `Info_csrsv2', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE xcsrsv2_zeroPivot #-}
+{# fun unsafe cusparseXcsrsv2_zeroPivot as xcsrsv2_zeroPivot { useHandle `Handle', useInfo_csrsv2 `Info_csrsv2', castPtr `Ptr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE shybmv #-}
+{# fun unsafe cusparseShybmv as shybmv { useHandle `Handle', cFromEnum `Operation', castPtr `Ptr Float', useMatDescr `MatrixDescriptor', useHYB `Hybrid', useDevP `DevicePtr Float', castPtr `Ptr Float', useDevP `DevicePtr Float' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dhybmv #-}
+{# fun unsafe cusparseDhybmv as dhybmv { useHandle `Handle', cFromEnum `Operation', castPtr `Ptr Double', useMatDescr `MatrixDescriptor', useHYB `Hybrid', useDevP `DevicePtr Double', castPtr `Ptr Double', useDevP `DevicePtr Double' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE chybmv #-}
+{# fun unsafe cusparseChybmv as chybmv { useHandle `Handle', cFromEnum `Operation', castPtr `Ptr (Complex Float)', useMatDescr `MatrixDescriptor', useHYB `Hybrid', useDevP `DevicePtr (Complex Float)', castPtr `Ptr (Complex Float)', useDevP `DevicePtr (Complex Float)' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zhybmv #-}
+{# fun unsafe cusparseZhybmv as zhybmv { useHandle `Handle', cFromEnum `Operation', castPtr `Ptr (Complex Double)', useMatDescr `MatrixDescriptor', useHYB `Hybrid', useDevP `DevicePtr (Complex Double)', castPtr `Ptr (Complex Double)', useDevP `DevicePtr (Complex Double)' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE shybsv_analysis #-}
+{# fun unsafe cusparseShybsv_analysis as shybsv_analysis { useHandle `Handle', cFromEnum `Operation', useMatDescr `MatrixDescriptor', useHYB `Hybrid', useInfo `Info' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dhybsv_analysis #-}
+{# fun unsafe cusparseDhybsv_analysis as dhybsv_analysis { useHandle `Handle', cFromEnum `Operation', useMatDescr `MatrixDescriptor', useHYB `Hybrid', useInfo `Info' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE chybsv_analysis #-}
+{# fun unsafe cusparseChybsv_analysis as chybsv_analysis { useHandle `Handle', cFromEnum `Operation', useMatDescr `MatrixDescriptor', useHYB `Hybrid', useInfo `Info' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zhybsv_analysis #-}
+{# fun unsafe cusparseZhybsv_analysis as zhybsv_analysis { useHandle `Handle', cFromEnum `Operation', useMatDescr `MatrixDescriptor', useHYB `Hybrid', useInfo `Info' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE shybsv_solve #-}
+{# fun unsafe cusparseShybsv_solve as shybsv_solve { useHandle `Handle', cFromEnum `Operation', castPtr `Ptr Float', useMatDescr `MatrixDescriptor', useHYB `Hybrid', useInfo `Info', useDevP `DevicePtr Float', useDevP `DevicePtr Float' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dhybsv_solve #-}
+{# fun unsafe cusparseDhybsv_solve as dhybsv_solve { useHandle `Handle', cFromEnum `Operation', castPtr `Ptr Double', useMatDescr `MatrixDescriptor', useHYB `Hybrid', useInfo `Info', useDevP `DevicePtr Double', useDevP `DevicePtr Double' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE chybsv_solve #-}
+{# fun unsafe cusparseChybsv_solve as chybsv_solve { useHandle `Handle', cFromEnum `Operation', castPtr `Ptr (Complex Float)', useMatDescr `MatrixDescriptor', useHYB `Hybrid', useInfo `Info', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zhybsv_solve #-}
+{# fun unsafe cusparseZhybsv_solve as zhybsv_solve { useHandle `Handle', cFromEnum `Operation', castPtr `Ptr (Complex Double)', useMatDescr `MatrixDescriptor', useHYB `Hybrid', useInfo `Info', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)' } -> `()' checkStatus*- #}
+#if CUDA_VERSION >= 7500
+
+{-# INLINEABLE sgemvi #-}
+{# fun unsafe cusparseSgemvi as sgemvi { useHandle `Handle', cFromEnum `Operation', `Int', `Int', castPtr `Ptr Float', useDevP `DevicePtr Float', `Int', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', castPtr `Ptr Float', useDevP `DevicePtr Float', cFromEnum `IndexBase', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dgemvi #-}
+{# fun unsafe cusparseDgemvi as dgemvi { useHandle `Handle', cFromEnum `Operation', `Int', `Int', castPtr `Ptr Double', useDevP `DevicePtr Double', `Int', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', castPtr `Ptr Double', useDevP `DevicePtr Double', cFromEnum `IndexBase', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cgemvi #-}
+{# fun unsafe cusparseCgemvi as cgemvi { useHandle `Handle', cFromEnum `Operation', `Int', `Int', castPtr `Ptr (Complex Float)', useDevP `DevicePtr (Complex Float)', `Int', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', castPtr `Ptr (Complex Float)', useDevP `DevicePtr (Complex Float)', cFromEnum `IndexBase', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zgemvi #-}
+{# fun unsafe cusparseZgemvi as zgemvi { useHandle `Handle', cFromEnum `Operation', `Int', `Int', castPtr `Ptr (Complex Double)', useDevP `DevicePtr (Complex Double)', `Int', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', castPtr `Ptr (Complex Double)', useDevP `DevicePtr (Complex Double)', cFromEnum `IndexBase', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sgemvi_bufferSize #-}
+{# fun unsafe cusparseSgemvi_bufferSize as sgemvi_bufferSize { useHandle `Handle', cFromEnum `Operation', `Int', `Int', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dgemvi_bufferSize #-}
+{# fun unsafe cusparseDgemvi_bufferSize as dgemvi_bufferSize { useHandle `Handle', cFromEnum `Operation', `Int', `Int', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cgemvi_bufferSize #-}
+{# fun unsafe cusparseCgemvi_bufferSize as cgemvi_bufferSize { useHandle `Handle', cFromEnum `Operation', `Int', `Int', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zgemvi_bufferSize #-}
+{# fun unsafe cusparseZgemvi_bufferSize as zgemvi_bufferSize { useHandle `Handle', cFromEnum `Operation', `Int', `Int', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+#else
+
+sgemvi :: Handle -> Operation -> Int -> Int -> Ptr Float -> DevicePtr Float -> Int -> Int -> DevicePtr Float -> DevicePtr Int32 -> Ptr Float -> DevicePtr Float -> IndexBase -> DevicePtr () -> IO ()
+sgemvi _ _ _ _ _ _ _ _ _ _ _ _ _ _ = cusparseError "'sgemvi' requires at least cuda-7.5"
+
+dgemvi :: Handle -> Operation -> Int -> Int -> Ptr Double -> DevicePtr Double -> Int -> Int -> DevicePtr Double -> DevicePtr Int32 -> Ptr Double -> DevicePtr Double -> IndexBase -> DevicePtr () -> IO ()
+dgemvi _ _ _ _ _ _ _ _ _ _ _ _ _ _ = cusparseError "'dgemvi' requires at least cuda-7.5"
+
+cgemvi :: Handle -> Operation -> Int -> Int -> Ptr (Complex Float) -> DevicePtr (Complex Float) -> Int -> Int -> DevicePtr (Complex Float) -> DevicePtr Int32 -> Ptr (Complex Float) -> DevicePtr (Complex Float) -> IndexBase -> DevicePtr () -> IO ()
+cgemvi _ _ _ _ _ _ _ _ _ _ _ _ _ _ = cusparseError "'cgemvi' requires at least cuda-7.5"
+
+zgemvi :: Handle -> Operation -> Int -> Int -> Ptr (Complex Double) -> DevicePtr (Complex Double) -> Int -> Int -> DevicePtr (Complex Double) -> DevicePtr Int32 -> Ptr (Complex Double) -> DevicePtr (Complex Double) -> IndexBase -> DevicePtr () -> IO ()
+zgemvi _ _ _ _ _ _ _ _ _ _ _ _ _ _ = cusparseError "'zgemvi' requires at least cuda-7.5"
+
+sgemvi_bufferSize :: Handle -> Operation -> Int -> Int -> Int -> Int -> IO ()
+sgemvi_bufferSize _ _ _ _ _ _ = cusparseError "'sgemvi_bufferSize' requires at least cuda-7.5"
+
+dgemvi_bufferSize :: Handle -> Operation -> Int -> Int -> Int -> Int -> IO ()
+dgemvi_bufferSize _ _ _ _ _ _ = cusparseError "'dgemvi_bufferSize' requires at least cuda-7.5"
+
+cgemvi_bufferSize :: Handle -> Operation -> Int -> Int -> Int -> Int -> IO ()
+cgemvi_bufferSize _ _ _ _ _ _ = cusparseError "'cgemvi_bufferSize' requires at least cuda-7.5"
+
+zgemvi_bufferSize :: Handle -> Operation -> Int -> Int -> Int -> Int -> IO ()
+zgemvi_bufferSize _ _ _ _ _ _ = cusparseError "'zgemvi_bufferSize' requires at least cuda-7.5"
+#endif
+#if CUDA_VERSION >= 8000
+
+{-# INLINEABLE csrmvEx #-}
+{# fun unsafe cusparseCsrmvEx as csrmvEx { useHandle `Handle', cFromEnum `Algorithm', cFromEnum `Operation', `Int', `Int', `Int', castPtr `Ptr ()', cFromEnum `Type', useMatDescr `MatrixDescriptor', useDevP `DevicePtr ()', cFromEnum `Type', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr ()', cFromEnum `Type', castPtr `Ptr ()', cFromEnum `Type', useDevP `DevicePtr ()', cFromEnum `Type', cFromEnum `Type', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE csrmvEx_bufferSize #-}
+{# fun unsafe cusparseCsrmvEx_bufferSize as csrmvEx_bufferSize { useHandle `Handle', cFromEnum `Algorithm', cFromEnum `Operation', `Int', `Int', `Int', castPtr `Ptr ()', cFromEnum `Type', useMatDescr `MatrixDescriptor', useDevP `DevicePtr ()', cFromEnum `Type', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr ()', cFromEnum `Type', castPtr `Ptr ()', cFromEnum `Type', useDevP `DevicePtr ()', cFromEnum `Type', cFromEnum `Type', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsrmv_mp #-}
+{# fun unsafe cusparseScsrmv_mp as scsrmv_mp { useHandle `Handle', cFromEnum `Operation', `Int', `Int', `Int', castPtr `Ptr Float', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Float', castPtr `Ptr Float', useDevP `DevicePtr Float' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsrmv_mp #-}
+{# fun unsafe cusparseDcsrmv_mp as dcsrmv_mp { useHandle `Handle', cFromEnum `Operation', `Int', `Int', `Int', castPtr `Ptr Double', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Double', castPtr `Ptr Double', useDevP `DevicePtr Double' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsrmv_mp #-}
+{# fun unsafe cusparseCcsrmv_mp as ccsrmv_mp { useHandle `Handle', cFromEnum `Operation', `Int', `Int', `Int', castPtr `Ptr (Complex Float)', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Float)', castPtr `Ptr (Complex Float)', useDevP `DevicePtr (Complex Float)' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsrmv_mp #-}
+{# fun unsafe cusparseZcsrmv_mp as zcsrmv_mp { useHandle `Handle', cFromEnum `Operation', `Int', `Int', `Int', castPtr `Ptr (Complex Double)', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Double)', castPtr `Ptr (Complex Double)', useDevP `DevicePtr (Complex Double)' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE csrsv_analysisEx #-}
+{# fun unsafe cusparseCsrsv_analysisEx as csrsv_analysisEx { useHandle `Handle', cFromEnum `Operation', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr ()', cFromEnum `Type', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo `Info', cFromEnum `Type' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE csrsv_solveEx #-}
+{# fun unsafe cusparseCsrsv_solveEx as csrsv_solveEx { useHandle `Handle', cFromEnum `Operation', `Int', castPtr `Ptr ()', cFromEnum `Type', useMatDescr `MatrixDescriptor', useDevP `DevicePtr ()', cFromEnum `Type', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo `Info', useDevP `DevicePtr ()', cFromEnum `Type', useDevP `DevicePtr ()', cFromEnum `Type', cFromEnum `Type' } -> `()' checkStatus*- #}
+#else
+
+csrmvEx :: Handle -> Algorithm -> Operation -> Int -> Int -> Int -> Ptr () -> Type -> MatrixDescriptor -> DevicePtr () -> Type -> DevicePtr Int32 -> DevicePtr Int32 -> DevicePtr () -> Type -> Ptr () -> Type -> DevicePtr () -> Type -> Type -> DevicePtr () -> IO ()
+csrmvEx _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ = cusparseError "'csrmvEx' requires at least cuda-8.0"
+
+csrmvEx_bufferSize :: Handle -> Algorithm -> Operation -> Int -> Int -> Int -> Ptr () -> Type -> MatrixDescriptor -> DevicePtr () -> Type -> DevicePtr Int32 -> DevicePtr Int32 -> DevicePtr () -> Type -> Ptr () -> Type -> DevicePtr () -> Type -> Type -> Int -> IO ()
+csrmvEx_bufferSize _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ = cusparseError "'csrmvEx_bufferSize' requires at least cuda-8.0"
+
+scsrmv_mp :: Handle -> Operation -> Int -> Int -> Int -> Ptr Float -> MatrixDescriptor -> DevicePtr Float -> DevicePtr Int32 -> DevicePtr Int32 -> DevicePtr Float -> Ptr Float -> DevicePtr Float -> IO ()
+scsrmv_mp _ _ _ _ _ _ _ _ _ _ _ _ _ = cusparseError "'scsrmv_mp' requires at least cuda-8.0"
+
+dcsrmv_mp :: Handle -> Operation -> Int -> Int -> Int -> Ptr Double -> MatrixDescriptor -> DevicePtr Double -> DevicePtr Int32 -> DevicePtr Int32 -> DevicePtr Double -> Ptr Double -> DevicePtr Double -> IO ()
+dcsrmv_mp _ _ _ _ _ _ _ _ _ _ _ _ _ = cusparseError "'dcsrmv_mp' requires at least cuda-8.0"
+
+ccsrmv_mp :: Handle -> Operation -> Int -> Int -> Int -> Ptr (Complex Float) -> MatrixDescriptor -> DevicePtr (Complex Float) -> DevicePtr Int32 -> DevicePtr Int32 -> DevicePtr (Complex Float) -> Ptr (Complex Float) -> DevicePtr (Complex Float) -> IO ()
+ccsrmv_mp _ _ _ _ _ _ _ _ _ _ _ _ _ = cusparseError "'ccsrmv_mp' requires at least cuda-8.0"
+
+zcsrmv_mp :: Handle -> Operation -> Int -> Int -> Int -> Ptr (Complex Double) -> MatrixDescriptor -> DevicePtr (Complex Double) -> DevicePtr Int32 -> DevicePtr Int32 -> DevicePtr (Complex Double) -> Ptr (Complex Double) -> DevicePtr (Complex Double) -> IO ()
+zcsrmv_mp _ _ _ _ _ _ _ _ _ _ _ _ _ = cusparseError "'zcsrmv_mp' requires at least cuda-8.0"
+
+csrsv_analysisEx :: Handle -> Operation -> Int -> Int -> MatrixDescriptor -> DevicePtr () -> Type -> DevicePtr Int32 -> DevicePtr Int32 -> Info -> Type -> IO ()
+csrsv_analysisEx _ _ _ _ _ _ _ _ _ _ _ = cusparseError "'csrsv_analysisEx' requires at least cuda-8.0"
+
+csrsv_solveEx :: Handle -> Operation -> Int -> Ptr () -> Type -> MatrixDescriptor -> DevicePtr () -> Type -> DevicePtr Int32 -> DevicePtr Int32 -> Info -> DevicePtr () -> Type -> DevicePtr () -> Type -> Type -> IO ()
+csrsv_solveEx _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ = cusparseError "'csrsv_solveEx' requires at least cuda-8.0"
+#endif
diff --git a/Foreign/CUDA/BLAS/Sparse/Level3.chs b/Foreign/CUDA/BLAS/Sparse/Level3.chs
new file mode 100644
--- /dev/null
+++ b/Foreign/CUDA/BLAS/Sparse/Level3.chs
@@ -0,0 +1,296 @@
+--
+-- This module is auto-generated. Do not edit directly.
+--
+
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds #-}
+-- |
+-- Module      : Foreign.CUDA.BLAS.Sparse.Level3
+-- Copyright   : [2017] Trevor L. McDonell
+-- License     : BSD3
+--
+-- Maintainer  : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+--
+-- For more information see the cuSPARSE Level-3 function reference:
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparse-level-3-function-reference>
+--
+
+module Foreign.CUDA.BLAS.Sparse.Level3 (
+
+  Operation(..),
+  Policy(..),
+  MatrixDescriptor,
+  Info,
+  Info_bsrsm2,
+  Info_csrgemm2,
+  scsrmm,
+  dcsrmm,
+  ccsrmm,
+  zcsrmm,
+  scsrmm2,
+  dcsrmm2,
+  ccsrmm2,
+  zcsrmm2,
+  scsrsm_analysis,
+  dcsrsm_analysis,
+  ccsrsm_analysis,
+  zcsrsm_analysis,
+  scsrsm_solve,
+  dcsrsm_solve,
+  ccsrsm_solve,
+  zcsrsm_solve,
+  sbsrmm,
+  dbsrmm,
+  cbsrmm,
+  zbsrmm,
+  sbsrsm2_bufferSize,
+  dbsrsm2_bufferSize,
+  cbsrsm2_bufferSize,
+  zbsrsm2_bufferSize,
+  sbsrsm2_analysis,
+  dbsrsm2_analysis,
+  cbsrsm2_analysis,
+  zbsrsm2_analysis,
+  sbsrsm2_solve,
+  dbsrsm2_solve,
+  cbsrsm2_solve,
+  zbsrsm2_solve,
+  xbsrsm2_zeroPivot,
+  xcsrgeamNnz,
+  scsrgeam,
+  dcsrgeam,
+  ccsrgeam,
+  zcsrgeam,
+  xcsrgemmNnz,
+  scsrgemm,
+  dcsrgemm,
+  ccsrgemm,
+  zcsrgemm,
+  scsrgemm2_bufferSizeExt,
+  dcsrgemm2_bufferSizeExt,
+  ccsrgemm2_bufferSizeExt,
+  zcsrgemm2_bufferSizeExt,
+  xcsrgemm2Nnz,
+  scsrgemm2,
+  dcsrgemm2,
+  ccsrgemm2,
+  zcsrgemm2,
+
+) where
+
+import Data.Complex
+import Numeric.Half
+import Foreign
+import Foreign.C
+import Foreign.Storable.Complex ()
+import Foreign.CUDA.Ptr
+import Foreign.CUDA.BLAS.Sparse.Analysis
+import Foreign.CUDA.BLAS.Sparse.Context
+import Foreign.CUDA.BLAS.Sparse.Error
+import Foreign.CUDA.BLAS.Sparse.Internal.C2HS
+import Foreign.CUDA.BLAS.Sparse.Internal.Types
+import Foreign.CUDA.BLAS.Sparse.Matrix.Descriptor
+import Foreign.CUDA.BLAS.Sparse.Matrix.Hybrid
+
+#include "cbits/stubs.h"
+{# context lib="cusparse" #}
+
+{-# INLINE useDevP #-}
+useDevP :: DevicePtr a -> Ptr b
+useDevP = useDevicePtr . castDevPtr
+
+{-# INLINE useHostP #-}
+useHostP :: HostPtr a -> Ptr b
+useHostP = useHostPtr . castHostPtr
+
+
+{-# INLINEABLE scsrmm #-}
+{# fun unsafe cusparseScsrmm as scsrmm { useHandle `Handle', cFromEnum `Operation', `Int', `Int', `Int', `Int', castPtr `Ptr Float', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Float', `Int', castPtr `Ptr Float', useDevP `DevicePtr Float', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsrmm #-}
+{# fun unsafe cusparseDcsrmm as dcsrmm { useHandle `Handle', cFromEnum `Operation', `Int', `Int', `Int', `Int', castPtr `Ptr Double', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Double', `Int', castPtr `Ptr Double', useDevP `DevicePtr Double', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsrmm #-}
+{# fun unsafe cusparseCcsrmm as ccsrmm { useHandle `Handle', cFromEnum `Operation', `Int', `Int', `Int', `Int', castPtr `Ptr (Complex Float)', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Float)', `Int', castPtr `Ptr (Complex Float)', useDevP `DevicePtr (Complex Float)', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsrmm #-}
+{# fun unsafe cusparseZcsrmm as zcsrmm { useHandle `Handle', cFromEnum `Operation', `Int', `Int', `Int', `Int', castPtr `Ptr (Complex Double)', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Double)', `Int', castPtr `Ptr (Complex Double)', useDevP `DevicePtr (Complex Double)', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsrmm2 #-}
+{# fun unsafe cusparseScsrmm2 as scsrmm2 { useHandle `Handle', cFromEnum `Operation', cFromEnum `Operation', `Int', `Int', `Int', `Int', castPtr `Ptr Float', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Float', `Int', castPtr `Ptr Float', useDevP `DevicePtr Float', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsrmm2 #-}
+{# fun unsafe cusparseDcsrmm2 as dcsrmm2 { useHandle `Handle', cFromEnum `Operation', cFromEnum `Operation', `Int', `Int', `Int', `Int', castPtr `Ptr Double', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Double', `Int', castPtr `Ptr Double', useDevP `DevicePtr Double', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsrmm2 #-}
+{# fun unsafe cusparseCcsrmm2 as ccsrmm2 { useHandle `Handle', cFromEnum `Operation', cFromEnum `Operation', `Int', `Int', `Int', `Int', castPtr `Ptr (Complex Float)', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Float)', `Int', castPtr `Ptr (Complex Float)', useDevP `DevicePtr (Complex Float)', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsrmm2 #-}
+{# fun unsafe cusparseZcsrmm2 as zcsrmm2 { useHandle `Handle', cFromEnum `Operation', cFromEnum `Operation', `Int', `Int', `Int', `Int', castPtr `Ptr (Complex Double)', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Double)', `Int', castPtr `Ptr (Complex Double)', useDevP `DevicePtr (Complex Double)', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsrsm_analysis #-}
+{# fun unsafe cusparseScsrsm_analysis as scsrsm_analysis { useHandle `Handle', cFromEnum `Operation', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo `Info' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsrsm_analysis #-}
+{# fun unsafe cusparseDcsrsm_analysis as dcsrsm_analysis { useHandle `Handle', cFromEnum `Operation', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo `Info' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsrsm_analysis #-}
+{# fun unsafe cusparseCcsrsm_analysis as ccsrsm_analysis { useHandle `Handle', cFromEnum `Operation', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo `Info' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsrsm_analysis #-}
+{# fun unsafe cusparseZcsrsm_analysis as zcsrsm_analysis { useHandle `Handle', cFromEnum `Operation', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo `Info' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsrsm_solve #-}
+{# fun unsafe cusparseScsrsm_solve as scsrsm_solve { useHandle `Handle', cFromEnum `Operation', `Int', `Int', castPtr `Ptr Float', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo `Info', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Float', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsrsm_solve #-}
+{# fun unsafe cusparseDcsrsm_solve as dcsrsm_solve { useHandle `Handle', cFromEnum `Operation', `Int', `Int', castPtr `Ptr Double', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo `Info', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Double', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsrsm_solve #-}
+{# fun unsafe cusparseCcsrsm_solve as ccsrsm_solve { useHandle `Handle', cFromEnum `Operation', `Int', `Int', castPtr `Ptr (Complex Float)', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo `Info', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr (Complex Float)', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsrsm_solve #-}
+{# fun unsafe cusparseZcsrsm_solve as zcsrsm_solve { useHandle `Handle', cFromEnum `Operation', `Int', `Int', castPtr `Ptr (Complex Double)', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo `Info', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr (Complex Double)', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sbsrmm #-}
+{# fun unsafe cusparseSbsrmm as sbsrmm { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', cFromEnum `Operation', `Int', `Int', `Int', `Int', castPtr `Ptr Float', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useDevP `DevicePtr Float', `Int', castPtr `Ptr Float', useDevP `DevicePtr Float', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dbsrmm #-}
+{# fun unsafe cusparseDbsrmm as dbsrmm { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', cFromEnum `Operation', `Int', `Int', `Int', `Int', castPtr `Ptr Double', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useDevP `DevicePtr Double', `Int', castPtr `Ptr Double', useDevP `DevicePtr Double', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cbsrmm #-}
+{# fun unsafe cusparseCbsrmm as cbsrmm { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', cFromEnum `Operation', `Int', `Int', `Int', `Int', castPtr `Ptr (Complex Float)', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useDevP `DevicePtr (Complex Float)', `Int', castPtr `Ptr (Complex Float)', useDevP `DevicePtr (Complex Float)', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zbsrmm #-}
+{# fun unsafe cusparseZbsrmm as zbsrmm { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', cFromEnum `Operation', `Int', `Int', `Int', `Int', castPtr `Ptr (Complex Double)', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useDevP `DevicePtr (Complex Double)', `Int', castPtr `Ptr (Complex Double)', useDevP `DevicePtr (Complex Double)', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sbsrsm2_bufferSize #-}
+{# fun unsafe cusparseSbsrsm2_bufferSize as sbsrsm2_bufferSize { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', cFromEnum `Operation', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrsm2 `Info_bsrsm2', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dbsrsm2_bufferSize #-}
+{# fun unsafe cusparseDbsrsm2_bufferSize as dbsrsm2_bufferSize { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', cFromEnum `Operation', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrsm2 `Info_bsrsm2', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cbsrsm2_bufferSize #-}
+{# fun unsafe cusparseCbsrsm2_bufferSize as cbsrsm2_bufferSize { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', cFromEnum `Operation', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrsm2 `Info_bsrsm2', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zbsrsm2_bufferSize #-}
+{# fun unsafe cusparseZbsrsm2_bufferSize as zbsrsm2_bufferSize { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', cFromEnum `Operation', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrsm2 `Info_bsrsm2', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sbsrsm2_analysis #-}
+{# fun unsafe cusparseSbsrsm2_analysis as sbsrsm2_analysis { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', cFromEnum `Operation', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrsm2 `Info_bsrsm2', cFromEnum `Policy', castPtr `Ptr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dbsrsm2_analysis #-}
+{# fun unsafe cusparseDbsrsm2_analysis as dbsrsm2_analysis { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', cFromEnum `Operation', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrsm2 `Info_bsrsm2', cFromEnum `Policy', castPtr `Ptr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cbsrsm2_analysis #-}
+{# fun unsafe cusparseCbsrsm2_analysis as cbsrsm2_analysis { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', cFromEnum `Operation', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrsm2 `Info_bsrsm2', cFromEnum `Policy', castPtr `Ptr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zbsrsm2_analysis #-}
+{# fun unsafe cusparseZbsrsm2_analysis as zbsrsm2_analysis { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', cFromEnum `Operation', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrsm2 `Info_bsrsm2', cFromEnum `Policy', castPtr `Ptr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sbsrsm2_solve #-}
+{# fun unsafe cusparseSbsrsm2_solve as sbsrsm2_solve { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', cFromEnum `Operation', `Int', `Int', `Int', castPtr `Ptr Float', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrsm2 `Info_bsrsm2', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Float', `Int', cFromEnum `Policy', castPtr `Ptr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dbsrsm2_solve #-}
+{# fun unsafe cusparseDbsrsm2_solve as dbsrsm2_solve { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', cFromEnum `Operation', `Int', `Int', `Int', castPtr `Ptr Double', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrsm2 `Info_bsrsm2', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Double', `Int', cFromEnum `Policy', castPtr `Ptr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cbsrsm2_solve #-}
+{# fun unsafe cusparseCbsrsm2_solve as cbsrsm2_solve { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', cFromEnum `Operation', `Int', `Int', `Int', castPtr `Ptr (Complex Float)', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrsm2 `Info_bsrsm2', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr (Complex Float)', `Int', cFromEnum `Policy', castPtr `Ptr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zbsrsm2_solve #-}
+{# fun unsafe cusparseZbsrsm2_solve as zbsrsm2_solve { useHandle `Handle', cFromEnum `Direction', cFromEnum `Operation', cFromEnum `Operation', `Int', `Int', `Int', castPtr `Ptr (Complex Double)', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrsm2 `Info_bsrsm2', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr (Complex Double)', `Int', cFromEnum `Policy', castPtr `Ptr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE xbsrsm2_zeroPivot #-}
+{# fun unsafe cusparseXbsrsm2_zeroPivot as xbsrsm2_zeroPivot { useHandle `Handle', useInfo_bsrsm2 `Info_bsrsm2', castPtr `Ptr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE xcsrgeamNnz #-}
+{# fun unsafe cusparseXcsrgeamNnz as xcsrgeamNnz { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Int32', castPtr `Ptr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsrgeam #-}
+{# fun unsafe cusparseScsrgeam as scsrgeam { useHandle `Handle', `Int', `Int', castPtr `Ptr Float', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', castPtr `Ptr Float', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsrgeam #-}
+{# fun unsafe cusparseDcsrgeam as dcsrgeam { useHandle `Handle', `Int', `Int', castPtr `Ptr Double', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', castPtr `Ptr Double', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsrgeam #-}
+{# fun unsafe cusparseCcsrgeam as ccsrgeam { useHandle `Handle', `Int', `Int', castPtr `Ptr (Complex Float)', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', castPtr `Ptr (Complex Float)', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsrgeam #-}
+{# fun unsafe cusparseZcsrgeam as zcsrgeam { useHandle `Handle', `Int', `Int', castPtr `Ptr (Complex Double)', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', castPtr `Ptr (Complex Double)', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE xcsrgemmNnz #-}
+{# fun unsafe cusparseXcsrgemmNnz as xcsrgemmNnz { useHandle `Handle', cFromEnum `Operation', cFromEnum `Operation', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Int32', castPtr `Ptr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsrgemm #-}
+{# fun unsafe cusparseScsrgemm as scsrgemm { useHandle `Handle', cFromEnum `Operation', cFromEnum `Operation', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsrgemm #-}
+{# fun unsafe cusparseDcsrgemm as dcsrgemm { useHandle `Handle', cFromEnum `Operation', cFromEnum `Operation', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsrgemm #-}
+{# fun unsafe cusparseCcsrgemm as ccsrgemm { useHandle `Handle', cFromEnum `Operation', cFromEnum `Operation', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsrgemm #-}
+{# fun unsafe cusparseZcsrgemm as zcsrgemm { useHandle `Handle', cFromEnum `Operation', cFromEnum `Operation', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+#if CUDA_VERSION >= 7000
+
+{-# INLINEABLE scsrgemm2_bufferSizeExt #-}
+{# fun unsafe cusparseScsrgemm2_bufferSizeExt as scsrgemm2_bufferSizeExt { useHandle `Handle', `Int', `Int', `Int', castPtr `Ptr Float', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', castPtr `Ptr Float', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrgemm2 `Info_csrgemm2', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsrgemm2_bufferSizeExt #-}
+{# fun unsafe cusparseDcsrgemm2_bufferSizeExt as dcsrgemm2_bufferSizeExt { useHandle `Handle', `Int', `Int', `Int', castPtr `Ptr Double', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', castPtr `Ptr Double', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrgemm2 `Info_csrgemm2', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsrgemm2_bufferSizeExt #-}
+{# fun unsafe cusparseCcsrgemm2_bufferSizeExt as ccsrgemm2_bufferSizeExt { useHandle `Handle', `Int', `Int', `Int', castPtr `Ptr (Complex Float)', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', castPtr `Ptr (Complex Float)', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrgemm2 `Info_csrgemm2', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsrgemm2_bufferSizeExt #-}
+{# fun unsafe cusparseZcsrgemm2_bufferSizeExt as zcsrgemm2_bufferSizeExt { useHandle `Handle', `Int', `Int', `Int', castPtr `Ptr (Complex Double)', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', castPtr `Ptr (Complex Double)', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrgemm2 `Info_csrgemm2', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE xcsrgemm2Nnz #-}
+{# fun unsafe cusparseXcsrgemm2Nnz as xcsrgemm2Nnz { useHandle `Handle', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Int32', castPtr `Ptr Int32', useInfo_csrgemm2 `Info_csrgemm2', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsrgemm2 #-}
+{# fun unsafe cusparseScsrgemm2 as scsrgemm2 { useHandle `Handle', `Int', `Int', `Int', castPtr `Ptr Float', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', castPtr `Ptr Float', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrgemm2 `Info_csrgemm2', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsrgemm2 #-}
+{# fun unsafe cusparseDcsrgemm2 as dcsrgemm2 { useHandle `Handle', `Int', `Int', `Int', castPtr `Ptr Double', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', castPtr `Ptr Double', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrgemm2 `Info_csrgemm2', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsrgemm2 #-}
+{# fun unsafe cusparseCcsrgemm2 as ccsrgemm2 { useHandle `Handle', `Int', `Int', `Int', castPtr `Ptr (Complex Float)', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', castPtr `Ptr (Complex Float)', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrgemm2 `Info_csrgemm2', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsrgemm2 #-}
+{# fun unsafe cusparseZcsrgemm2 as zcsrgemm2 { useHandle `Handle', `Int', `Int', `Int', castPtr `Ptr (Complex Double)', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', castPtr `Ptr (Complex Double)', useMatDescr `MatrixDescriptor', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrgemm2 `Info_csrgemm2', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+#else
+
+scsrgemm2_bufferSizeExt :: Handle -> Int -> Int -> Int -> Ptr Float -> MatrixDescriptor -> Int -> DevicePtr Int32 -> DevicePtr Int32 -> MatrixDescriptor -> Int -> DevicePtr Int32 -> DevicePtr Int32 -> Ptr Float -> MatrixDescriptor -> Int -> DevicePtr Int32 -> DevicePtr Int32 -> Info_csrgemm2 -> Int -> IO ()
+scsrgemm2_bufferSizeExt _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ = cusparseError "'scsrgemm2_bufferSizeExt' requires at least cuda-7.0"
+
+dcsrgemm2_bufferSizeExt :: Handle -> Int -> Int -> Int -> Ptr Double -> MatrixDescriptor -> Int -> DevicePtr Int32 -> DevicePtr Int32 -> MatrixDescriptor -> Int -> DevicePtr Int32 -> DevicePtr Int32 -> Ptr Double -> MatrixDescriptor -> Int -> DevicePtr Int32 -> DevicePtr Int32 -> Info_csrgemm2 -> Int -> IO ()
+dcsrgemm2_bufferSizeExt _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ = cusparseError "'dcsrgemm2_bufferSizeExt' requires at least cuda-7.0"
+
+ccsrgemm2_bufferSizeExt :: Handle -> Int -> Int -> Int -> Ptr (Complex Float) -> MatrixDescriptor -> Int -> DevicePtr Int32 -> DevicePtr Int32 -> MatrixDescriptor -> Int -> DevicePtr Int32 -> DevicePtr Int32 -> Ptr (Complex Float) -> MatrixDescriptor -> Int -> DevicePtr Int32 -> DevicePtr Int32 -> Info_csrgemm2 -> Int -> IO ()
+ccsrgemm2_bufferSizeExt _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ = cusparseError "'ccsrgemm2_bufferSizeExt' requires at least cuda-7.0"
+
+zcsrgemm2_bufferSizeExt :: Handle -> Int -> Int -> Int -> Ptr (Complex Double) -> MatrixDescriptor -> Int -> DevicePtr Int32 -> DevicePtr Int32 -> MatrixDescriptor -> Int -> DevicePtr Int32 -> DevicePtr Int32 -> Ptr (Complex Double) -> MatrixDescriptor -> Int -> DevicePtr Int32 -> DevicePtr Int32 -> Info_csrgemm2 -> Int -> IO ()
+zcsrgemm2_bufferSizeExt _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ = cusparseError "'zcsrgemm2_bufferSizeExt' requires at least cuda-7.0"
+
+xcsrgemm2Nnz :: Handle -> Int -> Int -> Int -> MatrixDescriptor -> Int -> DevicePtr Int32 -> DevicePtr Int32 -> MatrixDescriptor -> Int -> DevicePtr Int32 -> DevicePtr Int32 -> MatrixDescriptor -> Int -> DevicePtr Int32 -> DevicePtr Int32 -> MatrixDescriptor -> DevicePtr Int32 -> Ptr Int32 -> Info_csrgemm2 -> DevicePtr () -> IO ()
+xcsrgemm2Nnz _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ = cusparseError "'xcsrgemm2Nnz' requires at least cuda-7.0"
+
+scsrgemm2 :: Handle -> Int -> Int -> Int -> Ptr Float -> MatrixDescriptor -> Int -> DevicePtr Float -> DevicePtr Int32 -> DevicePtr Int32 -> MatrixDescriptor -> Int -> DevicePtr Float -> DevicePtr Int32 -> DevicePtr Int32 -> Ptr Float -> MatrixDescriptor -> Int -> DevicePtr Float -> DevicePtr Int32 -> DevicePtr Int32 -> MatrixDescriptor -> DevicePtr Float -> DevicePtr Int32 -> DevicePtr Int32 -> Info_csrgemm2 -> DevicePtr () -> IO ()
+scsrgemm2 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ = cusparseError "'scsrgemm2' requires at least cuda-7.0"
+
+dcsrgemm2 :: Handle -> Int -> Int -> Int -> Ptr Double -> MatrixDescriptor -> Int -> DevicePtr Double -> DevicePtr Int32 -> DevicePtr Int32 -> MatrixDescriptor -> Int -> DevicePtr Double -> DevicePtr Int32 -> DevicePtr Int32 -> Ptr Double -> MatrixDescriptor -> Int -> DevicePtr Double -> DevicePtr Int32 -> DevicePtr Int32 -> MatrixDescriptor -> DevicePtr Double -> DevicePtr Int32 -> DevicePtr Int32 -> Info_csrgemm2 -> DevicePtr () -> IO ()
+dcsrgemm2 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ = cusparseError "'dcsrgemm2' requires at least cuda-7.0"
+
+ccsrgemm2 :: Handle -> Int -> Int -> Int -> Ptr (Complex Float) -> MatrixDescriptor -> Int -> DevicePtr (Complex Float) -> DevicePtr Int32 -> DevicePtr Int32 -> MatrixDescriptor -> Int -> DevicePtr (Complex Float) -> DevicePtr Int32 -> DevicePtr Int32 -> Ptr (Complex Float) -> MatrixDescriptor -> Int -> DevicePtr (Complex Float) -> DevicePtr Int32 -> DevicePtr Int32 -> MatrixDescriptor -> DevicePtr (Complex Float) -> DevicePtr Int32 -> DevicePtr Int32 -> Info_csrgemm2 -> DevicePtr () -> IO ()
+ccsrgemm2 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ = cusparseError "'ccsrgemm2' requires at least cuda-7.0"
+
+zcsrgemm2 :: Handle -> Int -> Int -> Int -> Ptr (Complex Double) -> MatrixDescriptor -> Int -> DevicePtr (Complex Double) -> DevicePtr Int32 -> DevicePtr Int32 -> MatrixDescriptor -> Int -> DevicePtr (Complex Double) -> DevicePtr Int32 -> DevicePtr Int32 -> Ptr (Complex Double) -> MatrixDescriptor -> Int -> DevicePtr (Complex Double) -> DevicePtr Int32 -> DevicePtr Int32 -> MatrixDescriptor -> DevicePtr (Complex Double) -> DevicePtr Int32 -> DevicePtr Int32 -> Info_csrgemm2 -> DevicePtr () -> IO ()
+zcsrgemm2 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ = cusparseError "'zcsrgemm2' requires at least cuda-7.0"
+#endif
diff --git a/Foreign/CUDA/BLAS/Sparse/Matrix/Descriptor.chs b/Foreign/CUDA/BLAS/Sparse/Matrix/Descriptor.chs
new file mode 100644
--- /dev/null
+++ b/Foreign/CUDA/BLAS/Sparse/Matrix/Descriptor.chs
@@ -0,0 +1,177 @@
+{-# LANGUAGE CPP                      #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+-- |
+-- Module      : Foreign.CUDA.BLAS.Sparse.Matrix.Descriptor
+-- Copyright   : [2017] Trevor L. McDonell
+-- License     : BSD3
+--
+-- Maintainer  : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+--
+
+module Foreign.CUDA.BLAS.Sparse.Matrix.Descriptor (
+
+  MatrixDescriptor(..),
+  MatrixType(..),
+  IndexBase(..),
+  Diagonal(..),
+  Fill(..),
+
+  createMatDescr,
+  destroyMatDescr,
+
+  -- Querying properties
+  getDiagonal,
+  getFillMode,
+  getIndexBase,
+  getMatrixType,
+
+  -- Setting properties
+  setDiagonal,
+  setFillMode,
+  setIndexBase,
+  setMatrixType,
+
+) where
+
+-- Friends
+import Foreign.CUDA.BLAS.Sparse.Error
+import Foreign.CUDA.BLAS.Sparse.Internal.C2HS
+
+-- System
+import Foreign
+import Foreign.C
+import Control.Monad                                      ( liftM )
+
+#include "cbits/stubs.h"
+{# context lib="cusparse" #}
+
+
+-- | An opaque type used to describe the shape and properties of a matrix.
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparsematdescrt>
+--
+newtype MatrixDescriptor = MatrixDescriptor { useMatDescr :: {# type cusparseMatDescr_t #}}
+
+-- | Indicates whether the diagonal elements of the matrix are unity. The
+-- diagonal elements are always assumed to be present, but if 'Unit' is passed
+-- to an API routine, then the routine assumes that all diagonal entries are
+-- unity and will not read or modify those entries.
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparsediagtypet>
+--
+{# enum cusparseDiagType_t as Diagonal
+  { underscoreToCase }
+  with prefix="CUSPARSE_DIAG_TYPE" deriving (Eq, Show) #}
+
+-- | Indicates whether the upper or lower part of the sparse matrix is stored.
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparsefillmodet>
+--
+{# enum cusparseFillMode_t as Fill
+  { underscoreToCase }
+  with prefix="CUSPARSE_FILL_MODE" deriving (Eq, Show) #}
+
+-- | Indicates whether indexing of matrix elements starts at zero or one.
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparseindexbaset>
+--
+{# enum cusparseIndexBase_t as IndexBase
+  { underscoreToCase }
+  with prefix="CUSPARSE_INDEX_BASE" deriving (Eq, Show) #}
+
+-- | Indicates the type of matrix.
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparsematrixtypet>
+--
+{# enum cusparseMatrixType_t as MatrixType
+  { underscoreToCase }
+  with prefix="CUSPARSE_MATRIX_TYPE" deriving (Eq, Show) #}
+
+
+-- | Create a new matrix descriptor, with matrix type 'General' and index base
+-- 'Zero', while leaving other fields uninitialised.
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparsecreatematdescr>
+--
+{-# INLINEABLE createMatDescr #-}
+{# fun unsafe cusparseCreateMatDescr as createMatDescr
+  { alloca- `MatrixDescriptor' peekMD* } -> `()' checkStatus*- #}
+  where
+    peekMD = liftM MatrixDescriptor . peek
+
+-- | Release memory associated with a matrix descriptor.
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparsedestroymatdescr>
+--
+{-# INLINEABLE destroyMatDescr #-}
+{# fun unsafe cusparseDestroyMatDescr as destroyMatDescr
+  { useMatDescr `MatrixDescriptor' } -> `()' checkStatus* #}
+
+
+-- | Get the 'Diagonal' type field of the matrix descriptor.
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparsegetmatdiagtype>
+--
+{-# INLINEABLE getDiagonal #-}
+{# fun unsafe cusparseGetMatDiagType as getDiagonal
+  { useMatDescr `MatrixDescriptor' } -> `Diagonal' cToEnum #}
+
+-- | Get the 'Fill' mode of the matrix descriptor.
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparsegetmatfillmode>
+--
+{-# INLINEABLE getFillMode #-}
+{# fun unsafe cusparseGetMatFillMode as getFillMode
+  { useMatDescr `MatrixDescriptor' } -> `Fill' cToEnum #}
+
+-- | Get the 'IndexBase' mode of the matrix descriptor.
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparsegetmatindexbase>
+--
+{-# INLINEABLE getIndexBase #-}
+{# fun unsafe cusparseGetMatIndexBase as getIndexBase
+  { useMatDescr `MatrixDescriptor' } -> `IndexBase' cToEnum #}
+
+-- | Get the 'MatrixType' mode of the matrix descriptor.
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparsegetmattype>
+--
+{-# INLINEABLE getMatrixType #-}
+{# fun unsafe cusparseGetMatType as getMatrixType
+  { useMatDescr `MatrixDescriptor' } -> `MatrixType' cToEnum #}
+
+
+-- | Set the 'Diagonal' type field of the matrix descriptor.
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparsesetmatdiagtype>
+--
+{-# INLINEABLE setDiagonal #-}
+{# fun unsafe cusparseSetMatDiagType as setDiagonal
+  { useMatDescr `MatrixDescriptor', cFromEnum `Diagonal' } -> `()' checkStatus* #}
+
+-- | Set the 'Fill' mode of the matrix descriptor.
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparsesetmatfillmode>
+--
+{-# INLINEABLE setFillMode #-}
+{# fun unsafe cusparseSetMatFillMode as setFillMode
+  { useMatDescr `MatrixDescriptor', cFromEnum `Fill' } -> `()' checkStatus* #}
+
+-- | Set the 'IndexBase' mode of the matrix descriptor.
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparsesetmatindexbase>
+--
+{-# INLINEABLE setIndexBase #-}
+{# fun unsafe cusparseSetMatIndexBase as setIndexBase
+  { useMatDescr `MatrixDescriptor', cFromEnum `IndexBase' } -> `()' checkStatus* #}
+
+-- | Set the 'MatrixType' mode of the matrix descriptor.
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparsesetmattype>
+--
+{-# INLINEABLE setMatrixType #-}
+{# fun unsafe cusparseSetMatType as setMatrixType
+  { useMatDescr `MatrixDescriptor', cFromEnum `MatrixType' } -> `()' checkStatus* #}
+
diff --git a/Foreign/CUDA/BLAS/Sparse/Matrix/Hybrid.chs b/Foreign/CUDA/BLAS/Sparse/Matrix/Hybrid.chs
new file mode 100644
--- /dev/null
+++ b/Foreign/CUDA/BLAS/Sparse/Matrix/Hybrid.chs
@@ -0,0 +1,70 @@
+{-# LANGUAGE CPP                      #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+-- |
+-- Module      : Foreign.CUDA.BLAS.Sparse.Matrix.Hybrid
+-- Copyright   : [2017] Trevor L. McDonell
+-- License     : BSD3
+--
+-- Maintainer  : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+--
+
+module Foreign.CUDA.BLAS.Sparse.Matrix.Hybrid (
+
+  Hybrid(..),
+  HybridPartition(..),
+
+  createHYB,
+  destroyHYB,
+
+) where
+
+-- Friends
+import Foreign.CUDA.BLAS.Sparse.Error
+import Foreign.CUDA.BLAS.Sparse.Internal.C2HS
+
+-- System
+import Foreign
+import Foreign.C
+import Control.Monad                                      ( liftM )
+
+#include "cbits/stubs.h"
+{# context lib="cusparse" #}
+
+
+-- | An opaque structure holding the matrix in hybrid (HYB) format.
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparsehybmatt>
+--
+newtype Hybrid = Hybrid { useHYB :: {# type cusparseHybMat_t #}}
+
+-- | Indicates how to perform the partitioning of the matrix into regular (ELL)
+-- and irregular (COO) parts of the HYB format.
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparsehybpartitiont>
+--
+{# enum cusparseHybPartition_t as HybridPartition
+  { underscoreToCase }
+  with prefix="CUSPARSE_HYB_PARTITION" deriving (Eq, Show) #}
+
+
+-- | Create a new (opaque) hybrid matrix.
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparsecreatehybmat>
+--
+{-# INLINEABLE createHYB #-}
+{# fun unsafe cusparseCreateHybMat as createHYB
+  { alloca- `Hybrid' peekHYB* } -> `()' checkStatus*- #}
+  where
+    peekHYB = liftM Hybrid . peek
+
+
+-- | Destroy and release any memory associated with a hybrid matrix.
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparsedestroyhybmat>
+--
+{-# INLINEABLE destroyHYB #-}
+{# fun unsafe cusparseDestroyHybMat as destroyHYB
+  { useHYB `Hybrid' } -> `()' checkStatus* #}
+
diff --git a/Foreign/CUDA/BLAS/Sparse/Precondition.chs b/Foreign/CUDA/BLAS/Sparse/Precondition.chs
new file mode 100644
--- /dev/null
+++ b/Foreign/CUDA/BLAS/Sparse/Precondition.chs
@@ -0,0 +1,391 @@
+--
+-- This module is auto-generated. Do not edit directly.
+--
+
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds #-}
+-- |
+-- Module      : Foreign.CUDA.BLAS.Sparse.Precondition
+-- Copyright   : [2017] Trevor L. McDonell
+-- License     : BSD3
+--
+-- Maintainer  : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+--
+-- For more information see the cuSPARSE function reference:
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparse-preconditioners-reference>
+--
+
+module Foreign.CUDA.BLAS.Sparse.Precondition (
+
+  Operation(..),
+  Direction(..),
+  Policy(..),
+  MatrixDescriptor,
+  Info,
+  Info_csric02,
+  Info_csrilu02,
+  Info_bsric02,
+  Info_bsrilu02,
+  scsric0,
+  dcsric0,
+  ccsric0,
+  zcsric0,
+  scsric02_bufferSize,
+  dcsric02_bufferSize,
+  ccsric02_bufferSize,
+  zcsric02_bufferSize,
+  scsric02_analysis,
+  dcsric02_analysis,
+  ccsric02_analysis,
+  zcsric02_analysis,
+  scsric02,
+  dcsric02,
+  ccsric02,
+  zcsric02,
+  xcsric02_zeroPivot,
+  scsrilu0,
+  dcsrilu0,
+  ccsrilu0,
+  zcsrilu0,
+  scsrilu02_numericBoost,
+  dcsrilu02_numericBoost,
+  ccsrilu02_numericBoost,
+  zcsrilu02_numericBoost,
+  scsrilu02_bufferSize,
+  dcsrilu02_bufferSize,
+  ccsrilu02_bufferSize,
+  zcsrilu02_bufferSize,
+  scsrilu02_analysis,
+  dcsrilu02_analysis,
+  ccsrilu02_analysis,
+  zcsrilu02_analysis,
+  scsrilu02,
+  dcsrilu02,
+  ccsrilu02,
+  zcsrilu02,
+  xcsrilu02_zeroPivot,
+  sbsric02_bufferSize,
+  dbsric02_bufferSize,
+  cbsric02_bufferSize,
+  zbsric02_bufferSize,
+  sbsric02_analysis,
+  dbsric02_analysis,
+  cbsric02_analysis,
+  zbsric02_analysis,
+  sbsric02,
+  dbsric02,
+  cbsric02,
+  zbsric02,
+  xbsric02_zeroPivot,
+  sbsrilu02_numericBoost,
+  dbsrilu02_numericBoost,
+  cbsrilu02_numericBoost,
+  zbsrilu02_numericBoost,
+  sbsrilu02_bufferSize,
+  dbsrilu02_bufferSize,
+  cbsrilu02_bufferSize,
+  zbsrilu02_bufferSize,
+  sbsrilu02_analysis,
+  dbsrilu02_analysis,
+  cbsrilu02_analysis,
+  zbsrilu02_analysis,
+  sbsrilu02,
+  dbsrilu02,
+  cbsrilu02,
+  zbsrilu02,
+  xbsrilu02_zeroPivot,
+  sgtsv,
+  dgtsv,
+  cgtsv,
+  zgtsv,
+  sgtsv_nopivot,
+  dgtsv_nopivot,
+  cgtsv_nopivot,
+  zgtsv_nopivot,
+  sgtsvStridedBatch,
+  dgtsvStridedBatch,
+  cgtsvStridedBatch,
+  zgtsvStridedBatch,
+  csrilu0Ex,
+
+) where
+
+import Data.Complex
+import Numeric.Half
+import Foreign
+import Foreign.C
+import Foreign.Storable.Complex ()
+import Foreign.CUDA.Ptr
+import Foreign.CUDA.BLAS.Sparse.Analysis
+import Foreign.CUDA.BLAS.Sparse.Context
+import Foreign.CUDA.BLAS.Sparse.Error
+import Foreign.CUDA.BLAS.Sparse.Internal.C2HS
+import Foreign.CUDA.BLAS.Sparse.Internal.Types
+import Foreign.CUDA.BLAS.Sparse.Matrix.Descriptor
+import Foreign.CUDA.BLAS.Sparse.Matrix.Hybrid
+
+#include "cbits/stubs.h"
+{# context lib="cusparse" #}
+
+{-# INLINE useDevP #-}
+useDevP :: DevicePtr a -> Ptr b
+useDevP = useDevicePtr . castDevPtr
+
+{-# INLINE useHostP #-}
+useHostP :: HostPtr a -> Ptr b
+useHostP = useHostPtr . castHostPtr
+
+
+{-# INLINEABLE scsric0 #-}
+{# fun unsafe cusparseScsric0 as scsric0 { useHandle `Handle', cFromEnum `Operation', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo `Info' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsric0 #-}
+{# fun unsafe cusparseDcsric0 as dcsric0 { useHandle `Handle', cFromEnum `Operation', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo `Info' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsric0 #-}
+{# fun unsafe cusparseCcsric0 as ccsric0 { useHandle `Handle', cFromEnum `Operation', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo `Info' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsric0 #-}
+{# fun unsafe cusparseZcsric0 as zcsric0 { useHandle `Handle', cFromEnum `Operation', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo `Info' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsric02_bufferSize #-}
+{# fun unsafe cusparseScsric02_bufferSize as scsric02_bufferSize { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csric02 `Info_csric02', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsric02_bufferSize #-}
+{# fun unsafe cusparseDcsric02_bufferSize as dcsric02_bufferSize { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csric02 `Info_csric02', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsric02_bufferSize #-}
+{# fun unsafe cusparseCcsric02_bufferSize as ccsric02_bufferSize { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csric02 `Info_csric02', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsric02_bufferSize #-}
+{# fun unsafe cusparseZcsric02_bufferSize as zcsric02_bufferSize { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csric02 `Info_csric02', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsric02_analysis #-}
+{# fun unsafe cusparseScsric02_analysis as scsric02_analysis { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csric02 `Info_csric02', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsric02_analysis #-}
+{# fun unsafe cusparseDcsric02_analysis as dcsric02_analysis { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csric02 `Info_csric02', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsric02_analysis #-}
+{# fun unsafe cusparseCcsric02_analysis as ccsric02_analysis { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csric02 `Info_csric02', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsric02_analysis #-}
+{# fun unsafe cusparseZcsric02_analysis as zcsric02_analysis { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csric02 `Info_csric02', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsric02 #-}
+{# fun unsafe cusparseScsric02 as scsric02 { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csric02 `Info_csric02', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsric02 #-}
+{# fun unsafe cusparseDcsric02 as dcsric02 { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csric02 `Info_csric02', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsric02 #-}
+{# fun unsafe cusparseCcsric02 as ccsric02 { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csric02 `Info_csric02', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsric02 #-}
+{# fun unsafe cusparseZcsric02 as zcsric02 { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csric02 `Info_csric02', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE xcsric02_zeroPivot #-}
+{# fun unsafe cusparseXcsric02_zeroPivot as xcsric02_zeroPivot { useHandle `Handle', useInfo_csric02 `Info_csric02', castPtr `Ptr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsrilu0 #-}
+{# fun unsafe cusparseScsrilu0 as scsrilu0 { useHandle `Handle', cFromEnum `Operation', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo `Info' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsrilu0 #-}
+{# fun unsafe cusparseDcsrilu0 as dcsrilu0 { useHandle `Handle', cFromEnum `Operation', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo `Info' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsrilu0 #-}
+{# fun unsafe cusparseCcsrilu0 as ccsrilu0 { useHandle `Handle', cFromEnum `Operation', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo `Info' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsrilu0 #-}
+{# fun unsafe cusparseZcsrilu0 as zcsrilu0 { useHandle `Handle', cFromEnum `Operation', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo `Info' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsrilu02_numericBoost #-}
+{# fun unsafe cusparseScsrilu02_numericBoost as scsrilu02_numericBoost { useHandle `Handle', useInfo_csrilu02 `Info_csrilu02', `Int', castPtr `Ptr Double', castPtr `Ptr Float' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsrilu02_numericBoost #-}
+{# fun unsafe cusparseDcsrilu02_numericBoost as dcsrilu02_numericBoost { useHandle `Handle', useInfo_csrilu02 `Info_csrilu02', `Int', castPtr `Ptr Double', castPtr `Ptr Double' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsrilu02_numericBoost #-}
+{# fun unsafe cusparseCcsrilu02_numericBoost as ccsrilu02_numericBoost { useHandle `Handle', useInfo_csrilu02 `Info_csrilu02', `Int', castPtr `Ptr Double', castPtr `Ptr (Complex Float)' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsrilu02_numericBoost #-}
+{# fun unsafe cusparseZcsrilu02_numericBoost as zcsrilu02_numericBoost { useHandle `Handle', useInfo_csrilu02 `Info_csrilu02', `Int', castPtr `Ptr Double', castPtr `Ptr (Complex Double)' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsrilu02_bufferSize #-}
+{# fun unsafe cusparseScsrilu02_bufferSize as scsrilu02_bufferSize { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrilu02 `Info_csrilu02', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsrilu02_bufferSize #-}
+{# fun unsafe cusparseDcsrilu02_bufferSize as dcsrilu02_bufferSize { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrilu02 `Info_csrilu02', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsrilu02_bufferSize #-}
+{# fun unsafe cusparseCcsrilu02_bufferSize as ccsrilu02_bufferSize { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrilu02 `Info_csrilu02', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsrilu02_bufferSize #-}
+{# fun unsafe cusparseZcsrilu02_bufferSize as zcsrilu02_bufferSize { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrilu02 `Info_csrilu02', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsrilu02_analysis #-}
+{# fun unsafe cusparseScsrilu02_analysis as scsrilu02_analysis { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrilu02 `Info_csrilu02', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsrilu02_analysis #-}
+{# fun unsafe cusparseDcsrilu02_analysis as dcsrilu02_analysis { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrilu02 `Info_csrilu02', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsrilu02_analysis #-}
+{# fun unsafe cusparseCcsrilu02_analysis as ccsrilu02_analysis { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrilu02 `Info_csrilu02', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsrilu02_analysis #-}
+{# fun unsafe cusparseZcsrilu02_analysis as zcsrilu02_analysis { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrilu02 `Info_csrilu02', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsrilu02 #-}
+{# fun unsafe cusparseScsrilu02 as scsrilu02 { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrilu02 `Info_csrilu02', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsrilu02 #-}
+{# fun unsafe cusparseDcsrilu02 as dcsrilu02 { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrilu02 `Info_csrilu02', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsrilu02 #-}
+{# fun unsafe cusparseCcsrilu02 as ccsrilu02 { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrilu02 `Info_csrilu02', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsrilu02 #-}
+{# fun unsafe cusparseZcsrilu02 as zcsrilu02 { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrilu02 `Info_csrilu02', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE xcsrilu02_zeroPivot #-}
+{# fun unsafe cusparseXcsrilu02_zeroPivot as xcsrilu02_zeroPivot { useHandle `Handle', useInfo_csrilu02 `Info_csrilu02', castPtr `Ptr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sbsric02_bufferSize #-}
+{# fun unsafe cusparseSbsric02_bufferSize as sbsric02_bufferSize { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsric02 `Info_bsric02', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dbsric02_bufferSize #-}
+{# fun unsafe cusparseDbsric02_bufferSize as dbsric02_bufferSize { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsric02 `Info_bsric02', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cbsric02_bufferSize #-}
+{# fun unsafe cusparseCbsric02_bufferSize as cbsric02_bufferSize { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsric02 `Info_bsric02', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zbsric02_bufferSize #-}
+{# fun unsafe cusparseZbsric02_bufferSize as zbsric02_bufferSize { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsric02 `Info_bsric02', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sbsric02_analysis #-}
+{# fun unsafe cusparseSbsric02_analysis as sbsric02_analysis { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsric02 `Info_bsric02', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dbsric02_analysis #-}
+{# fun unsafe cusparseDbsric02_analysis as dbsric02_analysis { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsric02 `Info_bsric02', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cbsric02_analysis #-}
+{# fun unsafe cusparseCbsric02_analysis as cbsric02_analysis { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsric02 `Info_bsric02', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zbsric02_analysis #-}
+{# fun unsafe cusparseZbsric02_analysis as zbsric02_analysis { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsric02 `Info_bsric02', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sbsric02 #-}
+{# fun unsafe cusparseSbsric02 as sbsric02 { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsric02 `Info_bsric02', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dbsric02 #-}
+{# fun unsafe cusparseDbsric02 as dbsric02 { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsric02 `Info_bsric02', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cbsric02 #-}
+{# fun unsafe cusparseCbsric02 as cbsric02 { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsric02 `Info_bsric02', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zbsric02 #-}
+{# fun unsafe cusparseZbsric02 as zbsric02 { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsric02 `Info_bsric02', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE xbsric02_zeroPivot #-}
+{# fun unsafe cusparseXbsric02_zeroPivot as xbsric02_zeroPivot { useHandle `Handle', useInfo_bsric02 `Info_bsric02', castPtr `Ptr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sbsrilu02_numericBoost #-}
+{# fun unsafe cusparseSbsrilu02_numericBoost as sbsrilu02_numericBoost { useHandle `Handle', useInfo_bsrilu02 `Info_bsrilu02', `Int', castPtr `Ptr Double', castPtr `Ptr Float' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dbsrilu02_numericBoost #-}
+{# fun unsafe cusparseDbsrilu02_numericBoost as dbsrilu02_numericBoost { useHandle `Handle', useInfo_bsrilu02 `Info_bsrilu02', `Int', castPtr `Ptr Double', castPtr `Ptr Double' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cbsrilu02_numericBoost #-}
+{# fun unsafe cusparseCbsrilu02_numericBoost as cbsrilu02_numericBoost { useHandle `Handle', useInfo_bsrilu02 `Info_bsrilu02', `Int', castPtr `Ptr Double', castPtr `Ptr (Complex Float)' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zbsrilu02_numericBoost #-}
+{# fun unsafe cusparseZbsrilu02_numericBoost as zbsrilu02_numericBoost { useHandle `Handle', useInfo_bsrilu02 `Info_bsrilu02', `Int', castPtr `Ptr Double', castPtr `Ptr (Complex Double)' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sbsrilu02_bufferSize #-}
+{# fun unsafe cusparseSbsrilu02_bufferSize as sbsrilu02_bufferSize { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrilu02 `Info_bsrilu02', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dbsrilu02_bufferSize #-}
+{# fun unsafe cusparseDbsrilu02_bufferSize as dbsrilu02_bufferSize { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrilu02 `Info_bsrilu02', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cbsrilu02_bufferSize #-}
+{# fun unsafe cusparseCbsrilu02_bufferSize as cbsrilu02_bufferSize { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrilu02 `Info_bsrilu02', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zbsrilu02_bufferSize #-}
+{# fun unsafe cusparseZbsrilu02_bufferSize as zbsrilu02_bufferSize { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrilu02 `Info_bsrilu02', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sbsrilu02_analysis #-}
+{# fun unsafe cusparseSbsrilu02_analysis as sbsrilu02_analysis { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrilu02 `Info_bsrilu02', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dbsrilu02_analysis #-}
+{# fun unsafe cusparseDbsrilu02_analysis as dbsrilu02_analysis { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrilu02 `Info_bsrilu02', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cbsrilu02_analysis #-}
+{# fun unsafe cusparseCbsrilu02_analysis as cbsrilu02_analysis { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrilu02 `Info_bsrilu02', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zbsrilu02_analysis #-}
+{# fun unsafe cusparseZbsrilu02_analysis as zbsrilu02_analysis { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrilu02 `Info_bsrilu02', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sbsrilu02 #-}
+{# fun unsafe cusparseSbsrilu02 as sbsrilu02 { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrilu02 `Info_bsrilu02', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dbsrilu02 #-}
+{# fun unsafe cusparseDbsrilu02 as dbsrilu02 { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrilu02 `Info_bsrilu02', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cbsrilu02 #-}
+{# fun unsafe cusparseCbsrilu02 as cbsrilu02 { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrilu02 `Info_bsrilu02', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zbsrilu02 #-}
+{# fun unsafe cusparseZbsrilu02 as zbsrilu02 { useHandle `Handle', cFromEnum `Direction', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_bsrilu02 `Info_bsrilu02', cFromEnum `Policy', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE xbsrilu02_zeroPivot #-}
+{# fun unsafe cusparseXbsrilu02_zeroPivot as xbsrilu02_zeroPivot { useHandle `Handle', useInfo_bsrilu02 `Info_bsrilu02', castPtr `Ptr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sgtsv #-}
+{# fun unsafe cusparseSgtsv as sgtsv { useHandle `Handle', `Int', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Float', useDevP `DevicePtr Float', useDevP `DevicePtr Float', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dgtsv #-}
+{# fun unsafe cusparseDgtsv as dgtsv { useHandle `Handle', `Int', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Double', useDevP `DevicePtr Double', useDevP `DevicePtr Double', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cgtsv #-}
+{# fun unsafe cusparseCgtsv as cgtsv { useHandle `Handle', `Int', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zgtsv #-}
+{# fun unsafe cusparseZgtsv as zgtsv { useHandle `Handle', `Int', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sgtsv_nopivot #-}
+{# fun unsafe cusparseSgtsv_nopivot as sgtsv_nopivot { useHandle `Handle', `Int', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Float', useDevP `DevicePtr Float', useDevP `DevicePtr Float', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dgtsv_nopivot #-}
+{# fun unsafe cusparseDgtsv_nopivot as dgtsv_nopivot { useHandle `Handle', `Int', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Double', useDevP `DevicePtr Double', useDevP `DevicePtr Double', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cgtsv_nopivot #-}
+{# fun unsafe cusparseCgtsv_nopivot as cgtsv_nopivot { useHandle `Handle', `Int', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zgtsv_nopivot #-}
+{# fun unsafe cusparseZgtsv_nopivot as zgtsv_nopivot { useHandle `Handle', `Int', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sgtsvStridedBatch #-}
+{# fun unsafe cusparseSgtsvStridedBatch as sgtsvStridedBatch { useHandle `Handle', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Float', useDevP `DevicePtr Float', useDevP `DevicePtr Float', `Int', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dgtsvStridedBatch #-}
+{# fun unsafe cusparseDgtsvStridedBatch as dgtsvStridedBatch { useHandle `Handle', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Double', useDevP `DevicePtr Double', useDevP `DevicePtr Double', `Int', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cgtsvStridedBatch #-}
+{# fun unsafe cusparseCgtsvStridedBatch as cgtsvStridedBatch { useHandle `Handle', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', `Int', `Int' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zgtsvStridedBatch #-}
+{# fun unsafe cusparseZgtsvStridedBatch as zgtsvStridedBatch { useHandle `Handle', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', `Int', `Int' } -> `()' checkStatus*- #}
+#if CUDA_VERSION >= 8000
+
+{-# INLINEABLE csrilu0Ex #-}
+{# fun unsafe cusparseCsrilu0Ex as csrilu0Ex { useHandle `Handle', cFromEnum `Operation', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr ()', cFromEnum `Type', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo `Info', cFromEnum `Type' } -> `()' checkStatus*- #}
+#else
+
+csrilu0Ex :: Handle -> Operation -> Int -> MatrixDescriptor -> DevicePtr () -> Type -> DevicePtr Int32 -> DevicePtr Int32 -> Info -> Type -> IO ()
+csrilu0Ex _ _ _ _ _ _ _ _ _ _ = cusparseError "'csrilu0Ex' requires at least cuda-8.0"
+#endif
diff --git a/Foreign/CUDA/BLAS/Sparse/Reorder.chs b/Foreign/CUDA/BLAS/Sparse/Reorder.chs
new file mode 100644
--- /dev/null
+++ b/Foreign/CUDA/BLAS/Sparse/Reorder.chs
@@ -0,0 +1,84 @@
+--
+-- This module is auto-generated. Do not edit directly.
+--
+
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds #-}
+-- |
+-- Module      : Foreign.CUDA.BLAS.Sparse.Reorder
+-- Copyright   : [2017] Trevor L. McDonell
+-- License     : BSD3
+--
+-- Maintainer  : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+--
+-- For more information see the cuSPARSE function reference:
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparse-reorderings-reference>
+--
+
+module Foreign.CUDA.BLAS.Sparse.Reorder (
+
+  Info_color,
+  scsrcolor,
+  dcsrcolor,
+  ccsrcolor,
+  zcsrcolor,
+
+) where
+
+import Data.Complex
+import Numeric.Half
+import Foreign
+import Foreign.C
+import Foreign.Storable.Complex ()
+import Foreign.CUDA.Ptr
+import Foreign.CUDA.BLAS.Sparse.Analysis
+import Foreign.CUDA.BLAS.Sparse.Context
+import Foreign.CUDA.BLAS.Sparse.Error
+import Foreign.CUDA.BLAS.Sparse.Internal.C2HS
+import Foreign.CUDA.BLAS.Sparse.Internal.Types
+import Foreign.CUDA.BLAS.Sparse.Matrix.Descriptor
+import Foreign.CUDA.BLAS.Sparse.Matrix.Hybrid
+
+#include "cbits/stubs.h"
+{# context lib="cusparse" #}
+
+{-# INLINE useDevP #-}
+useDevP :: DevicePtr a -> Ptr b
+useDevP = useDevicePtr . castDevPtr
+
+{-# INLINE useHostP #-}
+useHostP :: HostPtr a -> Ptr b
+useHostP = useHostPtr . castHostPtr
+
+#if CUDA_VERSION >= 7000
+
+{-# INLINEABLE scsrcolor #-}
+{# fun unsafe cusparseScsrcolor as scsrcolor { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_color `Info_color' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsrcolor #-}
+{# fun unsafe cusparseDcsrcolor as dcsrcolor { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_color `Info_color' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsrcolor #-}
+{# fun unsafe cusparseCcsrcolor as ccsrcolor { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_color `Info_color' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsrcolor #-}
+{# fun unsafe cusparseZcsrcolor as zcsrcolor { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_color `Info_color' } -> `()' checkStatus*- #}
+#else
+
+scsrcolor :: Handle -> Int -> Int -> MatrixDescriptor -> DevicePtr Float -> DevicePtr Int32 -> DevicePtr Int32 -> DevicePtr Float -> DevicePtr Int32 -> DevicePtr Int32 -> DevicePtr Int32 -> Info_color -> IO ()
+scsrcolor _ _ _ _ _ _ _ _ _ _ _ _ = cusparseError "'scsrcolor' requires at least cuda-7.0"
+
+dcsrcolor :: Handle -> Int -> Int -> MatrixDescriptor -> DevicePtr Double -> DevicePtr Int32 -> DevicePtr Int32 -> DevicePtr Double -> DevicePtr Int32 -> DevicePtr Int32 -> DevicePtr Int32 -> Info_color -> IO ()
+dcsrcolor _ _ _ _ _ _ _ _ _ _ _ _ = cusparseError "'dcsrcolor' requires at least cuda-7.0"
+
+ccsrcolor :: Handle -> Int -> Int -> MatrixDescriptor -> DevicePtr (Complex Float) -> DevicePtr Int32 -> DevicePtr Int32 -> DevicePtr (Complex Float) -> DevicePtr Int32 -> DevicePtr Int32 -> DevicePtr Int32 -> Info_color -> IO ()
+ccsrcolor _ _ _ _ _ _ _ _ _ _ _ _ = cusparseError "'ccsrcolor' requires at least cuda-7.0"
+
+zcsrcolor :: Handle -> Int -> Int -> MatrixDescriptor -> DevicePtr (Complex Double) -> DevicePtr Int32 -> DevicePtr Int32 -> DevicePtr (Complex Double) -> DevicePtr Int32 -> DevicePtr Int32 -> DevicePtr Int32 -> Info_color -> IO ()
+zcsrcolor _ _ _ _ _ _ _ _ _ _ _ _ = cusparseError "'zcsrcolor' requires at least cuda-7.0"
+#endif
diff --git a/Foreign/CUDA/BLAS/Sparse/Stream.chs b/Foreign/CUDA/BLAS/Sparse/Stream.chs
new file mode 100644
--- /dev/null
+++ b/Foreign/CUDA/BLAS/Sparse/Stream.chs
@@ -0,0 +1,44 @@
+{-# LANGUAGE CPP                      #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+-- |
+-- Module      : Foreign.CUDA.BLAS.Sparse.Stream
+-- Copyright   : [2017] Trevor L. McDonell
+-- License     : BSD3
+--
+-- Maintainer  : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+--
+
+module Foreign.CUDA.BLAS.Sparse.Stream (
+
+  setStream,
+
+) where
+
+import Foreign.CUDA.Driver.Stream
+import Foreign.CUDA.BLAS.Sparse.Context
+import Foreign.CUDA.BLAS.Sparse.Error
+import Foreign.CUDA.BLAS.Sparse.Internal.C2HS
+import Foreign.CUDA.BLAS.Sparse.Internal.Types
+
+import Foreign.C
+import Foreign.Ptr
+
+#include "cbits/stubs.h"
+{# context lib="cusparse" #}
+
+
+-- | Sets the execution stream which all subsequent cuSPARSE library functions
+-- will execute with. If not set, functions execute in the default stream (which
+-- never overlaps any other operations).
+--
+-- <http://docs.nvidia.com/cuda/cusparse/index.html#cusparsesetstream>
+--
+{-# INLINEABLE setStream #-}
+{# fun unsafe cusparseSetStream as setStream
+  { useHandle `Handle'
+  , useStream `Stream'
+  }
+  -> `()' checkStatus* #}
+
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) [2017], Trevor L. McDonell
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Trevor L. McDonell nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,17 @@
+Haskell FFI Bindings to cuSPARSE
+================================
+
+[![Build status](https://travis-ci.org/tmcdonell/cusparse.svg?branch=master)](https://travis-ci.org/tmcdonell/cusparse)
+[![Hackage](https://img.shields.io/hackage/v/cusparse.svg)](https://hackage.haskell.org/package/cusparse)
+
+The cuSPARSE library contains a set of basic linear algebra subroutines for
+handling sparse matrices. Sparse vectors and matrices are those where the
+majority of elements are zero. Sparse BLAS routines are specifically implemented
+to take advantage of this sparsity. This package provides FFI bindings to the
+functions of the cuSPARSE library. You will need to install the CUDA driver and
+developer toolkit:
+
+  <http://developer.nvidia.com/cuda-downloads>
+
+  <http://docs.nvidia.com/cuda/cusparse/index.html>
+
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,246 @@
+{-# LANGUAGE CPP               #-}
+{-# LANGUAGE FlexibleInstances #-}
+
+#ifndef MIN_VERSION_Cabal
+#define MIN_VERSION_Cabal(major1,major2,minor) 0
+#endif
+
+import Distribution.PackageDescription
+import Distribution.PackageDescription.Parse
+import Distribution.Simple
+import Distribution.Simple.Command
+import Distribution.Simple.LocalBuildInfo
+import Distribution.Simple.PreProcess
+import Distribution.Simple.Program
+import Distribution.Simple.Setup
+import Distribution.Simple.Utils                                    hiding ( isInfixOf )
+import Distribution.System
+import Distribution.Verbosity
+
+#if MIN_VERSION_Cabal(1,25,0)
+import Distribution.PackageDescription.PrettyPrint
+import Distribution.Version
+#endif
+
+import Foreign.CUDA.Path
+import System.Directory
+import System.FilePath
+import Text.Printf
+import Prelude
+
+
+-- Configuration
+-- -------------
+
+customBuildInfoFilePath :: FilePath
+customBuildInfoFilePath = "cusparse" <.> "buildinfo"
+
+generatedBuildInfoFilePath :: FilePath
+generatedBuildInfoFilePath = customBuildInfoFilePath <.> "generated"
+
+
+-- http://docs.nvidia.com/cuda/cusparse/index.html#static-library
+--
+staticLibs :: Platform -> [String]
+staticLibs platform@(Platform _arch os) =
+  case os of
+    Windows -> dynamicLibs platform
+    _       -> ["cusparse_static", "culibos", "cudart_static", "pthread", "dl"]
+
+dynamicLibs :: Platform -> [String]
+dynamicLibs _ = ["cusparse"]
+
+
+-- Build setup
+-- -----------
+
+main :: IO ()
+main = defaultMainWithHooks customHooks
+  where
+    readHook get_verbosity args flags = do
+        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.
+    --
+    customHooks =
+      simpleUserHooks
+        { preBuild            = preBuildHook -- not using 'readHook' here because 'build' takes extra args
+        , preClean            = readHook cleanVerbosity
+        , preCopy             = readHook copyVerbosity
+        , preInst             = readHook installVerbosity
+        , preHscolour         = readHook hscolourVerbosity
+        , preHaddock          = readHook haddockVerbosity
+        , preReg              = readHook regVerbosity
+        , preUnreg            = readHook regVerbosity
+        , postConf            = postConfHook
+        , hookedPreProcessors = ("chs", pp_c2hs) : filter (\x -> fst x /= "chs") preprocessors
+        }
+
+    -- The hook just loads the HookedBuildInfo generated by postConfHook, unless
+    -- there is user-provided info that overwrites it.
+    --
+    preBuildHook :: Args -> BuildFlags -> IO HookedBuildInfo
+    preBuildHook _ flags = getHookedBuildInfo $ fromFlag $ buildVerbosity flags
+
+    -- The hook scans system in search for CUDA Toolkit. If the toolkit is not
+    -- found, an error is raised. Otherwise the toolkit location is used to
+    -- create a `cuda.buildinfo.generated` file with all the resulting flags.
+    --
+    postConfHook :: Args -> ConfigFlags -> PackageDescription -> LocalBuildInfo -> IO ()
+    postConfHook args flags pkg_descr lbi = do
+      let
+          verbosity       = fromFlagOrDefault normal (configVerbosity flags)
+          profile         = fromFlagOrDefault False  (configProfLib flags)
+          currentPlatform = hostPlatform lbi
+          compilerId_     = compilerId (compiler lbi)
+      --
+      noExtraFlags args
+      generateAndStoreBuildInfo verbosity profile currentPlatform compilerId_ generatedBuildInfoFilePath
+      --
+      actualBuildInfoToUse <- getHookedBuildInfo verbosity
+      let pkg_descr' = updatePackageDescription actualBuildInfoToUse pkg_descr
+      postConf simpleUserHooks args flags pkg_descr' lbi
+
+
+-- Generates build info with flags needed for CUDA Toolkit to be properly
+-- visible to underlying build tools.
+--
+libraryBuildInfo :: Bool -> Platform -> Version -> IO HookedBuildInfo
+libraryBuildInfo profile platform@(Platform arch os) ghcVersion = do
+  let
+      -- options for GHC
+      extraLibDirs'     = [ cudaLibraryPath ]
+      ccOptions'        = [ "-I" ++ cudaIncludePath ]
+      ldOptions'        = [ "-L" ++ cudaLibraryPath ]
+      ghcOptions        = map ("-optc"++) ccOptions'
+                       ++ map ("-optl"++) ldOptions'
+                       ++ if os /= Windows && not profile
+                            then map ("-optl-Wl,-rpath,"++) extraLibDirs'
+                            else []
+
+      extraLibs'        = staticLibs platform
+      extraGHCiLibs'    = dynamicLibs platform
+
+      -- options or c2hs
+      archFlag          = case arch of
+                            I386   -> "-m32"
+                            X86_64 -> "-m64"
+                            _      -> ""
+      emptyCase         = ["-DUSE_EMPTY_CASE" | versionBranch ghcVersion >= [7,8]]
+      blocksExtension   = [ "-U__BLOCKS__" | os == OSX ]
+      c2hsOptions       = unwords $ map ("--cppopts="++) ("-E" : archFlag : emptyCase ++ blocksExtension)
+      c2hsExtraOptions  = ("x-extra-c2hs-options", c2hsOptions)
+
+      addSystemSpecificOptions :: BuildInfo -> IO BuildInfo
+      addSystemSpecificOptions bi =
+        case os of
+          _ -> return bi
+
+  buildInfo' <- addSystemSpecificOptions $ emptyBuildInfo
+    { ccOptions      = ccOptions'
+    , ldOptions      = ldOptions'
+    , extraLibs      = extraLibs'
+    , extraGHCiLibs  = extraGHCiLibs'
+    , extraLibDirs   = extraLibDirs'
+    , options        = [(GHC, ghcOptions) | os /= Windows]
+    , customFieldsBI = [c2hsExtraOptions]
+    }
+
+  return (Just buildInfo', [])
+
+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 `cuda.buildinfo` if present, otherwise loads `cuda.buildinfo.generated`
+-- Outputs message informing about the other possibility.
+-- Calls die when neither of the files is available.
+-- (generated one should be always present, as it is created in the post-conf step)
+--
+getHookedBuildInfo :: Verbosity -> IO HookedBuildInfo
+getHookedBuildInfo verbosity = do
+  doesCustomBuildInfoExists <- doesFileExist customBuildInfoFilePath
+  if doesCustomBuildInfoExists
+    then do
+      notice verbosity $ printf "The user-provided buildinfo from file %s will be used. To use default settings, delete this file.\n" customBuildInfoFilePath
+      readHookedBuildInfo verbosity customBuildInfoFilePath
+    else do
+      doesGeneratedBuildInfoExists <- doesFileExist generatedBuildInfoFilePath
+      if doesGeneratedBuildInfoExists
+        then do
+          notice verbosity $ printf "Using build information from '%s'.\n" generatedBuildInfoFilePath
+          notice verbosity $ printf "Provide a '%s' file to override this behaviour.\n" customBuildInfoFilePath
+          readHookedBuildInfo verbosity generatedBuildInfoFilePath
+        else
+          die $ printf "Unexpected failure. Neither the default %s nor custom %s exist.\n" generatedBuildInfoFilePath customBuildInfoFilePath
+
+
+-- Replicate the default C2HS preprocessor hook here, and inject a value for
+-- extra-c2hs-options, if it was present in the buildinfo file
+--
+-- This is largely copied from Distribution.Simple.PreProcess, with some hacks
+-- to make it work with different versions of Cabal-the-library.
+--
+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]
+            ++ ["--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 v =
+  case versionBranch v of
+    []      -> "1"
+    [n]     -> show n
+    n1:n2:_ -> printf "%d%02d" n1 n2
+
+#if MIN_VERSION_Cabal(1,25,0)
+versionBranch :: Version -> [Int]
+versionBranch = versionNumbers
+#endif
+
diff --git a/cbits/stubs.h b/cbits/stubs.h
new file mode 100644
--- /dev/null
+++ b/cbits/stubs.h
@@ -0,0 +1,18 @@
+/*
+ * Extra bits for cuSPARSE bindings
+ */
+
+#ifndef C_STUBS_H
+#define C_STUBS_H
+
+#ifdef __MINGW32__
+#include <host_defines.h>
+#undef CUDARTAPI
+#define CUDARTAPI __stdcall
+#endif
+
+#include <cuda.h>
+#include <cusparse_v2.h>
+
+#endif /* C_STUBS_H */
+
diff --git a/cusparse.cabal b/cusparse.cabal
new file mode 100644
--- /dev/null
+++ b/cusparse.cabal
@@ -0,0 +1,88 @@
+name:                   cusparse
+version:                0.1.0.0
+synopsis:               FFI bindings to the CUDA Sparse BLAS library
+description:
+    The cuSPARSE library contains a set of basic linear algebra subroutines for
+    handling sparse matrices on NVIDIA GPUs. Sparse vectors and matrices are
+    those where the majority of elements are zero. Sparse BLAS routines are
+    specifically implemented to take advantage of this sparsity. This package
+    provides FFI bindings to the functions of the cuSPARSE library. You will
+    need to install the CUDA driver and developer toolkit:
+    .
+    <http://developer.nvidia.com/cuda-downloads>
+    .
+    See the <https://travis-ci.org/tmcdonell/cusparse travis-ci.org> build matrix
+    for tested CUDA library versions.
+
+license:                BSD3
+license-file:           LICENSE
+author:                 Trevor L. McDonell
+maintainer:             Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>
+copyright:              Copyright (c) [2017]. Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>
+category:               Foreign
+cabal-version:          >=1.8
+
+build-type:             Custom
+extra-tmp-files:        cusparse.buildinfo.generated
+extra-source-files:
+  README.md
+  CHANGELOG.md
+  cbits/stubs.h
+
+custom-setup
+  setup-depends:
+      base              >= 4.6
+    , Cabal             >= 1.22
+    , cuda              >= 0.8
+    , directory         >= 1.0
+    , filepath          >= 1.0
+
+library
+  hs-source-dirs:       .
+  include-dirs:         .
+
+  exposed-modules:
+      Foreign.CUDA.BLAS.Sparse
+      Foreign.CUDA.BLAS.Sparse.Analysis
+      Foreign.CUDA.BLAS.Sparse.Context
+      Foreign.CUDA.BLAS.Sparse.Convert
+      Foreign.CUDA.BLAS.Sparse.Error
+      Foreign.CUDA.BLAS.Sparse.Level1
+      Foreign.CUDA.BLAS.Sparse.Level2
+      Foreign.CUDA.BLAS.Sparse.Level3
+      Foreign.CUDA.BLAS.Sparse.Matrix.Descriptor
+      Foreign.CUDA.BLAS.Sparse.Matrix.Hybrid
+      Foreign.CUDA.BLAS.Sparse.Precondition
+      Foreign.CUDA.BLAS.Sparse.Reorder
+      Foreign.CUDA.BLAS.Sparse.Stream
+
+  other-modules:
+      Foreign.CUDA.BLAS.Sparse.Internal.C2HS
+      Foreign.CUDA.BLAS.Sparse.Internal.Types
+
+  build-depends:
+      base                              == 4.*
+    , cuda                              >= 0.8
+    , half                              >= 0.1
+    , storable-complex                  >= 0.2
+
+  build-tools:
+      c2hs                              >= 0.16
+
+  ghc-options:
+      -Wall
+      -O2
+      -funbox-strict-fields
+      -fwarn-tabs
+      -fno-warn-unused-imports
+
+source-repository head
+    type:               git
+    location:           https://github.com/tmcdonell/cusparse
+
+source-repository this
+    type:               git
+    location:           https://github.com/tmcdonell/cusparse
+    tag:                0.1.0.0
+
+-- vim: nospell
