diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,10 @@
+# Revision history for cusolver
+
+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. Released on an unsuspecting world.
+
diff --git a/Foreign/CUDA/Solver/Dense.hs b/Foreign/CUDA/Solver/Dense.hs
new file mode 100644
--- /dev/null
+++ b/Foreign/CUDA/Solver/Dense.hs
@@ -0,0 +1,52 @@
+-- |
+-- Module      : Foreign.CUDA.Solver.Dense
+-- Copyright   : [2017] Trevor L. McDonell
+-- License     : BSD3
+--
+-- Maintainer  : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+--
+-- The cuSolver library provides useful LAPACK-like features implemented on
+-- NVIDIA GPUs. This module implements a subset of LAPACK functions on dense
+-- matrices.
+--
+-- To use operations from the cuSolver library, the user must allocate the
+-- required vectors and matrices in the GPU memory space, fill them with data,
+-- call the desired sequence of cuSolver 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/]
+--
+-- /TODO/
+--
+-- [/Additional information/]
+--
+-- For more information, see the NVIDIA cuSolver documentation:
+--
+-- <http://docs.nvidia.com/cuda/cusolver/index.html>
+--
+
+module Foreign.CUDA.Solver.Dense (
+
+  -- * Control
+  module Foreign.CUDA.Solver.Dense.Context,
+  module Foreign.CUDA.Solver.Dense.Stream,
+  module Foreign.CUDA.Solver.Error,
+
+  -- * Operations
+  module Foreign.CUDA.Solver.Dense.Linear,
+  module Foreign.CUDA.Solver.Dense.Eigenvalue,
+
+) where
+
+import Foreign.CUDA.Solver.Dense.Context                  hiding ( useHandle )
+import Foreign.CUDA.Solver.Dense.Stream
+import Foreign.CUDA.Solver.Error
+
+import Foreign.CUDA.Solver.Dense.Linear
+import Foreign.CUDA.Solver.Dense.Eigenvalue
+
diff --git a/Foreign/CUDA/Solver/Dense/Analysis.chs b/Foreign/CUDA/Solver/Dense/Analysis.chs
new file mode 100644
--- /dev/null
+++ b/Foreign/CUDA/Solver/Dense/Analysis.chs
@@ -0,0 +1,29 @@
+{-# LANGUAGE CPP                      #-}
+{-# LANGUAGE EmptyDataDecls           #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+-- |
+-- Module      : Foreign.CUDA.Solver.Dense.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.Solver.Dense.Analysis (
+
+) where
+
+-- friends
+import Foreign.CUDA.Solver.Error
+import Foreign.CUDA.Solver.Internal.C2HS
+
+-- system
+import Foreign
+import Foreign.C
+import Control.Monad                                      ( liftM )
+
+#include "cbits/stubs.h"
+{# context lib="cusolver" #}
+
diff --git a/Foreign/CUDA/Solver/Dense/Context.chs b/Foreign/CUDA/Solver/Dense/Context.chs
new file mode 100644
--- /dev/null
+++ b/Foreign/CUDA/Solver/Dense/Context.chs
@@ -0,0 +1,63 @@
+{-# LANGUAGE CPP                      #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+-- |
+-- Module      : Foreign.CUDA.Solver.Dense.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.Solver.Dense.Context (
+
+  -- * Context management
+  Handle(..),
+  create,
+  destroy,
+
+) where
+
+-- Friends
+import Foreign.CUDA.Solver.Error
+import Foreign.CUDA.Solver.Internal.C2HS
+
+-- System
+import Foreign
+import Foreign.C
+import Control.Monad                                      ( liftM )
+
+#include "cbits/stubs.h"
+{# context lib="cusolver" #}
+
+
+-- | An opaque handle to the cuSolverDN context, which is passed to all library
+-- function calls.
+--
+-- <http://docs.nvidia.com/cuda/cusolver/index.html#cuSolverDNhandle>
+--
+newtype Handle = Handle { useHandle :: {# type cusolverDnHandle_t #}}
+
+
+-- | This function initializes the cuSolverDN library and creates a handle to
+-- the cuSolverDN context. It must be called before any other cuSolverDN API
+-- function is invoked. It allocates hardware resources necessary for accessing
+-- the GPU.
+--
+-- <http://docs.nvidia.com/cuda/cusolver/index.html#cuSolverDNcreate>
+--
+{-# INLINEABLE create #-}
+{# fun unsafe cusolverDnCreate as create
+  { alloca- `Handle' peekHdl* } -> `()' checkStatus*- #}
+  where
+    peekHdl = liftM Handle . peek
+
+-- | This function releases resources used by the cuSolverDN library.
+--
+-- <http://docs.nvidia.com/cuda/cusolver/index.html#cuSolverDNdestroy>
+--
+{-# INLINEABLE destroy #-}
+{# fun unsafe cusolverDnDestroy as destroy
+  { useHandle `Handle' } -> `()' checkStatus* #}
+
diff --git a/Foreign/CUDA/Solver/Dense/Eigenvalue.chs b/Foreign/CUDA/Solver/Dense/Eigenvalue.chs
new file mode 100644
--- /dev/null
+++ b/Foreign/CUDA/Solver/Dense/Eigenvalue.chs
@@ -0,0 +1,458 @@
+--
+-- 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.Solver.Dense.Eigenvalue
+-- 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 cuSolver function reference:
+--
+-- <http://docs.nvidia.com/cuda/cusolver/index.html#cuds-eigensolver-reference>
+--
+
+module Foreign.CUDA.Solver.Dense.Eigenvalue (
+
+  Handle,
+  Fill(..),
+  Side(..),
+  Operation(..),
+  EigMode(..),
+  EigType(..),
+  sgebrd_bufferSize,
+  dgebrd_bufferSize,
+  cgebrd_bufferSize,
+  zgebrd_bufferSize,
+  sgebrd,
+  dgebrd,
+  cgebrd,
+  zgebrd,
+  sgesvd_bufferSize,
+  dgesvd_bufferSize,
+  cgesvd_bufferSize,
+  zgesvd_bufferSize,
+  sgesvd,
+  dgesvd,
+  cgesvd,
+  zgesvd,
+  sorgbr_bufferSize,
+  dorgbr_bufferSize,
+  cungbr_bufferSize,
+  zungbr_bufferSize,
+  sorgbr,
+  dorgbr,
+  cungbr,
+  zungbr,
+  ssytrd_bufferSize,
+  dsytrd_bufferSize,
+  chetrd_bufferSize,
+  zhetrd_bufferSize,
+  ssytrd,
+  dsytrd,
+  chetrd,
+  zhetrd,
+  sormtr_bufferSize,
+  dormtr_bufferSize,
+  cunmtr_bufferSize,
+  zunmtr_bufferSize,
+  sormtr,
+  dormtr,
+  cunmtr,
+  zunmtr,
+  sorgtr_bufferSize,
+  dorgtr_bufferSize,
+  cungtr_bufferSize,
+  zungtr_bufferSize,
+  sorgtr,
+  dorgtr,
+  cungtr,
+  zungtr,
+  ssyevd_bufferSize,
+  dsyevd_bufferSize,
+  cheevd_bufferSize,
+  zheevd_bufferSize,
+  ssyevd,
+  dsyevd,
+  cheevd,
+  zheevd,
+  ssygvd_bufferSize,
+  dsygvd_bufferSize,
+  chegvd_bufferSize,
+  zhegvd_bufferSize,
+  ssygvd,
+  dsygvd,
+  chegvd,
+  zhegvd,
+
+) where
+
+import Data.Complex
+import Foreign
+import Foreign.C
+import Foreign.Storable.Complex ()
+import Foreign.CUDA.Ptr
+import Foreign.CUDA.Solver.Dense.Context
+import Foreign.CUDA.Solver.Dense.Analysis
+import Foreign.CUDA.Solver.Error
+import Foreign.CUDA.Solver.Internal.C2HS
+import Foreign.CUDA.Solver.Internal.Types
+
+#include "cbits/stubs.h"
+{# context lib="cusolver" #}
+
+{-# INLINE useDevP #-}
+useDevP :: DevicePtr a -> Ptr b
+useDevP = useDevicePtr . castDevPtr
+
+{-# INLINE useHostP #-}
+useHostP :: HostPtr a -> Ptr b
+useHostP = useHostPtr . castHostPtr
+
+
+{-# INLINEABLE sgebrd_bufferSize #-}
+{# fun unsafe cusolverDnSgebrd_bufferSize as sgebrd_bufferSize { useHandle `Handle', `Int', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dgebrd_bufferSize #-}
+{# fun unsafe cusolverDnDgebrd_bufferSize as dgebrd_bufferSize { useHandle `Handle', `Int', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cgebrd_bufferSize #-}
+{# fun unsafe cusolverDnCgebrd_bufferSize as cgebrd_bufferSize { useHandle `Handle', `Int', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zgebrd_bufferSize #-}
+{# fun unsafe cusolverDnZgebrd_bufferSize as zgebrd_bufferSize { useHandle `Handle', `Int', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sgebrd #-}
+{# fun unsafe cusolverDnSgebrd as sgebrd { useHandle `Handle', `Int', `Int', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Float', useDevP `DevicePtr Float', useDevP `DevicePtr Float', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dgebrd #-}
+{# fun unsafe cusolverDnDgebrd as dgebrd { useHandle `Handle', `Int', `Int', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Double', useDevP `DevicePtr Double', useDevP `DevicePtr Double', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cgebrd #-}
+{# fun unsafe cusolverDnCgebrd as cgebrd { useHandle `Handle', `Int', `Int', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zgebrd #-}
+{# fun unsafe cusolverDnZgebrd as zgebrd { useHandle `Handle', `Int', `Int', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sgesvd_bufferSize #-}
+{# fun unsafe cusolverDnSgesvd_bufferSize as sgesvd_bufferSize { useHandle `Handle', `Int', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dgesvd_bufferSize #-}
+{# fun unsafe cusolverDnDgesvd_bufferSize as dgesvd_bufferSize { useHandle `Handle', `Int', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cgesvd_bufferSize #-}
+{# fun unsafe cusolverDnCgesvd_bufferSize as cgesvd_bufferSize { useHandle `Handle', `Int', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zgesvd_bufferSize #-}
+{# fun unsafe cusolverDnZgesvd_bufferSize as zgesvd_bufferSize { useHandle `Handle', `Int', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sgesvd #-}
+{# fun unsafe cusolverDnSgesvd as sgesvd { useHandle `Handle', `Char', `Char', `Int', `Int', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dgesvd #-}
+{# fun unsafe cusolverDnDgesvd as dgesvd { useHandle `Handle', `Char', `Char', `Int', `Int', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cgesvd #-}
+{# fun unsafe cusolverDnCgesvd as cgesvd { useHandle `Handle', `Char', `Char', `Int', `Int', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zgesvd #-}
+{# fun unsafe cusolverDnZgesvd as zgesvd { useHandle `Handle', `Char', `Char', `Int', `Int', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+#if CUDA_VERSION >= 8000
+
+{-# INLINEABLE sorgbr_bufferSize #-}
+{# fun unsafe cusolverDnSorgbr_bufferSize as sorgbr_bufferSize { useHandle `Handle', cFromEnum `Side', `Int', `Int', `Int', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Float', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dorgbr_bufferSize #-}
+{# fun unsafe cusolverDnDorgbr_bufferSize as dorgbr_bufferSize { useHandle `Handle', cFromEnum `Side', `Int', `Int', `Int', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Double', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cungbr_bufferSize #-}
+{# fun unsafe cusolverDnCungbr_bufferSize as cungbr_bufferSize { useHandle `Handle', cFromEnum `Side', `Int', `Int', `Int', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr (Complex Float)', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zungbr_bufferSize #-}
+{# fun unsafe cusolverDnZungbr_bufferSize as zungbr_bufferSize { useHandle `Handle', cFromEnum `Side', `Int', `Int', `Int', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr (Complex Double)', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sorgbr #-}
+{# fun unsafe cusolverDnSorgbr as sorgbr { useHandle `Handle', cFromEnum `Side', `Int', `Int', `Int', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dorgbr #-}
+{# fun unsafe cusolverDnDorgbr as dorgbr { useHandle `Handle', cFromEnum `Side', `Int', `Int', `Int', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cungbr #-}
+{# fun unsafe cusolverDnCungbr as cungbr { useHandle `Handle', cFromEnum `Side', `Int', `Int', `Int', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zungbr #-}
+{# fun unsafe cusolverDnZungbr as zungbr { useHandle `Handle', cFromEnum `Side', `Int', `Int', `Int', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ssytrd_bufferSize #-}
+{# fun unsafe cusolverDnSsytrd_bufferSize as ssytrd_bufferSize { useHandle `Handle', cFromEnum `Fill', `Int', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Float', useDevP `DevicePtr Float', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dsytrd_bufferSize #-}
+{# fun unsafe cusolverDnDsytrd_bufferSize as dsytrd_bufferSize { useHandle `Handle', cFromEnum `Fill', `Int', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Double', useDevP `DevicePtr Double', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE chetrd_bufferSize #-}
+{# fun unsafe cusolverDnChetrd_bufferSize as chetrd_bufferSize { useHandle `Handle', cFromEnum `Fill', `Int', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zhetrd_bufferSize #-}
+{# fun unsafe cusolverDnZhetrd_bufferSize as zhetrd_bufferSize { useHandle `Handle', cFromEnum `Fill', `Int', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ssytrd #-}
+{# fun unsafe cusolverDnSsytrd as ssytrd { useHandle `Handle', cFromEnum `Fill', `Int', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Float', useDevP `DevicePtr Float', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dsytrd #-}
+{# fun unsafe cusolverDnDsytrd as dsytrd { useHandle `Handle', cFromEnum `Fill', `Int', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Double', useDevP `DevicePtr Double', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE chetrd #-}
+{# fun unsafe cusolverDnChetrd as chetrd { useHandle `Handle', cFromEnum `Fill', `Int', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zhetrd #-}
+{# fun unsafe cusolverDnZhetrd as zhetrd { useHandle `Handle', cFromEnum `Fill', `Int', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sormtr_bufferSize #-}
+{# fun unsafe cusolverDnSormtr_bufferSize as sormtr_bufferSize { useHandle `Handle', cFromEnum `Side', cFromEnum `Fill', cFromEnum `Operation', `Int', `Int', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Float', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dormtr_bufferSize #-}
+{# fun unsafe cusolverDnDormtr_bufferSize as dormtr_bufferSize { useHandle `Handle', cFromEnum `Side', cFromEnum `Fill', cFromEnum `Operation', `Int', `Int', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Double', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cunmtr_bufferSize #-}
+{# fun unsafe cusolverDnCunmtr_bufferSize as cunmtr_bufferSize { useHandle `Handle', cFromEnum `Side', cFromEnum `Fill', cFromEnum `Operation', `Int', `Int', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zunmtr_bufferSize #-}
+{# fun unsafe cusolverDnZunmtr_bufferSize as zunmtr_bufferSize { useHandle `Handle', cFromEnum `Side', cFromEnum `Fill', cFromEnum `Operation', `Int', `Int', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sormtr #-}
+{# fun unsafe cusolverDnSormtr as sormtr { useHandle `Handle', cFromEnum `Side', cFromEnum `Fill', cFromEnum `Operation', `Int', `Int', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dormtr #-}
+{# fun unsafe cusolverDnDormtr as dormtr { useHandle `Handle', cFromEnum `Side', cFromEnum `Fill', cFromEnum `Operation', `Int', `Int', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cunmtr #-}
+{# fun unsafe cusolverDnCunmtr as cunmtr { useHandle `Handle', cFromEnum `Side', cFromEnum `Fill', cFromEnum `Operation', `Int', `Int', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zunmtr #-}
+{# fun unsafe cusolverDnZunmtr as zunmtr { useHandle `Handle', cFromEnum `Side', cFromEnum `Fill', cFromEnum `Operation', `Int', `Int', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sorgtr_bufferSize #-}
+{# fun unsafe cusolverDnSorgtr_bufferSize as sorgtr_bufferSize { useHandle `Handle', cFromEnum `Fill', `Int', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Float', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dorgtr_bufferSize #-}
+{# fun unsafe cusolverDnDorgtr_bufferSize as dorgtr_bufferSize { useHandle `Handle', cFromEnum `Fill', `Int', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Double', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cungtr_bufferSize #-}
+{# fun unsafe cusolverDnCungtr_bufferSize as cungtr_bufferSize { useHandle `Handle', cFromEnum `Fill', `Int', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr (Complex Float)', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zungtr_bufferSize #-}
+{# fun unsafe cusolverDnZungtr_bufferSize as zungtr_bufferSize { useHandle `Handle', cFromEnum `Fill', `Int', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr (Complex Double)', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sorgtr #-}
+{# fun unsafe cusolverDnSorgtr as sorgtr { useHandle `Handle', cFromEnum `Fill', `Int', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dorgtr #-}
+{# fun unsafe cusolverDnDorgtr as dorgtr { useHandle `Handle', cFromEnum `Fill', `Int', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cungtr #-}
+{# fun unsafe cusolverDnCungtr as cungtr { useHandle `Handle', cFromEnum `Fill', `Int', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zungtr #-}
+{# fun unsafe cusolverDnZungtr as zungtr { useHandle `Handle', cFromEnum `Fill', `Int', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ssyevd_bufferSize #-}
+{# fun unsafe cusolverDnSsyevd_bufferSize as ssyevd_bufferSize { useHandle `Handle', cFromEnum `EigMode', cFromEnum `Fill', `Int', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Float', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dsyevd_bufferSize #-}
+{# fun unsafe cusolverDnDsyevd_bufferSize as dsyevd_bufferSize { useHandle `Handle', cFromEnum `EigMode', cFromEnum `Fill', `Int', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Double', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cheevd_bufferSize #-}
+{# fun unsafe cusolverDnCheevd_bufferSize as cheevd_bufferSize { useHandle `Handle', cFromEnum `EigMode', cFromEnum `Fill', `Int', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr (Complex Float)', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zheevd_bufferSize #-}
+{# fun unsafe cusolverDnZheevd_bufferSize as zheevd_bufferSize { useHandle `Handle', cFromEnum `EigMode', cFromEnum `Fill', `Int', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr (Complex Double)', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ssyevd #-}
+{# fun unsafe cusolverDnSsyevd as ssyevd { useHandle `Handle', cFromEnum `EigMode', cFromEnum `Fill', `Int', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dsyevd #-}
+{# fun unsafe cusolverDnDsyevd as dsyevd { useHandle `Handle', cFromEnum `EigMode', cFromEnum `Fill', `Int', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cheevd #-}
+{# fun unsafe cusolverDnCheevd as cheevd { useHandle `Handle', cFromEnum `EigMode', cFromEnum `Fill', `Int', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zheevd #-}
+{# fun unsafe cusolverDnZheevd as zheevd { useHandle `Handle', cFromEnum `EigMode', cFromEnum `Fill', `Int', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ssygvd_bufferSize #-}
+{# fun unsafe cusolverDnSsygvd_bufferSize as ssygvd_bufferSize { useHandle `Handle', cFromEnum `EigType', cFromEnum `EigMode', cFromEnum `Fill', `Int', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Float', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dsygvd_bufferSize #-}
+{# fun unsafe cusolverDnDsygvd_bufferSize as dsygvd_bufferSize { useHandle `Handle', cFromEnum `EigType', cFromEnum `EigMode', cFromEnum `Fill', `Int', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Double', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE chegvd_bufferSize #-}
+{# fun unsafe cusolverDnChegvd_bufferSize as chegvd_bufferSize { useHandle `Handle', cFromEnum `EigType', cFromEnum `EigMode', cFromEnum `Fill', `Int', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr (Complex Float)', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zhegvd_bufferSize #-}
+{# fun unsafe cusolverDnZhegvd_bufferSize as zhegvd_bufferSize { useHandle `Handle', cFromEnum `EigType', cFromEnum `EigMode', cFromEnum `Fill', `Int', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr (Complex Double)', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ssygvd #-}
+{# fun unsafe cusolverDnSsygvd as ssygvd { useHandle `Handle', cFromEnum `EigType', cFromEnum `EigMode', cFromEnum `Fill', `Int', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dsygvd #-}
+{# fun unsafe cusolverDnDsygvd as dsygvd { useHandle `Handle', cFromEnum `EigType', cFromEnum `EigMode', cFromEnum `Fill', `Int', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE chegvd #-}
+{# fun unsafe cusolverDnChegvd as chegvd { useHandle `Handle', cFromEnum `EigType', cFromEnum `EigMode', cFromEnum `Fill', `Int', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zhegvd #-}
+{# fun unsafe cusolverDnZhegvd as zhegvd { useHandle `Handle', cFromEnum `EigType', cFromEnum `EigMode', cFromEnum `Fill', `Int', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+#else
+
+sorgbr_bufferSize :: Handle -> Side -> Int -> Int -> Int -> DevicePtr Float -> Int -> DevicePtr Float -> Int -> IO ()
+sorgbr_bufferSize _ _ _ _ _ _ _ _ _ = cusolverError "'sorgbr_bufferSize' requires at least cuda-8.0"
+
+dorgbr_bufferSize :: Handle -> Side -> Int -> Int -> Int -> DevicePtr Double -> Int -> DevicePtr Double -> Int -> IO ()
+dorgbr_bufferSize _ _ _ _ _ _ _ _ _ = cusolverError "'dorgbr_bufferSize' requires at least cuda-8.0"
+
+cungbr_bufferSize :: Handle -> Side -> Int -> Int -> Int -> DevicePtr (Complex Float) -> Int -> DevicePtr (Complex Float) -> Int -> IO ()
+cungbr_bufferSize _ _ _ _ _ _ _ _ _ = cusolverError "'cungbr_bufferSize' requires at least cuda-8.0"
+
+zungbr_bufferSize :: Handle -> Side -> Int -> Int -> Int -> DevicePtr (Complex Double) -> Int -> DevicePtr (Complex Double) -> Int -> IO ()
+zungbr_bufferSize _ _ _ _ _ _ _ _ _ = cusolverError "'zungbr_bufferSize' requires at least cuda-8.0"
+
+sorgbr :: Handle -> Side -> Int -> Int -> Int -> DevicePtr Float -> Int -> DevicePtr Float -> DevicePtr Float -> Int -> DevicePtr Int32 -> IO ()
+sorgbr _ _ _ _ _ _ _ _ _ _ _ = cusolverError "'sorgbr' requires at least cuda-8.0"
+
+dorgbr :: Handle -> Side -> Int -> Int -> Int -> DevicePtr Double -> Int -> DevicePtr Double -> DevicePtr Double -> Int -> DevicePtr Int32 -> IO ()
+dorgbr _ _ _ _ _ _ _ _ _ _ _ = cusolverError "'dorgbr' requires at least cuda-8.0"
+
+cungbr :: Handle -> Side -> Int -> Int -> Int -> DevicePtr (Complex Float) -> Int -> DevicePtr (Complex Float) -> DevicePtr (Complex Float) -> Int -> DevicePtr Int32 -> IO ()
+cungbr _ _ _ _ _ _ _ _ _ _ _ = cusolverError "'cungbr' requires at least cuda-8.0"
+
+zungbr :: Handle -> Side -> Int -> Int -> Int -> DevicePtr (Complex Double) -> Int -> DevicePtr (Complex Double) -> DevicePtr (Complex Double) -> Int -> DevicePtr Int32 -> IO ()
+zungbr _ _ _ _ _ _ _ _ _ _ _ = cusolverError "'zungbr' requires at least cuda-8.0"
+
+ssytrd_bufferSize :: Handle -> Fill -> Int -> DevicePtr Float -> Int -> DevicePtr Float -> DevicePtr Float -> DevicePtr Float -> Int -> IO ()
+ssytrd_bufferSize _ _ _ _ _ _ _ _ _ = cusolverError "'ssytrd_bufferSize' requires at least cuda-8.0"
+
+dsytrd_bufferSize :: Handle -> Fill -> Int -> DevicePtr Double -> Int -> DevicePtr Double -> DevicePtr Double -> DevicePtr Double -> Int -> IO ()
+dsytrd_bufferSize _ _ _ _ _ _ _ _ _ = cusolverError "'dsytrd_bufferSize' requires at least cuda-8.0"
+
+chetrd_bufferSize :: Handle -> Fill -> Int -> DevicePtr (Complex Float) -> Int -> DevicePtr (Complex Float) -> DevicePtr (Complex Float) -> DevicePtr (Complex Float) -> Int -> IO ()
+chetrd_bufferSize _ _ _ _ _ _ _ _ _ = cusolverError "'chetrd_bufferSize' requires at least cuda-8.0"
+
+zhetrd_bufferSize :: Handle -> Fill -> Int -> DevicePtr (Complex Double) -> Int -> DevicePtr (Complex Double) -> DevicePtr (Complex Double) -> DevicePtr (Complex Double) -> Int -> IO ()
+zhetrd_bufferSize _ _ _ _ _ _ _ _ _ = cusolverError "'zhetrd_bufferSize' requires at least cuda-8.0"
+
+ssytrd :: Handle -> Fill -> Int -> DevicePtr Float -> Int -> DevicePtr Float -> DevicePtr Float -> DevicePtr Float -> DevicePtr Float -> Int -> DevicePtr Int32 -> IO ()
+ssytrd _ _ _ _ _ _ _ _ _ _ _ = cusolverError "'ssytrd' requires at least cuda-8.0"
+
+dsytrd :: Handle -> Fill -> Int -> DevicePtr Double -> Int -> DevicePtr Double -> DevicePtr Double -> DevicePtr Double -> DevicePtr Double -> Int -> DevicePtr Int32 -> IO ()
+dsytrd _ _ _ _ _ _ _ _ _ _ _ = cusolverError "'dsytrd' requires at least cuda-8.0"
+
+chetrd :: Handle -> Fill -> Int -> DevicePtr (Complex Float) -> Int -> DevicePtr (Complex Float) -> DevicePtr (Complex Float) -> DevicePtr (Complex Float) -> DevicePtr (Complex Float) -> Int -> DevicePtr Int32 -> IO ()
+chetrd _ _ _ _ _ _ _ _ _ _ _ = cusolverError "'chetrd' requires at least cuda-8.0"
+
+zhetrd :: Handle -> Fill -> Int -> DevicePtr (Complex Double) -> Int -> DevicePtr (Complex Double) -> DevicePtr (Complex Double) -> DevicePtr (Complex Double) -> DevicePtr (Complex Double) -> Int -> DevicePtr Int32 -> IO ()
+zhetrd _ _ _ _ _ _ _ _ _ _ _ = cusolverError "'zhetrd' requires at least cuda-8.0"
+
+sormtr_bufferSize :: Handle -> Side -> Fill -> Operation -> Int -> Int -> DevicePtr Float -> Int -> DevicePtr Float -> DevicePtr Float -> Int -> Int -> IO ()
+sormtr_bufferSize _ _ _ _ _ _ _ _ _ _ _ _ = cusolverError "'sormtr_bufferSize' requires at least cuda-8.0"
+
+dormtr_bufferSize :: Handle -> Side -> Fill -> Operation -> Int -> Int -> DevicePtr Double -> Int -> DevicePtr Double -> DevicePtr Double -> Int -> Int -> IO ()
+dormtr_bufferSize _ _ _ _ _ _ _ _ _ _ _ _ = cusolverError "'dormtr_bufferSize' requires at least cuda-8.0"
+
+cunmtr_bufferSize :: Handle -> Side -> Fill -> Operation -> Int -> Int -> DevicePtr (Complex Float) -> Int -> DevicePtr (Complex Float) -> DevicePtr (Complex Float) -> Int -> Int -> IO ()
+cunmtr_bufferSize _ _ _ _ _ _ _ _ _ _ _ _ = cusolverError "'cunmtr_bufferSize' requires at least cuda-8.0"
+
+zunmtr_bufferSize :: Handle -> Side -> Fill -> Operation -> Int -> Int -> DevicePtr (Complex Double) -> Int -> DevicePtr (Complex Double) -> DevicePtr (Complex Double) -> Int -> Int -> IO ()
+zunmtr_bufferSize _ _ _ _ _ _ _ _ _ _ _ _ = cusolverError "'zunmtr_bufferSize' requires at least cuda-8.0"
+
+sormtr :: Handle -> Side -> Fill -> Operation -> Int -> Int -> DevicePtr Float -> Int -> DevicePtr Float -> DevicePtr Float -> Int -> DevicePtr Float -> Int -> DevicePtr Int32 -> IO ()
+sormtr _ _ _ _ _ _ _ _ _ _ _ _ _ _ = cusolverError "'sormtr' requires at least cuda-8.0"
+
+dormtr :: Handle -> Side -> Fill -> Operation -> Int -> Int -> DevicePtr Double -> Int -> DevicePtr Double -> DevicePtr Double -> Int -> DevicePtr Double -> Int -> DevicePtr Int32 -> IO ()
+dormtr _ _ _ _ _ _ _ _ _ _ _ _ _ _ = cusolverError "'dormtr' requires at least cuda-8.0"
+
+cunmtr :: Handle -> Side -> Fill -> Operation -> Int -> Int -> DevicePtr (Complex Float) -> Int -> DevicePtr (Complex Float) -> DevicePtr (Complex Float) -> Int -> DevicePtr (Complex Float) -> Int -> DevicePtr Int32 -> IO ()
+cunmtr _ _ _ _ _ _ _ _ _ _ _ _ _ _ = cusolverError "'cunmtr' requires at least cuda-8.0"
+
+zunmtr :: Handle -> Side -> Fill -> Operation -> Int -> Int -> DevicePtr (Complex Double) -> Int -> DevicePtr (Complex Double) -> DevicePtr (Complex Double) -> Int -> DevicePtr (Complex Double) -> Int -> DevicePtr Int32 -> IO ()
+zunmtr _ _ _ _ _ _ _ _ _ _ _ _ _ _ = cusolverError "'zunmtr' requires at least cuda-8.0"
+
+sorgtr_bufferSize :: Handle -> Fill -> Int -> DevicePtr Float -> Int -> DevicePtr Float -> Int -> IO ()
+sorgtr_bufferSize _ _ _ _ _ _ _ = cusolverError "'sorgtr_bufferSize' requires at least cuda-8.0"
+
+dorgtr_bufferSize :: Handle -> Fill -> Int -> DevicePtr Double -> Int -> DevicePtr Double -> Int -> IO ()
+dorgtr_bufferSize _ _ _ _ _ _ _ = cusolverError "'dorgtr_bufferSize' requires at least cuda-8.0"
+
+cungtr_bufferSize :: Handle -> Fill -> Int -> DevicePtr (Complex Float) -> Int -> DevicePtr (Complex Float) -> Int -> IO ()
+cungtr_bufferSize _ _ _ _ _ _ _ = cusolverError "'cungtr_bufferSize' requires at least cuda-8.0"
+
+zungtr_bufferSize :: Handle -> Fill -> Int -> DevicePtr (Complex Double) -> Int -> DevicePtr (Complex Double) -> Int -> IO ()
+zungtr_bufferSize _ _ _ _ _ _ _ = cusolverError "'zungtr_bufferSize' requires at least cuda-8.0"
+
+sorgtr :: Handle -> Fill -> Int -> DevicePtr Float -> Int -> DevicePtr Float -> DevicePtr Float -> Int -> DevicePtr Int32 -> IO ()
+sorgtr _ _ _ _ _ _ _ _ _ = cusolverError "'sorgtr' requires at least cuda-8.0"
+
+dorgtr :: Handle -> Fill -> Int -> DevicePtr Double -> Int -> DevicePtr Double -> DevicePtr Double -> Int -> DevicePtr Int32 -> IO ()
+dorgtr _ _ _ _ _ _ _ _ _ = cusolverError "'dorgtr' requires at least cuda-8.0"
+
+cungtr :: Handle -> Fill -> Int -> DevicePtr (Complex Float) -> Int -> DevicePtr (Complex Float) -> DevicePtr (Complex Float) -> Int -> DevicePtr Int32 -> IO ()
+cungtr _ _ _ _ _ _ _ _ _ = cusolverError "'cungtr' requires at least cuda-8.0"
+
+zungtr :: Handle -> Fill -> Int -> DevicePtr (Complex Double) -> Int -> DevicePtr (Complex Double) -> DevicePtr (Complex Double) -> Int -> DevicePtr Int32 -> IO ()
+zungtr _ _ _ _ _ _ _ _ _ = cusolverError "'zungtr' requires at least cuda-8.0"
+
+ssyevd_bufferSize :: Handle -> EigMode -> Fill -> Int -> DevicePtr Float -> Int -> DevicePtr Float -> Int -> IO ()
+ssyevd_bufferSize _ _ _ _ _ _ _ _ = cusolverError "'ssyevd_bufferSize' requires at least cuda-8.0"
+
+dsyevd_bufferSize :: Handle -> EigMode -> Fill -> Int -> DevicePtr Double -> Int -> DevicePtr Double -> Int -> IO ()
+dsyevd_bufferSize _ _ _ _ _ _ _ _ = cusolverError "'dsyevd_bufferSize' requires at least cuda-8.0"
+
+cheevd_bufferSize :: Handle -> EigMode -> Fill -> Int -> DevicePtr (Complex Float) -> Int -> DevicePtr (Complex Float) -> Int -> IO ()
+cheevd_bufferSize _ _ _ _ _ _ _ _ = cusolverError "'cheevd_bufferSize' requires at least cuda-8.0"
+
+zheevd_bufferSize :: Handle -> EigMode -> Fill -> Int -> DevicePtr (Complex Double) -> Int -> DevicePtr (Complex Double) -> Int -> IO ()
+zheevd_bufferSize _ _ _ _ _ _ _ _ = cusolverError "'zheevd_bufferSize' requires at least cuda-8.0"
+
+ssyevd :: Handle -> EigMode -> Fill -> Int -> DevicePtr Float -> Int -> DevicePtr Float -> DevicePtr Float -> Int -> DevicePtr Int32 -> IO ()
+ssyevd _ _ _ _ _ _ _ _ _ _ = cusolverError "'ssyevd' requires at least cuda-8.0"
+
+dsyevd :: Handle -> EigMode -> Fill -> Int -> DevicePtr Double -> Int -> DevicePtr Double -> DevicePtr Double -> Int -> DevicePtr Int32 -> IO ()
+dsyevd _ _ _ _ _ _ _ _ _ _ = cusolverError "'dsyevd' requires at least cuda-8.0"
+
+cheevd :: Handle -> EigMode -> Fill -> Int -> DevicePtr (Complex Float) -> Int -> DevicePtr (Complex Float) -> DevicePtr (Complex Float) -> Int -> DevicePtr Int32 -> IO ()
+cheevd _ _ _ _ _ _ _ _ _ _ = cusolverError "'cheevd' requires at least cuda-8.0"
+
+zheevd :: Handle -> EigMode -> Fill -> Int -> DevicePtr (Complex Double) -> Int -> DevicePtr (Complex Double) -> DevicePtr (Complex Double) -> Int -> DevicePtr Int32 -> IO ()
+zheevd _ _ _ _ _ _ _ _ _ _ = cusolverError "'zheevd' requires at least cuda-8.0"
+
+ssygvd_bufferSize :: Handle -> EigType -> EigMode -> Fill -> Int -> DevicePtr Float -> Int -> DevicePtr Float -> Int -> DevicePtr Float -> Int -> IO ()
+ssygvd_bufferSize _ _ _ _ _ _ _ _ _ _ _ = cusolverError "'ssygvd_bufferSize' requires at least cuda-8.0"
+
+dsygvd_bufferSize :: Handle -> EigType -> EigMode -> Fill -> Int -> DevicePtr Double -> Int -> DevicePtr Double -> Int -> DevicePtr Double -> Int -> IO ()
+dsygvd_bufferSize _ _ _ _ _ _ _ _ _ _ _ = cusolverError "'dsygvd_bufferSize' requires at least cuda-8.0"
+
+chegvd_bufferSize :: Handle -> EigType -> EigMode -> Fill -> Int -> DevicePtr (Complex Float) -> Int -> DevicePtr (Complex Float) -> Int -> DevicePtr (Complex Float) -> Int -> IO ()
+chegvd_bufferSize _ _ _ _ _ _ _ _ _ _ _ = cusolverError "'chegvd_bufferSize' requires at least cuda-8.0"
+
+zhegvd_bufferSize :: Handle -> EigType -> EigMode -> Fill -> Int -> DevicePtr (Complex Double) -> Int -> DevicePtr (Complex Double) -> Int -> DevicePtr (Complex Double) -> Int -> IO ()
+zhegvd_bufferSize _ _ _ _ _ _ _ _ _ _ _ = cusolverError "'zhegvd_bufferSize' requires at least cuda-8.0"
+
+ssygvd :: Handle -> EigType -> EigMode -> Fill -> Int -> DevicePtr Float -> Int -> DevicePtr Float -> Int -> DevicePtr Float -> DevicePtr Float -> Int -> DevicePtr Int32 -> IO ()
+ssygvd _ _ _ _ _ _ _ _ _ _ _ _ _ = cusolverError "'ssygvd' requires at least cuda-8.0"
+
+dsygvd :: Handle -> EigType -> EigMode -> Fill -> Int -> DevicePtr Double -> Int -> DevicePtr Double -> Int -> DevicePtr Double -> DevicePtr Double -> Int -> DevicePtr Int32 -> IO ()
+dsygvd _ _ _ _ _ _ _ _ _ _ _ _ _ = cusolverError "'dsygvd' requires at least cuda-8.0"
+
+chegvd :: Handle -> EigType -> EigMode -> Fill -> Int -> DevicePtr (Complex Float) -> Int -> DevicePtr (Complex Float) -> Int -> DevicePtr (Complex Float) -> DevicePtr (Complex Float) -> Int -> DevicePtr Int32 -> IO ()
+chegvd _ _ _ _ _ _ _ _ _ _ _ _ _ = cusolverError "'chegvd' requires at least cuda-8.0"
+
+zhegvd :: Handle -> EigType -> EigMode -> Fill -> Int -> DevicePtr (Complex Double) -> Int -> DevicePtr (Complex Double) -> Int -> DevicePtr (Complex Double) -> DevicePtr (Complex Double) -> Int -> DevicePtr Int32 -> IO ()
+zhegvd _ _ _ _ _ _ _ _ _ _ _ _ _ = cusolverError "'zhegvd' requires at least cuda-8.0"
+#endif
diff --git a/Foreign/CUDA/Solver/Dense/Linear.chs b/Foreign/CUDA/Solver/Dense/Linear.chs
new file mode 100644
--- /dev/null
+++ b/Foreign/CUDA/Solver/Dense/Linear.chs
@@ -0,0 +1,315 @@
+--
+-- 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.Solver.Dense.Linear
+-- 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 cuSolver function reference:
+--
+-- <http://docs.nvidia.com/cuda/cusolver/index.html#cuds-linearsolver-reference>
+--
+
+module Foreign.CUDA.Solver.Dense.Linear (
+
+  Handle,
+  Fill(..),
+  Side(..),
+  spotrf_bufferSize,
+  dpotrf_bufferSize,
+  cpotrf_bufferSize,
+  zpotrf_bufferSize,
+  spotrf,
+  dpotrf,
+  cpotrf,
+  zpotrf,
+  spotrs,
+  dpotrs,
+  cpotrs,
+  zpotrs,
+  sgetrf_bufferSize,
+  dgetrf_bufferSize,
+  cgetrf_bufferSize,
+  zgetrf_bufferSize,
+  sgetrf,
+  dgetrf,
+  cgetrf,
+  zgetrf,
+  sgetrs,
+  dgetrs,
+  cgetrs,
+  zgetrs,
+  sgeqrf_bufferSize,
+  dgeqrf_bufferSize,
+  cgeqrf_bufferSize,
+  zgeqrf_bufferSize,
+  sgeqrf,
+  dgeqrf,
+  cgeqrf,
+  zgeqrf,
+  sormqr,
+  dormqr,
+  cunmqr,
+  zunmqr,
+  ssytrf_bufferSize,
+  dsytrf_bufferSize,
+  csytrf_bufferSize,
+  zsytrf_bufferSize,
+  ssytrf,
+  dsytrf,
+  csytrf,
+  zsytrf,
+  sorgqr_bufferSize,
+  dorgqr_bufferSize,
+  cungqr_bufferSize,
+  zungqr_bufferSize,
+  sorgqr,
+  dorgqr,
+  cungqr,
+  zungqr,
+  sormqr_bufferSize,
+  dormqr_bufferSize,
+  cunmqr_bufferSize,
+  zunmqr_bufferSize,
+
+) where
+
+import Data.Complex
+import Foreign
+import Foreign.C
+import Foreign.Storable.Complex ()
+import Foreign.CUDA.Ptr
+import Foreign.CUDA.Solver.Dense.Context
+import Foreign.CUDA.Solver.Dense.Analysis
+import Foreign.CUDA.Solver.Error
+import Foreign.CUDA.Solver.Internal.C2HS
+import Foreign.CUDA.Solver.Internal.Types
+
+#include "cbits/stubs.h"
+{# context lib="cusolver" #}
+
+{-# INLINE useDevP #-}
+useDevP :: DevicePtr a -> Ptr b
+useDevP = useDevicePtr . castDevPtr
+
+{-# INLINE useHostP #-}
+useHostP :: HostPtr a -> Ptr b
+useHostP = useHostPtr . castHostPtr
+
+
+{-# INLINEABLE spotrf_bufferSize #-}
+{# fun unsafe cusolverDnSpotrf_bufferSize as spotrf_bufferSize { useHandle `Handle', cFromEnum `Fill', `Int', useDevP `DevicePtr Float', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dpotrf_bufferSize #-}
+{# fun unsafe cusolverDnDpotrf_bufferSize as dpotrf_bufferSize { useHandle `Handle', cFromEnum `Fill', `Int', useDevP `DevicePtr Double', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cpotrf_bufferSize #-}
+{# fun unsafe cusolverDnCpotrf_bufferSize as cpotrf_bufferSize { useHandle `Handle', cFromEnum `Fill', `Int', useDevP `DevicePtr (Complex Float)', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zpotrf_bufferSize #-}
+{# fun unsafe cusolverDnZpotrf_bufferSize as zpotrf_bufferSize { useHandle `Handle', cFromEnum `Fill', `Int', useDevP `DevicePtr (Complex Double)', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE spotrf #-}
+{# fun unsafe cusolverDnSpotrf as spotrf { useHandle `Handle', cFromEnum `Fill', `Int', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dpotrf #-}
+{# fun unsafe cusolverDnDpotrf as dpotrf { useHandle `Handle', cFromEnum `Fill', `Int', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cpotrf #-}
+{# fun unsafe cusolverDnCpotrf as cpotrf { useHandle `Handle', cFromEnum `Fill', `Int', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zpotrf #-}
+{# fun unsafe cusolverDnZpotrf as zpotrf { useHandle `Handle', cFromEnum `Fill', `Int', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE spotrs #-}
+{# fun unsafe cusolverDnSpotrs as spotrs { useHandle `Handle', cFromEnum `Fill', `Int', `Int', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dpotrs #-}
+{# fun unsafe cusolverDnDpotrs as dpotrs { useHandle `Handle', cFromEnum `Fill', `Int', `Int', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cpotrs #-}
+{# fun unsafe cusolverDnCpotrs as cpotrs { useHandle `Handle', cFromEnum `Fill', `Int', `Int', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zpotrs #-}
+{# fun unsafe cusolverDnZpotrs as zpotrs { useHandle `Handle', cFromEnum `Fill', `Int', `Int', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sgetrf_bufferSize #-}
+{# fun unsafe cusolverDnSgetrf_bufferSize as sgetrf_bufferSize { useHandle `Handle', `Int', `Int', useDevP `DevicePtr Float', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dgetrf_bufferSize #-}
+{# fun unsafe cusolverDnDgetrf_bufferSize as dgetrf_bufferSize { useHandle `Handle', `Int', `Int', useDevP `DevicePtr Double', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cgetrf_bufferSize #-}
+{# fun unsafe cusolverDnCgetrf_bufferSize as cgetrf_bufferSize { useHandle `Handle', `Int', `Int', useDevP `DevicePtr (Complex Float)', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zgetrf_bufferSize #-}
+{# fun unsafe cusolverDnZgetrf_bufferSize as zgetrf_bufferSize { useHandle `Handle', `Int', `Int', useDevP `DevicePtr (Complex Double)', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sgetrf #-}
+{# fun unsafe cusolverDnSgetrf as sgetrf { useHandle `Handle', `Int', `Int', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dgetrf #-}
+{# fun unsafe cusolverDnDgetrf as dgetrf { useHandle `Handle', `Int', `Int', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cgetrf #-}
+{# fun unsafe cusolverDnCgetrf as cgetrf { useHandle `Handle', `Int', `Int', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zgetrf #-}
+{# fun unsafe cusolverDnZgetrf as zgetrf { useHandle `Handle', `Int', `Int', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sgetrs #-}
+{# fun unsafe cusolverDnSgetrs as sgetrs { useHandle `Handle', cFromEnum `Operation', `Int', `Int', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dgetrs #-}
+{# fun unsafe cusolverDnDgetrs as dgetrs { useHandle `Handle', cFromEnum `Operation', `Int', `Int', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cgetrs #-}
+{# fun unsafe cusolverDnCgetrs as cgetrs { useHandle `Handle', cFromEnum `Operation', `Int', `Int', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zgetrs #-}
+{# fun unsafe cusolverDnZgetrs as zgetrs { useHandle `Handle', cFromEnum `Operation', `Int', `Int', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sgeqrf_bufferSize #-}
+{# fun unsafe cusolverDnSgeqrf_bufferSize as sgeqrf_bufferSize { useHandle `Handle', `Int', `Int', useDevP `DevicePtr Float', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dgeqrf_bufferSize #-}
+{# fun unsafe cusolverDnDgeqrf_bufferSize as dgeqrf_bufferSize { useHandle `Handle', `Int', `Int', useDevP `DevicePtr Double', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cgeqrf_bufferSize #-}
+{# fun unsafe cusolverDnCgeqrf_bufferSize as cgeqrf_bufferSize { useHandle `Handle', `Int', `Int', useDevP `DevicePtr (Complex Float)', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zgeqrf_bufferSize #-}
+{# fun unsafe cusolverDnZgeqrf_bufferSize as zgeqrf_bufferSize { useHandle `Handle', `Int', `Int', useDevP `DevicePtr (Complex Double)', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sgeqrf #-}
+{# fun unsafe cusolverDnSgeqrf as sgeqrf { useHandle `Handle', `Int', `Int', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dgeqrf #-}
+{# fun unsafe cusolverDnDgeqrf as dgeqrf { useHandle `Handle', `Int', `Int', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cgeqrf #-}
+{# fun unsafe cusolverDnCgeqrf as cgeqrf { useHandle `Handle', `Int', `Int', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zgeqrf #-}
+{# fun unsafe cusolverDnZgeqrf as zgeqrf { useHandle `Handle', `Int', `Int', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sormqr #-}
+{# fun unsafe cusolverDnSormqr as sormqr { useHandle `Handle', cFromEnum `Side', cFromEnum `Operation', `Int', `Int', `Int', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dormqr #-}
+{# fun unsafe cusolverDnDormqr as dormqr { useHandle `Handle', cFromEnum `Side', cFromEnum `Operation', `Int', `Int', `Int', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cunmqr #-}
+{# fun unsafe cusolverDnCunmqr as cunmqr { useHandle `Handle', cFromEnum `Side', cFromEnum `Operation', `Int', `Int', `Int', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zunmqr #-}
+{# fun unsafe cusolverDnZunmqr as zunmqr { useHandle `Handle', cFromEnum `Side', cFromEnum `Operation', `Int', `Int', `Int', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ssytrf_bufferSize #-}
+{# fun unsafe cusolverDnSsytrf_bufferSize as ssytrf_bufferSize { useHandle `Handle', `Int', useDevP `DevicePtr Float', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dsytrf_bufferSize #-}
+{# fun unsafe cusolverDnDsytrf_bufferSize as dsytrf_bufferSize { useHandle `Handle', `Int', useDevP `DevicePtr Double', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE csytrf_bufferSize #-}
+{# fun unsafe cusolverDnCsytrf_bufferSize as csytrf_bufferSize { useHandle `Handle', `Int', useDevP `DevicePtr (Complex Float)', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zsytrf_bufferSize #-}
+{# fun unsafe cusolverDnZsytrf_bufferSize as zsytrf_bufferSize { useHandle `Handle', `Int', useDevP `DevicePtr (Complex Double)', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ssytrf #-}
+{# fun unsafe cusolverDnSsytrf as ssytrf { useHandle `Handle', cFromEnum `Fill', `Int', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dsytrf #-}
+{# fun unsafe cusolverDnDsytrf as dsytrf { useHandle `Handle', cFromEnum `Fill', `Int', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE csytrf #-}
+{# fun unsafe cusolverDnCsytrf as csytrf { useHandle `Handle', cFromEnum `Fill', `Int', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zsytrf #-}
+{# fun unsafe cusolverDnZsytrf as zsytrf { useHandle `Handle', cFromEnum `Fill', `Int', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+#if CUDA_VERSION >= 8000
+
+{-# INLINEABLE sorgqr_bufferSize #-}
+{# fun unsafe cusolverDnSorgqr_bufferSize as sorgqr_bufferSize { useHandle `Handle', `Int', `Int', `Int', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Float', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dorgqr_bufferSize #-}
+{# fun unsafe cusolverDnDorgqr_bufferSize as dorgqr_bufferSize { useHandle `Handle', `Int', `Int', `Int', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Double', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cungqr_bufferSize #-}
+{# fun unsafe cusolverDnCungqr_bufferSize as cungqr_bufferSize { useHandle `Handle', `Int', `Int', `Int', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr (Complex Float)', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zungqr_bufferSize #-}
+{# fun unsafe cusolverDnZungqr_bufferSize as zungqr_bufferSize { useHandle `Handle', `Int', `Int', `Int', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr (Complex Double)', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sorgqr #-}
+{# fun unsafe cusolverDnSorgqr as sorgqr { useHandle `Handle', `Int', `Int', `Int', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dorgqr #-}
+{# fun unsafe cusolverDnDorgqr as dorgqr { useHandle `Handle', `Int', `Int', `Int', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cungqr #-}
+{# fun unsafe cusolverDnCungqr as cungqr { useHandle `Handle', `Int', `Int', `Int', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zungqr #-}
+{# fun unsafe cusolverDnZungqr as zungqr { useHandle `Handle', `Int', `Int', `Int', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr Int32' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE sormqr_bufferSize #-}
+{# fun unsafe cusolverDnSormqr_bufferSize as sormqr_bufferSize { useHandle `Handle', cFromEnum `Side', cFromEnum `Operation', `Int', `Int', `Int', useDevP `DevicePtr Float', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Float', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dormqr_bufferSize #-}
+{# fun unsafe cusolverDnDormqr_bufferSize as dormqr_bufferSize { useHandle `Handle', cFromEnum `Side', cFromEnum `Operation', `Int', `Int', `Int', useDevP `DevicePtr Double', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Double', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE cunmqr_bufferSize #-}
+{# fun unsafe cusolverDnCunmqr_bufferSize as cunmqr_bufferSize { useHandle `Handle', cFromEnum `Side', cFromEnum `Operation', `Int', `Int', `Int', useDevP `DevicePtr (Complex Float)', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zunmqr_bufferSize #-}
+{# fun unsafe cusolverDnZunmqr_bufferSize as zunmqr_bufferSize { useHandle `Handle', cFromEnum `Side', cFromEnum `Operation', `Int', `Int', `Int', useDevP `DevicePtr (Complex Double)', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', `Int', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+#else
+
+sorgqr_bufferSize :: Handle -> Int -> Int -> Int -> DevicePtr Float -> Int -> DevicePtr Float -> Int -> IO ()
+sorgqr_bufferSize _ _ _ _ _ _ _ _ = cusolverError "'sorgqr_bufferSize' requires at least cuda-8.0"
+
+dorgqr_bufferSize :: Handle -> Int -> Int -> Int -> DevicePtr Double -> Int -> DevicePtr Double -> Int -> IO ()
+dorgqr_bufferSize _ _ _ _ _ _ _ _ = cusolverError "'dorgqr_bufferSize' requires at least cuda-8.0"
+
+cungqr_bufferSize :: Handle -> Int -> Int -> Int -> DevicePtr (Complex Float) -> Int -> DevicePtr (Complex Float) -> Int -> IO ()
+cungqr_bufferSize _ _ _ _ _ _ _ _ = cusolverError "'cungqr_bufferSize' requires at least cuda-8.0"
+
+zungqr_bufferSize :: Handle -> Int -> Int -> Int -> DevicePtr (Complex Double) -> Int -> DevicePtr (Complex Double) -> Int -> IO ()
+zungqr_bufferSize _ _ _ _ _ _ _ _ = cusolverError "'zungqr_bufferSize' requires at least cuda-8.0"
+
+sorgqr :: Handle -> Int -> Int -> Int -> DevicePtr Float -> Int -> DevicePtr Float -> DevicePtr Float -> Int -> DevicePtr Int32 -> IO ()
+sorgqr _ _ _ _ _ _ _ _ _ _ = cusolverError "'sorgqr' requires at least cuda-8.0"
+
+dorgqr :: Handle -> Int -> Int -> Int -> DevicePtr Double -> Int -> DevicePtr Double -> DevicePtr Double -> Int -> DevicePtr Int32 -> IO ()
+dorgqr _ _ _ _ _ _ _ _ _ _ = cusolverError "'dorgqr' requires at least cuda-8.0"
+
+cungqr :: Handle -> Int -> Int -> Int -> DevicePtr (Complex Float) -> Int -> DevicePtr (Complex Float) -> DevicePtr (Complex Float) -> Int -> DevicePtr Int32 -> IO ()
+cungqr _ _ _ _ _ _ _ _ _ _ = cusolverError "'cungqr' requires at least cuda-8.0"
+
+zungqr :: Handle -> Int -> Int -> Int -> DevicePtr (Complex Double) -> Int -> DevicePtr (Complex Double) -> DevicePtr (Complex Double) -> Int -> DevicePtr Int32 -> IO ()
+zungqr _ _ _ _ _ _ _ _ _ _ = cusolverError "'zungqr' requires at least cuda-8.0"
+
+sormqr_bufferSize :: Handle -> Side -> Operation -> Int -> Int -> Int -> DevicePtr Float -> Int -> DevicePtr Float -> DevicePtr Float -> Int -> Int -> IO ()
+sormqr_bufferSize _ _ _ _ _ _ _ _ _ _ _ _ = cusolverError "'sormqr_bufferSize' requires at least cuda-8.0"
+
+dormqr_bufferSize :: Handle -> Side -> Operation -> Int -> Int -> Int -> DevicePtr Double -> Int -> DevicePtr Double -> DevicePtr Double -> Int -> Int -> IO ()
+dormqr_bufferSize _ _ _ _ _ _ _ _ _ _ _ _ = cusolverError "'dormqr_bufferSize' requires at least cuda-8.0"
+
+cunmqr_bufferSize :: Handle -> Side -> Operation -> Int -> Int -> Int -> DevicePtr (Complex Float) -> Int -> DevicePtr (Complex Float) -> DevicePtr (Complex Float) -> Int -> Int -> IO ()
+cunmqr_bufferSize _ _ _ _ _ _ _ _ _ _ _ _ = cusolverError "'cunmqr_bufferSize' requires at least cuda-8.0"
+
+zunmqr_bufferSize :: Handle -> Side -> Operation -> Int -> Int -> Int -> DevicePtr (Complex Double) -> Int -> DevicePtr (Complex Double) -> DevicePtr (Complex Double) -> Int -> Int -> IO ()
+zunmqr_bufferSize _ _ _ _ _ _ _ _ _ _ _ _ = cusolverError "'zunmqr_bufferSize' requires at least cuda-8.0"
+#endif
diff --git a/Foreign/CUDA/Solver/Dense/Stream.chs b/Foreign/CUDA/Solver/Dense/Stream.chs
new file mode 100644
--- /dev/null
+++ b/Foreign/CUDA/Solver/Dense/Stream.chs
@@ -0,0 +1,42 @@
+{-# LANGUAGE CPP                      #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+-- |
+-- Module      : Foreign.CUDA.Solver.Dense.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.Solver.Dense.Stream (
+
+  setStream,
+
+) where
+
+import Foreign.CUDA.Driver.Stream
+import Foreign.CUDA.Solver.Dense.Context
+import Foreign.CUDA.Solver.Error
+
+import Foreign.C
+import Foreign.Ptr
+
+#include "cbits/stubs.h"
+{# context lib="cusparse" #}
+
+
+-- | Sets the execution stream which all subsequent cuSolverDn 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/cusolver/index.html#cudssetstream>
+--
+{-# INLINEABLE setStream #-}
+{# fun unsafe cusolverDnSetStream as setStream
+  { useHandle `Handle'
+  , useStream `Stream'
+  }
+  -> `()' checkStatus* #}
+
diff --git a/Foreign/CUDA/Solver/Error.chs b/Foreign/CUDA/Solver/Error.chs
new file mode 100644
--- /dev/null
+++ b/Foreign/CUDA/Solver/Error.chs
@@ -0,0 +1,99 @@
+{-# LANGUAGE CPP                      #-}
+{-# LANGUAGE DeriveDataTypeable       #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+-- |
+-- Module      : Foreign.CUDA.Solver.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.Solver.Error
+  where
+
+-- friends
+import Foreign.CUDA.Solver.Internal.C2HS
+
+-- system
+import Control.Exception
+import Data.Typeable
+import Foreign.C.Types
+
+#include "cbits/stubs.h"
+{# context lib="cusolver" #}
+
+
+-- | Error codes used by cuSolver library functions
+--
+-- <http://docs.nvidia.com/cuda/cusolver/index.html#cuSolverSPstatus>
+--
+{# enum cusolverStatus_t as Status
+  { underscoreToCase }
+  with prefix="CUSOLVER_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 NotSupported           = "operation not supported"
+describe ZeroPivot              = "zero pivot"
+describe InvalidLicense         = "invalid license"
+
+
+-- Exceptions ------------------------------------------------------------------
+--
+data CUSolverException
+  = ExitCode  Status
+  | UserError String
+  deriving Typeable
+
+instance Exception CUSolverException
+
+instance Show CUSolverException where
+  showsPrec _ (ExitCode  s) = showString ("CUSolver Exception: " ++ describe s)
+  showsPrec _ (UserError s) = showString ("CUSolver Exception: " ++ s)
+
+
+-- | Raise a CUSolverException in the IO Monad
+--
+cusolverError :: String -> IO a
+cusolverError 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/Solver/Internal/C2HS.hs b/Foreign/CUDA/Solver/Internal/C2HS.hs
new file mode 100644
--- /dev/null
+++ b/Foreign/CUDA/Solver/Internal/C2HS.hs
@@ -0,0 +1,93 @@
+-- |
+-- Module      : Foreign.CUDA.Solver.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.Solver.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
+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/Solver/Internal/Types.chs b/Foreign/CUDA/Solver/Internal/Types.chs
new file mode 100644
--- /dev/null
+++ b/Foreign/CUDA/Solver/Internal/Types.chs
@@ -0,0 +1,134 @@
+{-# LANGUAGE CPP                      #-}
+{-# LANGUAGE EmptyDataDecls           #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+-- |
+-- Module      : Foreign.CUDA.Solver.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.Solver.Internal.Types (
+
+  -- Dense
+  BLAS.Fill(..),
+  BLAS.Operation(..),
+  BLAS.Side(..),
+  EigType(..),
+  EigMode(..),
+
+  -- Sparse
+  Sparse.MatrixDescriptor(..),
+
+  -- Refactorisation
+  MatrixFormat(..),
+  NumericBoost(..),
+  ResetFastMode(..),
+  FactorizationAlgorithm(..),
+  TriangularSolveAlgorithm(..),
+  UnitDiagonal(..),
+
+) where
+
+-- friends
+import Foreign.CUDA.BLAS                                  as BLAS
+import Foreign.CUDA.BLAS.Sparse.Matrix.Descriptor         as Sparse
+
+-- other
+import Prelude
+import Foreign.Ptr
+
+#include "cbits/stubs.h"
+{# context lib="cusolver" #}
+
+
+-- | This type indicates which type of eigenvalue solver is used. It corresponds
+-- to the parameters used by legacy LAPACK implementations:
+--
+--    * @EigType1@: \( A*x = lambda*B*x \)
+--    * @EigType2@: \( A*B*x = lambda*x \)
+--    * @EigType3@: \( B*A*x = lambda*x \)
+--
+-- <http://docs.nvidia.com/cuda/cusolver/index.html#cusolverEigType>
+--
+#if CUDA_VERSION >= 8000
+{# enum cusolverEigType_t as EigType
+  { underscoreToCase }
+  with prefix="CUSOLVER" deriving (Eq, Show) #}
+#else
+data EigType
+#endif
+
+
+-- | This type indicates whether eigenvectors are computed.
+--
+-- <http://docs.nvidia.com/cuda/cusolver/index.html#cusolverEigMode>
+--
+#if CUDA_VERSION >= 8000
+{# enum cusolverEigMode_t as EigMode
+  { underscoreToCase
+  , CUSOLVER_EIG_MODE_NOVECTOR as NoVector
+  }
+  with prefix="CUSOLVER_EIG_MODE" deriving (Eq, Show) #}
+#else
+data EigMode
+#endif
+
+
+-- | Indicates the input/output matrix format
+--
+-- <http://docs.nvidia.com/cuda/cusolver/index.html#cusolverRfMatrixFormat>
+--
+{# enum cusolverRfMatrixFormat_t as MatrixFormat
+  { }
+  with prefix="CUSOLVERRF_MATRIX_FORMAT" deriving (Eq, Show) #}
+
+-- | Indicates whether numeric boosting of the pivot was used during
+-- refactorisation.
+--
+-- <http://docs.nvidia.com/cuda/cusolver/index.html#cusolverRfNumericBoostReport>
+--
+{# enum cusolverRfNumericBoostReport_t as NumericBoost
+  { underscoreToCase }
+  with prefix="CUSOLVERRF_NUMERIC" deriving (Eq, Show) #}
+
+-- | Indicates whether fast mode should be used in
+-- 'Foreign.CUDA.Solver.Refactorisation.resetValues'. Fast mode requires extra
+-- memory.
+--
+-- <http://docs.nvidia.com/cuda/cusolver/index.html#cusolverRfResetValuesFastMode>
+--
+{# enum cusolverRfResetValuesFastMode_t as ResetFastMode
+  { underscoreToCase }
+  with prefix="CUSOLVERRF_RESET_VALUES" deriving (Eq, Show) #}
+
+-- | Indicates which (internal) algorithm is used for refactorisation in the
+-- 'Foreign.CUDA.Solver.Refactorisation.refactor' routine.
+--
+-- <http://docs.nvidia.com/cuda/cusolver/index.html#cusolverRfFactorization>
+--
+{# enum cusolverRfFactorization_t as FactorizationAlgorithm
+  { underscoreToCase }
+  with prefix="CUSOLVERRF" deriving (Eq, Show) #}
+
+-- | Indicates which (internal) algorithm is used for the triangular solve
+-- routine 'Foreign.CUDA.Solver.Refactorisation.triangularSolve'.
+--
+-- <http://docs.nvidia.com/cuda/cusolver/index.html#cusolverRfTriangularSolve>
+--
+{# enum cusolverRfTriangularSolve_t as TriangularSolveAlgorithm
+  { underscoreToCase }
+  with prefix="CUSOLVERRF" deriving (Eq, Show) #}
+
+-- | Indicates whether and where the unit diagonal is stored in the input/output
+-- triangular factors.
+--
+-- <http://docs.nvidia.com/cuda/cusolver/index.html#cusolverRfUnitDiagonal>
+--
+{# enum cusolverRfUnitDiagonal_t as UnitDiagonal
+  { underscoreToCase }
+  with prefix="CUSOLVERRF_UNIT_DIAGONAL" deriving (Eq, Show) #}
+
diff --git a/Foreign/CUDA/Solver/Sparse.hs b/Foreign/CUDA/Solver/Sparse.hs
new file mode 100644
--- /dev/null
+++ b/Foreign/CUDA/Solver/Sparse.hs
@@ -0,0 +1,54 @@
+-- |
+-- Module      : Foreign.CUDA.Solver.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 cuSolver library provides useful LAPACK-like features implemented on
+-- NVIDIA GPUs. This module implements a subset of LAPACK functions on sparse
+-- matrices in CSR or CSC format.
+--
+-- To use operations from the cuSolver library, the user must allocate the
+-- required vectors and matrices in the GPU memory space, fill them with data,
+-- call the desired sequence of cuSolver 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/]
+--
+-- /TODO/
+--
+-- [/Additional information/]
+--
+-- For more information, see the NVIDIA cuSolver documentation:
+--
+-- <http://docs.nvidia.com/cuda/cusolver/index.html>
+--
+
+module Foreign.CUDA.Solver.Sparse (
+
+  -- * Control
+  module Foreign.CUDA.Solver.Sparse.Context,
+  module Foreign.CUDA.Solver.Sparse.Analysis,
+  module Foreign.CUDA.Solver.Sparse.Stream,
+  module Foreign.CUDA.Solver.Error,
+
+  -- * Operations
+  module Foreign.CUDA.Solver.Sparse.High,
+  module Foreign.CUDA.Solver.Sparse.Low,
+
+) where
+
+import Foreign.CUDA.Solver.Sparse.Context                  hiding ( useHandle )
+import Foreign.CUDA.Solver.Sparse.Analysis
+import Foreign.CUDA.Solver.Sparse.Stream
+import Foreign.CUDA.Solver.Error
+
+import Foreign.CUDA.Solver.Sparse.High
+import Foreign.CUDA.Solver.Sparse.Low
+
diff --git a/Foreign/CUDA/Solver/Sparse/Analysis.chs b/Foreign/CUDA/Solver/Sparse/Analysis.chs
new file mode 100644
--- /dev/null
+++ b/Foreign/CUDA/Solver/Sparse/Analysis.chs
@@ -0,0 +1,69 @@
+{-# LANGUAGE CPP                      #-}
+{-# LANGUAGE EmptyDataDecls           #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+-- |
+-- Module      : Foreign.CUDA.Solver.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.Solver.Sparse.Analysis (
+
+  Info_csrqr(..), createInfo_csrqr, destroyInfo_csrqr,
+  Info_csrchol(..), createInfo_csrchol, destroyInfo_csrchol,
+
+) where
+
+-- friends
+import Foreign.CUDA.Solver.Error
+import Foreign.CUDA.Solver.Internal.C2HS
+
+-- system
+import Foreign
+import Foreign.C
+import Control.Monad                                      ( liftM )
+
+#include "cbits/stubs.h"
+{# context lib="cusolver" #}
+
+
+newtype Info_csrqr = Info_csrqr { useInfo_csrqr :: {# type csrqrInfo_t #}}
+
+{-# INLINEABLE createInfo_csrqr #-}
+{# fun unsafe cusolverSpCreateCsrqrInfo as createInfo_csrqr
+  { alloca- `Info_csrqr' peekI* } -> `()' checkStatus*- #}
+  where
+    peekI = liftM Info_csrqr . peek
+
+{-# INLINEABLE destroyInfo_csrqr #-}
+{# fun unsafe cusolverSpDestroyCsrqrInfo as destroyInfo_csrqr
+  { useInfo_csrqr `Info_csrqr' } -> `()' checkStatus* #}
+
+
+#if CUDA_VERSION >= 7500
+newtype Info_csrchol = Info_csrchol { useInfo_csrchol :: {# type csrcholInfo_t #}}
+
+{-# INLINEABLE createInfo_csrchol #-}
+{# fun unsafe cusolverSpCreateCsrcholInfo as createInfo_csrchol
+  { alloca- `Info_csrchol' peekI* } -> `()' checkStatus*- #}
+  where
+    peekI = liftM Info_csrchol . peek
+
+{-# INLINEABLE destroyInfo_csrchol #-}
+{# fun unsafe cusolverSpDestroyCsrcholInfo as destroyInfo_csrchol
+  { useInfo_csrchol `Info_csrchol' } -> `()' checkStatus* #}
+
+#else
+data Info_csrchol
+
+createInfo_csrchol :: IO Info_csrchol
+createInfo_csrchol = cusolverError "'createInfo_csrchol requires at least cuda-7.5"
+
+destroyInfo_csrchol :: Info_csrchol -> IO ()
+destroyInfo_csrchol _ = cusolverError "'destroyInfo_csrchol requires at least cuda-7.5"
+#endif
+
diff --git a/Foreign/CUDA/Solver/Sparse/Context.chs b/Foreign/CUDA/Solver/Sparse/Context.chs
new file mode 100644
--- /dev/null
+++ b/Foreign/CUDA/Solver/Sparse/Context.chs
@@ -0,0 +1,63 @@
+{-# LANGUAGE CPP                      #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+-- |
+-- Module      : Foreign.CUDA.Solver.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.Solver.Sparse.Context (
+
+  -- * Context management
+  Handle(..),
+  create,
+  destroy,
+
+) where
+
+-- Friends
+import Foreign.CUDA.Solver.Error
+import Foreign.CUDA.Solver.Internal.C2HS
+
+-- System
+import Foreign
+import Foreign.C
+import Control.Monad                                      ( liftM )
+
+#include "cbits/stubs.h"
+{# context lib="cusolver" #}
+
+
+-- | An opaque handle to the cuSolverSP context, which is passed to all library
+-- function calls.
+--
+-- <http://docs.nvidia.com/cuda/cusolver/index.html#cuSolverSPhandle>
+--
+newtype Handle = Handle { useHandle :: {# type cusolverSpHandle_t #}}
+
+
+-- | This function initializes the cuSolverSP library and creates a handle to
+-- the cuSolverSP context. It must be called before any other cuSolverSP API
+-- function is invoked. It allocates hardware resources necessary for accessing
+-- the GPU.
+--
+-- <http://docs.nvidia.com/cuda/cusolver/index.html#cusolverecreate>
+--
+{-# INLINEABLE create #-}
+{# fun unsafe cusolverSpCreate as create
+  { alloca- `Handle' peekHdl* } -> `()' checkStatus*- #}
+  where
+    peekHdl = liftM Handle . peek
+
+-- | This function releases resources used by the cuSolverSP library.
+--
+-- <http://docs.nvidia.com/cuda/cusolver/index.html#cusparsedestroy>
+--
+{-# INLINEABLE destroy #-}
+{# fun unsafe cusolverSpDestroy as destroy
+  { useHandle `Handle' } -> `()' checkStatus* #}
+
diff --git a/Foreign/CUDA/Solver/Sparse/High.chs b/Foreign/CUDA/Solver/Sparse/High.chs
new file mode 100644
--- /dev/null
+++ b/Foreign/CUDA/Solver/Sparse/High.chs
@@ -0,0 +1,99 @@
+--
+-- 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.Solver.Sparse.High
+-- 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 cuSolver function reference:
+--
+-- <http://docs.nvidia.com/cuda/cusolver/index.html#cusolver-high-level-function-reference>
+--
+
+module Foreign.CUDA.Solver.Sparse.High (
+
+  Handle,
+  MatrixDescriptor,
+  scsrlsvqr,
+  dcsrlsvqr,
+  ccsrlsvqr,
+  zcsrlsvqr,
+  scsrlsvchol,
+  dcsrlsvchol,
+  ccsrlsvchol,
+  zcsrlsvchol,
+  scsreigvsi,
+  dcsreigvsi,
+  ccsreigvsi,
+  zcsreigvsi,
+
+) where
+
+import Data.Complex
+import Foreign
+import Foreign.C
+import Foreign.Storable.Complex ()
+import Foreign.CUDA.Ptr
+import Foreign.CUDA.Solver.Sparse.Context
+import Foreign.CUDA.Solver.Sparse.Analysis
+import Foreign.CUDA.Solver.Error
+import Foreign.CUDA.Solver.Internal.C2HS
+import Foreign.CUDA.Solver.Internal.Types
+
+#include "cbits/stubs.h"
+{# context lib="cusolver" #}
+
+{-# INLINE useDevP #-}
+useDevP :: DevicePtr a -> Ptr b
+useDevP = useDevicePtr . castDevPtr
+
+{-# INLINE useHostP #-}
+useHostP :: HostPtr a -> Ptr b
+useHostP = useHostPtr . castHostPtr
+
+
+{-# INLINEABLE scsrlsvqr #-}
+{# fun unsafe cusolverSpScsrlsvqr as scsrlsvqr { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Float', CFloat `Float', `Int', useDevP `DevicePtr Float', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsrlsvqr #-}
+{# fun unsafe cusolverSpDcsrlsvqr as dcsrlsvqr { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Double', CDouble `Double', `Int', useDevP `DevicePtr Double', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsrlsvqr #-}
+{# fun unsafe cusolverSpCcsrlsvqr as ccsrlsvqr { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Float)', CFloat `Float', `Int', useDevP `DevicePtr (Complex Float)', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsrlsvqr #-}
+{# fun unsafe cusolverSpZcsrlsvqr as zcsrlsvqr { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Double)', CDouble `Double', `Int', useDevP `DevicePtr (Complex Double)', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsrlsvchol #-}
+{# fun unsafe cusolverSpScsrlsvchol as scsrlsvchol { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Float', CFloat `Float', `Int', useDevP `DevicePtr Float', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsrlsvchol #-}
+{# fun unsafe cusolverSpDcsrlsvchol as dcsrlsvchol { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Double', CDouble `Double', `Int', useDevP `DevicePtr Double', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsrlsvchol #-}
+{# fun unsafe cusolverSpCcsrlsvchol as ccsrlsvchol { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Float)', CFloat `Float', `Int', useDevP `DevicePtr (Complex Float)', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsrlsvchol #-}
+{# fun unsafe cusolverSpZcsrlsvchol as zcsrlsvchol { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Double)', CDouble `Double', `Int', useDevP `DevicePtr (Complex Double)', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsreigvsi #-}
+{# fun unsafe cusolverSpScsreigvsi as scsreigvsi { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', CFloat `Float', useDevP `DevicePtr Float', `Int', CFloat `Float', useDevP `DevicePtr Float', useDevP `DevicePtr Float' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsreigvsi #-}
+{# fun unsafe cusolverSpDcsreigvsi as dcsreigvsi { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', CDouble `Double', useDevP `DevicePtr Double', `Int', CDouble `Double', useDevP `DevicePtr Double', useDevP `DevicePtr Double' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsreigvsi #-}
+{# fun unsafe cusolverSpCcsreigvsi as ccsreigvsi { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', withComplex* `(Complex Float)', useDevP `DevicePtr (Complex Float)', `Int', CFloat `Float', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsreigvsi #-}
+{# fun unsafe cusolverSpZcsreigvsi as zcsreigvsi { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', withComplex* `(Complex Double)', useDevP `DevicePtr (Complex Double)', `Int', CDouble `Double', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)' } -> `()' checkStatus*- #}
diff --git a/Foreign/CUDA/Solver/Sparse/Low.chs b/Foreign/CUDA/Solver/Sparse/Low.chs
new file mode 100644
--- /dev/null
+++ b/Foreign/CUDA/Solver/Sparse/Low.chs
@@ -0,0 +1,358 @@
+--
+-- 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.Solver.Sparse.Low
+-- 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 cuSolver function reference:
+--
+-- <http://docs.nvidia.com/cuda/cusolver/index.html#cusolver-low-level-function-reference>
+--
+
+module Foreign.CUDA.Solver.Sparse.Low (
+
+  Handle,
+  MatrixDescriptor,
+  Info_csrqr,
+  Info_csrchol,
+  xcsrqrAnalysisBatched,
+  scsrqrBufferInfoBatched,
+  dcsrqrBufferInfoBatched,
+  ccsrqrBufferInfoBatched,
+  zcsrqrBufferInfoBatched,
+  scsrqrsvBatched,
+  dcsrqrsvBatched,
+  ccsrqrsvBatched,
+  zcsrqrsvBatched,
+  xcsrqrAnalysis,
+  scsrqrBufferInfo,
+  dcsrqrBufferInfo,
+  ccsrqrBufferInfo,
+  zcsrqrBufferInfo,
+  scsrqrSetup,
+  dcsrqrSetup,
+  ccsrqrSetup,
+  zcsrqrSetup,
+  scsrqrFactor,
+  dcsrqrFactor,
+  ccsrqrFactor,
+  zcsrqrFactor,
+  scsrqrZeroPivot,
+  dcsrqrZeroPivot,
+  ccsrqrZeroPivot,
+  zcsrqrZeroPivot,
+  scsrqrSolve,
+  dcsrqrSolve,
+  ccsrqrSolve,
+  zcsrqrSolve,
+  xcsrcholAnalysis,
+  scsrcholBufferInfo,
+  dcsrcholBufferInfo,
+  ccsrcholBufferInfo,
+  zcsrcholBufferInfo,
+  scsrcholFactor,
+  dcsrcholFactor,
+  ccsrcholFactor,
+  zcsrcholFactor,
+  scsrcholZeroPivot,
+  dcsrcholZeroPivot,
+  ccsrcholZeroPivot,
+  zcsrcholZeroPivot,
+  scsrcholSolve,
+  dcsrcholSolve,
+  ccsrcholSolve,
+  zcsrcholSolve,
+
+) where
+
+import Data.Complex
+import Foreign
+import Foreign.C
+import Foreign.Storable.Complex ()
+import Foreign.CUDA.Ptr
+import Foreign.CUDA.Solver.Sparse.Context
+import Foreign.CUDA.Solver.Sparse.Analysis
+import Foreign.CUDA.Solver.Error
+import Foreign.CUDA.Solver.Internal.C2HS
+import Foreign.CUDA.Solver.Internal.Types
+
+#include "cbits/stubs.h"
+{# context lib="cusolver" #}
+
+{-# INLINE useDevP #-}
+useDevP :: DevicePtr a -> Ptr b
+useDevP = useDevicePtr . castDevPtr
+
+{-# INLINE useHostP #-}
+useHostP :: HostPtr a -> Ptr b
+useHostP = useHostPtr . castHostPtr
+
+
+{-# INLINEABLE xcsrqrAnalysisBatched #-}
+{# fun unsafe cusolverSpXcsrqrAnalysisBatched as xcsrqrAnalysisBatched { useHandle `Handle', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrqr `Info_csrqr' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsrqrBufferInfoBatched #-}
+{# fun unsafe cusolverSpScsrqrBufferInfoBatched as scsrqrBufferInfoBatched { useHandle `Handle', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_csrqr `Info_csrqr', alloca- `Int' peekIntConv*, alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsrqrBufferInfoBatched #-}
+{# fun unsafe cusolverSpDcsrqrBufferInfoBatched as dcsrqrBufferInfoBatched { useHandle `Handle', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_csrqr `Info_csrqr', alloca- `Int' peekIntConv*, alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsrqrBufferInfoBatched #-}
+{# fun unsafe cusolverSpCcsrqrBufferInfoBatched as ccsrqrBufferInfoBatched { useHandle `Handle', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_csrqr `Info_csrqr', alloca- `Int' peekIntConv*, alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsrqrBufferInfoBatched #-}
+{# fun unsafe cusolverSpZcsrqrBufferInfoBatched as zcsrqrBufferInfoBatched { useHandle `Handle', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', `Int', useInfo_csrqr `Info_csrqr', alloca- `Int' peekIntConv*, alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsrqrsvBatched #-}
+{# fun unsafe cusolverSpScsrqrsvBatched as scsrqrsvBatched { useHandle `Handle', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Float', useDevP `DevicePtr Float', `Int', useInfo_csrqr `Info_csrqr', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsrqrsvBatched #-}
+{# fun unsafe cusolverSpDcsrqrsvBatched as dcsrqrsvBatched { useHandle `Handle', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr Double', useDevP `DevicePtr Double', `Int', useInfo_csrqr `Info_csrqr', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsrqrsvBatched #-}
+{# fun unsafe cusolverSpCcsrqrsvBatched as ccsrqrsvBatched { useHandle `Handle', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', `Int', useInfo_csrqr `Info_csrqr', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsrqrsvBatched #-}
+{# fun unsafe cusolverSpZcsrqrsvBatched as zcsrqrsvBatched { useHandle `Handle', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', `Int', useInfo_csrqr `Info_csrqr', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+#if CUDA_VERSION >= 7500
+
+{-# INLINEABLE xcsrqrAnalysis #-}
+{# fun unsafe cusolverSpXcsrqrAnalysis as xcsrqrAnalysis { useHandle `Handle', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrqr `Info_csrqr' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsrqrBufferInfo #-}
+{# fun unsafe cusolverSpScsrqrBufferInfo as scsrqrBufferInfo { useHandle `Handle', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrqr `Info_csrqr', alloca- `Int' peekIntConv*, alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsrqrBufferInfo #-}
+{# fun unsafe cusolverSpDcsrqrBufferInfo as dcsrqrBufferInfo { useHandle `Handle', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrqr `Info_csrqr', alloca- `Int' peekIntConv*, alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsrqrBufferInfo #-}
+{# fun unsafe cusolverSpCcsrqrBufferInfo as ccsrqrBufferInfo { useHandle `Handle', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrqr `Info_csrqr', alloca- `Int' peekIntConv*, alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsrqrBufferInfo #-}
+{# fun unsafe cusolverSpZcsrqrBufferInfo as zcsrqrBufferInfo { useHandle `Handle', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrqr `Info_csrqr', alloca- `Int' peekIntConv*, alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsrqrSetup #-}
+{# fun unsafe cusolverSpScsrqrSetup as scsrqrSetup { useHandle `Handle', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', CFloat `Float', useInfo_csrqr `Info_csrqr' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsrqrSetup #-}
+{# fun unsafe cusolverSpDcsrqrSetup as dcsrqrSetup { useHandle `Handle', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', CDouble `Double', useInfo_csrqr `Info_csrqr' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsrqrSetup #-}
+{# fun unsafe cusolverSpCcsrqrSetup as ccsrqrSetup { useHandle `Handle', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', withComplex* `(Complex Float)', useInfo_csrqr `Info_csrqr' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsrqrSetup #-}
+{# fun unsafe cusolverSpZcsrqrSetup as zcsrqrSetup { useHandle `Handle', `Int', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', withComplex* `(Complex Double)', useInfo_csrqr `Info_csrqr' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsrqrFactor #-}
+{# fun unsafe cusolverSpScsrqrFactor as scsrqrFactor { useHandle `Handle', `Int', `Int', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Float', useInfo_csrqr `Info_csrqr', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsrqrFactor #-}
+{# fun unsafe cusolverSpDcsrqrFactor as dcsrqrFactor { useHandle `Handle', `Int', `Int', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Double', useInfo_csrqr `Info_csrqr', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsrqrFactor #-}
+{# fun unsafe cusolverSpCcsrqrFactor as ccsrqrFactor { useHandle `Handle', `Int', `Int', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', useInfo_csrqr `Info_csrqr', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsrqrFactor #-}
+{# fun unsafe cusolverSpZcsrqrFactor as zcsrqrFactor { useHandle `Handle', `Int', `Int', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', useInfo_csrqr `Info_csrqr', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsrqrZeroPivot #-}
+{# fun unsafe cusolverSpScsrqrZeroPivot as scsrqrZeroPivot { useHandle `Handle', useInfo_csrqr `Info_csrqr', CFloat `Float', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsrqrZeroPivot #-}
+{# fun unsafe cusolverSpDcsrqrZeroPivot as dcsrqrZeroPivot { useHandle `Handle', useInfo_csrqr `Info_csrqr', CDouble `Double', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsrqrZeroPivot #-}
+{# fun unsafe cusolverSpCcsrqrZeroPivot as ccsrqrZeroPivot { useHandle `Handle', useInfo_csrqr `Info_csrqr', CFloat `Float', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsrqrZeroPivot #-}
+{# fun unsafe cusolverSpZcsrqrZeroPivot as zcsrqrZeroPivot { useHandle `Handle', useInfo_csrqr `Info_csrqr', CDouble `Double', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsrqrSolve #-}
+{# fun unsafe cusolverSpScsrqrSolve as scsrqrSolve { useHandle `Handle', `Int', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Float', useInfo_csrqr `Info_csrqr', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsrqrSolve #-}
+{# fun unsafe cusolverSpDcsrqrSolve as dcsrqrSolve { useHandle `Handle', `Int', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Double', useInfo_csrqr `Info_csrqr', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsrqrSolve #-}
+{# fun unsafe cusolverSpCcsrqrSolve as ccsrqrSolve { useHandle `Handle', `Int', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', useInfo_csrqr `Info_csrqr', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsrqrSolve #-}
+{# fun unsafe cusolverSpZcsrqrSolve as zcsrqrSolve { useHandle `Handle', `Int', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', useInfo_csrqr `Info_csrqr', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE xcsrcholAnalysis #-}
+{# fun unsafe cusolverSpXcsrcholAnalysis as xcsrcholAnalysis { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrchol `Info_csrchol' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsrcholBufferInfo #-}
+{# fun unsafe cusolverSpScsrcholBufferInfo as scsrcholBufferInfo { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrchol `Info_csrchol', alloca- `Int' peekIntConv*, alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsrcholBufferInfo #-}
+{# fun unsafe cusolverSpDcsrcholBufferInfo as dcsrcholBufferInfo { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrchol `Info_csrchol', alloca- `Int' peekIntConv*, alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsrcholBufferInfo #-}
+{# fun unsafe cusolverSpCcsrcholBufferInfo as ccsrcholBufferInfo { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrchol `Info_csrchol', alloca- `Int' peekIntConv*, alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsrcholBufferInfo #-}
+{# fun unsafe cusolverSpZcsrcholBufferInfo as zcsrcholBufferInfo { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrchol `Info_csrchol', alloca- `Int' peekIntConv*, alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsrcholFactor #-}
+{# fun unsafe cusolverSpScsrcholFactor as scsrcholFactor { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Float', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrchol `Info_csrchol', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsrcholFactor #-}
+{# fun unsafe cusolverSpDcsrcholFactor as dcsrcholFactor { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr Double', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrchol `Info_csrchol', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsrcholFactor #-}
+{# fun unsafe cusolverSpCcsrcholFactor as ccsrcholFactor { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrchol `Info_csrchol', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsrcholFactor #-}
+{# fun unsafe cusolverSpZcsrcholFactor as zcsrcholFactor { useHandle `Handle', `Int', `Int', useMatDescr `MatrixDescriptor', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr Int32', useDevP `DevicePtr Int32', useInfo_csrchol `Info_csrchol', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsrcholZeroPivot #-}
+{# fun unsafe cusolverSpScsrcholZeroPivot as scsrcholZeroPivot { useHandle `Handle', useInfo_csrchol `Info_csrchol', CFloat `Float', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsrcholZeroPivot #-}
+{# fun unsafe cusolverSpDcsrcholZeroPivot as dcsrcholZeroPivot { useHandle `Handle', useInfo_csrchol `Info_csrchol', CDouble `Double', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsrcholZeroPivot #-}
+{# fun unsafe cusolverSpCcsrcholZeroPivot as ccsrcholZeroPivot { useHandle `Handle', useInfo_csrchol `Info_csrchol', CFloat `Float', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsrcholZeroPivot #-}
+{# fun unsafe cusolverSpZcsrcholZeroPivot as zcsrcholZeroPivot { useHandle `Handle', useInfo_csrchol `Info_csrchol', CDouble `Double', alloca- `Int' peekIntConv* } -> `()' checkStatus*- #}
+
+{-# INLINEABLE scsrcholSolve #-}
+{# fun unsafe cusolverSpScsrcholSolve as scsrcholSolve { useHandle `Handle', `Int', useDevP `DevicePtr Float', useDevP `DevicePtr Float', useInfo_csrchol `Info_csrchol', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE dcsrcholSolve #-}
+{# fun unsafe cusolverSpDcsrcholSolve as dcsrcholSolve { useHandle `Handle', `Int', useDevP `DevicePtr Double', useDevP `DevicePtr Double', useInfo_csrchol `Info_csrchol', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE ccsrcholSolve #-}
+{# fun unsafe cusolverSpCcsrcholSolve as ccsrcholSolve { useHandle `Handle', `Int', useDevP `DevicePtr (Complex Float)', useDevP `DevicePtr (Complex Float)', useInfo_csrchol `Info_csrchol', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+
+{-# INLINEABLE zcsrcholSolve #-}
+{# fun unsafe cusolverSpZcsrcholSolve as zcsrcholSolve { useHandle `Handle', `Int', useDevP `DevicePtr (Complex Double)', useDevP `DevicePtr (Complex Double)', useInfo_csrchol `Info_csrchol', useDevP `DevicePtr ()' } -> `()' checkStatus*- #}
+#else
+
+xcsrqrAnalysis :: Handle -> Int -> Int -> Int -> MatrixDescriptor -> DevicePtr Int32 -> DevicePtr Int32 -> Info_csrqr -> IO ()
+xcsrqrAnalysis _ _ _ _ _ _ _ _ = cusolverError "'xcsrqrAnalysis' requires at least cuda-7.5"
+
+scsrqrBufferInfo :: Handle -> Int -> Int -> Int -> MatrixDescriptor -> DevicePtr Float -> DevicePtr Int32 -> DevicePtr Int32 -> Info_csrqr -> Int -> Int -> IO ()
+scsrqrBufferInfo _ _ _ _ _ _ _ _ _ _ _ = cusolverError "'scsrqrBufferInfo' requires at least cuda-7.5"
+
+dcsrqrBufferInfo :: Handle -> Int -> Int -> Int -> MatrixDescriptor -> DevicePtr Double -> DevicePtr Int32 -> DevicePtr Int32 -> Info_csrqr -> Int -> Int -> IO ()
+dcsrqrBufferInfo _ _ _ _ _ _ _ _ _ _ _ = cusolverError "'dcsrqrBufferInfo' requires at least cuda-7.5"
+
+ccsrqrBufferInfo :: Handle -> Int -> Int -> Int -> MatrixDescriptor -> DevicePtr (Complex Float) -> DevicePtr Int32 -> DevicePtr Int32 -> Info_csrqr -> Int -> Int -> IO ()
+ccsrqrBufferInfo _ _ _ _ _ _ _ _ _ _ _ = cusolverError "'ccsrqrBufferInfo' requires at least cuda-7.5"
+
+zcsrqrBufferInfo :: Handle -> Int -> Int -> Int -> MatrixDescriptor -> DevicePtr (Complex Double) -> DevicePtr Int32 -> DevicePtr Int32 -> Info_csrqr -> Int -> Int -> IO ()
+zcsrqrBufferInfo _ _ _ _ _ _ _ _ _ _ _ = cusolverError "'zcsrqrBufferInfo' requires at least cuda-7.5"
+
+scsrqrSetup :: Handle -> Int -> Int -> Int -> MatrixDescriptor -> DevicePtr Float -> DevicePtr Int32 -> DevicePtr Int32 -> Float -> Info_csrqr -> IO ()
+scsrqrSetup _ _ _ _ _ _ _ _ _ _ = cusolverError "'scsrqrSetup' requires at least cuda-7.5"
+
+dcsrqrSetup :: Handle -> Int -> Int -> Int -> MatrixDescriptor -> DevicePtr Double -> DevicePtr Int32 -> DevicePtr Int32 -> Double -> Info_csrqr -> IO ()
+dcsrqrSetup _ _ _ _ _ _ _ _ _ _ = cusolverError "'dcsrqrSetup' requires at least cuda-7.5"
+
+ccsrqrSetup :: Handle -> Int -> Int -> Int -> MatrixDescriptor -> DevicePtr (Complex Float) -> DevicePtr Int32 -> DevicePtr Int32 -> (Complex Float) -> Info_csrqr -> IO ()
+ccsrqrSetup _ _ _ _ _ _ _ _ _ _ = cusolverError "'ccsrqrSetup' requires at least cuda-7.5"
+
+zcsrqrSetup :: Handle -> Int -> Int -> Int -> MatrixDescriptor -> DevicePtr (Complex Double) -> DevicePtr Int32 -> DevicePtr Int32 -> (Complex Double) -> Info_csrqr -> IO ()
+zcsrqrSetup _ _ _ _ _ _ _ _ _ _ = cusolverError "'zcsrqrSetup' requires at least cuda-7.5"
+
+scsrqrFactor :: Handle -> Int -> Int -> Int -> DevicePtr Float -> DevicePtr Float -> Info_csrqr -> DevicePtr () -> IO ()
+scsrqrFactor _ _ _ _ _ _ _ _ = cusolverError "'scsrqrFactor' requires at least cuda-7.5"
+
+dcsrqrFactor :: Handle -> Int -> Int -> Int -> DevicePtr Double -> DevicePtr Double -> Info_csrqr -> DevicePtr () -> IO ()
+dcsrqrFactor _ _ _ _ _ _ _ _ = cusolverError "'dcsrqrFactor' requires at least cuda-7.5"
+
+ccsrqrFactor :: Handle -> Int -> Int -> Int -> DevicePtr (Complex Float) -> DevicePtr (Complex Float) -> Info_csrqr -> DevicePtr () -> IO ()
+ccsrqrFactor _ _ _ _ _ _ _ _ = cusolverError "'ccsrqrFactor' requires at least cuda-7.5"
+
+zcsrqrFactor :: Handle -> Int -> Int -> Int -> DevicePtr (Complex Double) -> DevicePtr (Complex Double) -> Info_csrqr -> DevicePtr () -> IO ()
+zcsrqrFactor _ _ _ _ _ _ _ _ = cusolverError "'zcsrqrFactor' requires at least cuda-7.5"
+
+scsrqrZeroPivot :: Handle -> Info_csrqr -> Float -> Int -> IO ()
+scsrqrZeroPivot _ _ _ _ = cusolverError "'scsrqrZeroPivot' requires at least cuda-7.5"
+
+dcsrqrZeroPivot :: Handle -> Info_csrqr -> Double -> Int -> IO ()
+dcsrqrZeroPivot _ _ _ _ = cusolverError "'dcsrqrZeroPivot' requires at least cuda-7.5"
+
+ccsrqrZeroPivot :: Handle -> Info_csrqr -> Float -> Int -> IO ()
+ccsrqrZeroPivot _ _ _ _ = cusolverError "'ccsrqrZeroPivot' requires at least cuda-7.5"
+
+zcsrqrZeroPivot :: Handle -> Info_csrqr -> Double -> Int -> IO ()
+zcsrqrZeroPivot _ _ _ _ = cusolverError "'zcsrqrZeroPivot' requires at least cuda-7.5"
+
+scsrqrSolve :: Handle -> Int -> Int -> DevicePtr Float -> DevicePtr Float -> Info_csrqr -> DevicePtr () -> IO ()
+scsrqrSolve _ _ _ _ _ _ _ = cusolverError "'scsrqrSolve' requires at least cuda-7.5"
+
+dcsrqrSolve :: Handle -> Int -> Int -> DevicePtr Double -> DevicePtr Double -> Info_csrqr -> DevicePtr () -> IO ()
+dcsrqrSolve _ _ _ _ _ _ _ = cusolverError "'dcsrqrSolve' requires at least cuda-7.5"
+
+ccsrqrSolve :: Handle -> Int -> Int -> DevicePtr (Complex Float) -> DevicePtr (Complex Float) -> Info_csrqr -> DevicePtr () -> IO ()
+ccsrqrSolve _ _ _ _ _ _ _ = cusolverError "'ccsrqrSolve' requires at least cuda-7.5"
+
+zcsrqrSolve :: Handle -> Int -> Int -> DevicePtr (Complex Double) -> DevicePtr (Complex Double) -> Info_csrqr -> DevicePtr () -> IO ()
+zcsrqrSolve _ _ _ _ _ _ _ = cusolverError "'zcsrqrSolve' requires at least cuda-7.5"
+
+xcsrcholAnalysis :: Handle -> Int -> Int -> MatrixDescriptor -> DevicePtr Int32 -> DevicePtr Int32 -> Info_csrchol -> IO ()
+xcsrcholAnalysis _ _ _ _ _ _ _ = cusolverError "'xcsrcholAnalysis' requires at least cuda-7.5"
+
+scsrcholBufferInfo :: Handle -> Int -> Int -> MatrixDescriptor -> DevicePtr Float -> DevicePtr Int32 -> DevicePtr Int32 -> Info_csrchol -> Int -> Int -> IO ()
+scsrcholBufferInfo _ _ _ _ _ _ _ _ _ _ = cusolverError "'scsrcholBufferInfo' requires at least cuda-7.5"
+
+dcsrcholBufferInfo :: Handle -> Int -> Int -> MatrixDescriptor -> DevicePtr Double -> DevicePtr Int32 -> DevicePtr Int32 -> Info_csrchol -> Int -> Int -> IO ()
+dcsrcholBufferInfo _ _ _ _ _ _ _ _ _ _ = cusolverError "'dcsrcholBufferInfo' requires at least cuda-7.5"
+
+ccsrcholBufferInfo :: Handle -> Int -> Int -> MatrixDescriptor -> DevicePtr (Complex Float) -> DevicePtr Int32 -> DevicePtr Int32 -> Info_csrchol -> Int -> Int -> IO ()
+ccsrcholBufferInfo _ _ _ _ _ _ _ _ _ _ = cusolverError "'ccsrcholBufferInfo' requires at least cuda-7.5"
+
+zcsrcholBufferInfo :: Handle -> Int -> Int -> MatrixDescriptor -> DevicePtr (Complex Double) -> DevicePtr Int32 -> DevicePtr Int32 -> Info_csrchol -> Int -> Int -> IO ()
+zcsrcholBufferInfo _ _ _ _ _ _ _ _ _ _ = cusolverError "'zcsrcholBufferInfo' requires at least cuda-7.5"
+
+scsrcholFactor :: Handle -> Int -> Int -> MatrixDescriptor -> DevicePtr Float -> DevicePtr Int32 -> DevicePtr Int32 -> Info_csrchol -> DevicePtr () -> IO ()
+scsrcholFactor _ _ _ _ _ _ _ _ _ = cusolverError "'scsrcholFactor' requires at least cuda-7.5"
+
+dcsrcholFactor :: Handle -> Int -> Int -> MatrixDescriptor -> DevicePtr Double -> DevicePtr Int32 -> DevicePtr Int32 -> Info_csrchol -> DevicePtr () -> IO ()
+dcsrcholFactor _ _ _ _ _ _ _ _ _ = cusolverError "'dcsrcholFactor' requires at least cuda-7.5"
+
+ccsrcholFactor :: Handle -> Int -> Int -> MatrixDescriptor -> DevicePtr (Complex Float) -> DevicePtr Int32 -> DevicePtr Int32 -> Info_csrchol -> DevicePtr () -> IO ()
+ccsrcholFactor _ _ _ _ _ _ _ _ _ = cusolverError "'ccsrcholFactor' requires at least cuda-7.5"
+
+zcsrcholFactor :: Handle -> Int -> Int -> MatrixDescriptor -> DevicePtr (Complex Double) -> DevicePtr Int32 -> DevicePtr Int32 -> Info_csrchol -> DevicePtr () -> IO ()
+zcsrcholFactor _ _ _ _ _ _ _ _ _ = cusolverError "'zcsrcholFactor' requires at least cuda-7.5"
+
+scsrcholZeroPivot :: Handle -> Info_csrchol -> Float -> Int -> IO ()
+scsrcholZeroPivot _ _ _ _ = cusolverError "'scsrcholZeroPivot' requires at least cuda-7.5"
+
+dcsrcholZeroPivot :: Handle -> Info_csrchol -> Double -> Int -> IO ()
+dcsrcholZeroPivot _ _ _ _ = cusolverError "'dcsrcholZeroPivot' requires at least cuda-7.5"
+
+ccsrcholZeroPivot :: Handle -> Info_csrchol -> Float -> Int -> IO ()
+ccsrcholZeroPivot _ _ _ _ = cusolverError "'ccsrcholZeroPivot' requires at least cuda-7.5"
+
+zcsrcholZeroPivot :: Handle -> Info_csrchol -> Double -> Int -> IO ()
+zcsrcholZeroPivot _ _ _ _ = cusolverError "'zcsrcholZeroPivot' requires at least cuda-7.5"
+
+scsrcholSolve :: Handle -> Int -> DevicePtr Float -> DevicePtr Float -> Info_csrchol -> DevicePtr () -> IO ()
+scsrcholSolve _ _ _ _ _ _ = cusolverError "'scsrcholSolve' requires at least cuda-7.5"
+
+dcsrcholSolve :: Handle -> Int -> DevicePtr Double -> DevicePtr Double -> Info_csrchol -> DevicePtr () -> IO ()
+dcsrcholSolve _ _ _ _ _ _ = cusolverError "'dcsrcholSolve' requires at least cuda-7.5"
+
+ccsrcholSolve :: Handle -> Int -> DevicePtr (Complex Float) -> DevicePtr (Complex Float) -> Info_csrchol -> DevicePtr () -> IO ()
+ccsrcholSolve _ _ _ _ _ _ = cusolverError "'ccsrcholSolve' requires at least cuda-7.5"
+
+zcsrcholSolve :: Handle -> Int -> DevicePtr (Complex Double) -> DevicePtr (Complex Double) -> Info_csrchol -> DevicePtr () -> IO ()
+zcsrcholSolve _ _ _ _ _ _ = cusolverError "'zcsrcholSolve' requires at least cuda-7.5"
+#endif
diff --git a/Foreign/CUDA/Solver/Sparse/Stream.chs b/Foreign/CUDA/Solver/Sparse/Stream.chs
new file mode 100644
--- /dev/null
+++ b/Foreign/CUDA/Solver/Sparse/Stream.chs
@@ -0,0 +1,42 @@
+{-# LANGUAGE CPP                      #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+-- |
+-- Module      : Foreign.CUDA.Solver.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.Solver.Sparse.Stream (
+
+  setStream,
+
+) where
+
+import Foreign.CUDA.Driver.Stream
+import Foreign.CUDA.Solver.Error
+import Foreign.CUDA.Solver.Sparse.Context
+
+import Foreign.C
+import Foreign.Ptr
+
+#include "cbits/stubs.h"
+{# context lib="cusparse" #}
+
+
+-- | Sets the execution stream which all subsequent cuSolverSp 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/cusolver/index.html#cusparsesetstream>
+--
+{-# INLINEABLE setStream #-}
+{# fun unsafe cusolverSpSetStream 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,16 @@
+Haskell FFI Bindings to cuSolver
+================================
+
+[![Build status](https://travis-ci.org/tmcdonell/cusolver.svg?branch=master)](https://travis-ci.org/tmcdonell/cusolver)
+[![Hackage](https://img.shields.io/hackage/v/cusolver.svg)](https://hackage.haskell.org/package/cusolver)
+
+The cuSolver library provides useful LAPACK-like features implemented on NVIDIA
+GPUs, such as common matrix factorization and triangular solve routines for
+dense matrices, a sparse least-squares solver routine, and an eigenvalue solver.
+This package provides FFI bindings to the functions of the cuSolver library. You
+will need to install the CUDA driver and developer toolkit:
+
+  <http://developer.nvidia.com/cuda-downloads>
+
+  <http://docs.nvidia.com/cuda/cusolver/index.html>
+
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,244 @@
+{-# 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 = "cusolver" <.> "buildinfo"
+
+generatedBuildInfoFilePath :: FilePath
+generatedBuildInfoFilePath = customBuildInfoFilePath <.> "generated"
+
+
+staticLibs :: Platform -> [String]
+staticLibs platform@(Platform _arch os) =
+  case os of
+    Windows -> dynamicLibs platform
+    _       -> ["cusolver_static", "culibos", "cudart_static", "pthread", "dl"]
+
+dynamicLibs :: Platform -> [String]
+dynamicLibs _ = ["cusolver"]
+
+
+-- 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,25 @@
+/*
+ * Extra bits for cuSolver 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 <cusolverDn.h>
+#include <cusolverSp.h>
+#include <cusolverRf.h>
+#include <cusolver_common.h>
+
+#if CUDA_VERSION >= 7500
+#include <cusolverSp_LOWLEVEL_PREVIEW.h>
+#endif
+
+#endif /* C_STUBS_H */
+
diff --git a/cusolver.cabal b/cusolver.cabal
new file mode 100644
--- /dev/null
+++ b/cusolver.cabal
@@ -0,0 +1,99 @@
+name:                   cusolver
+version:                0.1.0.0
+synopsis:               FFI bindings to CUDA Solver, a LAPACK-like library
+description:
+    The cuSolver library provides useful LAPACK-like features implemented on
+    NVIDIA GPUs, such as common matrix factorization and triangular solve
+    routines for dense matrices, a sparse least-squares solver routine, and an
+    eigenvalue solver. This package provides FFI bindings to the functions of
+    the cuSolver 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/cusolver 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:        cusolver.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:
+      -- Dense LAPACK-like functions
+      Foreign.CUDA.Solver.Dense
+      Foreign.CUDA.Solver.Dense.Context
+      Foreign.CUDA.Solver.Dense.Stream
+      Foreign.CUDA.Solver.Dense.Linear
+      Foreign.CUDA.Solver.Dense.Eigenvalue
+
+      -- Sparse LAPACK-like functions
+      Foreign.CUDA.Solver.Sparse
+      Foreign.CUDA.Solver.Sparse.Analysis
+      Foreign.CUDA.Solver.Sparse.Context
+      Foreign.CUDA.Solver.Sparse.Stream
+      Foreign.CUDA.Solver.Sparse.High
+      Foreign.CUDA.Solver.Sparse.Low
+
+      -- Matrix refactorisation
+      -- Foreign.CUDA.Solver.Refactorisation
+      -- Foreign.CUDA.Solver.Refactorisation.Context
+
+      Foreign.CUDA.Solver.Error
+
+  other-modules:
+      Foreign.CUDA.Solver.Dense.Analysis
+      Foreign.CUDA.Solver.Internal.C2HS
+      Foreign.CUDA.Solver.Internal.Types
+
+
+  build-depends:
+      base                              == 4.*
+    , cuda                              >= 0.8
+    , cublas                            >= 0.3
+    , cusparse                          >= 0.1
+    , 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/cusolver
+
+source-repository this
+    type:               git
+    location:           https://github.com/tmcdonell/cusolver
+    tag:                0.1.0.0
+
+-- vim: nospell
