diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) Henning Thielemann 2017
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. 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.
+3. Neither the name of the author nor the names of his contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 AUTHORS 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/Setup.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,3 @@
+#! /usr/bin/env runhaskell
+> import Distribution.Simple
+> main = defaultMain
diff --git a/blas-carray.cabal b/blas-carray.cabal
new file mode 100644
--- /dev/null
+++ b/blas-carray.cabal
@@ -0,0 +1,52 @@
+Name:             blas-carray
+Version:          0.0
+License:          BSD3
+License-File:     LICENSE
+Author:           Henning Thielemann <haskell@henning-thielemann.de>
+Maintainer:       Henning Thielemann <haskell@henning-thielemann.de>
+Homepage:         http://hub.darcs.net/thielema/blas-carray/
+Category:         Math
+Synopsis:         Auto-generated interface to Fortran BLAS via CArrays
+Description:
+  BLAS is a package for efficient basic linear algebra operations.
+  The reference implementation is written in FORTRAN.
+  This is a semi-automatically generated mid-level wrapper.
+  The functions are not ready to use for high-level applications,
+  but they are a step closer.
+  .
+  See also package @lapack-carray@.
+Tested-With:      GHC==7.4.2, GHC==7.8.4
+Cabal-Version:    >=1.14
+Build-Type:       Simple
+
+Source-Repository this
+  Tag:         0.0
+  Type:        darcs
+  Location:    http://hub.darcs.net/thielema/blas-carray/
+
+Source-Repository head
+  Type:        darcs
+  Location:    http://hub.darcs.net/thielema/blas-carray/
+
+Library
+  Build-Depends:
+    blas-ffi >=0.0 && <0.1,
+    netlib-carray >=0.0 && <0.1,
+    netlib-ffi >=0.0 && <0.1,
+    carray >=0.1.5 && <0.2,
+    storable-complex >=0.2.2 && <0.3,
+    transformers >=0.4 && <0.6,
+    base >=4.5 && <5
+
+  GHC-Options:      -Wall -fwarn-missing-import-lists
+  Hs-Source-Dirs:   src
+  Default-Language: Haskell98
+  Exposed-Modules:
+    Numeric.BLAS.CArray.Float
+    Numeric.BLAS.CArray.Double
+    Numeric.BLAS.CArray.Real
+    Numeric.BLAS.CArray.ComplexFloat
+    Numeric.BLAS.CArray.ComplexDouble
+    Numeric.BLAS.CArray.Complex
+    Numeric.BLAS.CArray.Generic
+    Numeric.BLAS.CArray.Miscellaneous
diff --git a/src/Numeric/BLAS/CArray/Complex.hs b/src/Numeric/BLAS/CArray/Complex.hs
new file mode 100644
--- /dev/null
+++ b/src/Numeric/BLAS/CArray/Complex.hs
@@ -0,0 +1,274 @@
+-- Do not edit! Automatically generated by create-lapack-ffi.
+module Numeric.BLAS.CArray.Complex (
+   axpy,
+   cabs1,
+   casum,
+   cnrm2,
+   copy,
+   gbmv,
+   gemm,
+   gemv,
+   gerc,
+   geru,
+   hbmv,
+   hemm,
+   hemv,
+   her,
+   her2,
+   her2k,
+   herk,
+   hpmv,
+   hpr,
+   hpr2,
+   iamax,
+   rotg,
+   rrot,
+   rscal,
+   scal,
+   swap,
+   symm,
+   syr2k,
+   syrk,
+   tbmv,
+   tbsv,
+   tpmv,
+   tpsv,
+   trmm,
+   trmv,
+   trsm,
+   trsv,
+   ) where
+
+import qualified Numeric.BLAS.CArray.ComplexDouble as Z
+import qualified Numeric.BLAS.CArray.ComplexFloat as C
+import qualified Numeric.Netlib.Class as Class
+
+import Data.Complex (Complex)
+
+import Data.Array.IOCArray (IOCArray)
+import Data.Array.CArray (CArray)
+
+import Foreign.C.Types (CInt)
+
+
+
+newtype AXPY a = AXPY {getAXPY :: Int -> (Complex a) -> CArray Int (Complex a) -> Int -> IOCArray Int (Complex a) -> Int -> IO ()}
+
+axpy :: Class.Real a => Int -> (Complex a) -> CArray Int (Complex a) -> Int -> IOCArray Int (Complex a) -> Int -> IO ()
+axpy = getAXPY $ Class.switchReal (AXPY C.axpy) (AXPY Z.axpy)
+
+
+newtype CABS1 a = CABS1 {getCABS1 :: (Complex a) -> IO a}
+
+cabs1 :: Class.Real a => (Complex a) -> IO a
+cabs1 = getCABS1 $ Class.switchReal (CABS1 C.cabs1) (CABS1 Z.cabs1)
+
+
+newtype CASUM a = CASUM {getCASUM :: Int -> IOCArray Int (Complex a) -> Int -> IO a}
+
+casum :: Class.Real a => Int -> IOCArray Int (Complex a) -> Int -> IO a
+casum = getCASUM $ Class.switchReal (CASUM C.casum) (CASUM Z.casum)
+
+
+newtype CNRM2 a = CNRM2 {getCNRM2 :: CArray Int (Complex a) -> Int -> IO a}
+
+cnrm2 :: Class.Real a => CArray Int (Complex a) -> Int -> IO a
+cnrm2 = getCNRM2 $ Class.switchReal (CNRM2 C.cnrm2) (CNRM2 Z.cnrm2)
+
+
+newtype COPY a = COPY {getCOPY :: Int -> CArray Int (Complex a) -> Int -> Int -> IO (CArray Int (Complex a))}
+
+copy :: Class.Real a => Int -> CArray Int (Complex a) -> Int -> Int -> IO (CArray Int (Complex a))
+copy = getCOPY $ Class.switchReal (COPY C.copy) (COPY Z.copy)
+
+
+newtype GBMV a = GBMV {getGBMV :: Char -> Int -> Int -> Int -> (Complex a) -> CArray (Int,Int) (Complex a) -> CArray Int (Complex a) -> Int -> (Complex a) -> IOCArray Int (Complex a) -> Int -> IO ()}
+
+gbmv :: Class.Real a => Char -> Int -> Int -> Int -> (Complex a) -> CArray (Int,Int) (Complex a) -> CArray Int (Complex a) -> Int -> (Complex a) -> IOCArray Int (Complex a) -> Int -> IO ()
+gbmv = getGBMV $ Class.switchReal (GBMV C.gbmv) (GBMV Z.gbmv)
+
+
+newtype GEMM a = GEMM {getGEMM :: Char -> Char -> Int -> Int -> (Complex a) -> CArray (Int,Int) (Complex a) -> CArray (Int,Int) (Complex a) -> (Complex a) -> IOCArray (Int,Int) (Complex a) -> IO ()}
+
+gemm :: Class.Real a => Char -> Char -> Int -> Int -> (Complex a) -> CArray (Int,Int) (Complex a) -> CArray (Int,Int) (Complex a) -> (Complex a) -> IOCArray (Int,Int) (Complex a) -> IO ()
+gemm = getGEMM $ Class.switchReal (GEMM C.gemm) (GEMM Z.gemm)
+
+
+newtype GEMV a = GEMV {getGEMV :: Char -> Int -> (Complex a) -> CArray (Int,Int) (Complex a) -> CArray Int (Complex a) -> Int -> (Complex a) -> IOCArray Int (Complex a) -> Int -> IO ()}
+
+gemv :: Class.Real a => Char -> Int -> (Complex a) -> CArray (Int,Int) (Complex a) -> CArray Int (Complex a) -> Int -> (Complex a) -> IOCArray Int (Complex a) -> Int -> IO ()
+gemv = getGEMV $ Class.switchReal (GEMV C.gemv) (GEMV Z.gemv)
+
+
+newtype GERC a = GERC {getGERC :: Int -> (Complex a) -> CArray Int (Complex a) -> Int -> CArray Int (Complex a) -> Int -> IOCArray (Int,Int) (Complex a) -> IO ()}
+
+gerc :: Class.Real a => Int -> (Complex a) -> CArray Int (Complex a) -> Int -> CArray Int (Complex a) -> Int -> IOCArray (Int,Int) (Complex a) -> IO ()
+gerc = getGERC $ Class.switchReal (GERC C.gerc) (GERC Z.gerc)
+
+
+newtype GERU a = GERU {getGERU :: Int -> (Complex a) -> CArray Int (Complex a) -> Int -> CArray Int (Complex a) -> Int -> IOCArray (Int,Int) (Complex a) -> IO ()}
+
+geru :: Class.Real a => Int -> (Complex a) -> CArray Int (Complex a) -> Int -> CArray Int (Complex a) -> Int -> IOCArray (Int,Int) (Complex a) -> IO ()
+geru = getGERU $ Class.switchReal (GERU C.geru) (GERU Z.geru)
+
+
+newtype HBMV a = HBMV {getHBMV :: Char -> Int -> (Complex a) -> CArray (Int,Int) (Complex a) -> CArray Int (Complex a) -> Int -> (Complex a) -> IOCArray Int (Complex a) -> Int -> IO ()}
+
+hbmv :: Class.Real a => Char -> Int -> (Complex a) -> CArray (Int,Int) (Complex a) -> CArray Int (Complex a) -> Int -> (Complex a) -> IOCArray Int (Complex a) -> Int -> IO ()
+hbmv = getHBMV $ Class.switchReal (HBMV C.hbmv) (HBMV Z.hbmv)
+
+
+newtype HEMM a = HEMM {getHEMM :: Char -> Char -> Int -> (Complex a) -> CArray (Int,Int) (Complex a) -> CArray (Int,Int) (Complex a) -> (Complex a) -> IOCArray (Int,Int) (Complex a) -> IO ()}
+
+hemm :: Class.Real a => Char -> Char -> Int -> (Complex a) -> CArray (Int,Int) (Complex a) -> CArray (Int,Int) (Complex a) -> (Complex a) -> IOCArray (Int,Int) (Complex a) -> IO ()
+hemm = getHEMM $ Class.switchReal (HEMM C.hemm) (HEMM Z.hemm)
+
+
+newtype HEMV a = HEMV {getHEMV :: Char -> (Complex a) -> CArray (Int,Int) (Complex a) -> CArray Int (Complex a) -> Int -> (Complex a) -> IOCArray Int (Complex a) -> Int -> IO ()}
+
+hemv :: Class.Real a => Char -> (Complex a) -> CArray (Int,Int) (Complex a) -> CArray Int (Complex a) -> Int -> (Complex a) -> IOCArray Int (Complex a) -> Int -> IO ()
+hemv = getHEMV $ Class.switchReal (HEMV C.hemv) (HEMV Z.hemv)
+
+
+newtype HER a = HER {getHER :: Char -> a -> CArray Int (Complex a) -> Int -> IOCArray (Int,Int) (Complex a) -> IO ()}
+
+her :: Class.Real a => Char -> a -> CArray Int (Complex a) -> Int -> IOCArray (Int,Int) (Complex a) -> IO ()
+her = getHER $ Class.switchReal (HER C.her) (HER Z.her)
+
+
+newtype HER2 a = HER2 {getHER2 :: Char -> (Complex a) -> CArray Int (Complex a) -> Int -> CArray Int (Complex a) -> Int -> IOCArray (Int,Int) (Complex a) -> IO ()}
+
+her2 :: Class.Real a => Char -> (Complex a) -> CArray Int (Complex a) -> Int -> CArray Int (Complex a) -> Int -> IOCArray (Int,Int) (Complex a) -> IO ()
+her2 = getHER2 $ Class.switchReal (HER2 C.her2) (HER2 Z.her2)
+
+
+newtype HER2K a = HER2K {getHER2K :: Char -> Char -> Int -> (Complex a) -> CArray (Int,Int) (Complex a) -> CArray (Int,Int) (Complex a) -> a -> IOCArray (Int,Int) (Complex a) -> IO ()}
+
+her2k :: Class.Real a => Char -> Char -> Int -> (Complex a) -> CArray (Int,Int) (Complex a) -> CArray (Int,Int) (Complex a) -> a -> IOCArray (Int,Int) (Complex a) -> IO ()
+her2k = getHER2K $ Class.switchReal (HER2K C.her2k) (HER2K Z.her2k)
+
+
+newtype HERK a = HERK {getHERK :: Char -> Char -> Int -> a -> CArray (Int,Int) (Complex a) -> a -> IOCArray (Int,Int) (Complex a) -> IO ()}
+
+herk :: Class.Real a => Char -> Char -> Int -> a -> CArray (Int,Int) (Complex a) -> a -> IOCArray (Int,Int) (Complex a) -> IO ()
+herk = getHERK $ Class.switchReal (HERK C.herk) (HERK Z.herk)
+
+
+newtype HPMV a = HPMV {getHPMV :: Char -> Int -> (Complex a) -> CArray Int (Complex a) -> CArray Int (Complex a) -> Int -> (Complex a) -> IOCArray Int (Complex a) -> Int -> IO ()}
+
+hpmv :: Class.Real a => Char -> Int -> (Complex a) -> CArray Int (Complex a) -> CArray Int (Complex a) -> Int -> (Complex a) -> IOCArray Int (Complex a) -> Int -> IO ()
+hpmv = getHPMV $ Class.switchReal (HPMV C.hpmv) (HPMV Z.hpmv)
+
+
+newtype HPR a = HPR {getHPR :: Char -> Int -> a -> CArray Int (Complex a) -> Int -> IOCArray Int (Complex a) -> IO ()}
+
+hpr :: Class.Real a => Char -> Int -> a -> CArray Int (Complex a) -> Int -> IOCArray Int (Complex a) -> IO ()
+hpr = getHPR $ Class.switchReal (HPR C.hpr) (HPR Z.hpr)
+
+
+newtype HPR2 a = HPR2 {getHPR2 :: Char -> Int -> (Complex a) -> CArray Int (Complex a) -> Int -> CArray Int (Complex a) -> Int -> IOCArray Int (Complex a) -> IO ()}
+
+hpr2 :: Class.Real a => Char -> Int -> (Complex a) -> CArray Int (Complex a) -> Int -> CArray Int (Complex a) -> Int -> IOCArray Int (Complex a) -> IO ()
+hpr2 = getHPR2 $ Class.switchReal (HPR2 C.hpr2) (HPR2 Z.hpr2)
+
+
+newtype IAMAX a = IAMAX {getIAMAX :: Int -> CArray Int (Complex a) -> Int -> IO CInt}
+
+iamax :: Class.Real a => Int -> CArray Int (Complex a) -> Int -> IO CInt
+iamax = getIAMAX $ Class.switchReal (IAMAX C.iamax) (IAMAX Z.iamax)
+
+
+newtype ROTG a = ROTG {getROTG :: (Complex a) -> (Complex a) -> IO (a, (Complex a))}
+
+rotg :: Class.Real a => (Complex a) -> (Complex a) -> IO (a, (Complex a))
+rotg = getROTG $ Class.switchReal (ROTG C.rotg) (ROTG Z.rotg)
+
+
+newtype RROT a = RROT {getRROT :: Int -> IOCArray Int (Complex a) -> Int -> IOCArray Int (Complex a) -> Int -> a -> a -> IO ()}
+
+rrot :: Class.Real a => Int -> IOCArray Int (Complex a) -> Int -> IOCArray Int (Complex a) -> Int -> a -> a -> IO ()
+rrot = getRROT $ Class.switchReal (RROT C.rrot) (RROT Z.rrot)
+
+
+newtype RSCAL a = RSCAL {getRSCAL :: Int -> a -> IOCArray Int (Complex a) -> Int -> IO ()}
+
+rscal :: Class.Real a => Int -> a -> IOCArray Int (Complex a) -> Int -> IO ()
+rscal = getRSCAL $ Class.switchReal (RSCAL C.rscal) (RSCAL Z.rscal)
+
+
+newtype SCAL a = SCAL {getSCAL :: Int -> (Complex a) -> IOCArray Int (Complex a) -> Int -> IO ()}
+
+scal :: Class.Real a => Int -> (Complex a) -> IOCArray Int (Complex a) -> Int -> IO ()
+scal = getSCAL $ Class.switchReal (SCAL C.scal) (SCAL Z.scal)
+
+
+newtype SWAP a = SWAP {getSWAP :: Int -> IOCArray Int (Complex a) -> Int -> IOCArray Int (Complex a) -> Int -> IO ()}
+
+swap :: Class.Real a => Int -> IOCArray Int (Complex a) -> Int -> IOCArray Int (Complex a) -> Int -> IO ()
+swap = getSWAP $ Class.switchReal (SWAP C.swap) (SWAP Z.swap)
+
+
+newtype SYMM a = SYMM {getSYMM :: Char -> Char -> Int -> (Complex a) -> CArray (Int,Int) (Complex a) -> CArray (Int,Int) (Complex a) -> (Complex a) -> IOCArray (Int,Int) (Complex a) -> IO ()}
+
+symm :: Class.Real a => Char -> Char -> Int -> (Complex a) -> CArray (Int,Int) (Complex a) -> CArray (Int,Int) (Complex a) -> (Complex a) -> IOCArray (Int,Int) (Complex a) -> IO ()
+symm = getSYMM $ Class.switchReal (SYMM C.symm) (SYMM Z.symm)
+
+
+newtype SYR2K a = SYR2K {getSYR2K :: Char -> Char -> Int -> (Complex a) -> CArray (Int,Int) (Complex a) -> CArray (Int,Int) (Complex a) -> (Complex a) -> IOCArray (Int,Int) (Complex a) -> IO ()}
+
+syr2k :: Class.Real a => Char -> Char -> Int -> (Complex a) -> CArray (Int,Int) (Complex a) -> CArray (Int,Int) (Complex a) -> (Complex a) -> IOCArray (Int,Int) (Complex a) -> IO ()
+syr2k = getSYR2K $ Class.switchReal (SYR2K C.syr2k) (SYR2K Z.syr2k)
+
+
+newtype SYRK a = SYRK {getSYRK :: Char -> Char -> Int -> (Complex a) -> CArray (Int,Int) (Complex a) -> (Complex a) -> IOCArray (Int,Int) (Complex a) -> IO ()}
+
+syrk :: Class.Real a => Char -> Char -> Int -> (Complex a) -> CArray (Int,Int) (Complex a) -> (Complex a) -> IOCArray (Int,Int) (Complex a) -> IO ()
+syrk = getSYRK $ Class.switchReal (SYRK C.syrk) (SYRK Z.syrk)
+
+
+newtype TBMV a = TBMV {getTBMV :: Char -> Char -> Char -> Int -> CArray (Int,Int) (Complex a) -> IOCArray Int (Complex a) -> Int -> IO ()}
+
+tbmv :: Class.Real a => Char -> Char -> Char -> Int -> CArray (Int,Int) (Complex a) -> IOCArray Int (Complex a) -> Int -> IO ()
+tbmv = getTBMV $ Class.switchReal (TBMV C.tbmv) (TBMV Z.tbmv)
+
+
+newtype TBSV a = TBSV {getTBSV :: Char -> Char -> Char -> Int -> CArray (Int,Int) (Complex a) -> IOCArray Int (Complex a) -> Int -> IO ()}
+
+tbsv :: Class.Real a => Char -> Char -> Char -> Int -> CArray (Int,Int) (Complex a) -> IOCArray Int (Complex a) -> Int -> IO ()
+tbsv = getTBSV $ Class.switchReal (TBSV C.tbsv) (TBSV Z.tbsv)
+
+
+newtype TPMV a = TPMV {getTPMV :: Char -> Char -> Char -> Int -> CArray Int (Complex a) -> IOCArray Int (Complex a) -> Int -> IO ()}
+
+tpmv :: Class.Real a => Char -> Char -> Char -> Int -> CArray Int (Complex a) -> IOCArray Int (Complex a) -> Int -> IO ()
+tpmv = getTPMV $ Class.switchReal (TPMV C.tpmv) (TPMV Z.tpmv)
+
+
+newtype TPSV a = TPSV {getTPSV :: Char -> Char -> Char -> Int -> CArray Int (Complex a) -> IOCArray Int (Complex a) -> Int -> IO ()}
+
+tpsv :: Class.Real a => Char -> Char -> Char -> Int -> CArray Int (Complex a) -> IOCArray Int (Complex a) -> Int -> IO ()
+tpsv = getTPSV $ Class.switchReal (TPSV C.tpsv) (TPSV Z.tpsv)
+
+
+newtype TRMM a = TRMM {getTRMM :: Char -> Char -> Char -> Char -> Int -> (Complex a) -> CArray (Int,Int) (Complex a) -> IOCArray (Int,Int) (Complex a) -> IO ()}
+
+trmm :: Class.Real a => Char -> Char -> Char -> Char -> Int -> (Complex a) -> CArray (Int,Int) (Complex a) -> IOCArray (Int,Int) (Complex a) -> IO ()
+trmm = getTRMM $ Class.switchReal (TRMM C.trmm) (TRMM Z.trmm)
+
+
+newtype TRMV a = TRMV {getTRMV :: Char -> Char -> Char -> CArray (Int,Int) (Complex a) -> IOCArray Int (Complex a) -> Int -> IO ()}
+
+trmv :: Class.Real a => Char -> Char -> Char -> CArray (Int,Int) (Complex a) -> IOCArray Int (Complex a) -> Int -> IO ()
+trmv = getTRMV $ Class.switchReal (TRMV C.trmv) (TRMV Z.trmv)
+
+
+newtype TRSM a = TRSM {getTRSM :: Char -> Char -> Char -> Char -> Int -> (Complex a) -> CArray (Int,Int) (Complex a) -> IOCArray (Int,Int) (Complex a) -> IO ()}
+
+trsm :: Class.Real a => Char -> Char -> Char -> Char -> Int -> (Complex a) -> CArray (Int,Int) (Complex a) -> IOCArray (Int,Int) (Complex a) -> IO ()
+trsm = getTRSM $ Class.switchReal (TRSM C.trsm) (TRSM Z.trsm)
+
+
+newtype TRSV a = TRSV {getTRSV :: Char -> Char -> Char -> CArray (Int,Int) (Complex a) -> IOCArray Int (Complex a) -> Int -> IO ()}
+
+trsv :: Class.Real a => Char -> Char -> Char -> CArray (Int,Int) (Complex a) -> IOCArray Int (Complex a) -> Int -> IO ()
+trsv = getTRSV $ Class.switchReal (TRSV C.trsv) (TRSV Z.trsv)
diff --git a/src/Numeric/BLAS/CArray/ComplexDouble.hs b/src/Numeric/BLAS/CArray/ComplexDouble.hs
new file mode 100644
--- /dev/null
+++ b/src/Numeric/BLAS/CArray/ComplexDouble.hs
@@ -0,0 +1,973 @@
+-- Do not edit! Automatically generated by create-lapack-ffi.
+module Numeric.BLAS.CArray.ComplexDouble where
+
+import qualified Numeric.BLAS.FFI.ComplexDouble as FFI
+import qualified Numeric.Netlib.CArray.Utility as Call
+
+import Data.Array.IOCArray (IOCArray, getBounds)
+import Data.Array.CArray (CArray, bounds)
+
+import Data.Complex (Complex)
+
+import Foreign.Storable.Complex ()
+import Foreign.Storable (peek)
+import Foreign.C.Types (CInt)
+
+import Control.Monad.Trans.Cont (evalContT)
+import Control.Monad.IO.Class (liftIO)
+import Control.Applicative (pure, (<$>), (<*>))
+
+
+axpy ::
+   Int {- ^ n -} ->
+   Complex Double {- ^ za -} ->
+   CArray Int (Complex Double) {- ^ zx -} ->
+   Int {- ^ incx -} ->
+   IOCArray Int (Complex Double) {- ^ zy -} ->
+   Int {- ^ incy -} ->
+   IO ()
+axpy n za zx incx zy incy = do
+   let zxDim0 = Call.sizes1 $ bounds zx
+   zyDim0 <- Call.sizes1 <$> getBounds zy
+   Call.assert "axpy: 1+(n-1)*abs(incx) == zxDim0" (1+(n-1)*abs(incx) == zxDim0)
+   Call.assert "axpy: 1+(n-1)*abs(incy) == zyDim0" (1+(n-1)*abs(incy) == zyDim0)
+   evalContT $ do
+      nPtr <- Call.cint n
+      zaPtr <- Call.complexDouble za
+      zxPtr <- Call.array zx
+      incxPtr <- Call.cint incx
+      zyPtr <- Call.ioarray zy
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.axpy nPtr zaPtr zxPtr incxPtr zyPtr incyPtr
+
+cabs1 ::
+   Complex Double {- ^ z -} ->
+   IO Double
+cabs1 z = do
+   evalContT $ do
+      zPtr <- Call.complexDouble z
+      liftIO $ FFI.cabs1 zPtr
+
+casum ::
+   Int {- ^ n -} ->
+   IOCArray Int (Complex Double) {- ^ zx -} ->
+   Int {- ^ incx -} ->
+   IO Double
+casum n zx incx = do
+   zxDim0 <- Call.sizes1 <$> getBounds zx
+   Call.assert "casum: 1+(n-1)*abs(incx) == zxDim0" (1+(n-1)*abs(incx) == zxDim0)
+   evalContT $ do
+      nPtr <- Call.cint n
+      zxPtr <- Call.ioarray zx
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.casum nPtr zxPtr incxPtr
+
+cnrm2 ::
+   CArray Int (Complex Double) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IO Double
+cnrm2 x incx = do
+   let xDim0 = Call.sizes1 $ bounds x
+   let n = xDim0
+   evalContT $ do
+      nPtr <- Call.cint n
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.cnrm2 nPtr xPtr incxPtr
+
+copy ::
+   Int {- ^ n -} ->
+   CArray Int (Complex Double) {- ^ zx -} ->
+   Int {- ^ incx -} ->
+   Int {- ^ incy -} ->
+   IO (CArray Int (Complex Double))
+copy n zx incx incy = do
+   let zxDim0 = Call.sizes1 $ bounds zx
+   Call.assert "copy: 1+(n-1)*abs(incx) == zxDim0" (1+(n-1)*abs(incx) == zxDim0)
+   zy <- Call.newArray1 (1+(n-1)*abs(incy))
+   evalContT $ do
+      nPtr <- Call.cint n
+      zxPtr <- Call.array zx
+      incxPtr <- Call.cint incx
+      zyPtr <- Call.array zy
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.copy nPtr zxPtr incxPtr zyPtr incyPtr
+      liftIO $ pure zy
+
+gbmv ::
+   Char {- ^ trans -} ->
+   Int {- ^ m -} ->
+   Int {- ^ kl -} ->
+   Int {- ^ ku -} ->
+   Complex Double {- ^ alpha -} ->
+   CArray (Int,Int) (Complex Double) {- ^ a -} ->
+   CArray Int (Complex Double) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   Complex Double {- ^ beta -} ->
+   IOCArray Int (Complex Double) {- ^ y -} ->
+   Int {- ^ incy -} ->
+   IO ()
+gbmv trans m kl ku alpha a x incx beta y incy = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   let xDim0 = Call.sizes1 $ bounds x
+   yDim0 <- Call.sizes1 <$> getBounds y
+   let n = aDim0
+   let lda = aDim1
+   let _xSize = xDim0
+   let _ySize = yDim0
+   evalContT $ do
+      transPtr <- Call.char trans
+      mPtr <- Call.cint m
+      nPtr <- Call.cint n
+      klPtr <- Call.cint kl
+      kuPtr <- Call.cint ku
+      alphaPtr <- Call.complexDouble alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      betaPtr <- Call.complexDouble beta
+      yPtr <- Call.ioarray y
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.gbmv transPtr mPtr nPtr klPtr kuPtr alphaPtr aPtr ldaPtr xPtr incxPtr betaPtr yPtr incyPtr
+
+gemm ::
+   Char {- ^ transa -} ->
+   Char {- ^ transb -} ->
+   Int {- ^ m -} ->
+   Int {- ^ k -} ->
+   Complex Double {- ^ alpha -} ->
+   CArray (Int,Int) (Complex Double) {- ^ a -} ->
+   CArray (Int,Int) (Complex Double) {- ^ b -} ->
+   Complex Double {- ^ beta -} ->
+   IOCArray (Int,Int) (Complex Double) {- ^ c -} ->
+   IO ()
+gemm transa transb m k alpha a b beta c = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   let (bDim0,bDim1) = Call.sizes2 $ bounds b
+   (cDim0,cDim1) <- Call.sizes2 <$> getBounds c
+   let _ka = aDim0
+   let lda = aDim1
+   let _kb = bDim0
+   let ldb = bDim1
+   let n = cDim0
+   let ldc = cDim1
+   evalContT $ do
+      transaPtr <- Call.char transa
+      transbPtr <- Call.char transb
+      mPtr <- Call.cint m
+      nPtr <- Call.cint n
+      kPtr <- Call.cint k
+      alphaPtr <- Call.complexDouble alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      bPtr <- Call.array b
+      ldbPtr <- Call.cint ldb
+      betaPtr <- Call.complexDouble beta
+      cPtr <- Call.ioarray c
+      ldcPtr <- Call.cint ldc
+      liftIO $ FFI.gemm transaPtr transbPtr mPtr nPtr kPtr alphaPtr aPtr ldaPtr bPtr ldbPtr betaPtr cPtr ldcPtr
+
+gemv ::
+   Char {- ^ trans -} ->
+   Int {- ^ m -} ->
+   Complex Double {- ^ alpha -} ->
+   CArray (Int,Int) (Complex Double) {- ^ a -} ->
+   CArray Int (Complex Double) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   Complex Double {- ^ beta -} ->
+   IOCArray Int (Complex Double) {- ^ y -} ->
+   Int {- ^ incy -} ->
+   IO ()
+gemv trans m alpha a x incx beta y incy = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   let xDim0 = Call.sizes1 $ bounds x
+   yDim0 <- Call.sizes1 <$> getBounds y
+   let n = aDim0
+   let lda = aDim1
+   let _xSize = xDim0
+   let _ySize = yDim0
+   evalContT $ do
+      transPtr <- Call.char trans
+      mPtr <- Call.cint m
+      nPtr <- Call.cint n
+      alphaPtr <- Call.complexDouble alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      betaPtr <- Call.complexDouble beta
+      yPtr <- Call.ioarray y
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.gemv transPtr mPtr nPtr alphaPtr aPtr ldaPtr xPtr incxPtr betaPtr yPtr incyPtr
+
+gerc ::
+   Int {- ^ m -} ->
+   Complex Double {- ^ alpha -} ->
+   CArray Int (Complex Double) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   CArray Int (Complex Double) {- ^ y -} ->
+   Int {- ^ incy -} ->
+   IOCArray (Int,Int) (Complex Double) {- ^ a -} ->
+   IO ()
+gerc m alpha x incx y incy a = do
+   let xDim0 = Call.sizes1 $ bounds x
+   let yDim0 = Call.sizes1 $ bounds y
+   (aDim0,aDim1) <- Call.sizes2 <$> getBounds a
+   let _xSize = xDim0
+   let _ySize = yDim0
+   let n = aDim0
+   let lda = aDim1
+   evalContT $ do
+      mPtr <- Call.cint m
+      nPtr <- Call.cint n
+      alphaPtr <- Call.complexDouble alpha
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      yPtr <- Call.array y
+      incyPtr <- Call.cint incy
+      aPtr <- Call.ioarray a
+      ldaPtr <- Call.cint lda
+      liftIO $ FFI.gerc mPtr nPtr alphaPtr xPtr incxPtr yPtr incyPtr aPtr ldaPtr
+
+geru ::
+   Int {- ^ m -} ->
+   Complex Double {- ^ alpha -} ->
+   CArray Int (Complex Double) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   CArray Int (Complex Double) {- ^ y -} ->
+   Int {- ^ incy -} ->
+   IOCArray (Int,Int) (Complex Double) {- ^ a -} ->
+   IO ()
+geru m alpha x incx y incy a = do
+   let xDim0 = Call.sizes1 $ bounds x
+   let yDim0 = Call.sizes1 $ bounds y
+   (aDim0,aDim1) <- Call.sizes2 <$> getBounds a
+   let _xSize = xDim0
+   let _ySize = yDim0
+   let n = aDim0
+   let lda = aDim1
+   evalContT $ do
+      mPtr <- Call.cint m
+      nPtr <- Call.cint n
+      alphaPtr <- Call.complexDouble alpha
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      yPtr <- Call.array y
+      incyPtr <- Call.cint incy
+      aPtr <- Call.ioarray a
+      ldaPtr <- Call.cint lda
+      liftIO $ FFI.geru mPtr nPtr alphaPtr xPtr incxPtr yPtr incyPtr aPtr ldaPtr
+
+hbmv ::
+   Char {- ^ uplo -} ->
+   Int {- ^ k -} ->
+   Complex Double {- ^ alpha -} ->
+   CArray (Int,Int) (Complex Double) {- ^ a -} ->
+   CArray Int (Complex Double) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   Complex Double {- ^ beta -} ->
+   IOCArray Int (Complex Double) {- ^ y -} ->
+   Int {- ^ incy -} ->
+   IO ()
+hbmv uplo k alpha a x incx beta y incy = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   let xDim0 = Call.sizes1 $ bounds x
+   yDim0 <- Call.sizes1 <$> getBounds y
+   let n = aDim0
+   let lda = aDim1
+   let _xSize = xDim0
+   let _ySize = yDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      nPtr <- Call.cint n
+      kPtr <- Call.cint k
+      alphaPtr <- Call.complexDouble alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      betaPtr <- Call.complexDouble beta
+      yPtr <- Call.ioarray y
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.hbmv uploPtr nPtr kPtr alphaPtr aPtr ldaPtr xPtr incxPtr betaPtr yPtr incyPtr
+
+hemm ::
+   Char {- ^ side -} ->
+   Char {- ^ uplo -} ->
+   Int {- ^ m -} ->
+   Complex Double {- ^ alpha -} ->
+   CArray (Int,Int) (Complex Double) {- ^ a -} ->
+   CArray (Int,Int) (Complex Double) {- ^ b -} ->
+   Complex Double {- ^ beta -} ->
+   IOCArray (Int,Int) (Complex Double) {- ^ c -} ->
+   IO ()
+hemm side uplo m alpha a b beta c = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   let (bDim0,bDim1) = Call.sizes2 $ bounds b
+   (cDim0,cDim1) <- Call.sizes2 <$> getBounds c
+   let _ka = aDim0
+   let lda = aDim1
+   let n = bDim0
+   let ldb = bDim1
+   let ldc = cDim1
+   Call.assert "hemm: n == cDim0" (n == cDim0)
+   evalContT $ do
+      sidePtr <- Call.char side
+      uploPtr <- Call.char uplo
+      mPtr <- Call.cint m
+      nPtr <- Call.cint n
+      alphaPtr <- Call.complexDouble alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      bPtr <- Call.array b
+      ldbPtr <- Call.cint ldb
+      betaPtr <- Call.complexDouble beta
+      cPtr <- Call.ioarray c
+      ldcPtr <- Call.cint ldc
+      liftIO $ FFI.hemm sidePtr uploPtr mPtr nPtr alphaPtr aPtr ldaPtr bPtr ldbPtr betaPtr cPtr ldcPtr
+
+hemv ::
+   Char {- ^ uplo -} ->
+   Complex Double {- ^ alpha -} ->
+   CArray (Int,Int) (Complex Double) {- ^ a -} ->
+   CArray Int (Complex Double) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   Complex Double {- ^ beta -} ->
+   IOCArray Int (Complex Double) {- ^ y -} ->
+   Int {- ^ incy -} ->
+   IO ()
+hemv uplo alpha a x incx beta y incy = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   let xDim0 = Call.sizes1 $ bounds x
+   yDim0 <- Call.sizes1 <$> getBounds y
+   let n = aDim0
+   let lda = aDim1
+   let _xSize = xDim0
+   let _ySize = yDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      nPtr <- Call.cint n
+      alphaPtr <- Call.complexDouble alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      betaPtr <- Call.complexDouble beta
+      yPtr <- Call.ioarray y
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.hemv uploPtr nPtr alphaPtr aPtr ldaPtr xPtr incxPtr betaPtr yPtr incyPtr
+
+her ::
+   Char {- ^ uplo -} ->
+   Double {- ^ alpha -} ->
+   CArray Int (Complex Double) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IOCArray (Int,Int) (Complex Double) {- ^ a -} ->
+   IO ()
+her uplo alpha x incx a = do
+   let xDim0 = Call.sizes1 $ bounds x
+   (aDim0,aDim1) <- Call.sizes2 <$> getBounds a
+   let _xSize = xDim0
+   let n = aDim0
+   let lda = aDim1
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      nPtr <- Call.cint n
+      alphaPtr <- Call.double alpha
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      aPtr <- Call.ioarray a
+      ldaPtr <- Call.cint lda
+      liftIO $ FFI.her uploPtr nPtr alphaPtr xPtr incxPtr aPtr ldaPtr
+
+her2 ::
+   Char {- ^ uplo -} ->
+   Complex Double {- ^ alpha -} ->
+   CArray Int (Complex Double) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   CArray Int (Complex Double) {- ^ y -} ->
+   Int {- ^ incy -} ->
+   IOCArray (Int,Int) (Complex Double) {- ^ a -} ->
+   IO ()
+her2 uplo alpha x incx y incy a = do
+   let xDim0 = Call.sizes1 $ bounds x
+   let yDim0 = Call.sizes1 $ bounds y
+   (aDim0,aDim1) <- Call.sizes2 <$> getBounds a
+   let _xSize = xDim0
+   let _ySize = yDim0
+   let n = aDim0
+   let lda = aDim1
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      nPtr <- Call.cint n
+      alphaPtr <- Call.complexDouble alpha
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      yPtr <- Call.array y
+      incyPtr <- Call.cint incy
+      aPtr <- Call.ioarray a
+      ldaPtr <- Call.cint lda
+      liftIO $ FFI.her2 uploPtr nPtr alphaPtr xPtr incxPtr yPtr incyPtr aPtr ldaPtr
+
+her2k ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Int {- ^ k -} ->
+   Complex Double {- ^ alpha -} ->
+   CArray (Int,Int) (Complex Double) {- ^ a -} ->
+   CArray (Int,Int) (Complex Double) {- ^ b -} ->
+   Double {- ^ beta -} ->
+   IOCArray (Int,Int) (Complex Double) {- ^ c -} ->
+   IO ()
+her2k uplo trans k alpha a b beta c = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   let (bDim0,bDim1) = Call.sizes2 $ bounds b
+   (cDim0,cDim1) <- Call.sizes2 <$> getBounds c
+   let _ka = aDim0
+   let lda = aDim1
+   let _kb = bDim0
+   let ldb = bDim1
+   let n = cDim0
+   let ldc = cDim1
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      nPtr <- Call.cint n
+      kPtr <- Call.cint k
+      alphaPtr <- Call.complexDouble alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      bPtr <- Call.array b
+      ldbPtr <- Call.cint ldb
+      betaPtr <- Call.double beta
+      cPtr <- Call.ioarray c
+      ldcPtr <- Call.cint ldc
+      liftIO $ FFI.her2k uploPtr transPtr nPtr kPtr alphaPtr aPtr ldaPtr bPtr ldbPtr betaPtr cPtr ldcPtr
+
+herk ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Int {- ^ k -} ->
+   Double {- ^ alpha -} ->
+   CArray (Int,Int) (Complex Double) {- ^ a -} ->
+   Double {- ^ beta -} ->
+   IOCArray (Int,Int) (Complex Double) {- ^ c -} ->
+   IO ()
+herk uplo trans k alpha a beta c = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   (cDim0,cDim1) <- Call.sizes2 <$> getBounds c
+   let _ka = aDim0
+   let lda = aDim1
+   let n = cDim0
+   let ldc = cDim1
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      nPtr <- Call.cint n
+      kPtr <- Call.cint k
+      alphaPtr <- Call.double alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      betaPtr <- Call.double beta
+      cPtr <- Call.ioarray c
+      ldcPtr <- Call.cint ldc
+      liftIO $ FFI.herk uploPtr transPtr nPtr kPtr alphaPtr aPtr ldaPtr betaPtr cPtr ldcPtr
+
+hpmv ::
+   Char {- ^ uplo -} ->
+   Int {- ^ n -} ->
+   Complex Double {- ^ alpha -} ->
+   CArray Int (Complex Double) {- ^ ap -} ->
+   CArray Int (Complex Double) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   Complex Double {- ^ beta -} ->
+   IOCArray Int (Complex Double) {- ^ y -} ->
+   Int {- ^ incy -} ->
+   IO ()
+hpmv uplo n alpha ap x incx beta y incy = do
+   let apDim0 = Call.sizes1 $ bounds ap
+   let xDim0 = Call.sizes1 $ bounds x
+   yDim0 <- Call.sizes1 <$> getBounds y
+   let _apSize = apDim0
+   let _xSize = xDim0
+   let _ySize = yDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      nPtr <- Call.cint n
+      alphaPtr <- Call.complexDouble alpha
+      apPtr <- Call.array ap
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      betaPtr <- Call.complexDouble beta
+      yPtr <- Call.ioarray y
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.hpmv uploPtr nPtr alphaPtr apPtr xPtr incxPtr betaPtr yPtr incyPtr
+
+hpr ::
+   Char {- ^ uplo -} ->
+   Int {- ^ n -} ->
+   Double {- ^ alpha -} ->
+   CArray Int (Complex Double) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IOCArray Int (Complex Double) {- ^ ap -} ->
+   IO ()
+hpr uplo n alpha x incx ap = do
+   let xDim0 = Call.sizes1 $ bounds x
+   apDim0 <- Call.sizes1 <$> getBounds ap
+   let _xSize = xDim0
+   let _apSize = apDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      nPtr <- Call.cint n
+      alphaPtr <- Call.double alpha
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      apPtr <- Call.ioarray ap
+      liftIO $ FFI.hpr uploPtr nPtr alphaPtr xPtr incxPtr apPtr
+
+hpr2 ::
+   Char {- ^ uplo -} ->
+   Int {- ^ n -} ->
+   Complex Double {- ^ alpha -} ->
+   CArray Int (Complex Double) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   CArray Int (Complex Double) {- ^ y -} ->
+   Int {- ^ incy -} ->
+   IOCArray Int (Complex Double) {- ^ ap -} ->
+   IO ()
+hpr2 uplo n alpha x incx y incy ap = do
+   let xDim0 = Call.sizes1 $ bounds x
+   let yDim0 = Call.sizes1 $ bounds y
+   apDim0 <- Call.sizes1 <$> getBounds ap
+   let _xSize = xDim0
+   let _ySize = yDim0
+   let _apSize = apDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      nPtr <- Call.cint n
+      alphaPtr <- Call.complexDouble alpha
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      yPtr <- Call.array y
+      incyPtr <- Call.cint incy
+      apPtr <- Call.ioarray ap
+      liftIO $ FFI.hpr2 uploPtr nPtr alphaPtr xPtr incxPtr yPtr incyPtr apPtr
+
+iamax ::
+   Int {- ^ n -} ->
+   CArray Int (Complex Double) {- ^ zx -} ->
+   Int {- ^ incx -} ->
+   IO CInt
+iamax n zx incx = do
+   let zxDim0 = Call.sizes1 $ bounds zx
+   Call.assert "iamax: 1+(n-1)*abs(incx) == zxDim0" (1+(n-1)*abs(incx) == zxDim0)
+   evalContT $ do
+      nPtr <- Call.cint n
+      zxPtr <- Call.array zx
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.iamax nPtr zxPtr incxPtr
+
+rotg ::
+   Complex Double {- ^ ca -} ->
+   Complex Double {- ^ cb -} ->
+   IO (Double, Complex Double)
+rotg ca cb = do
+   evalContT $ do
+      caPtr <- Call.complexDouble ca
+      cbPtr <- Call.complexDouble cb
+      cPtr <- Call.alloca
+      sPtr <- Call.alloca
+      liftIO $ FFI.rotg caPtr cbPtr cPtr sPtr
+      liftIO $ pure (,)
+         <*> peek cPtr
+         <*> peek sPtr
+
+rrot ::
+   Int {- ^ n -} ->
+   IOCArray Int (Complex Double) {- ^ cx -} ->
+   Int {- ^ incx -} ->
+   IOCArray Int (Complex Double) {- ^ cy -} ->
+   Int {- ^ incy -} ->
+   Double {- ^ c -} ->
+   Double {- ^ s -} ->
+   IO ()
+rrot n cx incx cy incy c s = do
+   cxDim0 <- Call.sizes1 <$> getBounds cx
+   cyDim0 <- Call.sizes1 <$> getBounds cy
+   let _cxSize = cxDim0
+   let _cySize = cyDim0
+   evalContT $ do
+      nPtr <- Call.cint n
+      cxPtr <- Call.ioarray cx
+      incxPtr <- Call.cint incx
+      cyPtr <- Call.ioarray cy
+      incyPtr <- Call.cint incy
+      cPtr <- Call.double c
+      sPtr <- Call.double s
+      liftIO $ FFI.rrot nPtr cxPtr incxPtr cyPtr incyPtr cPtr sPtr
+
+rscal ::
+   Int {- ^ n -} ->
+   Double {- ^ da -} ->
+   IOCArray Int (Complex Double) {- ^ zx -} ->
+   Int {- ^ incx -} ->
+   IO ()
+rscal n da zx incx = do
+   zxDim0 <- Call.sizes1 <$> getBounds zx
+   Call.assert "rscal: 1+(n-1)*abs(incx) == zxDim0" (1+(n-1)*abs(incx) == zxDim0)
+   evalContT $ do
+      nPtr <- Call.cint n
+      daPtr <- Call.double da
+      zxPtr <- Call.ioarray zx
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.rscal nPtr daPtr zxPtr incxPtr
+
+scal ::
+   Int {- ^ n -} ->
+   Complex Double {- ^ za -} ->
+   IOCArray Int (Complex Double) {- ^ zx -} ->
+   Int {- ^ incx -} ->
+   IO ()
+scal n za zx incx = do
+   zxDim0 <- Call.sizes1 <$> getBounds zx
+   Call.assert "scal: 1+(n-1)*abs(incx) == zxDim0" (1+(n-1)*abs(incx) == zxDim0)
+   evalContT $ do
+      nPtr <- Call.cint n
+      zaPtr <- Call.complexDouble za
+      zxPtr <- Call.ioarray zx
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.scal nPtr zaPtr zxPtr incxPtr
+
+swap ::
+   Int {- ^ n -} ->
+   IOCArray Int (Complex Double) {- ^ zx -} ->
+   Int {- ^ incx -} ->
+   IOCArray Int (Complex Double) {- ^ zy -} ->
+   Int {- ^ incy -} ->
+   IO ()
+swap n zx incx zy incy = do
+   zxDim0 <- Call.sizes1 <$> getBounds zx
+   zyDim0 <- Call.sizes1 <$> getBounds zy
+   Call.assert "swap: 1+(n-1)*abs(incx) == zxDim0" (1+(n-1)*abs(incx) == zxDim0)
+   Call.assert "swap: 1+(n-1)*abs(incy) == zyDim0" (1+(n-1)*abs(incy) == zyDim0)
+   evalContT $ do
+      nPtr <- Call.cint n
+      zxPtr <- Call.ioarray zx
+      incxPtr <- Call.cint incx
+      zyPtr <- Call.ioarray zy
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.swap nPtr zxPtr incxPtr zyPtr incyPtr
+
+symm ::
+   Char {- ^ side -} ->
+   Char {- ^ uplo -} ->
+   Int {- ^ m -} ->
+   Complex Double {- ^ alpha -} ->
+   CArray (Int,Int) (Complex Double) {- ^ a -} ->
+   CArray (Int,Int) (Complex Double) {- ^ b -} ->
+   Complex Double {- ^ beta -} ->
+   IOCArray (Int,Int) (Complex Double) {- ^ c -} ->
+   IO ()
+symm side uplo m alpha a b beta c = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   let (bDim0,bDim1) = Call.sizes2 $ bounds b
+   (cDim0,cDim1) <- Call.sizes2 <$> getBounds c
+   let _ka = aDim0
+   let lda = aDim1
+   let n = bDim0
+   let ldb = bDim1
+   let ldc = cDim1
+   Call.assert "symm: n == cDim0" (n == cDim0)
+   evalContT $ do
+      sidePtr <- Call.char side
+      uploPtr <- Call.char uplo
+      mPtr <- Call.cint m
+      nPtr <- Call.cint n
+      alphaPtr <- Call.complexDouble alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      bPtr <- Call.array b
+      ldbPtr <- Call.cint ldb
+      betaPtr <- Call.complexDouble beta
+      cPtr <- Call.ioarray c
+      ldcPtr <- Call.cint ldc
+      liftIO $ FFI.symm sidePtr uploPtr mPtr nPtr alphaPtr aPtr ldaPtr bPtr ldbPtr betaPtr cPtr ldcPtr
+
+syr2k ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Int {- ^ k -} ->
+   Complex Double {- ^ alpha -} ->
+   CArray (Int,Int) (Complex Double) {- ^ a -} ->
+   CArray (Int,Int) (Complex Double) {- ^ b -} ->
+   Complex Double {- ^ beta -} ->
+   IOCArray (Int,Int) (Complex Double) {- ^ c -} ->
+   IO ()
+syr2k uplo trans k alpha a b beta c = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   let (bDim0,bDim1) = Call.sizes2 $ bounds b
+   (cDim0,cDim1) <- Call.sizes2 <$> getBounds c
+   let _ka = aDim0
+   let lda = aDim1
+   let _kb = bDim0
+   let ldb = bDim1
+   let n = cDim0
+   let ldc = cDim1
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      nPtr <- Call.cint n
+      kPtr <- Call.cint k
+      alphaPtr <- Call.complexDouble alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      bPtr <- Call.array b
+      ldbPtr <- Call.cint ldb
+      betaPtr <- Call.complexDouble beta
+      cPtr <- Call.ioarray c
+      ldcPtr <- Call.cint ldc
+      liftIO $ FFI.syr2k uploPtr transPtr nPtr kPtr alphaPtr aPtr ldaPtr bPtr ldbPtr betaPtr cPtr ldcPtr
+
+syrk ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Int {- ^ k -} ->
+   Complex Double {- ^ alpha -} ->
+   CArray (Int,Int) (Complex Double) {- ^ a -} ->
+   Complex Double {- ^ beta -} ->
+   IOCArray (Int,Int) (Complex Double) {- ^ c -} ->
+   IO ()
+syrk uplo trans k alpha a beta c = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   (cDim0,cDim1) <- Call.sizes2 <$> getBounds c
+   let _ka = aDim0
+   let lda = aDim1
+   let n = cDim0
+   let ldc = cDim1
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      nPtr <- Call.cint n
+      kPtr <- Call.cint k
+      alphaPtr <- Call.complexDouble alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      betaPtr <- Call.complexDouble beta
+      cPtr <- Call.ioarray c
+      ldcPtr <- Call.cint ldc
+      liftIO $ FFI.syrk uploPtr transPtr nPtr kPtr alphaPtr aPtr ldaPtr betaPtr cPtr ldcPtr
+
+tbmv ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Char {- ^ diag -} ->
+   Int {- ^ k -} ->
+   CArray (Int,Int) (Complex Double) {- ^ a -} ->
+   IOCArray Int (Complex Double) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IO ()
+tbmv uplo trans diag k a x incx = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   xDim0 <- Call.sizes1 <$> getBounds x
+   let n = aDim0
+   let lda = aDim1
+   let _xSize = xDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      diagPtr <- Call.char diag
+      nPtr <- Call.cint n
+      kPtr <- Call.cint k
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      xPtr <- Call.ioarray x
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.tbmv uploPtr transPtr diagPtr nPtr kPtr aPtr ldaPtr xPtr incxPtr
+
+tbsv ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Char {- ^ diag -} ->
+   Int {- ^ k -} ->
+   CArray (Int,Int) (Complex Double) {- ^ a -} ->
+   IOCArray Int (Complex Double) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IO ()
+tbsv uplo trans diag k a x incx = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   xDim0 <- Call.sizes1 <$> getBounds x
+   let n = aDim0
+   let lda = aDim1
+   let _xSize = xDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      diagPtr <- Call.char diag
+      nPtr <- Call.cint n
+      kPtr <- Call.cint k
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      xPtr <- Call.ioarray x
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.tbsv uploPtr transPtr diagPtr nPtr kPtr aPtr ldaPtr xPtr incxPtr
+
+tpmv ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Char {- ^ diag -} ->
+   Int {- ^ n -} ->
+   CArray Int (Complex Double) {- ^ ap -} ->
+   IOCArray Int (Complex Double) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IO ()
+tpmv uplo trans diag n ap x incx = do
+   let apDim0 = Call.sizes1 $ bounds ap
+   xDim0 <- Call.sizes1 <$> getBounds x
+   let _apSize = apDim0
+   let _xSize = xDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      diagPtr <- Call.char diag
+      nPtr <- Call.cint n
+      apPtr <- Call.array ap
+      xPtr <- Call.ioarray x
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.tpmv uploPtr transPtr diagPtr nPtr apPtr xPtr incxPtr
+
+tpsv ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Char {- ^ diag -} ->
+   Int {- ^ n -} ->
+   CArray Int (Complex Double) {- ^ ap -} ->
+   IOCArray Int (Complex Double) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IO ()
+tpsv uplo trans diag n ap x incx = do
+   let apDim0 = Call.sizes1 $ bounds ap
+   xDim0 <- Call.sizes1 <$> getBounds x
+   let _apSize = apDim0
+   let _xSize = xDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      diagPtr <- Call.char diag
+      nPtr <- Call.cint n
+      apPtr <- Call.array ap
+      xPtr <- Call.ioarray x
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.tpsv uploPtr transPtr diagPtr nPtr apPtr xPtr incxPtr
+
+trmm ::
+   Char {- ^ side -} ->
+   Char {- ^ uplo -} ->
+   Char {- ^ transa -} ->
+   Char {- ^ diag -} ->
+   Int {- ^ m -} ->
+   Complex Double {- ^ alpha -} ->
+   CArray (Int,Int) (Complex Double) {- ^ a -} ->
+   IOCArray (Int,Int) (Complex Double) {- ^ b -} ->
+   IO ()
+trmm side uplo transa diag m alpha a b = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   (bDim0,bDim1) <- Call.sizes2 <$> getBounds b
+   let _k = aDim0
+   let lda = aDim1
+   let n = bDim0
+   let ldb = bDim1
+   evalContT $ do
+      sidePtr <- Call.char side
+      uploPtr <- Call.char uplo
+      transaPtr <- Call.char transa
+      diagPtr <- Call.char diag
+      mPtr <- Call.cint m
+      nPtr <- Call.cint n
+      alphaPtr <- Call.complexDouble alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      bPtr <- Call.ioarray b
+      ldbPtr <- Call.cint ldb
+      liftIO $ FFI.trmm sidePtr uploPtr transaPtr diagPtr mPtr nPtr alphaPtr aPtr ldaPtr bPtr ldbPtr
+
+trmv ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Char {- ^ diag -} ->
+   CArray (Int,Int) (Complex Double) {- ^ a -} ->
+   IOCArray Int (Complex Double) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IO ()
+trmv uplo trans diag a x incx = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   xDim0 <- Call.sizes1 <$> getBounds x
+   let n = aDim0
+   let lda = aDim1
+   let _xSize = xDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      diagPtr <- Call.char diag
+      nPtr <- Call.cint n
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      xPtr <- Call.ioarray x
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.trmv uploPtr transPtr diagPtr nPtr aPtr ldaPtr xPtr incxPtr
+
+trsm ::
+   Char {- ^ side -} ->
+   Char {- ^ uplo -} ->
+   Char {- ^ transa -} ->
+   Char {- ^ diag -} ->
+   Int {- ^ m -} ->
+   Complex Double {- ^ alpha -} ->
+   CArray (Int,Int) (Complex Double) {- ^ a -} ->
+   IOCArray (Int,Int) (Complex Double) {- ^ b -} ->
+   IO ()
+trsm side uplo transa diag m alpha a b = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   (bDim0,bDim1) <- Call.sizes2 <$> getBounds b
+   let _k = aDim0
+   let lda = aDim1
+   let n = bDim0
+   let ldb = bDim1
+   evalContT $ do
+      sidePtr <- Call.char side
+      uploPtr <- Call.char uplo
+      transaPtr <- Call.char transa
+      diagPtr <- Call.char diag
+      mPtr <- Call.cint m
+      nPtr <- Call.cint n
+      alphaPtr <- Call.complexDouble alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      bPtr <- Call.ioarray b
+      ldbPtr <- Call.cint ldb
+      liftIO $ FFI.trsm sidePtr uploPtr transaPtr diagPtr mPtr nPtr alphaPtr aPtr ldaPtr bPtr ldbPtr
+
+trsv ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Char {- ^ diag -} ->
+   CArray (Int,Int) (Complex Double) {- ^ a -} ->
+   IOCArray Int (Complex Double) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IO ()
+trsv uplo trans diag a x incx = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   xDim0 <- Call.sizes1 <$> getBounds x
+   let n = aDim0
+   let lda = aDim1
+   let _xSize = xDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      diagPtr <- Call.char diag
+      nPtr <- Call.cint n
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      xPtr <- Call.ioarray x
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.trsv uploPtr transPtr diagPtr nPtr aPtr ldaPtr xPtr incxPtr
diff --git a/src/Numeric/BLAS/CArray/ComplexFloat.hs b/src/Numeric/BLAS/CArray/ComplexFloat.hs
new file mode 100644
--- /dev/null
+++ b/src/Numeric/BLAS/CArray/ComplexFloat.hs
@@ -0,0 +1,973 @@
+-- Do not edit! Automatically generated by create-lapack-ffi.
+module Numeric.BLAS.CArray.ComplexFloat where
+
+import qualified Numeric.BLAS.FFI.ComplexFloat as FFI
+import qualified Numeric.Netlib.CArray.Utility as Call
+
+import Data.Array.IOCArray (IOCArray, getBounds)
+import Data.Array.CArray (CArray, bounds)
+
+import Data.Complex (Complex)
+
+import Foreign.Storable.Complex ()
+import Foreign.Storable (peek)
+import Foreign.C.Types (CInt)
+
+import Control.Monad.Trans.Cont (evalContT)
+import Control.Monad.IO.Class (liftIO)
+import Control.Applicative (pure, (<$>), (<*>))
+
+
+axpy ::
+   Int {- ^ n -} ->
+   Complex Float {- ^ ca -} ->
+   CArray Int (Complex Float) {- ^ cx -} ->
+   Int {- ^ incx -} ->
+   IOCArray Int (Complex Float) {- ^ cy -} ->
+   Int {- ^ incy -} ->
+   IO ()
+axpy n ca cx incx cy incy = do
+   let cxDim0 = Call.sizes1 $ bounds cx
+   cyDim0 <- Call.sizes1 <$> getBounds cy
+   Call.assert "axpy: 1+(n-1)*abs(incx) == cxDim0" (1+(n-1)*abs(incx) == cxDim0)
+   Call.assert "axpy: 1+(n-1)*abs(incy) == cyDim0" (1+(n-1)*abs(incy) == cyDim0)
+   evalContT $ do
+      nPtr <- Call.cint n
+      caPtr <- Call.complexFloat ca
+      cxPtr <- Call.array cx
+      incxPtr <- Call.cint incx
+      cyPtr <- Call.ioarray cy
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.axpy nPtr caPtr cxPtr incxPtr cyPtr incyPtr
+
+cabs1 ::
+   Complex Float {- ^ z -} ->
+   IO Float
+cabs1 z = do
+   evalContT $ do
+      zPtr <- Call.complexFloat z
+      liftIO $ FFI.cabs1 zPtr
+
+casum ::
+   Int {- ^ n -} ->
+   IOCArray Int (Complex Float) {- ^ cx -} ->
+   Int {- ^ incx -} ->
+   IO Float
+casum n cx incx = do
+   cxDim0 <- Call.sizes1 <$> getBounds cx
+   Call.assert "casum: 1+(n-1)*abs(incx) == cxDim0" (1+(n-1)*abs(incx) == cxDim0)
+   evalContT $ do
+      nPtr <- Call.cint n
+      cxPtr <- Call.ioarray cx
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.casum nPtr cxPtr incxPtr
+
+cnrm2 ::
+   CArray Int (Complex Float) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IO Float
+cnrm2 x incx = do
+   let xDim0 = Call.sizes1 $ bounds x
+   let n = xDim0
+   evalContT $ do
+      nPtr <- Call.cint n
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.cnrm2 nPtr xPtr incxPtr
+
+copy ::
+   Int {- ^ n -} ->
+   CArray Int (Complex Float) {- ^ cx -} ->
+   Int {- ^ incx -} ->
+   Int {- ^ incy -} ->
+   IO (CArray Int (Complex Float))
+copy n cx incx incy = do
+   let cxDim0 = Call.sizes1 $ bounds cx
+   Call.assert "copy: 1+(n-1)*abs(incx) == cxDim0" (1+(n-1)*abs(incx) == cxDim0)
+   cy <- Call.newArray1 (1+(n-1)*abs(incy))
+   evalContT $ do
+      nPtr <- Call.cint n
+      cxPtr <- Call.array cx
+      incxPtr <- Call.cint incx
+      cyPtr <- Call.array cy
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.copy nPtr cxPtr incxPtr cyPtr incyPtr
+      liftIO $ pure cy
+
+gbmv ::
+   Char {- ^ trans -} ->
+   Int {- ^ m -} ->
+   Int {- ^ kl -} ->
+   Int {- ^ ku -} ->
+   Complex Float {- ^ alpha -} ->
+   CArray (Int,Int) (Complex Float) {- ^ a -} ->
+   CArray Int (Complex Float) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   Complex Float {- ^ beta -} ->
+   IOCArray Int (Complex Float) {- ^ y -} ->
+   Int {- ^ incy -} ->
+   IO ()
+gbmv trans m kl ku alpha a x incx beta y incy = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   let xDim0 = Call.sizes1 $ bounds x
+   yDim0 <- Call.sizes1 <$> getBounds y
+   let n = aDim0
+   let lda = aDim1
+   let _xSize = xDim0
+   let _ySize = yDim0
+   evalContT $ do
+      transPtr <- Call.char trans
+      mPtr <- Call.cint m
+      nPtr <- Call.cint n
+      klPtr <- Call.cint kl
+      kuPtr <- Call.cint ku
+      alphaPtr <- Call.complexFloat alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      betaPtr <- Call.complexFloat beta
+      yPtr <- Call.ioarray y
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.gbmv transPtr mPtr nPtr klPtr kuPtr alphaPtr aPtr ldaPtr xPtr incxPtr betaPtr yPtr incyPtr
+
+gemm ::
+   Char {- ^ transa -} ->
+   Char {- ^ transb -} ->
+   Int {- ^ m -} ->
+   Int {- ^ k -} ->
+   Complex Float {- ^ alpha -} ->
+   CArray (Int,Int) (Complex Float) {- ^ a -} ->
+   CArray (Int,Int) (Complex Float) {- ^ b -} ->
+   Complex Float {- ^ beta -} ->
+   IOCArray (Int,Int) (Complex Float) {- ^ c -} ->
+   IO ()
+gemm transa transb m k alpha a b beta c = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   let (bDim0,bDim1) = Call.sizes2 $ bounds b
+   (cDim0,cDim1) <- Call.sizes2 <$> getBounds c
+   let _ka = aDim0
+   let lda = aDim1
+   let _kb = bDim0
+   let ldb = bDim1
+   let n = cDim0
+   let ldc = cDim1
+   evalContT $ do
+      transaPtr <- Call.char transa
+      transbPtr <- Call.char transb
+      mPtr <- Call.cint m
+      nPtr <- Call.cint n
+      kPtr <- Call.cint k
+      alphaPtr <- Call.complexFloat alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      bPtr <- Call.array b
+      ldbPtr <- Call.cint ldb
+      betaPtr <- Call.complexFloat beta
+      cPtr <- Call.ioarray c
+      ldcPtr <- Call.cint ldc
+      liftIO $ FFI.gemm transaPtr transbPtr mPtr nPtr kPtr alphaPtr aPtr ldaPtr bPtr ldbPtr betaPtr cPtr ldcPtr
+
+gemv ::
+   Char {- ^ trans -} ->
+   Int {- ^ m -} ->
+   Complex Float {- ^ alpha -} ->
+   CArray (Int,Int) (Complex Float) {- ^ a -} ->
+   CArray Int (Complex Float) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   Complex Float {- ^ beta -} ->
+   IOCArray Int (Complex Float) {- ^ y -} ->
+   Int {- ^ incy -} ->
+   IO ()
+gemv trans m alpha a x incx beta y incy = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   let xDim0 = Call.sizes1 $ bounds x
+   yDim0 <- Call.sizes1 <$> getBounds y
+   let n = aDim0
+   let lda = aDim1
+   let _xSize = xDim0
+   let _ySize = yDim0
+   evalContT $ do
+      transPtr <- Call.char trans
+      mPtr <- Call.cint m
+      nPtr <- Call.cint n
+      alphaPtr <- Call.complexFloat alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      betaPtr <- Call.complexFloat beta
+      yPtr <- Call.ioarray y
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.gemv transPtr mPtr nPtr alphaPtr aPtr ldaPtr xPtr incxPtr betaPtr yPtr incyPtr
+
+gerc ::
+   Int {- ^ m -} ->
+   Complex Float {- ^ alpha -} ->
+   CArray Int (Complex Float) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   CArray Int (Complex Float) {- ^ y -} ->
+   Int {- ^ incy -} ->
+   IOCArray (Int,Int) (Complex Float) {- ^ a -} ->
+   IO ()
+gerc m alpha x incx y incy a = do
+   let xDim0 = Call.sizes1 $ bounds x
+   let yDim0 = Call.sizes1 $ bounds y
+   (aDim0,aDim1) <- Call.sizes2 <$> getBounds a
+   let _xSize = xDim0
+   let _ySize = yDim0
+   let n = aDim0
+   let lda = aDim1
+   evalContT $ do
+      mPtr <- Call.cint m
+      nPtr <- Call.cint n
+      alphaPtr <- Call.complexFloat alpha
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      yPtr <- Call.array y
+      incyPtr <- Call.cint incy
+      aPtr <- Call.ioarray a
+      ldaPtr <- Call.cint lda
+      liftIO $ FFI.gerc mPtr nPtr alphaPtr xPtr incxPtr yPtr incyPtr aPtr ldaPtr
+
+geru ::
+   Int {- ^ m -} ->
+   Complex Float {- ^ alpha -} ->
+   CArray Int (Complex Float) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   CArray Int (Complex Float) {- ^ y -} ->
+   Int {- ^ incy -} ->
+   IOCArray (Int,Int) (Complex Float) {- ^ a -} ->
+   IO ()
+geru m alpha x incx y incy a = do
+   let xDim0 = Call.sizes1 $ bounds x
+   let yDim0 = Call.sizes1 $ bounds y
+   (aDim0,aDim1) <- Call.sizes2 <$> getBounds a
+   let _xSize = xDim0
+   let _ySize = yDim0
+   let n = aDim0
+   let lda = aDim1
+   evalContT $ do
+      mPtr <- Call.cint m
+      nPtr <- Call.cint n
+      alphaPtr <- Call.complexFloat alpha
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      yPtr <- Call.array y
+      incyPtr <- Call.cint incy
+      aPtr <- Call.ioarray a
+      ldaPtr <- Call.cint lda
+      liftIO $ FFI.geru mPtr nPtr alphaPtr xPtr incxPtr yPtr incyPtr aPtr ldaPtr
+
+hbmv ::
+   Char {- ^ uplo -} ->
+   Int {- ^ k -} ->
+   Complex Float {- ^ alpha -} ->
+   CArray (Int,Int) (Complex Float) {- ^ a -} ->
+   CArray Int (Complex Float) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   Complex Float {- ^ beta -} ->
+   IOCArray Int (Complex Float) {- ^ y -} ->
+   Int {- ^ incy -} ->
+   IO ()
+hbmv uplo k alpha a x incx beta y incy = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   let xDim0 = Call.sizes1 $ bounds x
+   yDim0 <- Call.sizes1 <$> getBounds y
+   let n = aDim0
+   let lda = aDim1
+   let _xSize = xDim0
+   let _ySize = yDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      nPtr <- Call.cint n
+      kPtr <- Call.cint k
+      alphaPtr <- Call.complexFloat alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      betaPtr <- Call.complexFloat beta
+      yPtr <- Call.ioarray y
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.hbmv uploPtr nPtr kPtr alphaPtr aPtr ldaPtr xPtr incxPtr betaPtr yPtr incyPtr
+
+hemm ::
+   Char {- ^ side -} ->
+   Char {- ^ uplo -} ->
+   Int {- ^ m -} ->
+   Complex Float {- ^ alpha -} ->
+   CArray (Int,Int) (Complex Float) {- ^ a -} ->
+   CArray (Int,Int) (Complex Float) {- ^ b -} ->
+   Complex Float {- ^ beta -} ->
+   IOCArray (Int,Int) (Complex Float) {- ^ c -} ->
+   IO ()
+hemm side uplo m alpha a b beta c = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   let (bDim0,bDim1) = Call.sizes2 $ bounds b
+   (cDim0,cDim1) <- Call.sizes2 <$> getBounds c
+   let _ka = aDim0
+   let lda = aDim1
+   let n = bDim0
+   let ldb = bDim1
+   let ldc = cDim1
+   Call.assert "hemm: n == cDim0" (n == cDim0)
+   evalContT $ do
+      sidePtr <- Call.char side
+      uploPtr <- Call.char uplo
+      mPtr <- Call.cint m
+      nPtr <- Call.cint n
+      alphaPtr <- Call.complexFloat alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      bPtr <- Call.array b
+      ldbPtr <- Call.cint ldb
+      betaPtr <- Call.complexFloat beta
+      cPtr <- Call.ioarray c
+      ldcPtr <- Call.cint ldc
+      liftIO $ FFI.hemm sidePtr uploPtr mPtr nPtr alphaPtr aPtr ldaPtr bPtr ldbPtr betaPtr cPtr ldcPtr
+
+hemv ::
+   Char {- ^ uplo -} ->
+   Complex Float {- ^ alpha -} ->
+   CArray (Int,Int) (Complex Float) {- ^ a -} ->
+   CArray Int (Complex Float) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   Complex Float {- ^ beta -} ->
+   IOCArray Int (Complex Float) {- ^ y -} ->
+   Int {- ^ incy -} ->
+   IO ()
+hemv uplo alpha a x incx beta y incy = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   let xDim0 = Call.sizes1 $ bounds x
+   yDim0 <- Call.sizes1 <$> getBounds y
+   let n = aDim0
+   let lda = aDim1
+   let _xSize = xDim0
+   let _ySize = yDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      nPtr <- Call.cint n
+      alphaPtr <- Call.complexFloat alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      betaPtr <- Call.complexFloat beta
+      yPtr <- Call.ioarray y
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.hemv uploPtr nPtr alphaPtr aPtr ldaPtr xPtr incxPtr betaPtr yPtr incyPtr
+
+her ::
+   Char {- ^ uplo -} ->
+   Float {- ^ alpha -} ->
+   CArray Int (Complex Float) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IOCArray (Int,Int) (Complex Float) {- ^ a -} ->
+   IO ()
+her uplo alpha x incx a = do
+   let xDim0 = Call.sizes1 $ bounds x
+   (aDim0,aDim1) <- Call.sizes2 <$> getBounds a
+   let _xSize = xDim0
+   let n = aDim0
+   let lda = aDim1
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      nPtr <- Call.cint n
+      alphaPtr <- Call.float alpha
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      aPtr <- Call.ioarray a
+      ldaPtr <- Call.cint lda
+      liftIO $ FFI.her uploPtr nPtr alphaPtr xPtr incxPtr aPtr ldaPtr
+
+her2 ::
+   Char {- ^ uplo -} ->
+   Complex Float {- ^ alpha -} ->
+   CArray Int (Complex Float) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   CArray Int (Complex Float) {- ^ y -} ->
+   Int {- ^ incy -} ->
+   IOCArray (Int,Int) (Complex Float) {- ^ a -} ->
+   IO ()
+her2 uplo alpha x incx y incy a = do
+   let xDim0 = Call.sizes1 $ bounds x
+   let yDim0 = Call.sizes1 $ bounds y
+   (aDim0,aDim1) <- Call.sizes2 <$> getBounds a
+   let _xSize = xDim0
+   let _ySize = yDim0
+   let n = aDim0
+   let lda = aDim1
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      nPtr <- Call.cint n
+      alphaPtr <- Call.complexFloat alpha
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      yPtr <- Call.array y
+      incyPtr <- Call.cint incy
+      aPtr <- Call.ioarray a
+      ldaPtr <- Call.cint lda
+      liftIO $ FFI.her2 uploPtr nPtr alphaPtr xPtr incxPtr yPtr incyPtr aPtr ldaPtr
+
+her2k ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Int {- ^ k -} ->
+   Complex Float {- ^ alpha -} ->
+   CArray (Int,Int) (Complex Float) {- ^ a -} ->
+   CArray (Int,Int) (Complex Float) {- ^ b -} ->
+   Float {- ^ beta -} ->
+   IOCArray (Int,Int) (Complex Float) {- ^ c -} ->
+   IO ()
+her2k uplo trans k alpha a b beta c = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   let (bDim0,bDim1) = Call.sizes2 $ bounds b
+   (cDim0,cDim1) <- Call.sizes2 <$> getBounds c
+   let _ka = aDim0
+   let lda = aDim1
+   let _kb = bDim0
+   let ldb = bDim1
+   let n = cDim0
+   let ldc = cDim1
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      nPtr <- Call.cint n
+      kPtr <- Call.cint k
+      alphaPtr <- Call.complexFloat alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      bPtr <- Call.array b
+      ldbPtr <- Call.cint ldb
+      betaPtr <- Call.float beta
+      cPtr <- Call.ioarray c
+      ldcPtr <- Call.cint ldc
+      liftIO $ FFI.her2k uploPtr transPtr nPtr kPtr alphaPtr aPtr ldaPtr bPtr ldbPtr betaPtr cPtr ldcPtr
+
+herk ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Int {- ^ k -} ->
+   Float {- ^ alpha -} ->
+   CArray (Int,Int) (Complex Float) {- ^ a -} ->
+   Float {- ^ beta -} ->
+   IOCArray (Int,Int) (Complex Float) {- ^ c -} ->
+   IO ()
+herk uplo trans k alpha a beta c = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   (cDim0,cDim1) <- Call.sizes2 <$> getBounds c
+   let _ka = aDim0
+   let lda = aDim1
+   let n = cDim0
+   let ldc = cDim1
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      nPtr <- Call.cint n
+      kPtr <- Call.cint k
+      alphaPtr <- Call.float alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      betaPtr <- Call.float beta
+      cPtr <- Call.ioarray c
+      ldcPtr <- Call.cint ldc
+      liftIO $ FFI.herk uploPtr transPtr nPtr kPtr alphaPtr aPtr ldaPtr betaPtr cPtr ldcPtr
+
+hpmv ::
+   Char {- ^ uplo -} ->
+   Int {- ^ n -} ->
+   Complex Float {- ^ alpha -} ->
+   CArray Int (Complex Float) {- ^ ap -} ->
+   CArray Int (Complex Float) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   Complex Float {- ^ beta -} ->
+   IOCArray Int (Complex Float) {- ^ y -} ->
+   Int {- ^ incy -} ->
+   IO ()
+hpmv uplo n alpha ap x incx beta y incy = do
+   let apDim0 = Call.sizes1 $ bounds ap
+   let xDim0 = Call.sizes1 $ bounds x
+   yDim0 <- Call.sizes1 <$> getBounds y
+   let _apSize = apDim0
+   let _xSize = xDim0
+   let _ySize = yDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      nPtr <- Call.cint n
+      alphaPtr <- Call.complexFloat alpha
+      apPtr <- Call.array ap
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      betaPtr <- Call.complexFloat beta
+      yPtr <- Call.ioarray y
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.hpmv uploPtr nPtr alphaPtr apPtr xPtr incxPtr betaPtr yPtr incyPtr
+
+hpr ::
+   Char {- ^ uplo -} ->
+   Int {- ^ n -} ->
+   Float {- ^ alpha -} ->
+   CArray Int (Complex Float) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IOCArray Int (Complex Float) {- ^ ap -} ->
+   IO ()
+hpr uplo n alpha x incx ap = do
+   let xDim0 = Call.sizes1 $ bounds x
+   apDim0 <- Call.sizes1 <$> getBounds ap
+   let _xSize = xDim0
+   let _apSize = apDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      nPtr <- Call.cint n
+      alphaPtr <- Call.float alpha
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      apPtr <- Call.ioarray ap
+      liftIO $ FFI.hpr uploPtr nPtr alphaPtr xPtr incxPtr apPtr
+
+hpr2 ::
+   Char {- ^ uplo -} ->
+   Int {- ^ n -} ->
+   Complex Float {- ^ alpha -} ->
+   CArray Int (Complex Float) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   CArray Int (Complex Float) {- ^ y -} ->
+   Int {- ^ incy -} ->
+   IOCArray Int (Complex Float) {- ^ ap -} ->
+   IO ()
+hpr2 uplo n alpha x incx y incy ap = do
+   let xDim0 = Call.sizes1 $ bounds x
+   let yDim0 = Call.sizes1 $ bounds y
+   apDim0 <- Call.sizes1 <$> getBounds ap
+   let _xSize = xDim0
+   let _ySize = yDim0
+   let _apSize = apDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      nPtr <- Call.cint n
+      alphaPtr <- Call.complexFloat alpha
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      yPtr <- Call.array y
+      incyPtr <- Call.cint incy
+      apPtr <- Call.ioarray ap
+      liftIO $ FFI.hpr2 uploPtr nPtr alphaPtr xPtr incxPtr yPtr incyPtr apPtr
+
+iamax ::
+   Int {- ^ n -} ->
+   CArray Int (Complex Float) {- ^ cx -} ->
+   Int {- ^ incx -} ->
+   IO CInt
+iamax n cx incx = do
+   let cxDim0 = Call.sizes1 $ bounds cx
+   Call.assert "iamax: 1+(n-1)*abs(incx) == cxDim0" (1+(n-1)*abs(incx) == cxDim0)
+   evalContT $ do
+      nPtr <- Call.cint n
+      cxPtr <- Call.array cx
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.iamax nPtr cxPtr incxPtr
+
+rotg ::
+   Complex Float {- ^ ca -} ->
+   Complex Float {- ^ cb -} ->
+   IO (Float, Complex Float)
+rotg ca cb = do
+   evalContT $ do
+      caPtr <- Call.complexFloat ca
+      cbPtr <- Call.complexFloat cb
+      cPtr <- Call.alloca
+      sPtr <- Call.alloca
+      liftIO $ FFI.rotg caPtr cbPtr cPtr sPtr
+      liftIO $ pure (,)
+         <*> peek cPtr
+         <*> peek sPtr
+
+rrot ::
+   Int {- ^ n -} ->
+   IOCArray Int (Complex Float) {- ^ cx -} ->
+   Int {- ^ incx -} ->
+   IOCArray Int (Complex Float) {- ^ cy -} ->
+   Int {- ^ incy -} ->
+   Float {- ^ c -} ->
+   Float {- ^ s -} ->
+   IO ()
+rrot n cx incx cy incy c s = do
+   cxDim0 <- Call.sizes1 <$> getBounds cx
+   cyDim0 <- Call.sizes1 <$> getBounds cy
+   let _cxSize = cxDim0
+   let _cySize = cyDim0
+   evalContT $ do
+      nPtr <- Call.cint n
+      cxPtr <- Call.ioarray cx
+      incxPtr <- Call.cint incx
+      cyPtr <- Call.ioarray cy
+      incyPtr <- Call.cint incy
+      cPtr <- Call.float c
+      sPtr <- Call.float s
+      liftIO $ FFI.rrot nPtr cxPtr incxPtr cyPtr incyPtr cPtr sPtr
+
+rscal ::
+   Int {- ^ n -} ->
+   Float {- ^ sa -} ->
+   IOCArray Int (Complex Float) {- ^ cx -} ->
+   Int {- ^ incx -} ->
+   IO ()
+rscal n sa cx incx = do
+   cxDim0 <- Call.sizes1 <$> getBounds cx
+   Call.assert "rscal: 1+(n-1)*abs(incx) == cxDim0" (1+(n-1)*abs(incx) == cxDim0)
+   evalContT $ do
+      nPtr <- Call.cint n
+      saPtr <- Call.float sa
+      cxPtr <- Call.ioarray cx
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.rscal nPtr saPtr cxPtr incxPtr
+
+scal ::
+   Int {- ^ n -} ->
+   Complex Float {- ^ ca -} ->
+   IOCArray Int (Complex Float) {- ^ cx -} ->
+   Int {- ^ incx -} ->
+   IO ()
+scal n ca cx incx = do
+   cxDim0 <- Call.sizes1 <$> getBounds cx
+   Call.assert "scal: 1+(n-1)*abs(incx) == cxDim0" (1+(n-1)*abs(incx) == cxDim0)
+   evalContT $ do
+      nPtr <- Call.cint n
+      caPtr <- Call.complexFloat ca
+      cxPtr <- Call.ioarray cx
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.scal nPtr caPtr cxPtr incxPtr
+
+swap ::
+   Int {- ^ n -} ->
+   IOCArray Int (Complex Float) {- ^ cx -} ->
+   Int {- ^ incx -} ->
+   IOCArray Int (Complex Float) {- ^ cy -} ->
+   Int {- ^ incy -} ->
+   IO ()
+swap n cx incx cy incy = do
+   cxDim0 <- Call.sizes1 <$> getBounds cx
+   cyDim0 <- Call.sizes1 <$> getBounds cy
+   Call.assert "swap: 1+(n-1)*abs(incx) == cxDim0" (1+(n-1)*abs(incx) == cxDim0)
+   Call.assert "swap: 1+(n-1)*abs(incy) == cyDim0" (1+(n-1)*abs(incy) == cyDim0)
+   evalContT $ do
+      nPtr <- Call.cint n
+      cxPtr <- Call.ioarray cx
+      incxPtr <- Call.cint incx
+      cyPtr <- Call.ioarray cy
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.swap nPtr cxPtr incxPtr cyPtr incyPtr
+
+symm ::
+   Char {- ^ side -} ->
+   Char {- ^ uplo -} ->
+   Int {- ^ m -} ->
+   Complex Float {- ^ alpha -} ->
+   CArray (Int,Int) (Complex Float) {- ^ a -} ->
+   CArray (Int,Int) (Complex Float) {- ^ b -} ->
+   Complex Float {- ^ beta -} ->
+   IOCArray (Int,Int) (Complex Float) {- ^ c -} ->
+   IO ()
+symm side uplo m alpha a b beta c = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   let (bDim0,bDim1) = Call.sizes2 $ bounds b
+   (cDim0,cDim1) <- Call.sizes2 <$> getBounds c
+   let _ka = aDim0
+   let lda = aDim1
+   let n = bDim0
+   let ldb = bDim1
+   let ldc = cDim1
+   Call.assert "symm: n == cDim0" (n == cDim0)
+   evalContT $ do
+      sidePtr <- Call.char side
+      uploPtr <- Call.char uplo
+      mPtr <- Call.cint m
+      nPtr <- Call.cint n
+      alphaPtr <- Call.complexFloat alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      bPtr <- Call.array b
+      ldbPtr <- Call.cint ldb
+      betaPtr <- Call.complexFloat beta
+      cPtr <- Call.ioarray c
+      ldcPtr <- Call.cint ldc
+      liftIO $ FFI.symm sidePtr uploPtr mPtr nPtr alphaPtr aPtr ldaPtr bPtr ldbPtr betaPtr cPtr ldcPtr
+
+syr2k ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Int {- ^ k -} ->
+   Complex Float {- ^ alpha -} ->
+   CArray (Int,Int) (Complex Float) {- ^ a -} ->
+   CArray (Int,Int) (Complex Float) {- ^ b -} ->
+   Complex Float {- ^ beta -} ->
+   IOCArray (Int,Int) (Complex Float) {- ^ c -} ->
+   IO ()
+syr2k uplo trans k alpha a b beta c = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   let (bDim0,bDim1) = Call.sizes2 $ bounds b
+   (cDim0,cDim1) <- Call.sizes2 <$> getBounds c
+   let _ka = aDim0
+   let lda = aDim1
+   let _kb = bDim0
+   let ldb = bDim1
+   let n = cDim0
+   let ldc = cDim1
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      nPtr <- Call.cint n
+      kPtr <- Call.cint k
+      alphaPtr <- Call.complexFloat alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      bPtr <- Call.array b
+      ldbPtr <- Call.cint ldb
+      betaPtr <- Call.complexFloat beta
+      cPtr <- Call.ioarray c
+      ldcPtr <- Call.cint ldc
+      liftIO $ FFI.syr2k uploPtr transPtr nPtr kPtr alphaPtr aPtr ldaPtr bPtr ldbPtr betaPtr cPtr ldcPtr
+
+syrk ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Int {- ^ k -} ->
+   Complex Float {- ^ alpha -} ->
+   CArray (Int,Int) (Complex Float) {- ^ a -} ->
+   Complex Float {- ^ beta -} ->
+   IOCArray (Int,Int) (Complex Float) {- ^ c -} ->
+   IO ()
+syrk uplo trans k alpha a beta c = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   (cDim0,cDim1) <- Call.sizes2 <$> getBounds c
+   let _ka = aDim0
+   let lda = aDim1
+   let n = cDim0
+   let ldc = cDim1
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      nPtr <- Call.cint n
+      kPtr <- Call.cint k
+      alphaPtr <- Call.complexFloat alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      betaPtr <- Call.complexFloat beta
+      cPtr <- Call.ioarray c
+      ldcPtr <- Call.cint ldc
+      liftIO $ FFI.syrk uploPtr transPtr nPtr kPtr alphaPtr aPtr ldaPtr betaPtr cPtr ldcPtr
+
+tbmv ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Char {- ^ diag -} ->
+   Int {- ^ k -} ->
+   CArray (Int,Int) (Complex Float) {- ^ a -} ->
+   IOCArray Int (Complex Float) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IO ()
+tbmv uplo trans diag k a x incx = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   xDim0 <- Call.sizes1 <$> getBounds x
+   let n = aDim0
+   let lda = aDim1
+   let _xSize = xDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      diagPtr <- Call.char diag
+      nPtr <- Call.cint n
+      kPtr <- Call.cint k
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      xPtr <- Call.ioarray x
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.tbmv uploPtr transPtr diagPtr nPtr kPtr aPtr ldaPtr xPtr incxPtr
+
+tbsv ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Char {- ^ diag -} ->
+   Int {- ^ k -} ->
+   CArray (Int,Int) (Complex Float) {- ^ a -} ->
+   IOCArray Int (Complex Float) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IO ()
+tbsv uplo trans diag k a x incx = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   xDim0 <- Call.sizes1 <$> getBounds x
+   let n = aDim0
+   let lda = aDim1
+   let _xSize = xDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      diagPtr <- Call.char diag
+      nPtr <- Call.cint n
+      kPtr <- Call.cint k
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      xPtr <- Call.ioarray x
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.tbsv uploPtr transPtr diagPtr nPtr kPtr aPtr ldaPtr xPtr incxPtr
+
+tpmv ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Char {- ^ diag -} ->
+   Int {- ^ n -} ->
+   CArray Int (Complex Float) {- ^ ap -} ->
+   IOCArray Int (Complex Float) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IO ()
+tpmv uplo trans diag n ap x incx = do
+   let apDim0 = Call.sizes1 $ bounds ap
+   xDim0 <- Call.sizes1 <$> getBounds x
+   let _apSize = apDim0
+   let _xSize = xDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      diagPtr <- Call.char diag
+      nPtr <- Call.cint n
+      apPtr <- Call.array ap
+      xPtr <- Call.ioarray x
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.tpmv uploPtr transPtr diagPtr nPtr apPtr xPtr incxPtr
+
+tpsv ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Char {- ^ diag -} ->
+   Int {- ^ n -} ->
+   CArray Int (Complex Float) {- ^ ap -} ->
+   IOCArray Int (Complex Float) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IO ()
+tpsv uplo trans diag n ap x incx = do
+   let apDim0 = Call.sizes1 $ bounds ap
+   xDim0 <- Call.sizes1 <$> getBounds x
+   let _apSize = apDim0
+   let _xSize = xDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      diagPtr <- Call.char diag
+      nPtr <- Call.cint n
+      apPtr <- Call.array ap
+      xPtr <- Call.ioarray x
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.tpsv uploPtr transPtr diagPtr nPtr apPtr xPtr incxPtr
+
+trmm ::
+   Char {- ^ side -} ->
+   Char {- ^ uplo -} ->
+   Char {- ^ transa -} ->
+   Char {- ^ diag -} ->
+   Int {- ^ m -} ->
+   Complex Float {- ^ alpha -} ->
+   CArray (Int,Int) (Complex Float) {- ^ a -} ->
+   IOCArray (Int,Int) (Complex Float) {- ^ b -} ->
+   IO ()
+trmm side uplo transa diag m alpha a b = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   (bDim0,bDim1) <- Call.sizes2 <$> getBounds b
+   let _k = aDim0
+   let lda = aDim1
+   let n = bDim0
+   let ldb = bDim1
+   evalContT $ do
+      sidePtr <- Call.char side
+      uploPtr <- Call.char uplo
+      transaPtr <- Call.char transa
+      diagPtr <- Call.char diag
+      mPtr <- Call.cint m
+      nPtr <- Call.cint n
+      alphaPtr <- Call.complexFloat alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      bPtr <- Call.ioarray b
+      ldbPtr <- Call.cint ldb
+      liftIO $ FFI.trmm sidePtr uploPtr transaPtr diagPtr mPtr nPtr alphaPtr aPtr ldaPtr bPtr ldbPtr
+
+trmv ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Char {- ^ diag -} ->
+   CArray (Int,Int) (Complex Float) {- ^ a -} ->
+   IOCArray Int (Complex Float) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IO ()
+trmv uplo trans diag a x incx = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   xDim0 <- Call.sizes1 <$> getBounds x
+   let n = aDim0
+   let lda = aDim1
+   let _xSize = xDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      diagPtr <- Call.char diag
+      nPtr <- Call.cint n
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      xPtr <- Call.ioarray x
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.trmv uploPtr transPtr diagPtr nPtr aPtr ldaPtr xPtr incxPtr
+
+trsm ::
+   Char {- ^ side -} ->
+   Char {- ^ uplo -} ->
+   Char {- ^ transa -} ->
+   Char {- ^ diag -} ->
+   Int {- ^ m -} ->
+   Complex Float {- ^ alpha -} ->
+   CArray (Int,Int) (Complex Float) {- ^ a -} ->
+   IOCArray (Int,Int) (Complex Float) {- ^ b -} ->
+   IO ()
+trsm side uplo transa diag m alpha a b = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   (bDim0,bDim1) <- Call.sizes2 <$> getBounds b
+   let _k = aDim0
+   let lda = aDim1
+   let n = bDim0
+   let ldb = bDim1
+   evalContT $ do
+      sidePtr <- Call.char side
+      uploPtr <- Call.char uplo
+      transaPtr <- Call.char transa
+      diagPtr <- Call.char diag
+      mPtr <- Call.cint m
+      nPtr <- Call.cint n
+      alphaPtr <- Call.complexFloat alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      bPtr <- Call.ioarray b
+      ldbPtr <- Call.cint ldb
+      liftIO $ FFI.trsm sidePtr uploPtr transaPtr diagPtr mPtr nPtr alphaPtr aPtr ldaPtr bPtr ldbPtr
+
+trsv ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Char {- ^ diag -} ->
+   CArray (Int,Int) (Complex Float) {- ^ a -} ->
+   IOCArray Int (Complex Float) {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IO ()
+trsv uplo trans diag a x incx = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   xDim0 <- Call.sizes1 <$> getBounds x
+   let n = aDim0
+   let lda = aDim1
+   let _xSize = xDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      diagPtr <- Call.char diag
+      nPtr <- Call.cint n
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      xPtr <- Call.ioarray x
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.trsv uploPtr transPtr diagPtr nPtr aPtr ldaPtr xPtr incxPtr
diff --git a/src/Numeric/BLAS/CArray/Double.hs b/src/Numeric/BLAS/CArray/Double.hs
new file mode 100644
--- /dev/null
+++ b/src/Numeric/BLAS/CArray/Double.hs
@@ -0,0 +1,904 @@
+-- Do not edit! Automatically generated by create-lapack-ffi.
+module Numeric.BLAS.CArray.Double where
+
+import qualified Numeric.BLAS.FFI.Double as FFI
+import qualified Numeric.Netlib.CArray.Utility as Call
+
+import Data.Array.IOCArray (IOCArray, getBounds)
+import Data.Array.CArray (CArray, bounds)
+
+import Foreign.Storable.Complex ()
+import Foreign.Storable (peek)
+import Foreign.C.Types (CInt)
+
+import Control.Monad.Trans.Cont (evalContT)
+import Control.Monad.IO.Class (liftIO)
+import Control.Applicative (pure, (<*>), (<$>))
+
+
+asum ::
+   Int {- ^ n -} ->
+   CArray Int Double {- ^ dx -} ->
+   Int {- ^ incx -} ->
+   IO Double
+asum n dx incx = do
+   let dxDim0 = Call.sizes1 $ bounds dx
+   Call.assert "asum: 1+(n-1)*abs(incx) == dxDim0" (1+(n-1)*abs(incx) == dxDim0)
+   evalContT $ do
+      nPtr <- Call.cint n
+      dxPtr <- Call.array dx
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.asum nPtr dxPtr incxPtr
+
+axpy ::
+   Int {- ^ n -} ->
+   Double {- ^ da -} ->
+   CArray Int Double {- ^ dx -} ->
+   Int {- ^ incx -} ->
+   IOCArray Int Double {- ^ dy -} ->
+   Int {- ^ incy -} ->
+   IO ()
+axpy n da dx incx dy incy = do
+   let dxDim0 = Call.sizes1 $ bounds dx
+   dyDim0 <- Call.sizes1 <$> getBounds dy
+   Call.assert "axpy: 1+(n-1)*abs(incx) == dxDim0" (1+(n-1)*abs(incx) == dxDim0)
+   Call.assert "axpy: 1+(n-1)*abs(incy) == dyDim0" (1+(n-1)*abs(incy) == dyDim0)
+   evalContT $ do
+      nPtr <- Call.cint n
+      daPtr <- Call.double da
+      dxPtr <- Call.array dx
+      incxPtr <- Call.cint incx
+      dyPtr <- Call.ioarray dy
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.axpy nPtr daPtr dxPtr incxPtr dyPtr incyPtr
+
+copy ::
+   Int {- ^ n -} ->
+   CArray Int Double {- ^ dx -} ->
+   Int {- ^ incx -} ->
+   Int {- ^ incy -} ->
+   IO (CArray Int Double)
+copy n dx incx incy = do
+   let dxDim0 = Call.sizes1 $ bounds dx
+   Call.assert "copy: 1+(n-1)*abs(incx) == dxDim0" (1+(n-1)*abs(incx) == dxDim0)
+   dy <- Call.newArray1 (1+(n-1)*abs(incy))
+   evalContT $ do
+      nPtr <- Call.cint n
+      dxPtr <- Call.array dx
+      incxPtr <- Call.cint incx
+      dyPtr <- Call.array dy
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.copy nPtr dxPtr incxPtr dyPtr incyPtr
+      liftIO $ pure dy
+
+dot ::
+   Int {- ^ n -} ->
+   CArray Int Double {- ^ dx -} ->
+   Int {- ^ incx -} ->
+   CArray Int Double {- ^ dy -} ->
+   Int {- ^ incy -} ->
+   IO Double
+dot n dx incx dy incy = do
+   let dxDim0 = Call.sizes1 $ bounds dx
+   let dyDim0 = Call.sizes1 $ bounds dy
+   Call.assert "dot: 1+(n-1)*abs(incx) == dxDim0" (1+(n-1)*abs(incx) == dxDim0)
+   Call.assert "dot: 1+(n-1)*abs(incy) == dyDim0" (1+(n-1)*abs(incy) == dyDim0)
+   evalContT $ do
+      nPtr <- Call.cint n
+      dxPtr <- Call.array dx
+      incxPtr <- Call.cint incx
+      dyPtr <- Call.array dy
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.dot nPtr dxPtr incxPtr dyPtr incyPtr
+
+gbmv ::
+   Char {- ^ trans -} ->
+   Int {- ^ m -} ->
+   Int {- ^ kl -} ->
+   Int {- ^ ku -} ->
+   Double {- ^ alpha -} ->
+   CArray (Int,Int) Double {- ^ a -} ->
+   CArray Int Double {- ^ x -} ->
+   Int {- ^ incx -} ->
+   Double {- ^ beta -} ->
+   IOCArray Int Double {- ^ y -} ->
+   Int {- ^ incy -} ->
+   IO ()
+gbmv trans m kl ku alpha a x incx beta y incy = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   let xDim0 = Call.sizes1 $ bounds x
+   yDim0 <- Call.sizes1 <$> getBounds y
+   let n = aDim0
+   let lda = aDim1
+   let _xSize = xDim0
+   let _ySize = yDim0
+   evalContT $ do
+      transPtr <- Call.char trans
+      mPtr <- Call.cint m
+      nPtr <- Call.cint n
+      klPtr <- Call.cint kl
+      kuPtr <- Call.cint ku
+      alphaPtr <- Call.double alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      betaPtr <- Call.double beta
+      yPtr <- Call.ioarray y
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.gbmv transPtr mPtr nPtr klPtr kuPtr alphaPtr aPtr ldaPtr xPtr incxPtr betaPtr yPtr incyPtr
+
+gemm ::
+   Char {- ^ transa -} ->
+   Char {- ^ transb -} ->
+   Int {- ^ m -} ->
+   Int {- ^ k -} ->
+   Double {- ^ alpha -} ->
+   CArray (Int,Int) Double {- ^ a -} ->
+   CArray (Int,Int) Double {- ^ b -} ->
+   Double {- ^ beta -} ->
+   IOCArray (Int,Int) Double {- ^ c -} ->
+   IO ()
+gemm transa transb m k alpha a b beta c = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   let (bDim0,bDim1) = Call.sizes2 $ bounds b
+   (cDim0,cDim1) <- Call.sizes2 <$> getBounds c
+   let _ka = aDim0
+   let lda = aDim1
+   let _kb = bDim0
+   let ldb = bDim1
+   let n = cDim0
+   let ldc = cDim1
+   evalContT $ do
+      transaPtr <- Call.char transa
+      transbPtr <- Call.char transb
+      mPtr <- Call.cint m
+      nPtr <- Call.cint n
+      kPtr <- Call.cint k
+      alphaPtr <- Call.double alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      bPtr <- Call.array b
+      ldbPtr <- Call.cint ldb
+      betaPtr <- Call.double beta
+      cPtr <- Call.ioarray c
+      ldcPtr <- Call.cint ldc
+      liftIO $ FFI.gemm transaPtr transbPtr mPtr nPtr kPtr alphaPtr aPtr ldaPtr bPtr ldbPtr betaPtr cPtr ldcPtr
+
+gemv ::
+   Char {- ^ trans -} ->
+   Int {- ^ m -} ->
+   Double {- ^ alpha -} ->
+   CArray (Int,Int) Double {- ^ a -} ->
+   CArray Int Double {- ^ x -} ->
+   Int {- ^ incx -} ->
+   Double {- ^ beta -} ->
+   IOCArray Int Double {- ^ y -} ->
+   Int {- ^ incy -} ->
+   IO ()
+gemv trans m alpha a x incx beta y incy = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   let xDim0 = Call.sizes1 $ bounds x
+   yDim0 <- Call.sizes1 <$> getBounds y
+   let n = aDim0
+   let lda = aDim1
+   let _xSize = xDim0
+   let _ySize = yDim0
+   evalContT $ do
+      transPtr <- Call.char trans
+      mPtr <- Call.cint m
+      nPtr <- Call.cint n
+      alphaPtr <- Call.double alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      betaPtr <- Call.double beta
+      yPtr <- Call.ioarray y
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.gemv transPtr mPtr nPtr alphaPtr aPtr ldaPtr xPtr incxPtr betaPtr yPtr incyPtr
+
+ger ::
+   Int {- ^ m -} ->
+   Double {- ^ alpha -} ->
+   CArray Int Double {- ^ x -} ->
+   Int {- ^ incx -} ->
+   CArray Int Double {- ^ y -} ->
+   Int {- ^ incy -} ->
+   IOCArray (Int,Int) Double {- ^ a -} ->
+   IO ()
+ger m alpha x incx y incy a = do
+   let xDim0 = Call.sizes1 $ bounds x
+   let yDim0 = Call.sizes1 $ bounds y
+   (aDim0,aDim1) <- Call.sizes2 <$> getBounds a
+   let _xSize = xDim0
+   let _ySize = yDim0
+   let n = aDim0
+   let lda = aDim1
+   evalContT $ do
+      mPtr <- Call.cint m
+      nPtr <- Call.cint n
+      alphaPtr <- Call.double alpha
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      yPtr <- Call.array y
+      incyPtr <- Call.cint incy
+      aPtr <- Call.ioarray a
+      ldaPtr <- Call.cint lda
+      liftIO $ FFI.ger mPtr nPtr alphaPtr xPtr incxPtr yPtr incyPtr aPtr ldaPtr
+
+iamax ::
+   Int {- ^ n -} ->
+   CArray Int Double {- ^ dx -} ->
+   Int {- ^ incx -} ->
+   IO CInt
+iamax n dx incx = do
+   let dxDim0 = Call.sizes1 $ bounds dx
+   Call.assert "iamax: 1+(n-1)*abs(incx) == dxDim0" (1+(n-1)*abs(incx) == dxDim0)
+   evalContT $ do
+      nPtr <- Call.cint n
+      dxPtr <- Call.array dx
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.iamax nPtr dxPtr incxPtr
+
+nrm2 ::
+   Int {- ^ n -} ->
+   CArray Int Double {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IO Double
+nrm2 n x incx = do
+   let xDim0 = Call.sizes1 $ bounds x
+   Call.assert "nrm2: 1+(n-1)*abs(incx) == xDim0" (1+(n-1)*abs(incx) == xDim0)
+   evalContT $ do
+      nPtr <- Call.cint n
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.nrm2 nPtr xPtr incxPtr
+
+rot ::
+   Int {- ^ n -} ->
+   IOCArray Int Double {- ^ dx -} ->
+   Int {- ^ incx -} ->
+   IOCArray Int Double {- ^ dy -} ->
+   Int {- ^ incy -} ->
+   Double {- ^ c -} ->
+   Double {- ^ s -} ->
+   IO ()
+rot n dx incx dy incy c s = do
+   dxDim0 <- Call.sizes1 <$> getBounds dx
+   dyDim0 <- Call.sizes1 <$> getBounds dy
+   Call.assert "rot: 1+(n-1)*abs(incx) == dxDim0" (1+(n-1)*abs(incx) == dxDim0)
+   Call.assert "rot: 1+(n-1)*abs(incy) == dyDim0" (1+(n-1)*abs(incy) == dyDim0)
+   evalContT $ do
+      nPtr <- Call.cint n
+      dxPtr <- Call.ioarray dx
+      incxPtr <- Call.cint incx
+      dyPtr <- Call.ioarray dy
+      incyPtr <- Call.cint incy
+      cPtr <- Call.double c
+      sPtr <- Call.double s
+      liftIO $ FFI.rot nPtr dxPtr incxPtr dyPtr incyPtr cPtr sPtr
+
+rotg ::
+   Double {- ^ da -} ->
+   Double {- ^ db -} ->
+   IO (Double, Double)
+rotg da db = do
+   evalContT $ do
+      daPtr <- Call.double da
+      dbPtr <- Call.double db
+      cPtr <- Call.alloca
+      sPtr <- Call.alloca
+      liftIO $ FFI.rotg daPtr dbPtr cPtr sPtr
+      liftIO $ pure (,)
+         <*> peek cPtr
+         <*> peek sPtr
+
+rotm ::
+   Int {- ^ n -} ->
+   IOCArray Int Double {- ^ dx -} ->
+   Int {- ^ incx -} ->
+   IOCArray Int Double {- ^ dy -} ->
+   Int {- ^ incy -} ->
+   CArray Int Double {- ^ dparam -} ->
+   IO ()
+rotm n dx incx dy incy dparam = do
+   dxDim0 <- Call.sizes1 <$> getBounds dx
+   dyDim0 <- Call.sizes1 <$> getBounds dy
+   let dparamDim0 = Call.sizes1 $ bounds dparam
+   Call.assert "rotm: 1+(n-1)*abs(incx) == dxDim0" (1+(n-1)*abs(incx) == dxDim0)
+   Call.assert "rotm: 1+(n-1)*abs(incy) == dyDim0" (1+(n-1)*abs(incy) == dyDim0)
+   Call.assert "rotm: 5 == dparamDim0" (5 == dparamDim0)
+   evalContT $ do
+      nPtr <- Call.cint n
+      dxPtr <- Call.ioarray dx
+      incxPtr <- Call.cint incx
+      dyPtr <- Call.ioarray dy
+      incyPtr <- Call.cint incy
+      dparamPtr <- Call.array dparam
+      liftIO $ FFI.rotm nPtr dxPtr incxPtr dyPtr incyPtr dparamPtr
+
+rotmg ::
+   Double {- ^ dd1 -} ->
+   Double {- ^ dd2 -} ->
+   Double {- ^ dx1 -} ->
+   Double {- ^ dy1 -} ->
+   IO (Double, Double, Double, CArray Int Double)
+rotmg dd1 dd2 dx1 dy1 = do
+   dparam <- Call.newArray1 5
+   evalContT $ do
+      dd1Ptr <- Call.double dd1
+      dd2Ptr <- Call.double dd2
+      dx1Ptr <- Call.double dx1
+      dy1Ptr <- Call.double dy1
+      dparamPtr <- Call.array dparam
+      liftIO $ FFI.rotmg dd1Ptr dd2Ptr dx1Ptr dy1Ptr dparamPtr
+      liftIO $ pure (,,,)
+         <*> peek dd1Ptr
+         <*> peek dd2Ptr
+         <*> peek dx1Ptr
+         <*> pure dparam
+
+sbmv ::
+   Char {- ^ uplo -} ->
+   Int {- ^ k -} ->
+   Double {- ^ alpha -} ->
+   CArray (Int,Int) Double {- ^ a -} ->
+   CArray Int Double {- ^ x -} ->
+   Int {- ^ incx -} ->
+   Double {- ^ beta -} ->
+   IOCArray Int Double {- ^ y -} ->
+   Int {- ^ incy -} ->
+   IO ()
+sbmv uplo k alpha a x incx beta y incy = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   let xDim0 = Call.sizes1 $ bounds x
+   yDim0 <- Call.sizes1 <$> getBounds y
+   let n = aDim0
+   let lda = aDim1
+   let _xSize = xDim0
+   let _ySize = yDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      nPtr <- Call.cint n
+      kPtr <- Call.cint k
+      alphaPtr <- Call.double alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      betaPtr <- Call.double beta
+      yPtr <- Call.ioarray y
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.sbmv uploPtr nPtr kPtr alphaPtr aPtr ldaPtr xPtr incxPtr betaPtr yPtr incyPtr
+
+scal ::
+   Int {- ^ n -} ->
+   Double {- ^ da -} ->
+   IOCArray Int Double {- ^ dx -} ->
+   Int {- ^ incx -} ->
+   IO ()
+scal n da dx incx = do
+   dxDim0 <- Call.sizes1 <$> getBounds dx
+   Call.assert "scal: 1+(n-1)*abs(incx) == dxDim0" (1+(n-1)*abs(incx) == dxDim0)
+   evalContT $ do
+      nPtr <- Call.cint n
+      daPtr <- Call.double da
+      dxPtr <- Call.ioarray dx
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.scal nPtr daPtr dxPtr incxPtr
+
+sdot ::
+   CArray Int Float {- ^ sx -} ->
+   Int {- ^ incx -} ->
+   CArray Int Float {- ^ sy -} ->
+   Int {- ^ incy -} ->
+   IO Double
+sdot sx incx sy incy = do
+   let sxDim0 = Call.sizes1 $ bounds sx
+   let syDim0 = Call.sizes1 $ bounds sy
+   let n = sxDim0
+   Call.assert "sdot: n == syDim0" (n == syDim0)
+   evalContT $ do
+      nPtr <- Call.cint n
+      sxPtr <- Call.array sx
+      incxPtr <- Call.cint incx
+      syPtr <- Call.array sy
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.sdot nPtr sxPtr incxPtr syPtr incyPtr
+
+spmv ::
+   Char {- ^ uplo -} ->
+   Int {- ^ n -} ->
+   Double {- ^ alpha -} ->
+   CArray Int Double {- ^ ap -} ->
+   CArray Int Double {- ^ x -} ->
+   Int {- ^ incx -} ->
+   Double {- ^ beta -} ->
+   IOCArray Int Double {- ^ y -} ->
+   Int {- ^ incy -} ->
+   IO ()
+spmv uplo n alpha ap x incx beta y incy = do
+   let apDim0 = Call.sizes1 $ bounds ap
+   let xDim0 = Call.sizes1 $ bounds x
+   yDim0 <- Call.sizes1 <$> getBounds y
+   let _apSize = apDim0
+   let _xSize = xDim0
+   let _ySize = yDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      nPtr <- Call.cint n
+      alphaPtr <- Call.double alpha
+      apPtr <- Call.array ap
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      betaPtr <- Call.double beta
+      yPtr <- Call.ioarray y
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.spmv uploPtr nPtr alphaPtr apPtr xPtr incxPtr betaPtr yPtr incyPtr
+
+spr ::
+   Char {- ^ uplo -} ->
+   Int {- ^ n -} ->
+   Double {- ^ alpha -} ->
+   CArray Int Double {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IOCArray Int Double {- ^ ap -} ->
+   IO ()
+spr uplo n alpha x incx ap = do
+   let xDim0 = Call.sizes1 $ bounds x
+   apDim0 <- Call.sizes1 <$> getBounds ap
+   let _xSize = xDim0
+   let _apSize = apDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      nPtr <- Call.cint n
+      alphaPtr <- Call.double alpha
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      apPtr <- Call.ioarray ap
+      liftIO $ FFI.spr uploPtr nPtr alphaPtr xPtr incxPtr apPtr
+
+spr2 ::
+   Char {- ^ uplo -} ->
+   Int {- ^ n -} ->
+   Double {- ^ alpha -} ->
+   CArray Int Double {- ^ x -} ->
+   Int {- ^ incx -} ->
+   CArray Int Double {- ^ y -} ->
+   Int {- ^ incy -} ->
+   IOCArray Int Double {- ^ ap -} ->
+   IO ()
+spr2 uplo n alpha x incx y incy ap = do
+   let xDim0 = Call.sizes1 $ bounds x
+   let yDim0 = Call.sizes1 $ bounds y
+   apDim0 <- Call.sizes1 <$> getBounds ap
+   let _xSize = xDim0
+   let _ySize = yDim0
+   let _apSize = apDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      nPtr <- Call.cint n
+      alphaPtr <- Call.double alpha
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      yPtr <- Call.array y
+      incyPtr <- Call.cint incy
+      apPtr <- Call.ioarray ap
+      liftIO $ FFI.spr2 uploPtr nPtr alphaPtr xPtr incxPtr yPtr incyPtr apPtr
+
+swap ::
+   Int {- ^ n -} ->
+   IOCArray Int Double {- ^ dx -} ->
+   Int {- ^ incx -} ->
+   IOCArray Int Double {- ^ dy -} ->
+   Int {- ^ incy -} ->
+   IO ()
+swap n dx incx dy incy = do
+   dxDim0 <- Call.sizes1 <$> getBounds dx
+   dyDim0 <- Call.sizes1 <$> getBounds dy
+   Call.assert "swap: 1+(n-1)*abs(incx) == dxDim0" (1+(n-1)*abs(incx) == dxDim0)
+   Call.assert "swap: 1+(n-1)*abs(incy) == dyDim0" (1+(n-1)*abs(incy) == dyDim0)
+   evalContT $ do
+      nPtr <- Call.cint n
+      dxPtr <- Call.ioarray dx
+      incxPtr <- Call.cint incx
+      dyPtr <- Call.ioarray dy
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.swap nPtr dxPtr incxPtr dyPtr incyPtr
+
+symm ::
+   Char {- ^ side -} ->
+   Char {- ^ uplo -} ->
+   Int {- ^ m -} ->
+   Double {- ^ alpha -} ->
+   CArray (Int,Int) Double {- ^ a -} ->
+   CArray (Int,Int) Double {- ^ b -} ->
+   Double {- ^ beta -} ->
+   IOCArray (Int,Int) Double {- ^ c -} ->
+   IO ()
+symm side uplo m alpha a b beta c = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   let (bDim0,bDim1) = Call.sizes2 $ bounds b
+   (cDim0,cDim1) <- Call.sizes2 <$> getBounds c
+   let _ka = aDim0
+   let lda = aDim1
+   let n = bDim0
+   let ldb = bDim1
+   let ldc = cDim1
+   Call.assert "symm: n == cDim0" (n == cDim0)
+   evalContT $ do
+      sidePtr <- Call.char side
+      uploPtr <- Call.char uplo
+      mPtr <- Call.cint m
+      nPtr <- Call.cint n
+      alphaPtr <- Call.double alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      bPtr <- Call.array b
+      ldbPtr <- Call.cint ldb
+      betaPtr <- Call.double beta
+      cPtr <- Call.ioarray c
+      ldcPtr <- Call.cint ldc
+      liftIO $ FFI.symm sidePtr uploPtr mPtr nPtr alphaPtr aPtr ldaPtr bPtr ldbPtr betaPtr cPtr ldcPtr
+
+symv ::
+   Char {- ^ uplo -} ->
+   Double {- ^ alpha -} ->
+   CArray (Int,Int) Double {- ^ a -} ->
+   CArray Int Double {- ^ x -} ->
+   Int {- ^ incx -} ->
+   Double {- ^ beta -} ->
+   IOCArray Int Double {- ^ y -} ->
+   Int {- ^ incy -} ->
+   IO ()
+symv uplo alpha a x incx beta y incy = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   let xDim0 = Call.sizes1 $ bounds x
+   yDim0 <- Call.sizes1 <$> getBounds y
+   let n = aDim0
+   let lda = aDim1
+   let _xSize = xDim0
+   let _ySize = yDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      nPtr <- Call.cint n
+      alphaPtr <- Call.double alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      betaPtr <- Call.double beta
+      yPtr <- Call.ioarray y
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.symv uploPtr nPtr alphaPtr aPtr ldaPtr xPtr incxPtr betaPtr yPtr incyPtr
+
+syr ::
+   Char {- ^ uplo -} ->
+   Double {- ^ alpha -} ->
+   CArray Int Double {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IOCArray (Int,Int) Double {- ^ a -} ->
+   IO ()
+syr uplo alpha x incx a = do
+   let xDim0 = Call.sizes1 $ bounds x
+   (aDim0,aDim1) <- Call.sizes2 <$> getBounds a
+   let _xSize = xDim0
+   let n = aDim0
+   let lda = aDim1
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      nPtr <- Call.cint n
+      alphaPtr <- Call.double alpha
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      aPtr <- Call.ioarray a
+      ldaPtr <- Call.cint lda
+      liftIO $ FFI.syr uploPtr nPtr alphaPtr xPtr incxPtr aPtr ldaPtr
+
+syr2 ::
+   Char {- ^ uplo -} ->
+   Double {- ^ alpha -} ->
+   CArray Int Double {- ^ x -} ->
+   Int {- ^ incx -} ->
+   CArray Int Double {- ^ y -} ->
+   Int {- ^ incy -} ->
+   IOCArray (Int,Int) Double {- ^ a -} ->
+   IO ()
+syr2 uplo alpha x incx y incy a = do
+   let xDim0 = Call.sizes1 $ bounds x
+   let yDim0 = Call.sizes1 $ bounds y
+   (aDim0,aDim1) <- Call.sizes2 <$> getBounds a
+   let _xSize = xDim0
+   let _ySize = yDim0
+   let n = aDim0
+   let lda = aDim1
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      nPtr <- Call.cint n
+      alphaPtr <- Call.double alpha
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      yPtr <- Call.array y
+      incyPtr <- Call.cint incy
+      aPtr <- Call.ioarray a
+      ldaPtr <- Call.cint lda
+      liftIO $ FFI.syr2 uploPtr nPtr alphaPtr xPtr incxPtr yPtr incyPtr aPtr ldaPtr
+
+syr2k ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Int {- ^ k -} ->
+   Double {- ^ alpha -} ->
+   CArray (Int,Int) Double {- ^ a -} ->
+   CArray (Int,Int) Double {- ^ b -} ->
+   Double {- ^ beta -} ->
+   IOCArray (Int,Int) Double {- ^ c -} ->
+   IO ()
+syr2k uplo trans k alpha a b beta c = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   let (bDim0,bDim1) = Call.sizes2 $ bounds b
+   (cDim0,cDim1) <- Call.sizes2 <$> getBounds c
+   let _ka = aDim0
+   let lda = aDim1
+   let _kb = bDim0
+   let ldb = bDim1
+   let n = cDim0
+   let ldc = cDim1
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      nPtr <- Call.cint n
+      kPtr <- Call.cint k
+      alphaPtr <- Call.double alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      bPtr <- Call.array b
+      ldbPtr <- Call.cint ldb
+      betaPtr <- Call.double beta
+      cPtr <- Call.ioarray c
+      ldcPtr <- Call.cint ldc
+      liftIO $ FFI.syr2k uploPtr transPtr nPtr kPtr alphaPtr aPtr ldaPtr bPtr ldbPtr betaPtr cPtr ldcPtr
+
+syrk ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Int {- ^ k -} ->
+   Double {- ^ alpha -} ->
+   CArray (Int,Int) Double {- ^ a -} ->
+   Double {- ^ beta -} ->
+   IOCArray (Int,Int) Double {- ^ c -} ->
+   IO ()
+syrk uplo trans k alpha a beta c = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   (cDim0,cDim1) <- Call.sizes2 <$> getBounds c
+   let _ka = aDim0
+   let lda = aDim1
+   let n = cDim0
+   let ldc = cDim1
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      nPtr <- Call.cint n
+      kPtr <- Call.cint k
+      alphaPtr <- Call.double alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      betaPtr <- Call.double beta
+      cPtr <- Call.ioarray c
+      ldcPtr <- Call.cint ldc
+      liftIO $ FFI.syrk uploPtr transPtr nPtr kPtr alphaPtr aPtr ldaPtr betaPtr cPtr ldcPtr
+
+tbmv ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Char {- ^ diag -} ->
+   Int {- ^ k -} ->
+   CArray (Int,Int) Double {- ^ a -} ->
+   IOCArray Int Double {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IO ()
+tbmv uplo trans diag k a x incx = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   xDim0 <- Call.sizes1 <$> getBounds x
+   let n = aDim0
+   let lda = aDim1
+   let _xSize = xDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      diagPtr <- Call.char diag
+      nPtr <- Call.cint n
+      kPtr <- Call.cint k
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      xPtr <- Call.ioarray x
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.tbmv uploPtr transPtr diagPtr nPtr kPtr aPtr ldaPtr xPtr incxPtr
+
+tbsv ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Char {- ^ diag -} ->
+   Int {- ^ k -} ->
+   CArray (Int,Int) Double {- ^ a -} ->
+   IOCArray Int Double {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IO ()
+tbsv uplo trans diag k a x incx = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   xDim0 <- Call.sizes1 <$> getBounds x
+   let n = aDim0
+   let lda = aDim1
+   let _xSize = xDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      diagPtr <- Call.char diag
+      nPtr <- Call.cint n
+      kPtr <- Call.cint k
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      xPtr <- Call.ioarray x
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.tbsv uploPtr transPtr diagPtr nPtr kPtr aPtr ldaPtr xPtr incxPtr
+
+tpmv ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Char {- ^ diag -} ->
+   Int {- ^ n -} ->
+   CArray Int Double {- ^ ap -} ->
+   IOCArray Int Double {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IO ()
+tpmv uplo trans diag n ap x incx = do
+   let apDim0 = Call.sizes1 $ bounds ap
+   xDim0 <- Call.sizes1 <$> getBounds x
+   let _apSize = apDim0
+   let _xSize = xDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      diagPtr <- Call.char diag
+      nPtr <- Call.cint n
+      apPtr <- Call.array ap
+      xPtr <- Call.ioarray x
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.tpmv uploPtr transPtr diagPtr nPtr apPtr xPtr incxPtr
+
+tpsv ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Char {- ^ diag -} ->
+   Int {- ^ n -} ->
+   CArray Int Double {- ^ ap -} ->
+   IOCArray Int Double {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IO ()
+tpsv uplo trans diag n ap x incx = do
+   let apDim0 = Call.sizes1 $ bounds ap
+   xDim0 <- Call.sizes1 <$> getBounds x
+   let _apSize = apDim0
+   let _xSize = xDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      diagPtr <- Call.char diag
+      nPtr <- Call.cint n
+      apPtr <- Call.array ap
+      xPtr <- Call.ioarray x
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.tpsv uploPtr transPtr diagPtr nPtr apPtr xPtr incxPtr
+
+trmm ::
+   Char {- ^ side -} ->
+   Char {- ^ uplo -} ->
+   Char {- ^ transa -} ->
+   Char {- ^ diag -} ->
+   Int {- ^ m -} ->
+   Double {- ^ alpha -} ->
+   CArray (Int,Int) Double {- ^ a -} ->
+   IOCArray (Int,Int) Double {- ^ b -} ->
+   IO ()
+trmm side uplo transa diag m alpha a b = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   (bDim0,bDim1) <- Call.sizes2 <$> getBounds b
+   let _k = aDim0
+   let lda = aDim1
+   let n = bDim0
+   let ldb = bDim1
+   evalContT $ do
+      sidePtr <- Call.char side
+      uploPtr <- Call.char uplo
+      transaPtr <- Call.char transa
+      diagPtr <- Call.char diag
+      mPtr <- Call.cint m
+      nPtr <- Call.cint n
+      alphaPtr <- Call.double alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      bPtr <- Call.ioarray b
+      ldbPtr <- Call.cint ldb
+      liftIO $ FFI.trmm sidePtr uploPtr transaPtr diagPtr mPtr nPtr alphaPtr aPtr ldaPtr bPtr ldbPtr
+
+trmv ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Char {- ^ diag -} ->
+   CArray (Int,Int) Double {- ^ a -} ->
+   IOCArray Int Double {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IO ()
+trmv uplo trans diag a x incx = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   xDim0 <- Call.sizes1 <$> getBounds x
+   let n = aDim0
+   let lda = aDim1
+   let _xSize = xDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      diagPtr <- Call.char diag
+      nPtr <- Call.cint n
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      xPtr <- Call.ioarray x
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.trmv uploPtr transPtr diagPtr nPtr aPtr ldaPtr xPtr incxPtr
+
+trsm ::
+   Char {- ^ side -} ->
+   Char {- ^ uplo -} ->
+   Char {- ^ transa -} ->
+   Char {- ^ diag -} ->
+   Int {- ^ m -} ->
+   Double {- ^ alpha -} ->
+   CArray (Int,Int) Double {- ^ a -} ->
+   IOCArray (Int,Int) Double {- ^ b -} ->
+   IO ()
+trsm side uplo transa diag m alpha a b = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   (bDim0,bDim1) <- Call.sizes2 <$> getBounds b
+   let _k = aDim0
+   let lda = aDim1
+   let n = bDim0
+   let ldb = bDim1
+   evalContT $ do
+      sidePtr <- Call.char side
+      uploPtr <- Call.char uplo
+      transaPtr <- Call.char transa
+      diagPtr <- Call.char diag
+      mPtr <- Call.cint m
+      nPtr <- Call.cint n
+      alphaPtr <- Call.double alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      bPtr <- Call.ioarray b
+      ldbPtr <- Call.cint ldb
+      liftIO $ FFI.trsm sidePtr uploPtr transaPtr diagPtr mPtr nPtr alphaPtr aPtr ldaPtr bPtr ldbPtr
+
+trsv ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Char {- ^ diag -} ->
+   CArray (Int,Int) Double {- ^ a -} ->
+   IOCArray Int Double {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IO ()
+trsv uplo trans diag a x incx = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   xDim0 <- Call.sizes1 <$> getBounds x
+   let n = aDim0
+   let lda = aDim1
+   let _xSize = xDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      diagPtr <- Call.char diag
+      nPtr <- Call.cint n
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      xPtr <- Call.ioarray x
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.trsv uploPtr transPtr diagPtr nPtr aPtr ldaPtr xPtr incxPtr
diff --git a/src/Numeric/BLAS/CArray/Float.hs b/src/Numeric/BLAS/CArray/Float.hs
new file mode 100644
--- /dev/null
+++ b/src/Numeric/BLAS/CArray/Float.hs
@@ -0,0 +1,907 @@
+-- Do not edit! Automatically generated by create-lapack-ffi.
+module Numeric.BLAS.CArray.Float where
+
+import qualified Numeric.BLAS.FFI.Float as FFI
+import qualified Numeric.Netlib.CArray.Utility as Call
+
+import Data.Array.IOCArray (IOCArray, getBounds)
+import Data.Array.CArray (CArray, bounds)
+
+import Foreign.Storable.Complex ()
+import Foreign.Storable (peek)
+import Foreign.C.Types (CInt)
+
+import Control.Monad.Trans.Cont (evalContT)
+import Control.Monad.IO.Class (liftIO)
+import Control.Applicative (pure, (<*>), (<$>))
+
+
+asum ::
+   Int {- ^ n -} ->
+   CArray Int Float {- ^ sx -} ->
+   Int {- ^ incx -} ->
+   IO Float
+asum n sx incx = do
+   let sxDim0 = Call.sizes1 $ bounds sx
+   Call.assert "asum: 1+(n-1)*abs(incx) == sxDim0" (1+(n-1)*abs(incx) == sxDim0)
+   evalContT $ do
+      nPtr <- Call.cint n
+      sxPtr <- Call.array sx
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.asum nPtr sxPtr incxPtr
+
+axpy ::
+   Int {- ^ n -} ->
+   Float {- ^ sa -} ->
+   CArray Int Float {- ^ sx -} ->
+   Int {- ^ incx -} ->
+   IOCArray Int Float {- ^ sy -} ->
+   Int {- ^ incy -} ->
+   IO ()
+axpy n sa sx incx sy incy = do
+   let sxDim0 = Call.sizes1 $ bounds sx
+   syDim0 <- Call.sizes1 <$> getBounds sy
+   Call.assert "axpy: 1+(n-1)*abs(incx) == sxDim0" (1+(n-1)*abs(incx) == sxDim0)
+   Call.assert "axpy: 1+(n-1)*abs(incy) == syDim0" (1+(n-1)*abs(incy) == syDim0)
+   evalContT $ do
+      nPtr <- Call.cint n
+      saPtr <- Call.float sa
+      sxPtr <- Call.array sx
+      incxPtr <- Call.cint incx
+      syPtr <- Call.ioarray sy
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.axpy nPtr saPtr sxPtr incxPtr syPtr incyPtr
+
+copy ::
+   Int {- ^ n -} ->
+   CArray Int Float {- ^ sx -} ->
+   Int {- ^ incx -} ->
+   Int {- ^ incy -} ->
+   IO (CArray Int Float)
+copy n sx incx incy = do
+   let sxDim0 = Call.sizes1 $ bounds sx
+   Call.assert "copy: 1+(n-1)*abs(incx) == sxDim0" (1+(n-1)*abs(incx) == sxDim0)
+   sy <- Call.newArray1 (1+(n-1)*abs(incy))
+   evalContT $ do
+      nPtr <- Call.cint n
+      sxPtr <- Call.array sx
+      incxPtr <- Call.cint incx
+      syPtr <- Call.array sy
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.copy nPtr sxPtr incxPtr syPtr incyPtr
+      liftIO $ pure sy
+
+dot ::
+   Int {- ^ n -} ->
+   CArray Int Float {- ^ sx -} ->
+   Int {- ^ incx -} ->
+   CArray Int Float {- ^ sy -} ->
+   Int {- ^ incy -} ->
+   IO Float
+dot n sx incx sy incy = do
+   let sxDim0 = Call.sizes1 $ bounds sx
+   let syDim0 = Call.sizes1 $ bounds sy
+   Call.assert "dot: 1+(n-1)*abs(incx) == sxDim0" (1+(n-1)*abs(incx) == sxDim0)
+   Call.assert "dot: 1+(n-1)*abs(incy) == syDim0" (1+(n-1)*abs(incy) == syDim0)
+   evalContT $ do
+      nPtr <- Call.cint n
+      sxPtr <- Call.array sx
+      incxPtr <- Call.cint incx
+      syPtr <- Call.array sy
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.dot nPtr sxPtr incxPtr syPtr incyPtr
+
+dsdot ::
+   Int {- ^ n -} ->
+   Float {- ^ sb -} ->
+   CArray Int Float {- ^ sx -} ->
+   Int {- ^ incx -} ->
+   CArray Int Float {- ^ sy -} ->
+   Int {- ^ incy -} ->
+   IO Float
+dsdot n sb sx incx sy incy = do
+   let sxDim0 = Call.sizes1 $ bounds sx
+   let syDim0 = Call.sizes1 $ bounds sy
+   Call.assert "dsdot: 1+(n-1)*abs(incx) == sxDim0" (1+(n-1)*abs(incx) == sxDim0)
+   Call.assert "dsdot: 1+(n-1)*abs(incx) == syDim0" (1+(n-1)*abs(incx) == syDim0)
+   evalContT $ do
+      nPtr <- Call.cint n
+      sbPtr <- Call.float sb
+      sxPtr <- Call.array sx
+      incxPtr <- Call.cint incx
+      syPtr <- Call.array sy
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.dsdot nPtr sbPtr sxPtr incxPtr syPtr incyPtr
+
+gbmv ::
+   Char {- ^ trans -} ->
+   Int {- ^ m -} ->
+   Int {- ^ kl -} ->
+   Int {- ^ ku -} ->
+   Float {- ^ alpha -} ->
+   CArray (Int,Int) Float {- ^ a -} ->
+   CArray Int Float {- ^ x -} ->
+   Int {- ^ incx -} ->
+   Float {- ^ beta -} ->
+   IOCArray Int Float {- ^ y -} ->
+   Int {- ^ incy -} ->
+   IO ()
+gbmv trans m kl ku alpha a x incx beta y incy = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   let xDim0 = Call.sizes1 $ bounds x
+   yDim0 <- Call.sizes1 <$> getBounds y
+   let n = aDim0
+   let lda = aDim1
+   let _xSize = xDim0
+   let _ySize = yDim0
+   evalContT $ do
+      transPtr <- Call.char trans
+      mPtr <- Call.cint m
+      nPtr <- Call.cint n
+      klPtr <- Call.cint kl
+      kuPtr <- Call.cint ku
+      alphaPtr <- Call.float alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      betaPtr <- Call.float beta
+      yPtr <- Call.ioarray y
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.gbmv transPtr mPtr nPtr klPtr kuPtr alphaPtr aPtr ldaPtr xPtr incxPtr betaPtr yPtr incyPtr
+
+gemm ::
+   Char {- ^ transa -} ->
+   Char {- ^ transb -} ->
+   Int {- ^ m -} ->
+   Int {- ^ k -} ->
+   Float {- ^ alpha -} ->
+   CArray (Int,Int) Float {- ^ a -} ->
+   CArray (Int,Int) Float {- ^ b -} ->
+   Float {- ^ beta -} ->
+   IOCArray (Int,Int) Float {- ^ c -} ->
+   IO ()
+gemm transa transb m k alpha a b beta c = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   let (bDim0,bDim1) = Call.sizes2 $ bounds b
+   (cDim0,cDim1) <- Call.sizes2 <$> getBounds c
+   let _ka = aDim0
+   let lda = aDim1
+   let _kb = bDim0
+   let ldb = bDim1
+   let n = cDim0
+   let ldc = cDim1
+   evalContT $ do
+      transaPtr <- Call.char transa
+      transbPtr <- Call.char transb
+      mPtr <- Call.cint m
+      nPtr <- Call.cint n
+      kPtr <- Call.cint k
+      alphaPtr <- Call.float alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      bPtr <- Call.array b
+      ldbPtr <- Call.cint ldb
+      betaPtr <- Call.float beta
+      cPtr <- Call.ioarray c
+      ldcPtr <- Call.cint ldc
+      liftIO $ FFI.gemm transaPtr transbPtr mPtr nPtr kPtr alphaPtr aPtr ldaPtr bPtr ldbPtr betaPtr cPtr ldcPtr
+
+gemv ::
+   Char {- ^ trans -} ->
+   Int {- ^ m -} ->
+   Float {- ^ alpha -} ->
+   CArray (Int,Int) Float {- ^ a -} ->
+   CArray Int Float {- ^ x -} ->
+   Int {- ^ incx -} ->
+   Float {- ^ beta -} ->
+   IOCArray Int Float {- ^ y -} ->
+   Int {- ^ incy -} ->
+   IO ()
+gemv trans m alpha a x incx beta y incy = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   let xDim0 = Call.sizes1 $ bounds x
+   yDim0 <- Call.sizes1 <$> getBounds y
+   let n = aDim0
+   let lda = aDim1
+   let _xSize = xDim0
+   let _ySize = yDim0
+   evalContT $ do
+      transPtr <- Call.char trans
+      mPtr <- Call.cint m
+      nPtr <- Call.cint n
+      alphaPtr <- Call.float alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      betaPtr <- Call.float beta
+      yPtr <- Call.ioarray y
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.gemv transPtr mPtr nPtr alphaPtr aPtr ldaPtr xPtr incxPtr betaPtr yPtr incyPtr
+
+ger ::
+   Int {- ^ m -} ->
+   Float {- ^ alpha -} ->
+   CArray Int Float {- ^ x -} ->
+   Int {- ^ incx -} ->
+   CArray Int Float {- ^ y -} ->
+   Int {- ^ incy -} ->
+   IOCArray (Int,Int) Float {- ^ a -} ->
+   IO ()
+ger m alpha x incx y incy a = do
+   let xDim0 = Call.sizes1 $ bounds x
+   let yDim0 = Call.sizes1 $ bounds y
+   (aDim0,aDim1) <- Call.sizes2 <$> getBounds a
+   let _xSize = xDim0
+   let _ySize = yDim0
+   let n = aDim0
+   let lda = aDim1
+   evalContT $ do
+      mPtr <- Call.cint m
+      nPtr <- Call.cint n
+      alphaPtr <- Call.float alpha
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      yPtr <- Call.array y
+      incyPtr <- Call.cint incy
+      aPtr <- Call.ioarray a
+      ldaPtr <- Call.cint lda
+      liftIO $ FFI.ger mPtr nPtr alphaPtr xPtr incxPtr yPtr incyPtr aPtr ldaPtr
+
+iamax ::
+   Int {- ^ n -} ->
+   CArray Int Float {- ^ sx -} ->
+   Int {- ^ incx -} ->
+   IO CInt
+iamax n sx incx = do
+   let sxDim0 = Call.sizes1 $ bounds sx
+   Call.assert "iamax: 1+(n-1)*abs(incx) == sxDim0" (1+(n-1)*abs(incx) == sxDim0)
+   evalContT $ do
+      nPtr <- Call.cint n
+      sxPtr <- Call.array sx
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.iamax nPtr sxPtr incxPtr
+
+nrm2 ::
+   Int {- ^ n -} ->
+   CArray Int Float {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IO Float
+nrm2 n x incx = do
+   let xDim0 = Call.sizes1 $ bounds x
+   Call.assert "nrm2: 1+(n-1)*abs(incx) == xDim0" (1+(n-1)*abs(incx) == xDim0)
+   evalContT $ do
+      nPtr <- Call.cint n
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.nrm2 nPtr xPtr incxPtr
+
+rot ::
+   Int {- ^ n -} ->
+   IOCArray Int Float {- ^ sx -} ->
+   Int {- ^ incx -} ->
+   IOCArray Int Float {- ^ sy -} ->
+   Int {- ^ incy -} ->
+   Float {- ^ c -} ->
+   Float {- ^ s -} ->
+   IO ()
+rot n sx incx sy incy c s = do
+   sxDim0 <- Call.sizes1 <$> getBounds sx
+   syDim0 <- Call.sizes1 <$> getBounds sy
+   Call.assert "rot: 1+(n-1)*abs(incx) == sxDim0" (1+(n-1)*abs(incx) == sxDim0)
+   Call.assert "rot: 1+(n-1)*abs(incy) == syDim0" (1+(n-1)*abs(incy) == syDim0)
+   evalContT $ do
+      nPtr <- Call.cint n
+      sxPtr <- Call.ioarray sx
+      incxPtr <- Call.cint incx
+      syPtr <- Call.ioarray sy
+      incyPtr <- Call.cint incy
+      cPtr <- Call.float c
+      sPtr <- Call.float s
+      liftIO $ FFI.rot nPtr sxPtr incxPtr syPtr incyPtr cPtr sPtr
+
+rotg ::
+   Float {- ^ sa -} ->
+   Float {- ^ sb -} ->
+   IO (Float, Float)
+rotg sa sb = do
+   evalContT $ do
+      saPtr <- Call.float sa
+      sbPtr <- Call.float sb
+      cPtr <- Call.alloca
+      sPtr <- Call.alloca
+      liftIO $ FFI.rotg saPtr sbPtr cPtr sPtr
+      liftIO $ pure (,)
+         <*> peek cPtr
+         <*> peek sPtr
+
+rotm ::
+   Int {- ^ n -} ->
+   IOCArray Int Float {- ^ sx -} ->
+   Int {- ^ incx -} ->
+   IOCArray Int Float {- ^ sy -} ->
+   Int {- ^ incy -} ->
+   CArray Int Float {- ^ sparam -} ->
+   IO ()
+rotm n sx incx sy incy sparam = do
+   sxDim0 <- Call.sizes1 <$> getBounds sx
+   syDim0 <- Call.sizes1 <$> getBounds sy
+   let sparamDim0 = Call.sizes1 $ bounds sparam
+   Call.assert "rotm: 1+(n-1)*abs(incx) == sxDim0" (1+(n-1)*abs(incx) == sxDim0)
+   Call.assert "rotm: 1+(n-1)*abs(incy) == syDim0" (1+(n-1)*abs(incy) == syDim0)
+   Call.assert "rotm: 5 == sparamDim0" (5 == sparamDim0)
+   evalContT $ do
+      nPtr <- Call.cint n
+      sxPtr <- Call.ioarray sx
+      incxPtr <- Call.cint incx
+      syPtr <- Call.ioarray sy
+      incyPtr <- Call.cint incy
+      sparamPtr <- Call.array sparam
+      liftIO $ FFI.rotm nPtr sxPtr incxPtr syPtr incyPtr sparamPtr
+
+rotmg ::
+   Float {- ^ sd1 -} ->
+   Float {- ^ sd2 -} ->
+   Float {- ^ sx1 -} ->
+   Float {- ^ sy1 -} ->
+   IO (Float, Float, Float, CArray Int Float)
+rotmg sd1 sd2 sx1 sy1 = do
+   sparam <- Call.newArray1 5
+   evalContT $ do
+      sd1Ptr <- Call.float sd1
+      sd2Ptr <- Call.float sd2
+      sx1Ptr <- Call.float sx1
+      sy1Ptr <- Call.float sy1
+      sparamPtr <- Call.array sparam
+      liftIO $ FFI.rotmg sd1Ptr sd2Ptr sx1Ptr sy1Ptr sparamPtr
+      liftIO $ pure (,,,)
+         <*> peek sd1Ptr
+         <*> peek sd2Ptr
+         <*> peek sx1Ptr
+         <*> pure sparam
+
+sbmv ::
+   Char {- ^ uplo -} ->
+   Int {- ^ k -} ->
+   Float {- ^ alpha -} ->
+   CArray (Int,Int) Float {- ^ a -} ->
+   CArray Int Float {- ^ x -} ->
+   Int {- ^ incx -} ->
+   Float {- ^ beta -} ->
+   IOCArray Int Float {- ^ y -} ->
+   Int {- ^ incy -} ->
+   IO ()
+sbmv uplo k alpha a x incx beta y incy = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   let xDim0 = Call.sizes1 $ bounds x
+   yDim0 <- Call.sizes1 <$> getBounds y
+   let n = aDim0
+   let lda = aDim1
+   let _xSize = xDim0
+   let _ySize = yDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      nPtr <- Call.cint n
+      kPtr <- Call.cint k
+      alphaPtr <- Call.float alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      betaPtr <- Call.float beta
+      yPtr <- Call.ioarray y
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.sbmv uploPtr nPtr kPtr alphaPtr aPtr ldaPtr xPtr incxPtr betaPtr yPtr incyPtr
+
+scal ::
+   Int {- ^ n -} ->
+   Float {- ^ sa -} ->
+   IOCArray Int Float {- ^ sx -} ->
+   Int {- ^ incx -} ->
+   IO ()
+scal n sa sx incx = do
+   sxDim0 <- Call.sizes1 <$> getBounds sx
+   Call.assert "scal: 1+(n-1)*abs(incx) == sxDim0" (1+(n-1)*abs(incx) == sxDim0)
+   evalContT $ do
+      nPtr <- Call.cint n
+      saPtr <- Call.float sa
+      sxPtr <- Call.ioarray sx
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.scal nPtr saPtr sxPtr incxPtr
+
+spmv ::
+   Char {- ^ uplo -} ->
+   Int {- ^ n -} ->
+   Float {- ^ alpha -} ->
+   CArray Int Float {- ^ ap -} ->
+   CArray Int Float {- ^ x -} ->
+   Int {- ^ incx -} ->
+   Float {- ^ beta -} ->
+   IOCArray Int Float {- ^ y -} ->
+   Int {- ^ incy -} ->
+   IO ()
+spmv uplo n alpha ap x incx beta y incy = do
+   let apDim0 = Call.sizes1 $ bounds ap
+   let xDim0 = Call.sizes1 $ bounds x
+   yDim0 <- Call.sizes1 <$> getBounds y
+   let _apSize = apDim0
+   let _xSize = xDim0
+   let _ySize = yDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      nPtr <- Call.cint n
+      alphaPtr <- Call.float alpha
+      apPtr <- Call.array ap
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      betaPtr <- Call.float beta
+      yPtr <- Call.ioarray y
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.spmv uploPtr nPtr alphaPtr apPtr xPtr incxPtr betaPtr yPtr incyPtr
+
+spr ::
+   Char {- ^ uplo -} ->
+   Int {- ^ n -} ->
+   Float {- ^ alpha -} ->
+   CArray Int Float {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IOCArray Int Float {- ^ ap -} ->
+   IO ()
+spr uplo n alpha x incx ap = do
+   let xDim0 = Call.sizes1 $ bounds x
+   apDim0 <- Call.sizes1 <$> getBounds ap
+   let _xSize = xDim0
+   let _apSize = apDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      nPtr <- Call.cint n
+      alphaPtr <- Call.float alpha
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      apPtr <- Call.ioarray ap
+      liftIO $ FFI.spr uploPtr nPtr alphaPtr xPtr incxPtr apPtr
+
+spr2 ::
+   Char {- ^ uplo -} ->
+   Int {- ^ n -} ->
+   Float {- ^ alpha -} ->
+   CArray Int Float {- ^ x -} ->
+   Int {- ^ incx -} ->
+   CArray Int Float {- ^ y -} ->
+   Int {- ^ incy -} ->
+   IOCArray Int Float {- ^ ap -} ->
+   IO ()
+spr2 uplo n alpha x incx y incy ap = do
+   let xDim0 = Call.sizes1 $ bounds x
+   let yDim0 = Call.sizes1 $ bounds y
+   apDim0 <- Call.sizes1 <$> getBounds ap
+   let _xSize = xDim0
+   let _ySize = yDim0
+   let _apSize = apDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      nPtr <- Call.cint n
+      alphaPtr <- Call.float alpha
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      yPtr <- Call.array y
+      incyPtr <- Call.cint incy
+      apPtr <- Call.ioarray ap
+      liftIO $ FFI.spr2 uploPtr nPtr alphaPtr xPtr incxPtr yPtr incyPtr apPtr
+
+swap ::
+   Int {- ^ n -} ->
+   IOCArray Int Float {- ^ sx -} ->
+   Int {- ^ incx -} ->
+   IOCArray Int Float {- ^ sy -} ->
+   Int {- ^ incy -} ->
+   IO ()
+swap n sx incx sy incy = do
+   sxDim0 <- Call.sizes1 <$> getBounds sx
+   syDim0 <- Call.sizes1 <$> getBounds sy
+   Call.assert "swap: 1+(n-1)*abs(incx) == sxDim0" (1+(n-1)*abs(incx) == sxDim0)
+   Call.assert "swap: 1+(n-1)*abs(incy) == syDim0" (1+(n-1)*abs(incy) == syDim0)
+   evalContT $ do
+      nPtr <- Call.cint n
+      sxPtr <- Call.ioarray sx
+      incxPtr <- Call.cint incx
+      syPtr <- Call.ioarray sy
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.swap nPtr sxPtr incxPtr syPtr incyPtr
+
+symm ::
+   Char {- ^ side -} ->
+   Char {- ^ uplo -} ->
+   Int {- ^ m -} ->
+   Float {- ^ alpha -} ->
+   CArray (Int,Int) Float {- ^ a -} ->
+   CArray (Int,Int) Float {- ^ b -} ->
+   Float {- ^ beta -} ->
+   IOCArray (Int,Int) Float {- ^ c -} ->
+   IO ()
+symm side uplo m alpha a b beta c = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   let (bDim0,bDim1) = Call.sizes2 $ bounds b
+   (cDim0,cDim1) <- Call.sizes2 <$> getBounds c
+   let _ka = aDim0
+   let lda = aDim1
+   let n = bDim0
+   let ldb = bDim1
+   let ldc = cDim1
+   Call.assert "symm: n == cDim0" (n == cDim0)
+   evalContT $ do
+      sidePtr <- Call.char side
+      uploPtr <- Call.char uplo
+      mPtr <- Call.cint m
+      nPtr <- Call.cint n
+      alphaPtr <- Call.float alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      bPtr <- Call.array b
+      ldbPtr <- Call.cint ldb
+      betaPtr <- Call.float beta
+      cPtr <- Call.ioarray c
+      ldcPtr <- Call.cint ldc
+      liftIO $ FFI.symm sidePtr uploPtr mPtr nPtr alphaPtr aPtr ldaPtr bPtr ldbPtr betaPtr cPtr ldcPtr
+
+symv ::
+   Char {- ^ uplo -} ->
+   Float {- ^ alpha -} ->
+   CArray (Int,Int) Float {- ^ a -} ->
+   CArray Int Float {- ^ x -} ->
+   Int {- ^ incx -} ->
+   Float {- ^ beta -} ->
+   IOCArray Int Float {- ^ y -} ->
+   Int {- ^ incy -} ->
+   IO ()
+symv uplo alpha a x incx beta y incy = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   let xDim0 = Call.sizes1 $ bounds x
+   yDim0 <- Call.sizes1 <$> getBounds y
+   let n = aDim0
+   let lda = aDim1
+   let _xSize = xDim0
+   let _ySize = yDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      nPtr <- Call.cint n
+      alphaPtr <- Call.float alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      betaPtr <- Call.float beta
+      yPtr <- Call.ioarray y
+      incyPtr <- Call.cint incy
+      liftIO $ FFI.symv uploPtr nPtr alphaPtr aPtr ldaPtr xPtr incxPtr betaPtr yPtr incyPtr
+
+syr ::
+   Char {- ^ uplo -} ->
+   Float {- ^ alpha -} ->
+   CArray Int Float {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IOCArray (Int,Int) Float {- ^ a -} ->
+   IO ()
+syr uplo alpha x incx a = do
+   let xDim0 = Call.sizes1 $ bounds x
+   (aDim0,aDim1) <- Call.sizes2 <$> getBounds a
+   let _xSize = xDim0
+   let n = aDim0
+   let lda = aDim1
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      nPtr <- Call.cint n
+      alphaPtr <- Call.float alpha
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      aPtr <- Call.ioarray a
+      ldaPtr <- Call.cint lda
+      liftIO $ FFI.syr uploPtr nPtr alphaPtr xPtr incxPtr aPtr ldaPtr
+
+syr2 ::
+   Char {- ^ uplo -} ->
+   Float {- ^ alpha -} ->
+   CArray Int Float {- ^ x -} ->
+   Int {- ^ incx -} ->
+   CArray Int Float {- ^ y -} ->
+   Int {- ^ incy -} ->
+   IOCArray (Int,Int) Float {- ^ a -} ->
+   IO ()
+syr2 uplo alpha x incx y incy a = do
+   let xDim0 = Call.sizes1 $ bounds x
+   let yDim0 = Call.sizes1 $ bounds y
+   (aDim0,aDim1) <- Call.sizes2 <$> getBounds a
+   let _xSize = xDim0
+   let _ySize = yDim0
+   let n = aDim0
+   let lda = aDim1
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      nPtr <- Call.cint n
+      alphaPtr <- Call.float alpha
+      xPtr <- Call.array x
+      incxPtr <- Call.cint incx
+      yPtr <- Call.array y
+      incyPtr <- Call.cint incy
+      aPtr <- Call.ioarray a
+      ldaPtr <- Call.cint lda
+      liftIO $ FFI.syr2 uploPtr nPtr alphaPtr xPtr incxPtr yPtr incyPtr aPtr ldaPtr
+
+syr2k ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Int {- ^ k -} ->
+   Float {- ^ alpha -} ->
+   CArray (Int,Int) Float {- ^ a -} ->
+   CArray (Int,Int) Float {- ^ b -} ->
+   Float {- ^ beta -} ->
+   IOCArray (Int,Int) Float {- ^ c -} ->
+   IO ()
+syr2k uplo trans k alpha a b beta c = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   let (bDim0,bDim1) = Call.sizes2 $ bounds b
+   (cDim0,cDim1) <- Call.sizes2 <$> getBounds c
+   let _ka = aDim0
+   let lda = aDim1
+   let _kb = bDim0
+   let ldb = bDim1
+   let n = cDim0
+   let ldc = cDim1
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      nPtr <- Call.cint n
+      kPtr <- Call.cint k
+      alphaPtr <- Call.float alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      bPtr <- Call.array b
+      ldbPtr <- Call.cint ldb
+      betaPtr <- Call.float beta
+      cPtr <- Call.ioarray c
+      ldcPtr <- Call.cint ldc
+      liftIO $ FFI.syr2k uploPtr transPtr nPtr kPtr alphaPtr aPtr ldaPtr bPtr ldbPtr betaPtr cPtr ldcPtr
+
+syrk ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Int {- ^ k -} ->
+   Float {- ^ alpha -} ->
+   CArray (Int,Int) Float {- ^ a -} ->
+   Float {- ^ beta -} ->
+   IOCArray (Int,Int) Float {- ^ c -} ->
+   IO ()
+syrk uplo trans k alpha a beta c = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   (cDim0,cDim1) <- Call.sizes2 <$> getBounds c
+   let _ka = aDim0
+   let lda = aDim1
+   let n = cDim0
+   let ldc = cDim1
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      nPtr <- Call.cint n
+      kPtr <- Call.cint k
+      alphaPtr <- Call.float alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      betaPtr <- Call.float beta
+      cPtr <- Call.ioarray c
+      ldcPtr <- Call.cint ldc
+      liftIO $ FFI.syrk uploPtr transPtr nPtr kPtr alphaPtr aPtr ldaPtr betaPtr cPtr ldcPtr
+
+tbmv ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Char {- ^ diag -} ->
+   Int {- ^ k -} ->
+   CArray (Int,Int) Float {- ^ a -} ->
+   IOCArray Int Float {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IO ()
+tbmv uplo trans diag k a x incx = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   xDim0 <- Call.sizes1 <$> getBounds x
+   let n = aDim0
+   let lda = aDim1
+   let _xSize = xDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      diagPtr <- Call.char diag
+      nPtr <- Call.cint n
+      kPtr <- Call.cint k
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      xPtr <- Call.ioarray x
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.tbmv uploPtr transPtr diagPtr nPtr kPtr aPtr ldaPtr xPtr incxPtr
+
+tbsv ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Char {- ^ diag -} ->
+   Int {- ^ k -} ->
+   CArray (Int,Int) Float {- ^ a -} ->
+   IOCArray Int Float {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IO ()
+tbsv uplo trans diag k a x incx = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   xDim0 <- Call.sizes1 <$> getBounds x
+   let n = aDim0
+   let lda = aDim1
+   let _xSize = xDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      diagPtr <- Call.char diag
+      nPtr <- Call.cint n
+      kPtr <- Call.cint k
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      xPtr <- Call.ioarray x
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.tbsv uploPtr transPtr diagPtr nPtr kPtr aPtr ldaPtr xPtr incxPtr
+
+tpmv ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Char {- ^ diag -} ->
+   Int {- ^ n -} ->
+   CArray Int Float {- ^ ap -} ->
+   IOCArray Int Float {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IO ()
+tpmv uplo trans diag n ap x incx = do
+   let apDim0 = Call.sizes1 $ bounds ap
+   xDim0 <- Call.sizes1 <$> getBounds x
+   let _apSize = apDim0
+   let _xSize = xDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      diagPtr <- Call.char diag
+      nPtr <- Call.cint n
+      apPtr <- Call.array ap
+      xPtr <- Call.ioarray x
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.tpmv uploPtr transPtr diagPtr nPtr apPtr xPtr incxPtr
+
+tpsv ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Char {- ^ diag -} ->
+   Int {- ^ n -} ->
+   CArray Int Float {- ^ ap -} ->
+   IOCArray Int Float {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IO ()
+tpsv uplo trans diag n ap x incx = do
+   let apDim0 = Call.sizes1 $ bounds ap
+   xDim0 <- Call.sizes1 <$> getBounds x
+   let _apSize = apDim0
+   let _xSize = xDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      diagPtr <- Call.char diag
+      nPtr <- Call.cint n
+      apPtr <- Call.array ap
+      xPtr <- Call.ioarray x
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.tpsv uploPtr transPtr diagPtr nPtr apPtr xPtr incxPtr
+
+trmm ::
+   Char {- ^ side -} ->
+   Char {- ^ uplo -} ->
+   Char {- ^ transa -} ->
+   Char {- ^ diag -} ->
+   Int {- ^ m -} ->
+   Float {- ^ alpha -} ->
+   CArray (Int,Int) Float {- ^ a -} ->
+   IOCArray (Int,Int) Float {- ^ b -} ->
+   IO ()
+trmm side uplo transa diag m alpha a b = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   (bDim0,bDim1) <- Call.sizes2 <$> getBounds b
+   let _k = aDim0
+   let lda = aDim1
+   let n = bDim0
+   let ldb = bDim1
+   evalContT $ do
+      sidePtr <- Call.char side
+      uploPtr <- Call.char uplo
+      transaPtr <- Call.char transa
+      diagPtr <- Call.char diag
+      mPtr <- Call.cint m
+      nPtr <- Call.cint n
+      alphaPtr <- Call.float alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      bPtr <- Call.ioarray b
+      ldbPtr <- Call.cint ldb
+      liftIO $ FFI.trmm sidePtr uploPtr transaPtr diagPtr mPtr nPtr alphaPtr aPtr ldaPtr bPtr ldbPtr
+
+trmv ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Char {- ^ diag -} ->
+   CArray (Int,Int) Float {- ^ a -} ->
+   IOCArray Int Float {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IO ()
+trmv uplo trans diag a x incx = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   xDim0 <- Call.sizes1 <$> getBounds x
+   let n = aDim0
+   let lda = aDim1
+   let _xSize = xDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      diagPtr <- Call.char diag
+      nPtr <- Call.cint n
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      xPtr <- Call.ioarray x
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.trmv uploPtr transPtr diagPtr nPtr aPtr ldaPtr xPtr incxPtr
+
+trsm ::
+   Char {- ^ side -} ->
+   Char {- ^ uplo -} ->
+   Char {- ^ transa -} ->
+   Char {- ^ diag -} ->
+   Int {- ^ m -} ->
+   Float {- ^ alpha -} ->
+   CArray (Int,Int) Float {- ^ a -} ->
+   IOCArray (Int,Int) Float {- ^ b -} ->
+   IO ()
+trsm side uplo transa diag m alpha a b = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   (bDim0,bDim1) <- Call.sizes2 <$> getBounds b
+   let _k = aDim0
+   let lda = aDim1
+   let n = bDim0
+   let ldb = bDim1
+   evalContT $ do
+      sidePtr <- Call.char side
+      uploPtr <- Call.char uplo
+      transaPtr <- Call.char transa
+      diagPtr <- Call.char diag
+      mPtr <- Call.cint m
+      nPtr <- Call.cint n
+      alphaPtr <- Call.float alpha
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      bPtr <- Call.ioarray b
+      ldbPtr <- Call.cint ldb
+      liftIO $ FFI.trsm sidePtr uploPtr transaPtr diagPtr mPtr nPtr alphaPtr aPtr ldaPtr bPtr ldbPtr
+
+trsv ::
+   Char {- ^ uplo -} ->
+   Char {- ^ trans -} ->
+   Char {- ^ diag -} ->
+   CArray (Int,Int) Float {- ^ a -} ->
+   IOCArray Int Float {- ^ x -} ->
+   Int {- ^ incx -} ->
+   IO ()
+trsv uplo trans diag a x incx = do
+   let (aDim0,aDim1) = Call.sizes2 $ bounds a
+   xDim0 <- Call.sizes1 <$> getBounds x
+   let n = aDim0
+   let lda = aDim1
+   let _xSize = xDim0
+   evalContT $ do
+      uploPtr <- Call.char uplo
+      transPtr <- Call.char trans
+      diagPtr <- Call.char diag
+      nPtr <- Call.cint n
+      aPtr <- Call.array a
+      ldaPtr <- Call.cint lda
+      xPtr <- Call.ioarray x
+      incxPtr <- Call.cint incx
+      liftIO $ FFI.trsv uploPtr transPtr diagPtr nPtr aPtr ldaPtr xPtr incxPtr
diff --git a/src/Numeric/BLAS/CArray/Generic.hs b/src/Numeric/BLAS/CArray/Generic.hs
new file mode 100644
--- /dev/null
+++ b/src/Numeric/BLAS/CArray/Generic.hs
@@ -0,0 +1,148 @@
+-- Do not edit! Automatically generated by create-lapack-ffi.
+module Numeric.BLAS.CArray.Generic (
+   axpy,
+   copy,
+   gbmv,
+   gemm,
+   gemv,
+   iamax,
+   scal,
+   swap,
+   symm,
+   syr2k,
+   syrk,
+   tbmv,
+   tbsv,
+   tpmv,
+   tpsv,
+   trmm,
+   trmv,
+   trsm,
+   trsv,
+   ) where
+
+import qualified Numeric.BLAS.CArray.ComplexDouble as Z
+import qualified Numeric.BLAS.CArray.ComplexFloat as C
+import qualified Numeric.BLAS.CArray.Double as D
+import qualified Numeric.BLAS.CArray.Float as S
+import qualified Numeric.Netlib.Class as Class
+
+import Data.Array.IOCArray (IOCArray)
+import Data.Array.CArray (CArray)
+
+import Foreign.C.Types (CInt)
+
+
+
+newtype AXPY a = AXPY {getAXPY :: Int -> a -> CArray Int a -> Int -> IOCArray Int a -> Int -> IO ()}
+
+axpy :: Class.Floating a => Int -> a -> CArray Int a -> Int -> IOCArray Int a -> Int -> IO ()
+axpy = getAXPY $ Class.switchFloating (AXPY S.axpy) (AXPY D.axpy) (AXPY C.axpy) (AXPY Z.axpy)
+
+
+newtype COPY a = COPY {getCOPY :: Int -> CArray Int a -> Int -> Int -> IO (CArray Int a)}
+
+copy :: Class.Floating a => Int -> CArray Int a -> Int -> Int -> IO (CArray Int a)
+copy = getCOPY $ Class.switchFloating (COPY S.copy) (COPY D.copy) (COPY C.copy) (COPY Z.copy)
+
+
+newtype GBMV a = GBMV {getGBMV :: Char -> Int -> Int -> Int -> a -> CArray (Int,Int) a -> CArray Int a -> Int -> a -> IOCArray Int a -> Int -> IO ()}
+
+gbmv :: Class.Floating a => Char -> Int -> Int -> Int -> a -> CArray (Int,Int) a -> CArray Int a -> Int -> a -> IOCArray Int a -> Int -> IO ()
+gbmv = getGBMV $ Class.switchFloating (GBMV S.gbmv) (GBMV D.gbmv) (GBMV C.gbmv) (GBMV Z.gbmv)
+
+
+newtype GEMM a = GEMM {getGEMM :: Char -> Char -> Int -> Int -> a -> CArray (Int,Int) a -> CArray (Int,Int) a -> a -> IOCArray (Int,Int) a -> IO ()}
+
+gemm :: Class.Floating a => Char -> Char -> Int -> Int -> a -> CArray (Int,Int) a -> CArray (Int,Int) a -> a -> IOCArray (Int,Int) a -> IO ()
+gemm = getGEMM $ Class.switchFloating (GEMM S.gemm) (GEMM D.gemm) (GEMM C.gemm) (GEMM Z.gemm)
+
+
+newtype GEMV a = GEMV {getGEMV :: Char -> Int -> a -> CArray (Int,Int) a -> CArray Int a -> Int -> a -> IOCArray Int a -> Int -> IO ()}
+
+gemv :: Class.Floating a => Char -> Int -> a -> CArray (Int,Int) a -> CArray Int a -> Int -> a -> IOCArray Int a -> Int -> IO ()
+gemv = getGEMV $ Class.switchFloating (GEMV S.gemv) (GEMV D.gemv) (GEMV C.gemv) (GEMV Z.gemv)
+
+
+newtype IAMAX a = IAMAX {getIAMAX :: Int -> CArray Int a -> Int -> IO CInt}
+
+iamax :: Class.Floating a => Int -> CArray Int a -> Int -> IO CInt
+iamax = getIAMAX $ Class.switchFloating (IAMAX S.iamax) (IAMAX D.iamax) (IAMAX C.iamax) (IAMAX Z.iamax)
+
+
+newtype SCAL a = SCAL {getSCAL :: Int -> a -> IOCArray Int a -> Int -> IO ()}
+
+scal :: Class.Floating a => Int -> a -> IOCArray Int a -> Int -> IO ()
+scal = getSCAL $ Class.switchFloating (SCAL S.scal) (SCAL D.scal) (SCAL C.scal) (SCAL Z.scal)
+
+
+newtype SWAP a = SWAP {getSWAP :: Int -> IOCArray Int a -> Int -> IOCArray Int a -> Int -> IO ()}
+
+swap :: Class.Floating a => Int -> IOCArray Int a -> Int -> IOCArray Int a -> Int -> IO ()
+swap = getSWAP $ Class.switchFloating (SWAP S.swap) (SWAP D.swap) (SWAP C.swap) (SWAP Z.swap)
+
+
+newtype SYMM a = SYMM {getSYMM :: Char -> Char -> Int -> a -> CArray (Int,Int) a -> CArray (Int,Int) a -> a -> IOCArray (Int,Int) a -> IO ()}
+
+symm :: Class.Floating a => Char -> Char -> Int -> a -> CArray (Int,Int) a -> CArray (Int,Int) a -> a -> IOCArray (Int,Int) a -> IO ()
+symm = getSYMM $ Class.switchFloating (SYMM S.symm) (SYMM D.symm) (SYMM C.symm) (SYMM Z.symm)
+
+
+newtype SYR2K a = SYR2K {getSYR2K :: Char -> Char -> Int -> a -> CArray (Int,Int) a -> CArray (Int,Int) a -> a -> IOCArray (Int,Int) a -> IO ()}
+
+syr2k :: Class.Floating a => Char -> Char -> Int -> a -> CArray (Int,Int) a -> CArray (Int,Int) a -> a -> IOCArray (Int,Int) a -> IO ()
+syr2k = getSYR2K $ Class.switchFloating (SYR2K S.syr2k) (SYR2K D.syr2k) (SYR2K C.syr2k) (SYR2K Z.syr2k)
+
+
+newtype SYRK a = SYRK {getSYRK :: Char -> Char -> Int -> a -> CArray (Int,Int) a -> a -> IOCArray (Int,Int) a -> IO ()}
+
+syrk :: Class.Floating a => Char -> Char -> Int -> a -> CArray (Int,Int) a -> a -> IOCArray (Int,Int) a -> IO ()
+syrk = getSYRK $ Class.switchFloating (SYRK S.syrk) (SYRK D.syrk) (SYRK C.syrk) (SYRK Z.syrk)
+
+
+newtype TBMV a = TBMV {getTBMV :: Char -> Char -> Char -> Int -> CArray (Int,Int) a -> IOCArray Int a -> Int -> IO ()}
+
+tbmv :: Class.Floating a => Char -> Char -> Char -> Int -> CArray (Int,Int) a -> IOCArray Int a -> Int -> IO ()
+tbmv = getTBMV $ Class.switchFloating (TBMV S.tbmv) (TBMV D.tbmv) (TBMV C.tbmv) (TBMV Z.tbmv)
+
+
+newtype TBSV a = TBSV {getTBSV :: Char -> Char -> Char -> Int -> CArray (Int,Int) a -> IOCArray Int a -> Int -> IO ()}
+
+tbsv :: Class.Floating a => Char -> Char -> Char -> Int -> CArray (Int,Int) a -> IOCArray Int a -> Int -> IO ()
+tbsv = getTBSV $ Class.switchFloating (TBSV S.tbsv) (TBSV D.tbsv) (TBSV C.tbsv) (TBSV Z.tbsv)
+
+
+newtype TPMV a = TPMV {getTPMV :: Char -> Char -> Char -> Int -> CArray Int a -> IOCArray Int a -> Int -> IO ()}
+
+tpmv :: Class.Floating a => Char -> Char -> Char -> Int -> CArray Int a -> IOCArray Int a -> Int -> IO ()
+tpmv = getTPMV $ Class.switchFloating (TPMV S.tpmv) (TPMV D.tpmv) (TPMV C.tpmv) (TPMV Z.tpmv)
+
+
+newtype TPSV a = TPSV {getTPSV :: Char -> Char -> Char -> Int -> CArray Int a -> IOCArray Int a -> Int -> IO ()}
+
+tpsv :: Class.Floating a => Char -> Char -> Char -> Int -> CArray Int a -> IOCArray Int a -> Int -> IO ()
+tpsv = getTPSV $ Class.switchFloating (TPSV S.tpsv) (TPSV D.tpsv) (TPSV C.tpsv) (TPSV Z.tpsv)
+
+
+newtype TRMM a = TRMM {getTRMM :: Char -> Char -> Char -> Char -> Int -> a -> CArray (Int,Int) a -> IOCArray (Int,Int) a -> IO ()}
+
+trmm :: Class.Floating a => Char -> Char -> Char -> Char -> Int -> a -> CArray (Int,Int) a -> IOCArray (Int,Int) a -> IO ()
+trmm = getTRMM $ Class.switchFloating (TRMM S.trmm) (TRMM D.trmm) (TRMM C.trmm) (TRMM Z.trmm)
+
+
+newtype TRMV a = TRMV {getTRMV :: Char -> Char -> Char -> CArray (Int,Int) a -> IOCArray Int a -> Int -> IO ()}
+
+trmv :: Class.Floating a => Char -> Char -> Char -> CArray (Int,Int) a -> IOCArray Int a -> Int -> IO ()
+trmv = getTRMV $ Class.switchFloating (TRMV S.trmv) (TRMV D.trmv) (TRMV C.trmv) (TRMV Z.trmv)
+
+
+newtype TRSM a = TRSM {getTRSM :: Char -> Char -> Char -> Char -> Int -> a -> CArray (Int,Int) a -> IOCArray (Int,Int) a -> IO ()}
+
+trsm :: Class.Floating a => Char -> Char -> Char -> Char -> Int -> a -> CArray (Int,Int) a -> IOCArray (Int,Int) a -> IO ()
+trsm = getTRSM $ Class.switchFloating (TRSM S.trsm) (TRSM D.trsm) (TRSM C.trsm) (TRSM Z.trsm)
+
+
+newtype TRSV a = TRSV {getTRSV :: Char -> Char -> Char -> CArray (Int,Int) a -> IOCArray Int a -> Int -> IO ()}
+
+trsv :: Class.Floating a => Char -> Char -> Char -> CArray (Int,Int) a -> IOCArray Int a -> Int -> IO ()
+trsv = getTRSV $ Class.switchFloating (TRSV S.trsv) (TRSV D.trsv) (TRSV C.trsv) (TRSV Z.trsv)
diff --git a/src/Numeric/BLAS/CArray/Miscellaneous.hs b/src/Numeric/BLAS/CArray/Miscellaneous.hs
new file mode 100644
--- /dev/null
+++ b/src/Numeric/BLAS/CArray/Miscellaneous.hs
@@ -0,0 +1,19 @@
+-- Do not edit! Automatically generated by create-lapack-ffi.
+module Numeric.BLAS.CArray.Miscellaneous where
+
+import qualified Numeric.BLAS.FFI.Miscellaneous as FFI
+import qualified Numeric.Netlib.CArray.Utility as Call
+
+import Control.Monad.Trans.Cont (evalContT)
+import Control.Monad.IO.Class (liftIO)
+
+
+lsame ::
+   Char {- ^ ca -} ->
+   Char {- ^ cb -} ->
+   IO Bool
+lsame ca cb = do
+   evalContT $ do
+      caPtr <- Call.char ca
+      cbPtr <- Call.char cb
+      liftIO $ FFI.lsame caPtr cbPtr
diff --git a/src/Numeric/BLAS/CArray/Real.hs b/src/Numeric/BLAS/CArray/Real.hs
new file mode 100644
--- /dev/null
+++ b/src/Numeric/BLAS/CArray/Real.hs
@@ -0,0 +1,251 @@
+-- Do not edit! Automatically generated by create-lapack-ffi.
+module Numeric.BLAS.CArray.Real (
+   asum,
+   axpy,
+   copy,
+   dot,
+   gbmv,
+   gemm,
+   gemv,
+   ger,
+   iamax,
+   nrm2,
+   rot,
+   rotg,
+   rotm,
+   rotmg,
+   sbmv,
+   scal,
+   spmv,
+   spr,
+   spr2,
+   swap,
+   symm,
+   symv,
+   syr,
+   syr2,
+   syr2k,
+   syrk,
+   tbmv,
+   tbsv,
+   tpmv,
+   tpsv,
+   trmm,
+   trmv,
+   trsm,
+   trsv,
+   ) where
+
+import qualified Numeric.BLAS.CArray.Double as D
+import qualified Numeric.BLAS.CArray.Float as S
+import qualified Numeric.Netlib.Class as Class
+
+import Data.Array.IOCArray (IOCArray)
+import Data.Array.CArray (CArray)
+
+import Foreign.C.Types (CInt)
+
+
+
+newtype ASUM a = ASUM {getASUM :: Int -> CArray Int a -> Int -> IO a}
+
+asum :: Class.Real a => Int -> CArray Int a -> Int -> IO a
+asum = getASUM $ Class.switchReal (ASUM S.asum) (ASUM D.asum)
+
+
+newtype AXPY a = AXPY {getAXPY :: Int -> a -> CArray Int a -> Int -> IOCArray Int a -> Int -> IO ()}
+
+axpy :: Class.Real a => Int -> a -> CArray Int a -> Int -> IOCArray Int a -> Int -> IO ()
+axpy = getAXPY $ Class.switchReal (AXPY S.axpy) (AXPY D.axpy)
+
+
+newtype COPY a = COPY {getCOPY :: Int -> CArray Int a -> Int -> Int -> IO (CArray Int a)}
+
+copy :: Class.Real a => Int -> CArray Int a -> Int -> Int -> IO (CArray Int a)
+copy = getCOPY $ Class.switchReal (COPY S.copy) (COPY D.copy)
+
+
+newtype DOT a = DOT {getDOT :: Int -> CArray Int a -> Int -> CArray Int a -> Int -> IO a}
+
+dot :: Class.Real a => Int -> CArray Int a -> Int -> CArray Int a -> Int -> IO a
+dot = getDOT $ Class.switchReal (DOT S.dot) (DOT D.dot)
+
+
+newtype GBMV a = GBMV {getGBMV :: Char -> Int -> Int -> Int -> a -> CArray (Int,Int) a -> CArray Int a -> Int -> a -> IOCArray Int a -> Int -> IO ()}
+
+gbmv :: Class.Real a => Char -> Int -> Int -> Int -> a -> CArray (Int,Int) a -> CArray Int a -> Int -> a -> IOCArray Int a -> Int -> IO ()
+gbmv = getGBMV $ Class.switchReal (GBMV S.gbmv) (GBMV D.gbmv)
+
+
+newtype GEMM a = GEMM {getGEMM :: Char -> Char -> Int -> Int -> a -> CArray (Int,Int) a -> CArray (Int,Int) a -> a -> IOCArray (Int,Int) a -> IO ()}
+
+gemm :: Class.Real a => Char -> Char -> Int -> Int -> a -> CArray (Int,Int) a -> CArray (Int,Int) a -> a -> IOCArray (Int,Int) a -> IO ()
+gemm = getGEMM $ Class.switchReal (GEMM S.gemm) (GEMM D.gemm)
+
+
+newtype GEMV a = GEMV {getGEMV :: Char -> Int -> a -> CArray (Int,Int) a -> CArray Int a -> Int -> a -> IOCArray Int a -> Int -> IO ()}
+
+gemv :: Class.Real a => Char -> Int -> a -> CArray (Int,Int) a -> CArray Int a -> Int -> a -> IOCArray Int a -> Int -> IO ()
+gemv = getGEMV $ Class.switchReal (GEMV S.gemv) (GEMV D.gemv)
+
+
+newtype GER a = GER {getGER :: Int -> a -> CArray Int a -> Int -> CArray Int a -> Int -> IOCArray (Int,Int) a -> IO ()}
+
+ger :: Class.Real a => Int -> a -> CArray Int a -> Int -> CArray Int a -> Int -> IOCArray (Int,Int) a -> IO ()
+ger = getGER $ Class.switchReal (GER S.ger) (GER D.ger)
+
+
+newtype IAMAX a = IAMAX {getIAMAX :: Int -> CArray Int a -> Int -> IO CInt}
+
+iamax :: Class.Real a => Int -> CArray Int a -> Int -> IO CInt
+iamax = getIAMAX $ Class.switchReal (IAMAX S.iamax) (IAMAX D.iamax)
+
+
+newtype NRM2 a = NRM2 {getNRM2 :: Int -> CArray Int a -> Int -> IO a}
+
+nrm2 :: Class.Real a => Int -> CArray Int a -> Int -> IO a
+nrm2 = getNRM2 $ Class.switchReal (NRM2 S.nrm2) (NRM2 D.nrm2)
+
+
+newtype ROT a = ROT {getROT :: Int -> IOCArray Int a -> Int -> IOCArray Int a -> Int -> a -> a -> IO ()}
+
+rot :: Class.Real a => Int -> IOCArray Int a -> Int -> IOCArray Int a -> Int -> a -> a -> IO ()
+rot = getROT $ Class.switchReal (ROT S.rot) (ROT D.rot)
+
+
+newtype ROTG a = ROTG {getROTG :: a -> a -> IO (a, a)}
+
+rotg :: Class.Real a => a -> a -> IO (a, a)
+rotg = getROTG $ Class.switchReal (ROTG S.rotg) (ROTG D.rotg)
+
+
+newtype ROTM a = ROTM {getROTM :: Int -> IOCArray Int a -> Int -> IOCArray Int a -> Int -> CArray Int a -> IO ()}
+
+rotm :: Class.Real a => Int -> IOCArray Int a -> Int -> IOCArray Int a -> Int -> CArray Int a -> IO ()
+rotm = getROTM $ Class.switchReal (ROTM S.rotm) (ROTM D.rotm)
+
+
+newtype ROTMG a = ROTMG {getROTMG :: a -> a -> a -> a -> IO (a, a, a, CArray Int a)}
+
+rotmg :: Class.Real a => a -> a -> a -> a -> IO (a, a, a, CArray Int a)
+rotmg = getROTMG $ Class.switchReal (ROTMG S.rotmg) (ROTMG D.rotmg)
+
+
+newtype SBMV a = SBMV {getSBMV :: Char -> Int -> a -> CArray (Int,Int) a -> CArray Int a -> Int -> a -> IOCArray Int a -> Int -> IO ()}
+
+sbmv :: Class.Real a => Char -> Int -> a -> CArray (Int,Int) a -> CArray Int a -> Int -> a -> IOCArray Int a -> Int -> IO ()
+sbmv = getSBMV $ Class.switchReal (SBMV S.sbmv) (SBMV D.sbmv)
+
+
+newtype SCAL a = SCAL {getSCAL :: Int -> a -> IOCArray Int a -> Int -> IO ()}
+
+scal :: Class.Real a => Int -> a -> IOCArray Int a -> Int -> IO ()
+scal = getSCAL $ Class.switchReal (SCAL S.scal) (SCAL D.scal)
+
+
+newtype SPMV a = SPMV {getSPMV :: Char -> Int -> a -> CArray Int a -> CArray Int a -> Int -> a -> IOCArray Int a -> Int -> IO ()}
+
+spmv :: Class.Real a => Char -> Int -> a -> CArray Int a -> CArray Int a -> Int -> a -> IOCArray Int a -> Int -> IO ()
+spmv = getSPMV $ Class.switchReal (SPMV S.spmv) (SPMV D.spmv)
+
+
+newtype SPR a = SPR {getSPR :: Char -> Int -> a -> CArray Int a -> Int -> IOCArray Int a -> IO ()}
+
+spr :: Class.Real a => Char -> Int -> a -> CArray Int a -> Int -> IOCArray Int a -> IO ()
+spr = getSPR $ Class.switchReal (SPR S.spr) (SPR D.spr)
+
+
+newtype SPR2 a = SPR2 {getSPR2 :: Char -> Int -> a -> CArray Int a -> Int -> CArray Int a -> Int -> IOCArray Int a -> IO ()}
+
+spr2 :: Class.Real a => Char -> Int -> a -> CArray Int a -> Int -> CArray Int a -> Int -> IOCArray Int a -> IO ()
+spr2 = getSPR2 $ Class.switchReal (SPR2 S.spr2) (SPR2 D.spr2)
+
+
+newtype SWAP a = SWAP {getSWAP :: Int -> IOCArray Int a -> Int -> IOCArray Int a -> Int -> IO ()}
+
+swap :: Class.Real a => Int -> IOCArray Int a -> Int -> IOCArray Int a -> Int -> IO ()
+swap = getSWAP $ Class.switchReal (SWAP S.swap) (SWAP D.swap)
+
+
+newtype SYMM a = SYMM {getSYMM :: Char -> Char -> Int -> a -> CArray (Int,Int) a -> CArray (Int,Int) a -> a -> IOCArray (Int,Int) a -> IO ()}
+
+symm :: Class.Real a => Char -> Char -> Int -> a -> CArray (Int,Int) a -> CArray (Int,Int) a -> a -> IOCArray (Int,Int) a -> IO ()
+symm = getSYMM $ Class.switchReal (SYMM S.symm) (SYMM D.symm)
+
+
+newtype SYMV a = SYMV {getSYMV :: Char -> a -> CArray (Int,Int) a -> CArray Int a -> Int -> a -> IOCArray Int a -> Int -> IO ()}
+
+symv :: Class.Real a => Char -> a -> CArray (Int,Int) a -> CArray Int a -> Int -> a -> IOCArray Int a -> Int -> IO ()
+symv = getSYMV $ Class.switchReal (SYMV S.symv) (SYMV D.symv)
+
+
+newtype SYR a = SYR {getSYR :: Char -> a -> CArray Int a -> Int -> IOCArray (Int,Int) a -> IO ()}
+
+syr :: Class.Real a => Char -> a -> CArray Int a -> Int -> IOCArray (Int,Int) a -> IO ()
+syr = getSYR $ Class.switchReal (SYR S.syr) (SYR D.syr)
+
+
+newtype SYR2 a = SYR2 {getSYR2 :: Char -> a -> CArray Int a -> Int -> CArray Int a -> Int -> IOCArray (Int,Int) a -> IO ()}
+
+syr2 :: Class.Real a => Char -> a -> CArray Int a -> Int -> CArray Int a -> Int -> IOCArray (Int,Int) a -> IO ()
+syr2 = getSYR2 $ Class.switchReal (SYR2 S.syr2) (SYR2 D.syr2)
+
+
+newtype SYR2K a = SYR2K {getSYR2K :: Char -> Char -> Int -> a -> CArray (Int,Int) a -> CArray (Int,Int) a -> a -> IOCArray (Int,Int) a -> IO ()}
+
+syr2k :: Class.Real a => Char -> Char -> Int -> a -> CArray (Int,Int) a -> CArray (Int,Int) a -> a -> IOCArray (Int,Int) a -> IO ()
+syr2k = getSYR2K $ Class.switchReal (SYR2K S.syr2k) (SYR2K D.syr2k)
+
+
+newtype SYRK a = SYRK {getSYRK :: Char -> Char -> Int -> a -> CArray (Int,Int) a -> a -> IOCArray (Int,Int) a -> IO ()}
+
+syrk :: Class.Real a => Char -> Char -> Int -> a -> CArray (Int,Int) a -> a -> IOCArray (Int,Int) a -> IO ()
+syrk = getSYRK $ Class.switchReal (SYRK S.syrk) (SYRK D.syrk)
+
+
+newtype TBMV a = TBMV {getTBMV :: Char -> Char -> Char -> Int -> CArray (Int,Int) a -> IOCArray Int a -> Int -> IO ()}
+
+tbmv :: Class.Real a => Char -> Char -> Char -> Int -> CArray (Int,Int) a -> IOCArray Int a -> Int -> IO ()
+tbmv = getTBMV $ Class.switchReal (TBMV S.tbmv) (TBMV D.tbmv)
+
+
+newtype TBSV a = TBSV {getTBSV :: Char -> Char -> Char -> Int -> CArray (Int,Int) a -> IOCArray Int a -> Int -> IO ()}
+
+tbsv :: Class.Real a => Char -> Char -> Char -> Int -> CArray (Int,Int) a -> IOCArray Int a -> Int -> IO ()
+tbsv = getTBSV $ Class.switchReal (TBSV S.tbsv) (TBSV D.tbsv)
+
+
+newtype TPMV a = TPMV {getTPMV :: Char -> Char -> Char -> Int -> CArray Int a -> IOCArray Int a -> Int -> IO ()}
+
+tpmv :: Class.Real a => Char -> Char -> Char -> Int -> CArray Int a -> IOCArray Int a -> Int -> IO ()
+tpmv = getTPMV $ Class.switchReal (TPMV S.tpmv) (TPMV D.tpmv)
+
+
+newtype TPSV a = TPSV {getTPSV :: Char -> Char -> Char -> Int -> CArray Int a -> IOCArray Int a -> Int -> IO ()}
+
+tpsv :: Class.Real a => Char -> Char -> Char -> Int -> CArray Int a -> IOCArray Int a -> Int -> IO ()
+tpsv = getTPSV $ Class.switchReal (TPSV S.tpsv) (TPSV D.tpsv)
+
+
+newtype TRMM a = TRMM {getTRMM :: Char -> Char -> Char -> Char -> Int -> a -> CArray (Int,Int) a -> IOCArray (Int,Int) a -> IO ()}
+
+trmm :: Class.Real a => Char -> Char -> Char -> Char -> Int -> a -> CArray (Int,Int) a -> IOCArray (Int,Int) a -> IO ()
+trmm = getTRMM $ Class.switchReal (TRMM S.trmm) (TRMM D.trmm)
+
+
+newtype TRMV a = TRMV {getTRMV :: Char -> Char -> Char -> CArray (Int,Int) a -> IOCArray Int a -> Int -> IO ()}
+
+trmv :: Class.Real a => Char -> Char -> Char -> CArray (Int,Int) a -> IOCArray Int a -> Int -> IO ()
+trmv = getTRMV $ Class.switchReal (TRMV S.trmv) (TRMV D.trmv)
+
+
+newtype TRSM a = TRSM {getTRSM :: Char -> Char -> Char -> Char -> Int -> a -> CArray (Int,Int) a -> IOCArray (Int,Int) a -> IO ()}
+
+trsm :: Class.Real a => Char -> Char -> Char -> Char -> Int -> a -> CArray (Int,Int) a -> IOCArray (Int,Int) a -> IO ()
+trsm = getTRSM $ Class.switchReal (TRSM S.trsm) (TRSM D.trsm)
+
+
+newtype TRSV a = TRSV {getTRSV :: Char -> Char -> Char -> CArray (Int,Int) a -> IOCArray Int a -> Int -> IO ()}
+
+trsv :: Class.Real a => Char -> Char -> Char -> CArray (Int,Int) a -> IOCArray Int a -> Int -> IO ()
+trsv = getTRSV $ Class.switchReal (TRSV S.trsv) (TRSV D.trsv)
