diff --git a/arrayfire.cabal b/arrayfire.cabal
--- a/arrayfire.cabal
+++ b/arrayfire.cabal
@@ -1,16 +1,16 @@
+cabal-version:       3.0
 name:                arrayfire
-version:             0.6.0.0
+version:             0.7.0.0
 synopsis:            Haskell bindings to the ArrayFire general-purpose GPU library
 homepage:            https://github.com/arrayfire/arrayfire-haskell
-license:             BSD3
+license:             BSD-3-Clause
 license-file:        LICENSE
 author:              David Johnson
 maintainer:          djohnson.m@gmail.com
-copyright:           David Johnson (c) 2018-2020
+copyright:           David Johnson (c) 2018-2023
 category:            Math
 build-type:          Custom
 extra-source-files:  CHANGELOG.md
-cabal-version:       >=1.10
 description:         High-level Haskell bindings to the ArrayFire General-purpose GPU library
     .
     <<https://user-images.githubusercontent.com/875324/59819388-9ff83f00-92f5-11e9-9ac0-51eef200c716.png>>
@@ -75,8 +75,8 @@
     ArrayFire.Internal.Types
     ArrayFire.Internal.Util
     ArrayFire.Internal.Vision
-  build-tools:
-    hsc2hs
+  build-tool-depends:
+    hsc2hs:hsc2hs
   extra-libraries:
     af
   c-sources:
@@ -145,10 +145,11 @@
     base < 5,
     directory,
     hspec,
-    hspec-discover,
     QuickCheck,
     quickcheck-classes,
     vector
+  build-tool-depends:
+    hspec-discover:hspec-discover
   default-language:
     Haskell2010
   other-modules:
diff --git a/src/ArrayFire/Arith.hs b/src/ArrayFire/Arith.hs
--- a/src/ArrayFire/Arith.hs
+++ b/src/ArrayFire/Arith.hs
@@ -719,7 +719,7 @@
 cast afArr =
   coerce $ afArr `op1` (\x y -> af_cast x y dtyp)
     where
-      dtyp = afType (Proxy @ b)
+      dtyp = afType (Proxy @b)
 
 -- | Find the minimum of two 'Array's
 --
diff --git a/src/ArrayFire/Array.hs b/src/ArrayFire/Array.hs
--- a/src/ArrayFire/Array.hs
+++ b/src/ArrayFire/Array.hs
@@ -196,7 +196,7 @@
       Array <$> newForeignPtr af_release_array_finalizer arr
     where
       size  = Prelude.product dims
-      dType = afType (Proxy @ array)
+      dType = afType (Proxy @array)
 
 -- af_err af_create_handle(af_array *arr, const unsigned ndims, const dim_t * const dims, const af_dtype type);
 
@@ -482,7 +482,7 @@
 toVector arr@(Array fptr) = do
   unsafePerformIO . mask_ . withForeignPtr fptr $ \arrPtr -> do
     let len = getElements arr
-        size = len * getSizeOf (Proxy @ a)
+        size = len * getSizeOf (Proxy @a)
     ptr <- mallocBytes (len * size)
     throwAFError =<< af_get_data_ptr (castPtr ptr) arrPtr
     newFptr <- newForeignPtr finalizerFree ptr
diff --git a/src/ArrayFire/Data.hs b/src/ArrayFire/Data.hs
--- a/src/ArrayFire/Data.hs
+++ b/src/ArrayFire/Data.hs
@@ -91,7 +91,7 @@
         cast $ constant' dims (realToFrac (unsafeCoerce val :: Float))
       | otherwise -> error "constant: Invalid array fire type"
   where
-    dtyp = afType (Proxy @ a)
+    dtyp = afType (Proxy @a)
 
     constant'
       :: [Int]
@@ -112,7 +112,7 @@
               ptr
           where
             n = fromIntegral (length dims')
-            typ = afType (Proxy @ Double)
+            typ = afType (Proxy @Double)
 
     -- | Creates an 'Array (Complex Double)' from a scalar val'ue
     --
@@ -139,7 +139,7 @@
             ptr
           where
             n = fromIntegral (length dims')
-            typ = afType (Proxy @ (Complex arr))
+            typ = afType (Proxy @(Complex arr))
 
     -- | Creates an 'Array Int64' from a scalar val'ue
     --
@@ -221,7 +221,7 @@
         ptr
       where
         n = fromIntegral (length dims)
-        typ = afType (Proxy @ a)
+        typ = afType (Proxy @a)
 
 -- | Create an sequence [0, dims.elements() - 1] and modify to specified dimensions dims and then tile it according to tile_dims.
 --
@@ -266,7 +266,7 @@
       af_release_array_finalizer
         ptr
       where
-        typ = afType (Proxy @ a)
+        typ = afType (Proxy @a)
 
 -- | Creates the identity `Array` from given dimensions
 --
@@ -293,7 +293,7 @@
         ptr
       where
         n = fromIntegral (length dims)
-        typ = afType (Proxy @ a)
+        typ = afType (Proxy @a)
 
 -- | Create a diagonal matrix from input array when extract is set to false
 --
diff --git a/src/ArrayFire/Image.hs b/src/ArrayFire/Image.hs
--- a/src/ArrayFire/Image.hs
+++ b/src/ArrayFire/Image.hs
@@ -423,7 +423,7 @@
 regions in' (fromConnectivity -> conn) =
   in' `op1` (\ptr k -> af_regions ptr k conn dtype)
     where
-      dtype = afType (Proxy @ a)
+      dtype = afType (Proxy @a)
 
 -- | Sobel Operators.
 --
diff --git a/src/ArrayFire/Internal/Arith.hs b/src/ArrayFire/Internal/Arith.hs
new file mode 100644
--- /dev/null
+++ b/src/ArrayFire/Internal/Arith.hs
@@ -0,0 +1,150 @@
+{-# LINE 1 "src/ArrayFire/Internal/Arith.hsc" #-}
+{-# LANGUAGE CPP #-}
+module ArrayFire.Internal.Arith where
+
+import ArrayFire.Internal.Defines
+
+import Foreign.Ptr
+import Foreign.C.Types
+
+
+foreign import ccall unsafe "af_add"
+    af_add :: Ptr AFArray -> AFArray -> AFArray -> CBool -> IO AFErr
+foreign import ccall unsafe "af_sub"
+    af_sub :: Ptr AFArray -> AFArray -> AFArray -> CBool -> IO AFErr
+foreign import ccall unsafe "af_mul"
+    af_mul :: Ptr AFArray -> AFArray -> AFArray -> CBool -> IO AFErr
+foreign import ccall unsafe "af_div"
+    af_div :: Ptr AFArray -> AFArray -> AFArray -> CBool -> IO AFErr
+foreign import ccall unsafe "af_lt"
+    af_lt :: Ptr AFArray -> AFArray -> AFArray -> CBool -> IO AFErr
+foreign import ccall unsafe "af_gt"
+    af_gt :: Ptr AFArray -> AFArray -> AFArray -> CBool -> IO AFErr
+foreign import ccall unsafe "af_le"
+    af_le :: Ptr AFArray -> AFArray -> AFArray -> CBool -> IO AFErr
+foreign import ccall unsafe "af_ge"
+    af_ge :: Ptr AFArray -> AFArray -> AFArray -> CBool -> IO AFErr
+foreign import ccall unsafe "af_eq"
+    af_eq :: Ptr AFArray -> AFArray -> AFArray -> CBool -> IO AFErr
+foreign import ccall unsafe "af_neq"
+    af_neq :: Ptr AFArray -> AFArray -> AFArray -> CBool -> IO AFErr
+foreign import ccall unsafe "af_and"
+    af_and :: Ptr AFArray -> AFArray -> AFArray -> CBool -> IO AFErr
+foreign import ccall unsafe "af_or"
+    af_or :: Ptr AFArray -> AFArray -> AFArray -> CBool -> IO AFErr
+foreign import ccall unsafe "af_not"
+    af_not :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_bitand"
+    af_bitand :: Ptr AFArray -> AFArray -> AFArray -> CBool -> IO AFErr
+foreign import ccall unsafe "af_bitor"
+    af_bitor :: Ptr AFArray -> AFArray -> AFArray -> CBool -> IO AFErr
+foreign import ccall unsafe "af_bitxor"
+    af_bitxor :: Ptr AFArray -> AFArray -> AFArray -> CBool -> IO AFErr
+foreign import ccall unsafe "af_bitshiftl"
+    af_bitshiftl :: Ptr AFArray -> AFArray -> AFArray -> CBool -> IO AFErr
+foreign import ccall unsafe "af_bitshiftr"
+    af_bitshiftr :: Ptr AFArray -> AFArray -> AFArray -> CBool -> IO AFErr
+foreign import ccall unsafe "af_cast"
+    af_cast :: Ptr AFArray -> AFArray -> AFDtype -> IO AFErr
+foreign import ccall unsafe "af_minof"
+    af_minof :: Ptr AFArray -> AFArray -> AFArray -> CBool -> IO AFErr
+foreign import ccall unsafe "af_maxof"
+    af_maxof :: Ptr AFArray -> AFArray -> AFArray -> CBool -> IO AFErr
+foreign import ccall unsafe "af_clamp"
+    af_clamp :: Ptr AFArray -> AFArray -> AFArray -> AFArray -> CBool -> IO AFErr
+foreign import ccall unsafe "af_rem"
+    af_rem :: Ptr AFArray -> AFArray -> AFArray -> CBool -> IO AFErr
+foreign import ccall unsafe "af_mod"
+    af_mod :: Ptr AFArray -> AFArray -> AFArray -> CBool -> IO AFErr
+foreign import ccall unsafe "af_abs"
+    af_abs :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_arg"
+    af_arg :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_sign"
+    af_sign :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_round"
+    af_round :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_trunc"
+    af_trunc :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_floor"
+    af_floor :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_ceil"
+    af_ceil :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_hypot"
+    af_hypot :: Ptr AFArray -> AFArray -> AFArray -> CBool -> IO AFErr
+foreign import ccall unsafe "af_sin"
+    af_sin :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_cos"
+    af_cos :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_tan"
+    af_tan :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_asin"
+    af_asin :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_acos"
+    af_acos :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_atan"
+    af_atan :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_atan2"
+    af_atan2 :: Ptr AFArray -> AFArray -> AFArray -> CBool -> IO AFErr
+foreign import ccall unsafe "af_cplx2"
+    af_cplx2 :: Ptr AFArray -> AFArray -> AFArray -> CBool -> IO AFErr
+foreign import ccall unsafe "af_cplx"
+    af_cplx :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_real"
+    af_real :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_imag"
+    af_imag :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_conjg"
+    af_conjg :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_sinh"
+    af_sinh :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_cosh"
+    af_cosh :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_tanh"
+    af_tanh :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_asinh"
+    af_asinh :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_acosh"
+    af_acosh :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_atanh"
+    af_atanh :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_root"
+    af_root :: Ptr AFArray -> AFArray -> AFArray -> CBool -> IO AFErr
+foreign import ccall unsafe "af_pow"
+    af_pow :: Ptr AFArray -> AFArray -> AFArray -> CBool -> IO AFErr
+foreign import ccall unsafe "af_pow2"
+    af_pow2 :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_exp"
+    af_exp :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_sigmoid"
+    af_sigmoid :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_expm1"
+    af_expm1 :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_erf"
+    af_erf :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_erfc"
+    af_erfc :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_log"
+    af_log :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_log1p"
+    af_log1p :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_log10"
+    af_log10 :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_log2"
+    af_log2 :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_sqrt"
+    af_sqrt :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_cbrt"
+    af_cbrt :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_factorial"
+    af_factorial :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_tgamma"
+    af_tgamma :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_lgamma"
+    af_lgamma :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_iszero"
+    af_iszero :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_isinf"
+    af_isinf :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_isnan"
+    af_isnan :: Ptr AFArray -> AFArray -> IO AFErr
diff --git a/src/ArrayFire/Internal/Array.hs b/src/ArrayFire/Internal/Array.hs
new file mode 100644
--- /dev/null
+++ b/src/ArrayFire/Internal/Array.hs
@@ -0,0 +1,72 @@
+{-# LINE 1 "src/ArrayFire/Internal/Array.hsc" #-}
+{-# LANGUAGE CPP #-}
+module ArrayFire.Internal.Array where
+
+import ArrayFire.Internal.Defines
+
+import Foreign.Ptr
+import Foreign.C.Types
+
+
+foreign import ccall unsafe "af_create_array"
+    af_create_array :: Ptr AFArray -> Ptr () -> CUInt -> Ptr DimT -> AFDtype -> IO AFErr
+foreign import ccall unsafe "af_create_handle"
+    af_create_handle :: Ptr AFArray -> CUInt -> Ptr DimT -> AFDtype -> IO AFErr
+foreign import ccall unsafe "af_copy_array"
+    af_copy_array :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_write_array"
+    af_write_array :: AFArray -> Ptr () -> CSize -> AFSource -> IO AFErr
+foreign import ccall unsafe "af_get_data_ptr"
+    af_get_data_ptr :: Ptr () -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_release_array"
+    af_release_array :: AFArray -> IO AFErr
+foreign import ccall unsafe "af_retain_array"
+    af_retain_array :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_get_data_ref_count"
+    af_get_data_ref_count :: Ptr CInt -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_eval"
+    af_eval :: AFArray -> IO AFErr
+foreign import ccall unsafe "af_eval_multiple"
+    af_eval_multiple :: CInt -> Ptr AFArray -> IO AFErr
+foreign import ccall unsafe "af_set_manual_eval_flag"
+    af_set_manual_eval_flag :: CBool -> IO AFErr
+foreign import ccall unsafe "af_get_manual_eval_flag"
+    af_get_manual_eval_flag :: Ptr CBool -> IO AFErr
+foreign import ccall unsafe "af_get_elements"
+    af_get_elements :: Ptr DimT -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_get_type"
+    af_get_type :: Ptr AFDtype -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_get_dims"
+    af_get_dims :: Ptr DimT -> Ptr DimT -> Ptr DimT -> Ptr DimT -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_get_numdims"
+    af_get_numdims :: Ptr CUInt -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_is_empty"
+    af_is_empty :: Ptr CBool -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_is_scalar"
+    af_is_scalar :: Ptr CBool -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_is_row"
+    af_is_row :: Ptr CBool -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_is_column"
+    af_is_column :: Ptr CBool -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_is_vector"
+    af_is_vector :: Ptr CBool -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_is_complex"
+    af_is_complex :: Ptr CBool -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_is_real"
+    af_is_real :: Ptr CBool -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_is_double"
+    af_is_double :: Ptr CBool -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_is_single"
+    af_is_single :: Ptr CBool -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_is_realfloating"
+    af_is_realfloating :: Ptr CBool -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_is_floating"
+    af_is_floating :: Ptr CBool -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_is_integer"
+    af_is_integer :: Ptr CBool -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_is_bool"
+    af_is_bool :: Ptr CBool -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_is_sparse"
+    af_is_sparse :: Ptr CBool -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_get_scalar"
+    af_get_scalar :: Ptr () -> AFArray -> IO AFErr
diff --git a/src/ArrayFire/Internal/BLAS.hs b/src/ArrayFire/Internal/BLAS.hs
new file mode 100644
--- /dev/null
+++ b/src/ArrayFire/Internal/BLAS.hs
@@ -0,0 +1,20 @@
+{-# LINE 1 "src/ArrayFire/Internal/BLAS.hsc" #-}
+{-# LANGUAGE CPP #-}
+module ArrayFire.Internal.BLAS where
+
+import ArrayFire.Internal.Defines
+
+import Foreign.Ptr
+import Foreign.C.Types
+
+
+foreign import ccall unsafe "af_matmul"
+    af_matmul :: Ptr AFArray -> AFArray -> AFArray -> AFMatProp -> AFMatProp -> IO AFErr
+foreign import ccall unsafe "af_dot"
+    af_dot :: Ptr AFArray -> AFArray -> AFArray -> AFMatProp -> AFMatProp -> IO AFErr
+foreign import ccall unsafe "af_dot_all"
+    af_dot_all :: Ptr Double -> Ptr Double -> AFArray -> AFArray -> AFMatProp -> AFMatProp -> IO AFErr
+foreign import ccall unsafe "af_transpose"
+    af_transpose :: Ptr AFArray -> AFArray -> CBool -> IO AFErr
+foreign import ccall unsafe "af_transpose_inplace"
+    af_transpose_inplace :: AFArray -> CBool -> IO AFErr
diff --git a/src/ArrayFire/Internal/Backend.hs b/src/ArrayFire/Internal/Backend.hs
new file mode 100644
--- /dev/null
+++ b/src/ArrayFire/Internal/Backend.hs
@@ -0,0 +1,22 @@
+{-# LINE 1 "src/ArrayFire/Internal/Backend.hsc" #-}
+{-# LANGUAGE CPP #-}
+module ArrayFire.Internal.Backend where
+
+import ArrayFire.Internal.Defines
+
+import Foreign.Ptr
+import Foreign.C.Types
+
+
+foreign import ccall unsafe "af_set_backend"
+    af_set_backend :: AFBackend -> IO AFErr
+foreign import ccall unsafe "af_get_backend_count"
+    af_get_backend_count :: Ptr CUInt -> IO AFErr
+foreign import ccall unsafe "af_get_available_backends"
+    af_get_available_backends :: Ptr CInt -> IO AFErr
+foreign import ccall unsafe "af_get_backend_id"
+    af_get_backend_id :: Ptr AFBackend -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_get_active_backend"
+    af_get_active_backend :: Ptr AFBackend -> IO AFErr
+foreign import ccall unsafe "af_get_device_id"
+    af_get_device_id :: Ptr CInt -> AFArray -> IO AFErr
diff --git a/src/ArrayFire/Internal/Data.hs b/src/ArrayFire/Internal/Data.hs
new file mode 100644
--- /dev/null
+++ b/src/ArrayFire/Internal/Data.hs
@@ -0,0 +1,58 @@
+{-# LINE 1 "src/ArrayFire/Internal/Data.hsc" #-}
+{-# LANGUAGE CPP #-}
+module ArrayFire.Internal.Data where
+
+import ArrayFire.Internal.Defines
+
+import Foreign.Ptr
+import Foreign.C.Types
+
+
+foreign import ccall unsafe "af_constant"
+    af_constant :: Ptr AFArray -> Double -> CUInt -> Ptr DimT -> AFDtype -> IO AFErr
+foreign import ccall unsafe "af_constant_complex"
+    af_constant_complex :: Ptr AFArray -> Double -> Double -> CUInt -> Ptr DimT -> AFDtype -> IO AFErr
+foreign import ccall unsafe "af_constant_long"
+    af_constant_long :: Ptr AFArray -> IntL -> CUInt -> Ptr DimT -> IO AFErr
+foreign import ccall unsafe "af_constant_ulong"
+    af_constant_ulong :: Ptr AFArray -> UIntL -> CUInt -> Ptr DimT -> IO AFErr
+foreign import ccall unsafe "af_range"
+    af_range :: Ptr AFArray -> CUInt -> Ptr DimT -> CInt -> AFDtype -> IO AFErr
+foreign import ccall unsafe "af_iota"
+    af_iota :: Ptr AFArray -> CUInt -> Ptr DimT -> CUInt -> Ptr DimT -> AFDtype -> IO AFErr
+foreign import ccall unsafe "af_identity"
+    af_identity :: Ptr AFArray -> CUInt -> Ptr DimT -> AFDtype -> IO AFErr
+foreign import ccall unsafe "af_diag_create"
+    af_diag_create :: Ptr AFArray -> AFArray -> CInt -> IO AFErr
+foreign import ccall unsafe "af_diag_extract"
+    af_diag_extract :: Ptr AFArray -> AFArray -> CInt -> IO AFErr
+foreign import ccall unsafe "af_join"
+    af_join :: Ptr AFArray -> CInt -> AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_join_many"
+    af_join_many :: Ptr AFArray -> CInt -> CUInt -> Ptr AFArray -> IO AFErr
+foreign import ccall unsafe "af_tile"
+    af_tile :: Ptr AFArray -> AFArray -> CUInt -> CUInt -> CUInt -> CUInt -> IO AFErr
+foreign import ccall unsafe "af_reorder"
+    af_reorder :: Ptr AFArray -> AFArray -> CUInt -> CUInt -> CUInt -> CUInt -> IO AFErr
+foreign import ccall unsafe "af_shift"
+    af_shift :: Ptr AFArray -> AFArray -> CInt -> CInt -> CInt -> CInt -> IO AFErr
+foreign import ccall unsafe "af_moddims"
+    af_moddims :: Ptr AFArray -> AFArray -> CUInt -> Ptr DimT -> IO AFErr
+foreign import ccall unsafe "af_flat"
+    af_flat :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_flip"
+    af_flip :: Ptr AFArray -> AFArray -> CUInt -> IO AFErr
+foreign import ccall unsafe "af_lower"
+    af_lower :: Ptr AFArray -> AFArray -> CBool -> IO AFErr
+foreign import ccall unsafe "af_upper"
+    af_upper :: Ptr AFArray -> AFArray -> CBool -> IO AFErr
+foreign import ccall unsafe "af_select"
+    af_select :: Ptr AFArray -> AFArray -> AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_select_scalar_r"
+    af_select_scalar_r :: Ptr AFArray -> AFArray -> AFArray -> Double -> IO AFErr
+foreign import ccall unsafe "af_select_scalar_l"
+    af_select_scalar_l :: Ptr AFArray -> AFArray -> Double -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_replace"
+    af_replace :: AFArray -> AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_replace_scalar"
+    af_replace_scalar :: AFArray -> AFArray -> Double -> IO AFErr
diff --git a/src/ArrayFire/Internal/Defines.hs b/src/ArrayFire/Internal/Defines.hs
new file mode 100644
--- /dev/null
+++ b/src/ArrayFire/Internal/Defines.hs
@@ -0,0 +1,586 @@
+{-# LINE 1 "src/ArrayFire/Internal/Defines.hsc" #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE CPP             #-}
+{-# LANGUAGE RecordWildCards #-}
+module ArrayFire.Internal.Defines where
+
+import Foreign.Ptr
+import Foreign.C.Types
+import Foreign.Storable
+
+
+
+
+
+
+afVersion :: Integer
+afVersion = 38
+{-# LINE 17 "src/ArrayFire/Internal/Defines.hsc" #-}
+
+newtype AFErr = AFErr { afError :: CInt }
+  deriving (Show, Eq)
+
+afSuccess  :: AFErr
+afSuccess  = AFErr 0
+afErrNoMem  :: AFErr
+afErrNoMem  = AFErr 101
+afErrDriver  :: AFErr
+afErrDriver  = AFErr 102
+afErrRuntime  :: AFErr
+afErrRuntime  = AFErr 103
+afErrInvalidArray  :: AFErr
+afErrInvalidArray  = AFErr 201
+afErrArg  :: AFErr
+afErrArg  = AFErr 202
+afErrSize  :: AFErr
+afErrSize  = AFErr 203
+afErrType  :: AFErr
+afErrType  = AFErr 204
+afErrDiffType  :: AFErr
+afErrDiffType  = AFErr 205
+afErrBatch  :: AFErr
+afErrBatch  = AFErr 207
+afErrDevice  :: AFErr
+afErrDevice  = AFErr 208
+afErrNotSupported  :: AFErr
+afErrNotSupported  = AFErr 301
+afErrNotConfigured  :: AFErr
+afErrNotConfigured  = AFErr 302
+afErrNonFree  :: AFErr
+afErrNonFree  = AFErr 303
+afErrNoDbl  :: AFErr
+afErrNoDbl  = AFErr 401
+afErrNoGfx  :: AFErr
+afErrNoGfx  = AFErr 402
+afErrLoadLib  :: AFErr
+afErrLoadLib  = AFErr 501
+afErrLoadSym  :: AFErr
+afErrLoadSym  = AFErr 502
+afErrArrBkndMismatch  :: AFErr
+afErrArrBkndMismatch  = AFErr 503
+afErrInternal  :: AFErr
+afErrInternal  = AFErr 998
+afErrUnknown  :: AFErr
+afErrUnknown  = AFErr 999
+
+{-# LINE 44 "src/ArrayFire/Internal/Defines.hsc" #-}
+
+-- | Low-level for representation of ArrayFire types
+
+-- | AFDType
+-- Newtype over ArrayFire's internal type tag
+newtype AFDtype = AFDtype
+  { afDType :: CInt
+  -- ^ Value corresponding to ArrayFire type
+  } deriving (Show, Eq, Storable)
+
+-- | Enums for AFDtype
+f32  :: AFDtype
+f32  = AFDtype 0
+c32  :: AFDtype
+c32  = AFDtype 1
+f64  :: AFDtype
+f64  = AFDtype 2
+c64  :: AFDtype
+c64  = AFDtype 3
+b8  :: AFDtype
+b8  = AFDtype 4
+s32  :: AFDtype
+s32  = AFDtype 5
+u32  :: AFDtype
+u32  = AFDtype 6
+u8  :: AFDtype
+u8  = AFDtype 7
+s64  :: AFDtype
+s64  = AFDtype 8
+u64  :: AFDtype
+u64  = AFDtype 9
+s16  :: AFDtype
+s16  = AFDtype 10
+u16  :: AFDtype
+u16  = AFDtype 11
+
+{-# LINE 69 "src/ArrayFire/Internal/Defines.hsc" #-}
+
+newtype AFSource = AFSource CInt
+  deriving (Ord, Show, Eq)
+
+afDevice  :: AFSource
+afDevice  = AFSource 0
+afHost  :: AFSource
+afHost  = AFSource 1
+
+{-# LINE 77 "src/ArrayFire/Internal/Defines.hsc" #-}
+
+afMaxDims :: Integer
+afMaxDims = 4
+{-# LINE 80 "src/ArrayFire/Internal/Defines.hsc" #-}
+
+newtype AFSomeEnum = AFSomeEnum Int
+  deriving (Ord, Show, Eq, Storable)
+
+afSomeEnum  :: AFSomeEnum
+afSomeEnum  = AFSomeEnum 0
+
+{-# LINE 87 "src/ArrayFire/Internal/Defines.hsc" #-}
+
+
+-- // A handle for an internal array object
+type AFArray = Ptr ()
+type AFFeatures = Ptr ()
+type AFRandomEngine = Ptr ()
+
+-- // A handle for an internal array object
+type AFWindow = Ptr ()
+
+newtype AFInterpType = AFInterpType CInt
+  deriving (Ord, Show, Eq, Storable)
+
+afInterpNearest  :: AFInterpType
+afInterpNearest  = AFInterpType 0
+afInterpLinear  :: AFInterpType
+afInterpLinear  = AFInterpType 1
+afInterpBilinear  :: AFInterpType
+afInterpBilinear  = AFInterpType 2
+afInterpCubic  :: AFInterpType
+afInterpCubic  = AFInterpType 3
+afInterpLower  :: AFInterpType
+afInterpLower  = AFInterpType 4
+afInterpLinearCosine  :: AFInterpType
+afInterpLinearCosine  = AFInterpType 5
+afInterpBilinearCosine  :: AFInterpType
+afInterpBilinearCosine  = AFInterpType 6
+afInterpBicubic  :: AFInterpType
+afInterpBicubic  = AFInterpType 7
+afInterpCubicSpline  :: AFInterpType
+afInterpCubicSpline  = AFInterpType 8
+afInterpBicubicSpline  :: AFInterpType
+afInterpBicubicSpline  = AFInterpType 9
+
+{-# LINE 112 "src/ArrayFire/Internal/Defines.hsc" #-}
+
+newtype AFBorderType = AFBorderType CInt
+  deriving (Ord, Show, Eq, Storable)
+
+afBorderPadZero  :: AFBorderType
+afBorderPadZero  = AFBorderType 0
+afPadSym  :: AFBorderType
+afPadSym  = AFBorderType 1
+
+{-# LINE 120 "src/ArrayFire/Internal/Defines.hsc" #-}
+
+newtype AFConnectivity = AFConnectivity CInt
+  deriving (Ord, Show, Eq, Storable)
+
+afConnectivity4  :: AFConnectivity
+afConnectivity4  = AFConnectivity 4
+afConnectivity8  :: AFConnectivity
+afConnectivity8  = AFConnectivity 8
+
+{-# LINE 128 "src/ArrayFire/Internal/Defines.hsc" #-}
+
+newtype AFConvMode = AFConvMode CInt
+  deriving (Ord, Show, Eq, Storable)
+
+afConvDefault  :: AFConvMode
+afConvDefault  = AFConvMode 0
+afConvExpand  :: AFConvMode
+afConvExpand  = AFConvMode 1
+
+{-# LINE 136 "src/ArrayFire/Internal/Defines.hsc" #-}
+
+newtype AFConvDomain = AFConvDomain CInt
+  deriving (Ord, Show, Eq, Storable)
+
+afConvAuto  :: AFConvDomain
+afConvAuto  = AFConvDomain 0
+afConvSpatial  :: AFConvDomain
+afConvSpatial  = AFConvDomain 1
+afConvFreq  :: AFConvDomain
+afConvFreq  = AFConvDomain 2
+
+{-# LINE 145 "src/ArrayFire/Internal/Defines.hsc" #-}
+
+newtype AFMatchType = AFMatchType CInt
+  deriving (Ord, Show, Eq, Storable)
+
+afSAD   :: AFMatchType
+afSAD   = AFMatchType 0
+afZSAD  :: AFMatchType
+afZSAD  = AFMatchType 1
+afLSAD  :: AFMatchType
+afLSAD  = AFMatchType 2
+afSSD   :: AFMatchType
+afSSD   = AFMatchType 3
+afZSSD  :: AFMatchType
+afZSSD  = AFMatchType 4
+afLSSD  :: AFMatchType
+afLSSD  = AFMatchType 5
+afNCC   :: AFMatchType
+afNCC   = AFMatchType 6
+afZNCC  :: AFMatchType
+afZNCC  = AFMatchType 7
+afSHD   :: AFMatchType
+afSHD   = AFMatchType 8
+
+{-# LINE 160 "src/ArrayFire/Internal/Defines.hsc" #-}
+
+newtype AFYccStd = AFYccStd Int
+  deriving (Ord, Show, Eq, Storable)
+
+afYcc601  :: AFYccStd
+afYcc601  = AFYccStd 601
+afYcc709  :: AFYccStd
+afYcc709  = AFYccStd 709
+afYcc2020  :: AFYccStd
+afYcc2020  = AFYccStd 2020
+
+{-# LINE 169 "src/ArrayFire/Internal/Defines.hsc" #-}
+
+newtype AFCSpace = AFCSpace Int
+  deriving (Ord, Show, Eq, Storable)
+
+afGray  :: AFCSpace
+afGray  = AFCSpace 0
+afRgb  :: AFCSpace
+afRgb  = AFCSpace 1
+afHsv  :: AFCSpace
+afHsv  = AFCSpace 2
+afYCbCr  :: AFCSpace
+afYCbCr  = AFCSpace 3
+
+{-# LINE 179 "src/ArrayFire/Internal/Defines.hsc" #-}
+
+newtype AFMatProp = AFMatProp Int
+  deriving (Ord, Show, Eq, Storable)
+
+afMatNone  :: AFMatProp
+afMatNone  = AFMatProp 0
+afMatTrans  :: AFMatProp
+afMatTrans  = AFMatProp 1
+afMatCtrans  :: AFMatProp
+afMatCtrans  = AFMatProp 2
+afMatConj  :: AFMatProp
+afMatConj  = AFMatProp 4
+afMatUpper  :: AFMatProp
+afMatUpper  = AFMatProp 32
+afMatLower  :: AFMatProp
+afMatLower  = AFMatProp 64
+afMatDiagUnit  :: AFMatProp
+afMatDiagUnit  = AFMatProp 128
+afMatSym  :: AFMatProp
+afMatSym  = AFMatProp 512
+afMatPosdef  :: AFMatProp
+afMatPosdef  = AFMatProp 1024
+afMatOrthog  :: AFMatProp
+afMatOrthog  = AFMatProp 2048
+afMatTriDiag  :: AFMatProp
+afMatTriDiag  = AFMatProp 4096
+afMatBlockDiag  :: AFMatProp
+afMatBlockDiag  = AFMatProp 8192
+
+{-# LINE 197 "src/ArrayFire/Internal/Defines.hsc" #-}
+
+newtype AFNormType = AFNormType Int
+  deriving (Ord, Show, Eq, Storable)
+
+afNormVector1  :: AFNormType
+afNormVector1  = AFNormType 0
+afNormVectorInf  :: AFNormType
+afNormVectorInf  = AFNormType 1
+afNormVector2  :: AFNormType
+afNormVector2  = AFNormType 2
+afNormVectorP  :: AFNormType
+afNormVectorP  = AFNormType 3
+afNormMatrix1  :: AFNormType
+afNormMatrix1  = AFNormType 4
+afNormMatrixInf  :: AFNormType
+afNormMatrixInf  = AFNormType 5
+afNormMatrix2  :: AFNormType
+afNormMatrix2  = AFNormType 6
+afNormMatrixLPq  :: AFNormType
+afNormMatrixLPq  = AFNormType 7
+afNormEuclid  :: AFNormType
+afNormEuclid  = AFNormType 2
+
+{-# LINE 212 "src/ArrayFire/Internal/Defines.hsc" #-}
+
+newtype AFImageFormat = AFImageFormat Int
+  deriving (Ord, Show, Eq, Storable)
+
+afFIFBmp  :: AFImageFormat
+afFIFBmp  = AFImageFormat 0
+afFIFIco  :: AFImageFormat
+afFIFIco  = AFImageFormat 1
+afFIFJpeg  :: AFImageFormat
+afFIFJpeg  = AFImageFormat 2
+afFIFJng  :: AFImageFormat
+afFIFJng  = AFImageFormat 3
+afFIFPng  :: AFImageFormat
+afFIFPng  = AFImageFormat 13
+afFIFPpm  :: AFImageFormat
+afFIFPpm  = AFImageFormat 14
+afFIFPpmraw  :: AFImageFormat
+afFIFPpmraw  = AFImageFormat 15
+afFIFTiff  :: AFImageFormat
+afFIFTiff  = AFImageFormat 18
+afFIFPsd  :: AFImageFormat
+afFIFPsd  = AFImageFormat 20
+afFIFHdr  :: AFImageFormat
+afFIFHdr  = AFImageFormat 26
+afFIFExr  :: AFImageFormat
+afFIFExr  = AFImageFormat 29
+afFIFJp2  :: AFImageFormat
+afFIFJp2  = AFImageFormat 31
+afFIFRaw  :: AFImageFormat
+afFIFRaw  = AFImageFormat 34
+
+{-# LINE 231 "src/ArrayFire/Internal/Defines.hsc" #-}
+
+newtype AFMomentType = AFMomentType Int
+  deriving (Ord, Show, Eq, Storable)
+
+afMomentM00  :: AFMomentType
+afMomentM00  = AFMomentType 1
+afMomentM01  :: AFMomentType
+afMomentM01  = AFMomentType 2
+afMomentM10  :: AFMomentType
+afMomentM10  = AFMomentType 4
+afMomentM11  :: AFMomentType
+afMomentM11  = AFMomentType 8
+afMomentFirstOrder  :: AFMomentType
+afMomentFirstOrder  = AFMomentType 15
+
+{-# LINE 242 "src/ArrayFire/Internal/Defines.hsc" #-}
+
+newtype AFHomographyType = AFHomographyType CInt
+  deriving (Ord, Show, Eq, Storable)
+
+afHomographyRansac  :: AFHomographyType
+afHomographyRansac  = AFHomographyType 0
+afHomographyLmeds   :: AFHomographyType
+afHomographyLmeds   = AFHomographyType 1
+
+{-# LINE 250 "src/ArrayFire/Internal/Defines.hsc" #-}
+
+newtype AFBackend = AFBackend CInt
+  deriving (Ord, Show, Eq, Storable)
+
+afBackendDefault  :: AFBackend
+afBackendDefault  = AFBackend 0
+afBackendCpu      :: AFBackend
+afBackendCpu      = AFBackend 0
+afBackendCuda     :: AFBackend
+afBackendCuda     = AFBackend 2
+afBackendOpencl   :: AFBackend
+afBackendOpencl   = AFBackend 4
+
+{-# LINE 260 "src/ArrayFire/Internal/Defines.hsc" #-}
+
+newtype AFID = AFID CInt
+  deriving (Ord, Show, Eq, Storable)
+
+
+{-# LINE 267 "src/ArrayFire/Internal/Defines.hsc" #-}
+
+newtype AFBinaryOp = AFBinaryOp CInt
+  deriving (Ord, Show, Eq, Storable)
+
+afBinaryAdd   :: AFBinaryOp
+afBinaryAdd   = AFBinaryOp 0
+afBinaryMul   :: AFBinaryOp
+afBinaryMul   = AFBinaryOp 1
+afBinaryMin   :: AFBinaryOp
+afBinaryMin   = AFBinaryOp 2
+afBinaryMax   :: AFBinaryOp
+afBinaryMax   = AFBinaryOp 3
+
+{-# LINE 277 "src/ArrayFire/Internal/Defines.hsc" #-}
+
+newtype AFRandomEngineType = AFRandomEngineType CInt
+  deriving (Ord, Show, Eq, Storable)
+
+afRandomEnginePhilox4X3210  :: AFRandomEngineType
+afRandomEnginePhilox4X3210  = AFRandomEngineType 100
+afRandomEngineThreefry2X3216  :: AFRandomEngineType
+afRandomEngineThreefry2X3216  = AFRandomEngineType 200
+afRandomEngineMersenneGp11213  :: AFRandomEngineType
+afRandomEngineMersenneGp11213  = AFRandomEngineType 300
+afRandomEnginePhilox   :: AFRandomEngineType
+afRandomEnginePhilox   = AFRandomEngineType 100
+afRandomEngineThreefry  :: AFRandomEngineType
+afRandomEngineThreefry  = AFRandomEngineType 200
+afRandomEngineMersenne  :: AFRandomEngineType
+afRandomEngineMersenne  = AFRandomEngineType 300
+afRandomEngineDefault  :: AFRandomEngineType
+afRandomEngineDefault  = AFRandomEngineType 100
+
+{-# LINE 290 "src/ArrayFire/Internal/Defines.hsc" #-}
+
+newtype AFColorMap = AFColorMap CInt
+  deriving (Ord, Show, Eq, Storable)
+
+afColormapDefault  :: AFColorMap
+afColormapDefault  = AFColorMap 0
+afColormapSpectrum :: AFColorMap
+afColormapSpectrum = AFColorMap 1
+afColormapColors   :: AFColorMap
+afColormapColors   = AFColorMap 2
+afColormapRed      :: AFColorMap
+afColormapRed      = AFColorMap 3
+afColormapMood     :: AFColorMap
+afColormapMood     = AFColorMap 4
+afColormapHeat     :: AFColorMap
+afColormapHeat     = AFColorMap 5
+afColormapBlue     :: AFColorMap
+afColormapBlue     = AFColorMap 6
+afColormapInferno  :: AFColorMap
+afColormapInferno  = AFColorMap 7
+afColormapMagma    :: AFColorMap
+afColormapMagma    = AFColorMap 8
+afColormapPlasma   :: AFColorMap
+afColormapPlasma   = AFColorMap 9
+afColormapViridis  :: AFColorMap
+afColormapViridis  = AFColorMap 10
+
+{-# LINE 307 "src/ArrayFire/Internal/Defines.hsc" #-}
+
+newtype AFMarkerType = AFMarkerType CInt
+  deriving (Ord, Show, Eq, Storable)
+
+afMarkerNone      :: AFMarkerType
+afMarkerNone      = AFMarkerType 0
+afMarkerPoint     :: AFMarkerType
+afMarkerPoint     = AFMarkerType 1
+afMarkerCircle    :: AFMarkerType
+afMarkerCircle    = AFMarkerType 2
+afMarkerSquare    :: AFMarkerType
+afMarkerSquare    = AFMarkerType 3
+afMarkerTriangle  :: AFMarkerType
+afMarkerTriangle  = AFMarkerType 4
+afMarkerCross     :: AFMarkerType
+afMarkerCross     = AFMarkerType 5
+afMarkerPlus      :: AFMarkerType
+afMarkerPlus      = AFMarkerType 6
+afMarkerStar      :: AFMarkerType
+afMarkerStar      = AFMarkerType 7
+
+{-# LINE 321 "src/ArrayFire/Internal/Defines.hsc" #-}
+
+newtype AFCannyThreshold = AFCannyThreshold CInt
+  deriving (Ord, Show, Eq, Storable)
+
+afCannyThresholdManual  :: AFCannyThreshold
+afCannyThresholdManual  = AFCannyThreshold 0
+afCannyThresholdAutoOtsu  :: AFCannyThreshold
+afCannyThresholdAutoOtsu  = AFCannyThreshold 1
+
+{-# LINE 329 "src/ArrayFire/Internal/Defines.hsc" #-}
+
+newtype AFStorage = AFStorage CInt
+  deriving (Ord, Show, Eq, Storable)
+
+afStorageDense  :: AFStorage
+afStorageDense  = AFStorage 0
+afStorageCsr  :: AFStorage
+afStorageCsr  = AFStorage 1
+afStorageCsc  :: AFStorage
+afStorageCsc  = AFStorage 2
+afStorageCoo  :: AFStorage
+afStorageCoo  = AFStorage 3
+
+{-# LINE 339 "src/ArrayFire/Internal/Defines.hsc" #-}
+
+newtype AFFluxFunction = AFFluxFunction CInt
+  deriving (Ord, Show, Eq, Storable)
+
+afFluxQuadratic  :: AFFluxFunction
+afFluxQuadratic  = AFFluxFunction 1
+afFluxExponential  :: AFFluxFunction
+afFluxExponential  = AFFluxFunction 2
+afFluxDefault  :: AFFluxFunction
+afFluxDefault  = AFFluxFunction 0
+
+{-# LINE 348 "src/ArrayFire/Internal/Defines.hsc" #-}
+
+newtype AFDiffusionEq = AFDiffusionEq CInt
+  deriving (Ord, Show, Eq, Storable)
+
+afDiffusionGrad  :: AFDiffusionEq
+afDiffusionGrad  = AFDiffusionEq 1
+afDiffusionMcde  :: AFDiffusionEq
+afDiffusionMcde  = AFDiffusionEq 2
+afDiffusionDefault  :: AFDiffusionEq
+afDiffusionDefault  = AFDiffusionEq 0
+
+{-# LINE 357 "src/ArrayFire/Internal/Defines.hsc" #-}
+
+newtype AFTopkFunction = AFTopkFunction CInt
+  deriving (Ord, Show, Eq, Storable)
+
+afTopkMin  :: AFTopkFunction
+afTopkMin  = AFTopkFunction 1
+afTopkMax  :: AFTopkFunction
+afTopkMax  = AFTopkFunction 2
+afTopkDefault  :: AFTopkFunction
+afTopkDefault  = AFTopkFunction 0
+
+{-# LINE 366 "src/ArrayFire/Internal/Defines.hsc" #-}
+
+newtype AFIterativeDeconvAlgo = AFIterativeDeconvAlgo CInt
+  deriving (Ord, Show, Eq, Storable)
+
+-- #{enum AFIterativeDeconvAlgo, AFIterativeDeconvAlgo
+-- , afIterativeDeconvLandweber       = AF_ITERATIVE_DECONV_LANDWEBER
+-- , afIterativeDeconvRichardsonlucy  = AF_ITERATIVE_DECONV_RICHARDSONLUCY
+-- , afIterativeDeconvDefault         = AF_ITERATIVE_DECONV_DEFAULT
+-- }
+
+newtype AFInverseDeconvAlgo = AFInverseDeconvAlgo CInt
+  deriving (Ord, Show, Eq, Storable)
+
+
+{-# LINE 383 "src/ArrayFire/Internal/Defines.hsc" #-}
+
+-- newtype AFVarBias = AFVarBias Int
+--   deriving (Ord, Show, Eq)
+
+-- #{enum AFVarBias, AFVarBias
+--  , afVarianceDefault = AF_VARIANCE_DEFAULT
+--  , afVarianceSample = AF_VARIANCE_SAMPLE
+--  , afVariancePopulation = AF_VARIANCE_POPULATION
+-- }
+
+newtype DimT = DimT CLLong
+  deriving (Show, Eq, Storable, Num, Integral, Real, Enum, Ord)
+
+newtype UIntL = UIntL CULLong
+  deriving (Show, Eq, Storable, Num, Integral, Real, Enum, Ord)
+
+newtype IntL = IntL CLLong
+  deriving (Show, Eq, Storable, Num, Integral, Real, Enum, Ord)
+
+-- static const af_seq af_span = {1, 1, 0};
+
+-- newtype AFCLPlatform = AFCLPlatform Int
+--   deriving (Show, Eq)
+
+-- #{enum AFCLPlatform, AFCLPlatform
+--  , afclPlatformAMD = AFCL_PLATFORM_AMD
+--  , afclPlatformApple = AFCL_PLATFORM_APPLE
+--  , afclPlatformIntel = AFCL_PLATFORM_INTEL
+--  , afclPlatformNVIDIA = AFCL_PLATFORM_NVIDIA
+--  , afclPlatformBEIGNET = AFCL_PLATFORM_BEIGNET
+--  , afclPlatformPOCL = AFCL_PLATFORM_POCL
+--  , afclPlatformUnknown = AFCL_PLATFORM_UNKNOWN
+-- }
+
+-- newtype DeviceType = DeviceType Int
+--   deriving (Show, Eq)
+
+-- #{enum DeviceType, DeviceType
+--  , afCLDeviceTypeCPU = AFCL_DEVICE_TYPE_CPU
+--  , afCLDeviceTypeGPU = AFCL_DEVICE_TYPE_GPU
+--  , afCLDeviceTypeAccel = AFCL_DEVICE_TYPE_ACCEL
+--  , afCLDeviceTypeUnknown = AFCL_DEVICE_TYPE_UNKNOWN
+-- }
diff --git a/src/ArrayFire/Internal/Device.hs b/src/ArrayFire/Internal/Device.hs
new file mode 100644
--- /dev/null
+++ b/src/ArrayFire/Internal/Device.hs
@@ -0,0 +1,62 @@
+{-# LINE 1 "src/ArrayFire/Internal/Device.hsc" #-}
+{-# LANGUAGE CPP #-}
+module ArrayFire.Internal.Device where
+
+import ArrayFire.Internal.Defines
+
+import Foreign.Ptr
+import Foreign.C.Types
+
+
+foreign import ccall unsafe "af_info"
+    af_info :: IO AFErr
+foreign import ccall unsafe "af_init"
+    af_init :: IO AFErr
+foreign import ccall unsafe "af_info_string"
+    af_info_string :: Ptr (Ptr CChar) -> CBool -> IO AFErr
+foreign import ccall unsafe "af_device_info"
+    af_device_info :: Ptr CChar -> Ptr CChar -> Ptr CChar -> Ptr CChar -> IO AFErr
+foreign import ccall unsafe "af_get_device_count"
+    af_get_device_count :: Ptr CInt -> IO AFErr
+foreign import ccall unsafe "af_get_dbl_support"
+    af_get_dbl_support :: Ptr CBool -> CInt -> IO AFErr
+foreign import ccall unsafe "af_set_device"
+    af_set_device :: CInt -> IO AFErr
+foreign import ccall unsafe "af_get_device"
+    af_get_device :: Ptr CInt -> IO AFErr
+foreign import ccall unsafe "af_sync"
+    af_sync :: CInt -> IO AFErr
+foreign import ccall unsafe "af_alloc_device"
+    af_alloc_device :: Ptr (Ptr ()) -> DimT -> IO AFErr
+foreign import ccall unsafe "af_free_device"
+    af_free_device :: Ptr () -> IO AFErr
+foreign import ccall unsafe "af_alloc_pinned"
+    af_alloc_pinned :: Ptr (Ptr ()) -> DimT -> IO AFErr
+foreign import ccall unsafe "af_free_pinned"
+    af_free_pinned :: Ptr () -> IO AFErr
+foreign import ccall unsafe "af_alloc_host"
+    af_alloc_host :: Ptr (Ptr ()) -> DimT -> IO AFErr
+foreign import ccall unsafe "af_free_host"
+    af_free_host :: Ptr () -> IO AFErr
+foreign import ccall unsafe "af_device_array"
+    af_device_array :: Ptr AFArray -> Ptr () -> CUInt -> Ptr DimT -> AFDtype -> IO AFErr
+foreign import ccall unsafe "af_device_mem_info"
+    af_device_mem_info :: Ptr CSize -> Ptr CSize -> Ptr CSize -> Ptr CSize -> IO AFErr
+foreign import ccall unsafe "af_print_mem_info"
+    af_print_mem_info :: Ptr CChar -> CInt -> IO AFErr
+foreign import ccall unsafe "af_device_gc"
+    af_device_gc :: IO AFErr
+foreign import ccall unsafe "af_set_mem_step_size"
+    af_set_mem_step_size :: CSize -> IO AFErr
+foreign import ccall unsafe "af_get_mem_step_size"
+    af_get_mem_step_size :: Ptr CSize -> IO AFErr
+foreign import ccall unsafe "af_lock_device_ptr"
+    af_lock_device_ptr :: AFArray -> IO AFErr
+foreign import ccall unsafe "af_unlock_device_ptr"
+    af_unlock_device_ptr :: AFArray -> IO AFErr
+foreign import ccall unsafe "af_lock_array"
+    af_lock_array :: AFArray -> IO AFErr
+foreign import ccall unsafe "af_is_locked_array"
+    af_is_locked_array :: Ptr CBool -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_get_device_ptr"
+    af_get_device_ptr :: Ptr (Ptr ()) -> AFArray -> IO AFErr
diff --git a/src/ArrayFire/Internal/Exception.hs b/src/ArrayFire/Internal/Exception.hs
new file mode 100644
--- /dev/null
+++ b/src/ArrayFire/Internal/Exception.hs
@@ -0,0 +1,14 @@
+{-# LINE 1 "src/ArrayFire/Internal/Exception.hsc" #-}
+{-# LANGUAGE CPP #-}
+module ArrayFire.Internal.Exception where
+
+import ArrayFire.Internal.Defines
+
+import Foreign.Ptr
+import Foreign.C.Types
+
+
+foreign import ccall unsafe "af_get_last_error"
+    af_get_last_error :: Ptr (Ptr CChar) -> Ptr DimT -> IO ()
+foreign import ccall unsafe "af_err_to_string"
+    af_err_to_string :: AFErr -> IO (Ptr CChar)
diff --git a/src/ArrayFire/Internal/Features.hs b/src/ArrayFire/Internal/Features.hs
new file mode 100644
--- /dev/null
+++ b/src/ArrayFire/Internal/Features.hs
@@ -0,0 +1,28 @@
+{-# LINE 1 "src/ArrayFire/Internal/Features.hsc" #-}
+{-# LANGUAGE CPP #-}
+module ArrayFire.Internal.Features where
+
+import ArrayFire.Internal.Defines
+
+import Foreign.Ptr
+import Foreign.C.Types
+
+
+foreign import ccall unsafe "af_create_features"
+    af_create_features :: Ptr AFFeatures -> DimT -> IO AFErr
+foreign import ccall unsafe "af_retain_features"
+    af_retain_features :: Ptr AFFeatures -> AFFeatures -> IO AFErr
+foreign import ccall unsafe "af_get_features_num"
+    af_get_features_num :: Ptr DimT -> AFFeatures -> IO AFErr
+foreign import ccall unsafe "af_get_features_xpos"
+    af_get_features_xpos :: Ptr AFArray -> AFFeatures -> IO AFErr
+foreign import ccall unsafe "af_get_features_ypos"
+    af_get_features_ypos :: Ptr AFArray -> AFFeatures -> IO AFErr
+foreign import ccall unsafe "af_get_features_score"
+    af_get_features_score :: Ptr AFArray -> AFFeatures -> IO AFErr
+foreign import ccall unsafe "af_get_features_orientation"
+    af_get_features_orientation :: Ptr AFArray -> AFFeatures -> IO AFErr
+foreign import ccall unsafe "af_get_features_size"
+    af_get_features_size :: Ptr AFArray -> AFFeatures -> IO AFErr
+foreign import ccall unsafe "&af_release_features"
+    af_release_features :: FunPtr (AFFeatures -> IO ())
diff --git a/src/ArrayFire/Internal/Graphics.hs b/src/ArrayFire/Internal/Graphics.hs
new file mode 100644
--- /dev/null
+++ b/src/ArrayFire/Internal/Graphics.hs
@@ -0,0 +1,69 @@
+{-# LINE 1 "src/ArrayFire/Internal/Graphics.hsc" #-}
+{-# LANGUAGE CPP #-}
+module ArrayFire.Internal.Graphics where
+
+import ArrayFire.Internal.Defines
+import ArrayFire.Internal.Types
+
+import Foreign.Ptr
+import Foreign.C.Types
+
+
+foreign import ccall unsafe "af_create_window"
+    af_create_window :: Ptr AFWindow -> CInt -> CInt -> Ptr CChar -> IO AFErr
+foreign import ccall unsafe "af_set_position"
+    af_set_position :: AFWindow -> CUInt -> CUInt -> IO AFErr
+foreign import ccall unsafe "af_set_title"
+    af_set_title :: AFWindow -> Ptr CChar -> IO AFErr
+foreign import ccall unsafe "af_set_size"
+    af_set_size :: AFWindow -> CUInt -> CUInt -> IO AFErr
+foreign import ccall unsafe "af_draw_image"
+    af_draw_image :: AFWindow -> AFArray -> Ptr AFCell -> IO AFErr
+foreign import ccall unsafe "af_draw_plot"
+    af_draw_plot :: AFWindow -> AFArray -> AFArray -> Ptr AFCell -> IO AFErr
+foreign import ccall unsafe "af_draw_plot3"
+    af_draw_plot3 :: AFWindow -> AFArray -> Ptr AFCell -> IO AFErr
+foreign import ccall unsafe "af_draw_plot_nd"
+    af_draw_plot_nd :: AFWindow -> AFArray -> Ptr AFCell -> IO AFErr
+foreign import ccall unsafe "af_draw_plot_2d"
+    af_draw_plot_2d :: AFWindow -> AFArray -> AFArray -> Ptr AFCell -> IO AFErr
+foreign import ccall unsafe "af_draw_plot_3d"
+    af_draw_plot_3d :: AFWindow -> AFArray -> AFArray -> AFArray -> Ptr AFCell -> IO AFErr
+foreign import ccall unsafe "af_draw_scatter"
+    af_draw_scatter :: AFWindow -> AFArray -> AFArray -> AFMarkerType -> Ptr AFCell -> IO AFErr
+foreign import ccall unsafe "af_draw_scatter3"
+    af_draw_scatter3 :: AFWindow -> AFArray -> AFMarkerType -> Ptr AFCell -> IO AFErr
+foreign import ccall unsafe "af_draw_scatter_nd"
+    af_draw_scatter_nd :: AFWindow -> AFArray -> AFMarkerType -> Ptr AFCell -> IO AFErr
+foreign import ccall unsafe "af_draw_scatter_2d"
+    af_draw_scatter_2d :: AFWindow -> AFArray -> AFArray -> AFMarkerType -> Ptr AFCell -> IO AFErr
+foreign import ccall unsafe "af_draw_scatter_3d"
+    af_draw_scatter_3d :: AFWindow -> AFArray -> AFArray -> AFArray -> AFMarkerType -> Ptr AFCell -> IO AFErr
+foreign import ccall unsafe "af_draw_hist"
+    af_draw_hist :: AFWindow -> AFArray -> Double -> Double -> Ptr AFCell -> IO AFErr
+foreign import ccall unsafe "af_draw_surface"
+    af_draw_surface :: AFWindow -> AFArray -> AFArray -> AFArray -> Ptr AFCell -> IO AFErr
+foreign import ccall unsafe "af_draw_vector_field_nd"
+    af_draw_vector_field_nd :: AFWindow -> AFArray -> AFArray -> Ptr AFCell -> IO AFErr
+foreign import ccall unsafe "af_draw_vector_field_3d"
+    af_draw_vector_field_3d :: AFWindow -> AFArray -> AFArray -> AFArray -> AFArray -> AFArray -> AFArray -> Ptr AFCell -> IO AFErr
+foreign import ccall unsafe "af_draw_vector_field_2d"
+    af_draw_vector_field_2d :: AFWindow -> AFArray -> AFArray -> AFArray -> AFArray -> Ptr AFCell -> IO AFErr
+foreign import ccall unsafe "af_grid"
+    af_grid :: AFWindow -> CInt -> CInt -> IO AFErr
+foreign import ccall unsafe "af_set_axes_limits_compute"
+    af_set_axes_limits_compute :: AFWindow -> AFArray -> AFArray -> AFArray -> CBool -> Ptr AFCell -> IO AFErr
+foreign import ccall unsafe "af_set_axes_limits_2d"
+    af_set_axes_limits_2d :: AFWindow -> Float -> Float -> Float -> Float -> CBool -> Ptr AFCell -> IO AFErr
+foreign import ccall unsafe "af_set_axes_limits_3d"
+    af_set_axes_limits_3d :: AFWindow -> Float -> Float -> Float -> Float -> Float -> Float -> CBool -> Ptr AFCell -> IO AFErr
+foreign import ccall unsafe "af_set_axes_titles"
+    af_set_axes_titles :: AFWindow -> Ptr CChar -> Ptr CChar -> Ptr CChar -> Ptr AFCell -> IO AFErr
+foreign import ccall unsafe "af_show"
+    af_show :: AFWindow -> IO AFErr
+foreign import ccall unsafe "af_is_window_closed"
+    af_is_window_closed :: Ptr CBool -> AFWindow -> IO AFErr
+foreign import ccall unsafe "af_set_visibility"
+    af_set_visibility :: AFWindow -> CBool -> IO AFErr
+foreign import ccall unsafe "af_destroy_window"
+    af_destroy_window :: AFWindow -> IO AFErr
diff --git a/src/ArrayFire/Internal/Image.hs b/src/ArrayFire/Internal/Image.hs
new file mode 100644
--- /dev/null
+++ b/src/ArrayFire/Internal/Image.hs
@@ -0,0 +1,96 @@
+{-# LINE 1 "src/ArrayFire/Internal/Image.hsc" #-}
+{-# LANGUAGE CPP #-}
+module ArrayFire.Internal.Image where
+
+import ArrayFire.Internal.Defines
+
+import Foreign.Ptr
+import Foreign.C.Types
+
+
+foreign import ccall unsafe "af_gradient"
+    af_gradient :: Ptr AFArray -> Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_load_image"
+    af_load_image :: Ptr AFArray -> Ptr CChar -> CBool -> IO AFErr
+foreign import ccall unsafe "af_save_image"
+    af_save_image :: Ptr CChar -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_load_image_memory"
+    af_load_image_memory :: Ptr AFArray -> Ptr () -> IO AFErr
+foreign import ccall unsafe "af_save_image_memory"
+    af_save_image_memory :: Ptr (Ptr ()) -> AFArray -> AFImageFormat -> IO AFErr
+foreign import ccall unsafe "af_delete_image_memory"
+    af_delete_image_memory :: Ptr () -> IO AFErr
+foreign import ccall unsafe "af_load_image_native"
+    af_load_image_native :: Ptr AFArray -> Ptr CChar -> IO AFErr
+foreign import ccall unsafe "af_save_image_native"
+    af_save_image_native :: Ptr CChar -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_is_image_io_available"
+    af_is_image_io_available :: Ptr CBool -> IO AFErr
+foreign import ccall unsafe "af_resize"
+    af_resize :: Ptr AFArray -> AFArray -> DimT -> DimT -> AFInterpType -> IO AFErr
+foreign import ccall unsafe "af_transform"
+    af_transform :: Ptr AFArray -> AFArray -> AFArray -> DimT -> DimT -> AFInterpType -> CBool -> IO AFErr
+foreign import ccall unsafe "af_transform_coordinates"
+    af_transform_coordinates :: Ptr AFArray -> AFArray -> Float -> Float -> IO AFErr
+foreign import ccall unsafe "af_rotate"
+    af_rotate :: Ptr AFArray -> AFArray -> Float -> CBool -> AFInterpType -> IO AFErr
+foreign import ccall unsafe "af_translate"
+    af_translate :: Ptr AFArray -> AFArray -> Float -> Float -> DimT -> DimT -> AFInterpType -> IO AFErr
+foreign import ccall unsafe "af_scale"
+    af_scale :: Ptr AFArray -> AFArray -> Float -> Float -> DimT -> DimT -> AFInterpType -> IO AFErr
+foreign import ccall unsafe "af_skew"
+    af_skew :: Ptr AFArray -> AFArray -> Float -> Float -> DimT -> DimT -> AFInterpType -> CBool -> IO AFErr
+foreign import ccall unsafe "af_histogram"
+    af_histogram :: Ptr AFArray -> AFArray -> CUInt -> Double -> Double -> IO AFErr
+foreign import ccall unsafe "af_dilate"
+    af_dilate :: Ptr AFArray -> AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_dilate3"
+    af_dilate3 :: Ptr AFArray -> AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_erode"
+    af_erode :: Ptr AFArray -> AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_erode3"
+    af_erode3 :: Ptr AFArray -> AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_bilateral"
+    af_bilateral :: Ptr AFArray -> AFArray -> Float -> Float -> CBool -> IO AFErr
+foreign import ccall unsafe "af_mean_shift"
+    af_mean_shift :: Ptr AFArray -> AFArray -> Float -> Float -> CUInt -> CBool -> IO AFErr
+foreign import ccall unsafe "af_minfilt"
+    af_minfilt :: Ptr AFArray -> AFArray -> DimT -> DimT -> AFBorderType -> IO AFErr
+foreign import ccall unsafe "af_maxfilt"
+    af_maxfilt :: Ptr AFArray -> AFArray -> DimT -> DimT -> AFBorderType -> IO AFErr
+foreign import ccall unsafe "af_regions"
+    af_regions :: Ptr AFArray -> AFArray -> AFConnectivity -> AFDtype -> IO AFErr
+foreign import ccall unsafe "af_sobel_operator"
+    af_sobel_operator :: Ptr AFArray -> Ptr AFArray -> AFArray -> CUInt -> IO AFErr
+foreign import ccall unsafe "af_rgb2gray"
+    af_rgb2gray :: Ptr AFArray -> AFArray -> Float -> Float -> Float -> IO AFErr
+foreign import ccall unsafe "af_gray2rgb"
+    af_gray2rgb :: Ptr AFArray -> AFArray -> Float -> Float -> Float -> IO AFErr
+foreign import ccall unsafe "af_hist_equal"
+    af_hist_equal :: Ptr AFArray -> AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_gaussian_kernel"
+    af_gaussian_kernel :: Ptr AFArray -> CInt -> CInt -> Double -> Double -> IO AFErr
+foreign import ccall unsafe "af_hsv2rgb"
+    af_hsv2rgb :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_rgb2hsv"
+    af_rgb2hsv :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_color_space"
+    af_color_space :: Ptr AFArray -> AFArray -> AFCSpace -> AFCSpace -> IO AFErr
+foreign import ccall unsafe "af_unwrap"
+    af_unwrap :: Ptr AFArray -> AFArray -> DimT -> DimT -> DimT -> DimT -> DimT -> DimT -> CBool -> IO AFErr
+foreign import ccall unsafe "af_wrap"
+    af_wrap :: Ptr AFArray -> AFArray -> DimT -> DimT -> DimT -> DimT -> DimT -> DimT -> DimT -> DimT -> CBool -> IO AFErr
+foreign import ccall unsafe "af_sat"
+    af_sat :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_ycbcr2rgb"
+    af_ycbcr2rgb :: Ptr AFArray -> AFArray -> AFYccStd -> IO AFErr
+foreign import ccall unsafe "af_rgb2ycbcr"
+    af_rgb2ycbcr :: Ptr AFArray -> AFArray -> AFYccStd -> IO AFErr
+foreign import ccall unsafe "af_moments"
+    af_moments :: Ptr AFArray -> AFArray -> AFMomentType -> IO AFErr
+foreign import ccall unsafe "af_moments_all"
+    af_moments_all :: Ptr Double -> AFArray -> AFMomentType -> IO AFErr
+foreign import ccall unsafe "af_canny"
+    af_canny :: Ptr AFArray -> AFArray -> AFCannyThreshold -> Float -> Float -> CUInt -> CBool -> IO AFErr
+foreign import ccall unsafe "af_anisotropic_diffusion"
+    af_anisotropic_diffusion :: Ptr AFArray -> AFArray -> Float -> Float -> CUInt -> AFFluxFunction -> AFDiffusionEq -> IO AFErr
diff --git a/src/ArrayFire/Internal/Index.hs b/src/ArrayFire/Internal/Index.hs
new file mode 100644
--- /dev/null
+++ b/src/ArrayFire/Internal/Index.hs
@@ -0,0 +1,31 @@
+{-# LINE 1 "src/ArrayFire/Internal/Index.hsc" #-}
+{-# LANGUAGE CPP #-}
+module ArrayFire.Internal.Index where
+
+import ArrayFire.Internal.Defines
+import ArrayFire.Internal.Types
+
+import Foreign.Ptr
+import Foreign.C.Types
+
+
+foreign import ccall unsafe "af_index"
+    af_index :: Ptr AFArray -> AFArray -> CUInt -> Ptr AFSeq -> IO AFErr
+foreign import ccall unsafe "af_lookup"
+    af_lookup :: Ptr AFArray -> AFArray -> AFArray -> CUInt -> IO AFErr
+foreign import ccall unsafe "af_assign_seq"
+    af_assign_seq :: Ptr AFArray -> AFArray -> CUInt -> Ptr AFSeq -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_index_gen"
+    af_index_gen :: Ptr AFArray -> AFArray -> DimT -> Ptr AFIndex -> IO AFErr
+foreign import ccall unsafe "af_assign_gen"
+    af_assign_gen :: Ptr AFArray -> AFArray -> DimT -> Ptr AFIndex -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_create_indexers"
+    af_create_indexers :: Ptr (Ptr AFIndex) -> IO AFErr
+foreign import ccall unsafe "af_set_array_indexer"
+    af_set_array_indexer :: Ptr AFIndex -> AFArray -> DimT -> IO AFErr
+foreign import ccall unsafe "af_set_seq_indexer"
+    af_set_seq_indexer :: Ptr AFIndex -> Ptr AFSeq -> DimT -> CBool -> IO AFErr
+foreign import ccall unsafe "af_set_seq_param_indexer"
+    af_set_seq_param_indexer :: Ptr AFIndex -> Double -> Double -> Double -> DimT -> CBool -> IO AFErr
+foreign import ccall unsafe "af_release_indexers"
+    af_release_indexers :: Ptr AFIndex -> IO AFErr
diff --git a/src/ArrayFire/Internal/LAPACK.hs b/src/ArrayFire/Internal/LAPACK.hs
new file mode 100644
--- /dev/null
+++ b/src/ArrayFire/Internal/LAPACK.hs
@@ -0,0 +1,40 @@
+{-# LINE 1 "src/ArrayFire/Internal/LAPACK.hsc" #-}
+{-# LANGUAGE CPP #-}
+module ArrayFire.Internal.LAPACK where
+
+import ArrayFire.Internal.Defines
+
+import Foreign.Ptr
+import Foreign.C.Types
+
+
+foreign import ccall unsafe "af_svd"
+    af_svd :: Ptr AFArray -> Ptr AFArray -> Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_svd_inplace"
+    af_svd_inplace :: Ptr AFArray -> Ptr AFArray -> Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_lu"
+    af_lu :: Ptr AFArray -> Ptr AFArray -> Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_lu_inplace"
+    af_lu_inplace :: Ptr AFArray -> AFArray -> CBool -> IO AFErr
+foreign import ccall unsafe "af_qr"
+    af_qr :: Ptr AFArray -> Ptr AFArray -> Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_qr_inplace"
+    af_qr_inplace :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_cholesky"
+    af_cholesky :: Ptr AFArray -> Ptr CInt -> AFArray -> CBool -> IO AFErr
+foreign import ccall unsafe "af_cholesky_inplace"
+    af_cholesky_inplace :: Ptr CInt -> AFArray -> CBool -> IO AFErr
+foreign import ccall unsafe "af_solve"
+    af_solve :: Ptr AFArray -> AFArray -> AFArray -> AFMatProp -> IO AFErr
+foreign import ccall unsafe "af_solve_lu"
+    af_solve_lu :: Ptr AFArray -> AFArray -> AFArray -> AFArray -> AFMatProp -> IO AFErr
+foreign import ccall unsafe "af_inverse"
+    af_inverse :: Ptr AFArray -> AFArray -> AFMatProp -> IO AFErr
+foreign import ccall unsafe "af_rank"
+    af_rank :: Ptr CUInt -> AFArray -> Double -> IO AFErr
+foreign import ccall unsafe "af_det"
+    af_det :: Ptr Double -> Ptr Double -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_norm"
+    af_norm :: Ptr Double -> AFArray -> AFNormType -> Double -> Double -> IO AFErr
+foreign import ccall unsafe "af_is_lapack_available"
+    af_is_lapack_available :: Ptr CBool -> IO AFErr
diff --git a/src/ArrayFire/Internal/Random.hs b/src/ArrayFire/Internal/Random.hs
new file mode 100644
--- /dev/null
+++ b/src/ArrayFire/Internal/Random.hs
@@ -0,0 +1,40 @@
+{-# LINE 1 "src/ArrayFire/Internal/Random.hsc" #-}
+{-# LANGUAGE CPP #-}
+module ArrayFire.Internal.Random where
+
+import ArrayFire.Internal.Defines
+
+import Foreign.Ptr
+import Foreign.C.Types
+
+
+foreign import ccall unsafe "af_create_random_engine"
+    af_create_random_engine :: Ptr AFRandomEngine -> AFRandomEngineType -> UIntL -> IO AFErr
+foreign import ccall unsafe "af_retain_random_engine"
+    af_retain_random_engine :: Ptr AFRandomEngine -> AFRandomEngine -> IO AFErr
+foreign import ccall unsafe "af_random_engine_set_type"
+    af_random_engine_set_type :: Ptr AFRandomEngine -> AFRandomEngineType -> IO AFErr
+foreign import ccall unsafe "af_random_engine_get_type"
+    af_random_engine_get_type :: Ptr AFRandomEngineType -> AFRandomEngine -> IO AFErr
+foreign import ccall unsafe "af_random_uniform"
+    af_random_uniform :: Ptr AFArray -> CUInt -> Ptr DimT -> AFDtype -> AFRandomEngine -> IO AFErr
+foreign import ccall unsafe "af_random_normal"
+    af_random_normal :: Ptr AFArray -> CUInt -> Ptr DimT -> AFDtype -> AFRandomEngine -> IO AFErr
+foreign import ccall unsafe "af_random_engine_set_seed"
+    af_random_engine_set_seed :: Ptr AFRandomEngine -> UIntL -> IO AFErr
+foreign import ccall unsafe "af_get_default_random_engine"
+    af_get_default_random_engine :: Ptr AFRandomEngine -> IO AFErr
+foreign import ccall unsafe "af_set_default_random_engine_type"
+    af_set_default_random_engine_type :: AFRandomEngineType -> IO AFErr
+foreign import ccall unsafe "af_random_engine_get_seed"
+    af_random_engine_get_seed :: Ptr UIntL -> AFRandomEngine -> IO AFErr
+foreign import ccall unsafe "af_release_random_engine"
+    af_release_random_engine :: AFRandomEngine -> IO AFErr
+foreign import ccall unsafe "af_randu"
+    af_randu :: Ptr AFArray -> CUInt -> Ptr DimT -> AFDtype -> IO AFErr
+foreign import ccall unsafe "af_randn"
+    af_randn :: Ptr AFArray -> CUInt -> Ptr DimT -> AFDtype -> IO AFErr
+foreign import ccall unsafe "af_set_seed"
+    af_set_seed :: UIntL -> IO AFErr
+foreign import ccall unsafe "af_get_seed"
+    af_get_seed :: Ptr UIntL -> IO AFErr
diff --git a/src/ArrayFire/Internal/Signal.hs b/src/ArrayFire/Internal/Signal.hs
new file mode 100644
--- /dev/null
+++ b/src/ArrayFire/Internal/Signal.hs
@@ -0,0 +1,75 @@
+{-# LINE 1 "src/ArrayFire/Internal/Signal.hsc" #-}
+{-# LANGUAGE CPP #-}
+module ArrayFire.Internal.Signal where
+
+import ArrayFire.Internal.Defines
+import Foreign.Ptr
+import Foreign.C.Types
+
+
+foreign import ccall unsafe "af_approx1"
+    af_approx1 :: Ptr AFArray -> AFArray -> AFArray -> AFInterpType -> Float -> IO AFErr
+foreign import ccall unsafe "af_approx2"
+    af_approx2 :: Ptr AFArray -> AFArray -> AFArray -> AFArray -> AFInterpType -> Float -> IO AFErr
+foreign import ccall unsafe "af_fft"
+    af_fft :: Ptr AFArray -> AFArray -> Double -> DimT -> IO AFErr
+foreign import ccall unsafe "af_fft_inplace"
+    af_fft_inplace :: AFArray -> Double -> IO AFErr
+foreign import ccall unsafe "af_fft2"
+    af_fft2 :: Ptr AFArray -> AFArray -> Double -> DimT -> DimT -> IO AFErr
+foreign import ccall unsafe "af_fft2_inplace"
+    af_fft2_inplace :: AFArray -> Double -> IO AFErr
+foreign import ccall unsafe "af_fft3"
+    af_fft3 :: Ptr AFArray -> AFArray -> Double -> DimT -> DimT -> DimT -> IO AFErr
+foreign import ccall unsafe "af_fft3_inplace"
+    af_fft3_inplace :: AFArray -> Double -> IO AFErr
+foreign import ccall unsafe "af_ifft"
+    af_ifft :: Ptr AFArray -> AFArray -> Double -> DimT -> IO AFErr
+foreign import ccall unsafe "af_ifft_inplace"
+    af_ifft_inplace :: AFArray -> Double -> IO AFErr
+foreign import ccall unsafe "af_ifft2"
+    af_ifft2 :: Ptr AFArray -> AFArray -> Double -> DimT -> DimT -> IO AFErr
+foreign import ccall unsafe "af_ifft2_inplace"
+    af_ifft2_inplace :: AFArray -> Double -> IO AFErr
+foreign import ccall unsafe "af_ifft3"
+    af_ifft3 :: Ptr AFArray -> AFArray -> Double -> DimT -> DimT -> DimT -> IO AFErr
+foreign import ccall unsafe "af_ifft3_inplace"
+    af_ifft3_inplace :: AFArray -> Double -> IO AFErr
+foreign import ccall unsafe "af_fft_r2c"
+    af_fft_r2c :: Ptr AFArray -> AFArray -> Double -> DimT -> IO AFErr
+foreign import ccall unsafe "af_fft2_r2c"
+    af_fft2_r2c :: Ptr AFArray -> AFArray -> Double -> DimT -> DimT -> IO AFErr
+foreign import ccall unsafe "af_fft3_r2c"
+    af_fft3_r2c :: Ptr AFArray -> AFArray -> Double -> DimT -> DimT -> DimT -> IO AFErr
+foreign import ccall unsafe "af_fft_c2r"
+    af_fft_c2r :: Ptr AFArray -> AFArray -> Double -> CBool -> IO AFErr
+foreign import ccall unsafe "af_fft2_c2r"
+    af_fft2_c2r :: Ptr AFArray -> AFArray -> Double -> CBool -> IO AFErr
+foreign import ccall unsafe "af_fft3_c2r"
+    af_fft3_c2r :: Ptr AFArray -> AFArray -> Double -> CBool -> IO AFErr
+foreign import ccall unsafe "af_convolve1"
+    af_convolve1 :: Ptr AFArray -> AFArray -> AFArray -> AFConvMode -> AFConvDomain -> IO AFErr
+foreign import ccall unsafe "af_convolve2"
+    af_convolve2 :: Ptr AFArray -> AFArray -> AFArray -> AFConvMode -> AFConvDomain -> IO AFErr
+foreign import ccall unsafe "af_convolve3"
+    af_convolve3 :: Ptr AFArray -> AFArray -> AFArray -> AFConvMode -> AFConvDomain -> IO AFErr
+foreign import ccall unsafe "af_convolve2_sep"
+    af_convolve2_sep :: Ptr AFArray -> AFArray -> AFArray -> AFArray -> AFConvMode -> IO AFErr
+foreign import ccall unsafe "af_fft_convolve1"
+    af_fft_convolve1 :: Ptr AFArray -> AFArray -> AFArray -> AFConvMode -> IO AFErr
+foreign import ccall unsafe "af_fft_convolve2"
+    af_fft_convolve2 :: Ptr AFArray -> AFArray -> AFArray -> AFConvMode -> IO AFErr
+foreign import ccall unsafe "af_fft_convolve3"
+    af_fft_convolve3 :: Ptr AFArray -> AFArray -> AFArray -> AFConvMode -> IO AFErr
+foreign import ccall unsafe "af_fir"
+    af_fir :: Ptr AFArray -> AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_iir"
+    af_iir :: Ptr AFArray -> AFArray -> AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_medfilt"
+    af_medfilt :: Ptr AFArray -> AFArray -> DimT -> DimT -> AFBorderType -> IO AFErr
+foreign import ccall unsafe "af_medfilt1"
+    af_medfilt1 :: Ptr AFArray -> AFArray -> DimT -> AFBorderType -> IO AFErr
+foreign import ccall unsafe "af_medfilt2"
+    af_medfilt2 :: Ptr AFArray -> AFArray -> DimT -> DimT -> AFBorderType -> IO AFErr
+foreign import ccall unsafe "af_set_fft_plan_cache_size"
+    af_set_fft_plan_cache_size :: CSize -> IO AFErr
diff --git a/src/ArrayFire/Internal/Sparse.hs b/src/ArrayFire/Internal/Sparse.hs
new file mode 100644
--- /dev/null
+++ b/src/ArrayFire/Internal/Sparse.hs
@@ -0,0 +1,31 @@
+{-# LINE 1 "src/ArrayFire/Internal/Sparse.hsc" #-}
+{-# LANGUAGE CPP #-}
+module ArrayFire.Internal.Sparse where
+
+import ArrayFire.Internal.Defines
+import Foreign.Ptr
+import Foreign.C.Types
+
+
+foreign import ccall unsafe "af_create_sparse_array"
+    af_create_sparse_array :: Ptr AFArray -> DimT -> DimT -> AFArray -> AFArray -> AFArray -> AFStorage -> IO AFErr
+foreign import ccall unsafe "af_create_sparse_array_from_ptr"
+    af_create_sparse_array_from_ptr :: Ptr AFArray -> DimT -> DimT -> DimT -> Ptr () -> Ptr CInt -> Ptr CInt -> AFDtype -> AFStorage -> AFSource -> IO AFErr
+foreign import ccall unsafe "af_create_sparse_array_from_dense"
+    af_create_sparse_array_from_dense :: Ptr AFArray -> AFArray -> AFStorage -> IO AFErr
+foreign import ccall unsafe "af_sparse_convert_to"
+    af_sparse_convert_to :: Ptr AFArray -> AFArray -> AFStorage -> IO AFErr
+foreign import ccall unsafe "af_sparse_to_dense"
+    af_sparse_to_dense :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_sparse_get_info"
+    af_sparse_get_info :: Ptr AFArray -> Ptr AFArray -> Ptr AFArray -> Ptr AFStorage -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_sparse_get_values"
+    af_sparse_get_values :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_sparse_get_row_idx"
+    af_sparse_get_row_idx :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_sparse_get_col_idx"
+    af_sparse_get_col_idx :: Ptr AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_sparse_get_nnz"
+    af_sparse_get_nnz :: Ptr DimT -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_sparse_get_storage"
+    af_sparse_get_storage :: Ptr AFStorage -> AFArray -> IO AFErr
diff --git a/src/ArrayFire/Internal/Statistics.hs b/src/ArrayFire/Internal/Statistics.hs
new file mode 100644
--- /dev/null
+++ b/src/ArrayFire/Internal/Statistics.hs
@@ -0,0 +1,39 @@
+{-# LINE 1 "src/ArrayFire/Internal/Statistics.hsc" #-}
+{-# LANGUAGE CPP #-}
+module ArrayFire.Internal.Statistics where
+
+import ArrayFire.Internal.Defines
+import Foreign.Ptr
+import Foreign.C.Types
+
+
+foreign import ccall unsafe "af_mean"
+    af_mean :: Ptr AFArray -> AFArray -> DimT -> IO AFErr
+foreign import ccall unsafe "af_mean_weighted"
+    af_mean_weighted :: Ptr AFArray -> AFArray -> AFArray -> DimT -> IO AFErr
+foreign import ccall unsafe "af_var"
+    af_var :: Ptr AFArray -> AFArray -> CBool -> DimT -> IO AFErr
+foreign import ccall unsafe "af_var_weighted"
+    af_var_weighted :: Ptr AFArray -> AFArray -> AFArray -> DimT -> IO AFErr
+foreign import ccall unsafe "af_stdev"
+    af_stdev :: Ptr AFArray -> AFArray -> DimT -> IO AFErr
+foreign import ccall unsafe "af_cov"
+    af_cov :: Ptr AFArray -> AFArray -> AFArray -> CBool -> IO AFErr
+foreign import ccall unsafe "af_median"
+    af_median :: Ptr AFArray -> AFArray -> DimT -> IO AFErr
+foreign import ccall unsafe "af_mean_all"
+    af_mean_all :: Ptr Double -> Ptr Double -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_mean_all_weighted"
+    af_mean_all_weighted :: Ptr Double -> Ptr Double -> AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_var_all"
+    af_var_all :: Ptr Double -> Ptr Double -> AFArray -> CBool -> IO AFErr
+foreign import ccall unsafe "af_var_all_weighted"
+    af_var_all_weighted :: Ptr Double -> Ptr Double -> AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_stdev_all"
+    af_stdev_all :: Ptr Double -> Ptr Double -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_median_all"
+    af_median_all :: Ptr Double -> Ptr Double -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_corrcoef"
+    af_corrcoef :: Ptr Double -> Ptr Double -> AFArray -> AFArray -> IO AFErr
+foreign import ccall unsafe "af_topk"
+    af_topk :: Ptr AFArray -> Ptr AFArray -> AFArray -> CInt -> CInt -> AFTopkFunction -> IO AFErr
diff --git a/src/ArrayFire/Internal/Types.hs b/src/ArrayFire/Internal/Types.hs
new file mode 100644
--- /dev/null
+++ b/src/ArrayFire/Internal/Types.hs
@@ -0,0 +1,728 @@
+{-# LINE 1 "src/ArrayFire/Internal/Types.hsc" #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE ViewPatterns      #-}
+{-# LANGUAGE RecordWildCards   #-}
+{-# LANGUAGE CPP               #-}
+module ArrayFire.Internal.Types where
+
+
+
+
+
+
+import ArrayFire.Internal.Defines
+
+import Data.Complex
+import Data.Proxy
+import Data.Word
+import Foreign.C.String
+import Foreign.C.Types
+import Foreign.ForeignPtr
+import Foreign.Storable
+import GHC.Int
+
+data AFSeq
+  = AFSeq
+  { afSeqBegin :: {-# UNPACK #-} !Double
+  , afSeqEnd   :: {-# UNPACK #-} !Double
+  , afSeqStep  :: {-# UNPACK #-} !Double
+  } deriving (Show, Eq)
+
+instance Storable AFSeq where
+  sizeOf _ = (24)
+{-# LINE 32 "src/ArrayFire/Internal/Types.hsc" #-}
+  alignment _ = 8
+{-# LINE 33 "src/ArrayFire/Internal/Types.hsc" #-}
+  peek ptr = do
+    afSeqBegin <- (\hsc_ptr -> peekByteOff hsc_ptr 0) ptr
+{-# LINE 35 "src/ArrayFire/Internal/Types.hsc" #-}
+    afSeqEnd <- (\hsc_ptr -> peekByteOff hsc_ptr 8) ptr
+{-# LINE 36 "src/ArrayFire/Internal/Types.hsc" #-}
+    afSeqStep <- (\hsc_ptr -> peekByteOff hsc_ptr 16) ptr
+{-# LINE 37 "src/ArrayFire/Internal/Types.hsc" #-}
+    pure AFSeq {..}
+  poke ptr AFSeq{..} = do
+    (\hsc_ptr -> pokeByteOff hsc_ptr 0) ptr afSeqBegin
+{-# LINE 40 "src/ArrayFire/Internal/Types.hsc" #-}
+    (\hsc_ptr -> pokeByteOff hsc_ptr 8) ptr afSeqEnd
+{-# LINE 41 "src/ArrayFire/Internal/Types.hsc" #-}
+    (\hsc_ptr -> pokeByteOff hsc_ptr 16) ptr afSeqStep
+{-# LINE 42 "src/ArrayFire/Internal/Types.hsc" #-}
+
+-- | Type used for indexing into 'Array'
+data AFIndex
+  = AFIndex
+  { afIdx :: !(Either AFArray AFSeq)
+  , afIsSeq :: !Bool
+  , afIsBatch :: !Bool
+  }
+instance Storable AFIndex where
+  sizeOf _ = (32)
+{-# LINE 52 "src/ArrayFire/Internal/Types.hsc" #-}
+  alignment _ = 8
+{-# LINE 53 "src/ArrayFire/Internal/Types.hsc" #-}
+  peek ptr = do
+    afIsSeq <- (\hsc_ptr -> peekByteOff hsc_ptr 24) ptr
+{-# LINE 55 "src/ArrayFire/Internal/Types.hsc" #-}
+    afIsBatch <- (\hsc_ptr -> peekByteOff hsc_ptr 25) ptr
+{-# LINE 56 "src/ArrayFire/Internal/Types.hsc" #-}
+    afIdx <-
+      if afIsSeq
+        then Left <$> (\hsc_ptr -> peekByteOff hsc_ptr 0) ptr
+{-# LINE 59 "src/ArrayFire/Internal/Types.hsc" #-}
+        else Right <$> (\hsc_ptr -> peekByteOff hsc_ptr 0) ptr
+{-# LINE 60 "src/ArrayFire/Internal/Types.hsc" #-}
+    pure AFIndex{..}
+  poke ptr AFIndex{..} = do
+    case afIdx of
+      Left afarr -> (\hsc_ptr -> pokeByteOff hsc_ptr 0) ptr afarr
+{-# LINE 64 "src/ArrayFire/Internal/Types.hsc" #-}
+      Right afseq -> (\hsc_ptr -> pokeByteOff hsc_ptr 0) ptr afseq
+{-# LINE 65 "src/ArrayFire/Internal/Types.hsc" #-}
+    (\hsc_ptr -> pokeByteOff hsc_ptr 24) ptr afIsSeq
+{-# LINE 66 "src/ArrayFire/Internal/Types.hsc" #-}
+    (\hsc_ptr -> pokeByteOff hsc_ptr 25) ptr afIsBatch
+{-# LINE 67 "src/ArrayFire/Internal/Types.hsc" #-}
+
+data AFCFloat
+  = AFCFloat
+  { afcReal :: {-# UNPACK #-} !Float
+  , afcImag :: {-# UNPACK #-} !Float
+  } deriving (Eq, Show)
+
+instance Storable AFCFloat where
+  sizeOf _ = (8)
+{-# LINE 76 "src/ArrayFire/Internal/Types.hsc" #-}
+  alignment _ = 4
+{-# LINE 77 "src/ArrayFire/Internal/Types.hsc" #-}
+  peek ptr = do
+    afcReal <- (\hsc_ptr -> peekByteOff hsc_ptr 0) ptr
+{-# LINE 79 "src/ArrayFire/Internal/Types.hsc" #-}
+    afcImag <- (\hsc_ptr -> peekByteOff hsc_ptr 4) ptr
+{-# LINE 80 "src/ArrayFire/Internal/Types.hsc" #-}
+    pure AFCFloat{..}
+  poke ptr AFCFloat{..} = do
+    (\hsc_ptr -> pokeByteOff hsc_ptr 0) ptr afcReal
+{-# LINE 83 "src/ArrayFire/Internal/Types.hsc" #-}
+    (\hsc_ptr -> pokeByteOff hsc_ptr 4) ptr afcImag
+{-# LINE 84 "src/ArrayFire/Internal/Types.hsc" #-}
+
+data AFCell
+  = AFCell
+  { afCellRow :: {-# UNPACK #-} !Int
+  , afCellCol :: {-# UNPACK #-} !Int
+  , afCellTitle :: {-# UNPACK #-} !CString
+  , afCellColorMap :: {-# UNPACK #-} !AFColorMap
+  } deriving (Show, Eq)
+
+instance Storable AFCell where
+  sizeOf _ = (24)
+{-# LINE 95 "src/ArrayFire/Internal/Types.hsc" #-}
+  alignment _ = 8
+{-# LINE 96 "src/ArrayFire/Internal/Types.hsc" #-}
+  peek ptr = do
+    afCellRow <- (\hsc_ptr -> peekByteOff hsc_ptr 0) ptr
+{-# LINE 98 "src/ArrayFire/Internal/Types.hsc" #-}
+    afCellCol <- (\hsc_ptr -> peekByteOff hsc_ptr 4) ptr
+{-# LINE 99 "src/ArrayFire/Internal/Types.hsc" #-}
+    afCellTitle <- (\hsc_ptr -> peekByteOff hsc_ptr 8) ptr
+{-# LINE 100 "src/ArrayFire/Internal/Types.hsc" #-}
+    afCellColorMap <- (\hsc_ptr -> peekByteOff hsc_ptr 16) ptr
+{-# LINE 101 "src/ArrayFire/Internal/Types.hsc" #-}
+    pure AFCell{..}
+  poke ptr AFCell{..} = do
+    (\hsc_ptr -> pokeByteOff hsc_ptr 0) ptr afCellRow
+{-# LINE 104 "src/ArrayFire/Internal/Types.hsc" #-}
+    (\hsc_ptr -> pokeByteOff hsc_ptr 4) ptr afCellCol
+{-# LINE 105 "src/ArrayFire/Internal/Types.hsc" #-}
+    (\hsc_ptr -> pokeByteOff hsc_ptr 8) ptr afCellTitle
+{-# LINE 106 "src/ArrayFire/Internal/Types.hsc" #-}
+    (\hsc_ptr -> pokeByteOff hsc_ptr 16) ptr afCellColorMap
+{-# LINE 107 "src/ArrayFire/Internal/Types.hsc" #-}
+
+-- | ArrayFire 'Array'
+newtype Array a = Array (ForeignPtr ())
+
+-- | ArrayFire 'Features'
+newtype Features = Features (ForeignPtr ())
+
+-- | ArrayFire 'RandomEngine'
+newtype RandomEngine = RandomEngine (ForeignPtr ())
+
+-- | ArrayFire 'Window'
+newtype Window = Window (ForeignPtr ())
+
+-- | Mapping of Haskell types to ArrayFire types
+class Storable a => AFType a where
+  afType :: Proxy a -> AFDtype
+
+instance AFType Double where
+  afType Proxy = f64
+
+instance AFType Float where
+  afType Proxy = f32
+
+instance AFType (Complex Double) where
+  afType Proxy = c64
+
+instance AFType (Complex Float) where
+  afType Proxy = c32
+
+instance AFType CBool where
+  afType Proxy = b8
+
+instance AFType Int32 where
+  afType Proxy = s32
+
+instance AFType Word32 where
+  afType Proxy = u32
+
+instance AFType Word8 where
+  afType Proxy = u8
+
+instance AFType Int64 where
+  afType Proxy = s64
+
+instance AFType Int where
+  afType Proxy = s64
+
+instance AFType Int16 where
+  afType Proxy = s16
+
+instance AFType Word16 where
+  afType Proxy = u16
+
+instance AFType Word64 where
+  afType Proxy = u64
+
+instance AFType Word where
+  afType Proxy = u64
+
+-- | ArrayFire backends
+data Backend
+  = Default
+  | CPU
+  | CUDA
+  | OpenCL
+  deriving (Show, Eq, Ord)
+
+-- | Low-level to high-level Backend conversion
+toBackend :: AFBackend -> Backend
+toBackend (AFBackend 0) = Default
+toBackend (AFBackend 1) = CPU
+toBackend (AFBackend 2) = CUDA
+toBackend (AFBackend 4) = OpenCL
+toBackend (AFBackend x) = error $ "Invalid backend: " <> show x
+
+-- | High-level to low-level Backend conversion
+toAFBackend :: Backend -> AFBackend
+toAFBackend Default = (AFBackend 0)
+toAFBackend CPU = (AFBackend 1)
+toAFBackend CUDA = (AFBackend 2)
+toAFBackend OpenCL = (AFBackend 4)
+
+-- | Read multiple backends
+toBackends :: Int -> [Backend]
+toBackends 1 = [CPU]
+toBackends 2 = [CUDA]
+toBackends 3 = [CPU,CUDA]
+toBackends 4 = [OpenCL]
+toBackends 5 = [CPU,OpenCL]
+toBackends 6 = [CUDA,OpenCL]
+toBackends 7 = [CPU,CUDA,OpenCL]
+toBackends _ = []
+
+-- | Matrix properties
+data MatProp
+  = None
+  | Trans
+  | CTrans
+  | Conj
+  | Upper
+  | Lower
+  | DiagUnit
+  | Sym
+  | PosDef
+  | Orthog
+  | TriDiag
+  | BlockDiag
+  deriving (Show, Eq, Ord)
+
+-- | Low-level to High-level 'MatProp' conversion
+fromMatProp
+  :: AFMatProp
+  -> MatProp
+fromMatProp (AFMatProp 0) = None
+fromMatProp (AFMatProp 1) = Trans
+fromMatProp (AFMatProp 2) = CTrans
+fromMatProp (AFMatProp 4) = Conj
+fromMatProp (AFMatProp 32) = Upper
+fromMatProp (AFMatProp 64) = Lower
+fromMatProp (AFMatProp 128) = DiagUnit
+fromMatProp (AFMatProp 512) = Sym
+fromMatProp (AFMatProp 1024) = PosDef
+fromMatProp (AFMatProp 2048) = Orthog
+fromMatProp (AFMatProp 4096) = TriDiag
+fromMatProp (AFMatProp 8192) = BlockDiag
+fromMatProp x = error $ "Invalid AFMatProp value: " <> show x
+
+-- | High-level to low-level 'MatProp' conversion
+toMatProp
+  :: MatProp
+  -> AFMatProp
+toMatProp None = (AFMatProp 0)
+toMatProp Trans = (AFMatProp 1)
+toMatProp CTrans = (AFMatProp 2)
+toMatProp Conj = (AFMatProp 4)
+toMatProp Upper = (AFMatProp 32)
+toMatProp Lower = (AFMatProp 64)
+toMatProp DiagUnit = (AFMatProp 128)
+toMatProp Sym = (AFMatProp 512)
+toMatProp PosDef = (AFMatProp 1024)
+toMatProp Orthog = (AFMatProp 2048)
+toMatProp TriDiag = (AFMatProp 4096)
+toMatProp BlockDiag = (AFMatProp 8192)
+
+-- | Binary operation support
+data BinaryOp
+  = Add
+  | Mul
+  | Min
+  | Max
+  deriving (Show, Eq, Ord)
+
+-- | High-level to low-level 'MatProp' conversion
+toBinaryOp :: BinaryOp -> AFBinaryOp
+toBinaryOp Add = AFBinaryOp 0
+toBinaryOp Mul = AFBinaryOp 1
+toBinaryOp Min = AFBinaryOp 2
+toBinaryOp Max = AFBinaryOp 3
+
+-- | 'BinaryOp' conversion helper
+fromBinaryOp :: AFBinaryOp -> BinaryOp
+fromBinaryOp (AFBinaryOp 0) = Add
+fromBinaryOp (AFBinaryOp 1) = Mul
+fromBinaryOp (AFBinaryOp 2) = Min
+fromBinaryOp (AFBinaryOp 3) = Max
+fromBinaryOp x = error ("Invalid Binary Op: " <> show x)
+
+-- | Storage type used for Sparse arrays
+data Storage
+  = Dense
+  | CSR
+  | CSC
+  | COO
+  deriving (Show, Eq, Ord, Enum)
+
+toStorage :: Storage -> AFStorage
+toStorage = AFStorage . fromIntegral . fromEnum
+
+fromStorage :: AFStorage -> Storage
+fromStorage (AFStorage (fromIntegral -> x))
+  | x `elem` [0..3] = toEnum x
+  | otherwise = error $ "Invalid Storage " <> (show x)
+
+-- | Type for different RandomEngines
+data RandomEngineType
+  = Philox
+  | ThreeFry
+  | Mersenne
+  deriving (Eq, Show)
+
+toRandomEngine :: AFRandomEngineType -> RandomEngineType
+toRandomEngine (AFRandomEngineType 100) = Philox
+toRandomEngine (AFRandomEngineType 200) = ThreeFry
+toRandomEngine (AFRandomEngineType 300) = Mersenne
+toRandomEngine (AFRandomEngineType x) =
+  error ("Invalid random engine: " <> show x)
+
+fromRandomEngine :: RandomEngineType ->  AFRandomEngineType
+fromRandomEngine Philox = (AFRandomEngineType 100)
+fromRandomEngine ThreeFry = (AFRandomEngineType 200)
+fromRandomEngine Mersenne = (AFRandomEngineType 300)
+
+-- | Interpolation type
+data InterpType
+  = Nearest
+  | Linear
+  | Bilinear
+  | Cubic
+  | LowerInterp
+  | LinearCosine
+  | BilinearCosine
+  | Bicubic
+  | CubicSpline
+  | BicubicSpline
+  deriving (Show, Eq, Ord, Enum)
+
+toInterpType :: AFInterpType -> InterpType
+toInterpType (AFInterpType (fromIntegral -> x)) = toEnum x
+
+fromInterpType :: InterpType -> AFInterpType
+fromInterpType = AFInterpType . fromIntegral . fromEnum
+
+-- | Border Type
+data BorderType
+  = PadZero
+  | PadSym
+  deriving (Show, Ord, Enum, Eq)
+
+toBorderType :: AFBorderType -> BorderType
+toBorderType (AFBorderType (fromIntegral -> x)) = toEnum x
+
+fromBorderType :: BorderType -> AFBorderType
+fromBorderType = AFBorderType . fromIntegral . fromEnum
+
+-- | Connectivity Type
+data Connectivity
+  = Conn4
+  | Conn8
+  deriving (Show, Ord, Enum, Eq)
+
+toConnectivity :: AFConnectivity -> Connectivity
+toConnectivity (AFConnectivity 4) = Conn4
+toConnectivity (AFConnectivity 8) = Conn4
+toConnectivity (AFConnectivity x) = error ("Unknown connectivity option: " <> show x)
+
+fromConnectivity :: Connectivity -> AFConnectivity
+fromConnectivity Conn4 = AFConnectivity 4
+fromConnectivity Conn8 = AFConnectivity 8
+
+-- | Color Space type
+data CSpace
+  = Gray
+  | RGB
+  | HSV
+  | YCBCR
+  deriving (Show, Eq, Ord, Enum)
+
+toCSpace :: AFCSpace -> CSpace
+toCSpace (AFCSpace (fromIntegral -> x)) = toEnum x
+
+fromCSpace :: CSpace -> AFCSpace
+fromCSpace = AFCSpace . fromIntegral . fromEnum
+
+-- | YccStd type
+data YccStd
+  = Ycc601
+  | Ycc709
+  | Ycc2020
+  deriving (Show, Eq, Ord)
+
+toAFYccStd :: AFYccStd -> YccStd
+toAFYccStd (AFYccStd 601) = Ycc601
+toAFYccStd (AFYccStd 709) = Ycc709
+toAFYccStd (AFYccStd 2020) = Ycc2020
+toAFYccStd (AFYccStd x) = error ("Unknown AFYccStd option: " <> show x)
+
+fromAFYccStd :: YccStd -> AFYccStd
+fromAFYccStd Ycc601 = afYcc601
+fromAFYccStd Ycc709 = afYcc709
+fromAFYccStd Ycc2020 = afYcc2020
+
+-- | Moment types
+data MomentType
+  = M00
+  | M01
+  | M10
+  | M11
+  | FirstOrder
+  deriving (Show, Eq, Ord)
+
+toMomentType :: AFMomentType -> MomentType
+toMomentType x
+  | x == afMomentM00 = M00
+  | x == afMomentM01 = M01
+  | x == afMomentM10 = M10
+  | x == afMomentM11 = M11
+  | x == afMomentFirstOrder = FirstOrder
+  | otherwise = error ("Unknown moment type: " <> show x)
+
+fromMomentType :: MomentType -> AFMomentType
+fromMomentType M00 = afMomentM00
+fromMomentType M01 = afMomentM01
+fromMomentType M10 = afMomentM10
+fromMomentType M11 = afMomentM11
+fromMomentType FirstOrder = afMomentFirstOrder
+
+-- | Canny Theshold type
+data CannyThreshold
+  = Manual
+  | AutoOtsu
+  deriving (Show, Eq, Ord, Enum)
+
+toCannyThreshold :: AFCannyThreshold -> CannyThreshold
+toCannyThreshold (AFCannyThreshold (fromIntegral -> x)) = toEnum x
+
+fromCannyThreshold :: CannyThreshold -> AFCannyThreshold
+fromCannyThreshold = AFCannyThreshold . fromIntegral . fromEnum
+
+-- | Flux function type
+data FluxFunction
+  = FluxDefault
+  | FluxQuadratic
+  | FluxExponential
+  deriving (Show, Eq, Ord, Enum)
+
+toFluxFunction :: AFFluxFunction -> FluxFunction
+toFluxFunction (AFFluxFunction (fromIntegral -> x)) = toEnum x
+
+fromFluxFunction :: FluxFunction -> AFFluxFunction
+fromFluxFunction = AFFluxFunction . fromIntegral . fromEnum
+
+-- | Diffusion type
+data DiffusionEq
+  = DiffusionDefault
+  | DiffusionGrad
+  | DiffusionMCDE
+  deriving (Show, Eq, Ord, Enum)
+
+toDiffusionEq :: AFDiffusionEq -> DiffusionEq
+toDiffusionEq (AFDiffusionEq (fromIntegral -> x)) = toEnum x
+
+fromDiffusionEq :: DiffusionEq -> AFDiffusionEq
+fromDiffusionEq = AFDiffusionEq . fromIntegral . fromEnum
+
+-- | Iterative deconvolution algo type
+data IterativeDeconvAlgo
+  = DeconvDefault
+  | DeconvLandweber
+  | DeconvRichardsonLucy
+  deriving (Show, Eq, Ord, Enum)
+
+toIterativeDeconvAlgo :: AFIterativeDeconvAlgo -> IterativeDeconvAlgo
+toIterativeDeconvAlgo (AFIterativeDeconvAlgo (fromIntegral -> x)) = toEnum x
+
+fromIterativeDeconvAlgo :: IterativeDeconvAlgo -> AFIterativeDeconvAlgo
+fromIterativeDeconvAlgo = AFIterativeDeconvAlgo . fromIntegral . fromEnum
+
+-- | Inverse deconvolution algo type
+data InverseDeconvAlgo
+  = InverseDeconvDefault
+  | InverseDeconvTikhonov
+  deriving (Show, Eq, Ord, Enum)
+
+toInverseDeconvAlgo :: AFInverseDeconvAlgo -> InverseDeconvAlgo
+toInverseDeconvAlgo (AFInverseDeconvAlgo (fromIntegral -> x)) = toEnum x
+
+fromInverseDeconvAlgo :: InverseDeconvAlgo -> AFInverseDeconvAlgo
+fromInverseDeconvAlgo = AFInverseDeconvAlgo . fromIntegral . fromEnum
+
+-- | Cell type, used in Graphics module
+data Cell
+  = Cell
+  { cellRow :: Int
+  , cellCol :: Int
+  , cellTitle :: String
+  , cellColorMap :: ColorMap
+  } deriving (Show, Eq)
+
+cellToAFCell :: Cell -> IO AFCell
+cellToAFCell Cell {..} =
+  withCString cellTitle $ \cstr ->
+    pure AFCell { afCellRow = cellRow
+                , afCellCol = cellCol
+                , afCellTitle = cstr
+                , afCellColorMap = fromColorMap cellColorMap
+                }
+
+-- | ColorMap type
+data ColorMap
+  = ColorMapDefault
+  | ColorMapSpectrum
+  | ColorMapColors
+  | ColorMapRed
+  | ColorMapMood
+  | ColorMapHeat
+  | ColorMapBlue
+  | ColorMapInferno
+  | ColorMapMagma
+  | ColorMapPlasma
+  | ColorMapViridis
+  deriving (Show, Eq, Ord, Enum)
+
+fromColorMap :: ColorMap -> AFColorMap
+fromColorMap = AFColorMap . fromIntegral . fromEnum
+
+toColorMap :: AFColorMap -> ColorMap
+toColorMap (AFColorMap (fromIntegral -> x)) = toEnum x
+
+-- | Marker type
+data MarkerType
+  = MarkerTypeNone
+  | MarkerTypePoint
+  | MarkerTypeCircle
+  | MarkerTypeSquare
+  | MarkerTypeTriangle
+  | MarkerTypeCross
+  | MarkerTypePlus
+  | MarkerTypeStar
+  deriving (Show, Eq, Ord, Enum)
+
+fromMarkerType :: MarkerType -> AFMarkerType
+fromMarkerType = AFMarkerType . fromIntegral . fromEnum
+
+toMarkerType :: AFMarkerType -> MarkerType
+toMarkerType (AFMarkerType (fromIntegral -> x)) = toEnum x
+
+-- | Match type
+data MatchType
+  = MatchTypeSAD
+  | MatchTypeZSAD
+  | MatchTypeLSAD
+  | MatchTypeSSD
+  | MatchTypeZSSD
+  | MatchTypeLSSD
+  | MatchTypeNCC
+  | MatchTypeZNCC
+  | MatchTypeSHD
+  deriving (Show, Eq, Ord, Enum)
+
+fromMatchType :: MatchType -> AFMatchType
+fromMatchType = AFMatchType . fromIntegral . fromEnum
+
+toMatchType :: AFMatchType -> MatchType
+toMatchType (AFMatchType (fromIntegral -> x)) = toEnum x
+
+-- | TopK type
+data TopK
+  = TopKDefault
+  | TopKMin
+  | TopKMax
+  deriving (Show, Eq, Ord, Enum)
+
+fromTopK :: TopK -> AFTopkFunction
+fromTopK = AFTopkFunction . fromIntegral . fromEnum
+
+toTopK :: AFTopkFunction -> TopK
+toTopK (AFTopkFunction (fromIntegral -> x)) = toEnum x
+
+-- | Homography Type
+data HomographyType
+  = RANSAC
+  | LMEDS
+  deriving (Show, Eq, Ord, Enum)
+
+fromHomographyType :: HomographyType -> AFHomographyType
+fromHomographyType = AFHomographyType . fromIntegral . fromEnum
+
+toHomographyType :: AFHomographyType -> HomographyType
+toHomographyType (AFHomographyType (fromIntegral -> x)) = toEnum x
+
+-- | Sequence Type
+data Seq
+  = Seq
+  { seqBegin :: !Double
+  , seqEnd :: !Double
+  , seqStep :: !Double
+  } deriving (Show, Eq, Ord)
+
+toAFSeq :: Seq -> AFSeq
+toAFSeq (Seq x y z) = (AFSeq x y z)
+
+-- | Index Type
+data Index a
+  = Index
+  { idx :: Either (Array a) Seq
+  , isSeq :: !Bool
+  , isBatch :: !Bool
+  }
+
+seqIdx :: Seq -> Bool -> Index a
+seqIdx s = Index (Right s) True
+
+arrIdx :: Array a -> Bool -> Index a
+arrIdx a = Index (Left a) False
+
+toAFIndex :: Index a -> IO AFIndex
+toAFIndex (Index a b c) = do
+  case a of
+    Right s -> pure $ AFIndex (Right (toAFSeq s)) b c
+    Left (Array fptr) -> do
+      withForeignPtr fptr $ \ptr ->
+        pure $ AFIndex (Left ptr) b c
+
+
+-- | Type alias for ArrayFire API version
+type Version = (Int,Int,Int)
+
+-- | Norm Type
+data NormType
+  = NormVectorOne
+  -- ^ treats the input as a vector and returns the sum of absolute values
+  | NormVectorInf
+  -- ^ treats the input as a vector and returns the max of absolute values
+  | NormVector2
+  -- ^ treats the input as a vector and returns euclidean norm
+  | NormVectorP
+  -- ^ treats the input as a vector and returns the p-norm
+  | NormMatrix1
+  -- ^ return the max of column sums
+  | NormMatrixInf
+  -- ^ return the max of row sums
+  | NormMatrix2
+  -- ^ returns the max singular value). Currently NOT SUPPORTED
+  | NormMatrixLPQ
+  -- ^ returns Lpq-norm
+  | NormEuclid
+  -- ^ The default. Same as AF_NORM_VECTOR_2
+  deriving (Show, Eq, Enum)
+
+fromNormType :: NormType -> AFNormType
+fromNormType = AFNormType . fromIntegral . fromEnum
+
+toNormType :: AFNormType -> NormType
+toNormType (AFNormType (fromIntegral -> x)) = toEnum x
+
+-- | Convolution Domain
+data ConvDomain
+  = ConvDomainAuto
+  -- ^ ArrayFire automatically picks the right convolution algorithm
+  | ConvDomainSpatial
+  -- ^ Perform convolution in spatial domain
+  | ConvDomainFreq
+  -- ^ Perform convolution in frequency domain
+  deriving (Show, Eq, Enum)
+
+-- | Convolution Mode
+data ConvMode
+  = ConvDefault
+  -- ^ Output of the convolution is the same size as input
+  | ConvExpand
+  -- ^ Output of the convolution is signal_len + filter_len - 1
+  deriving (Show, Eq, Enum)
+
+fromConvDomain :: ConvDomain -> AFConvDomain
+fromConvDomain = AFConvDomain . fromIntegral . fromEnum
+
+toConvDomain :: AFConvDomain -> ConvDomain
+toConvDomain (AFConvDomain (fromIntegral -> x)) = toEnum x
+
+fromConvMode :: AFConvMode -> ConvMode
+fromConvMode (AFConvMode (fromIntegral -> x)) = toEnum x
+
+toConvMode :: ConvMode -> AFConvMode
+toConvMode = AFConvMode . fromIntegral . fromEnum
+
+-- | Array Fire types
+data AFDType
+  = F32
+  | C32
+  | F64
+  | C64
+  | B8
+  | S32
+  | U32
+  | U8
+  | S64
+  | U64
+  | S16
+  | U16
+  deriving (Show, Eq, Enum)
+
+fromAFType :: AFDtype -> AFDType
+fromAFType (AFDtype (fromIntegral -> x)) = toEnum x
+
+toAFType :: AFDType -> AFDtype
+toAFType = AFDtype . fromIntegral . fromEnum
+
diff --git a/src/ArrayFire/Internal/Util.hs b/src/ArrayFire/Internal/Util.hs
new file mode 100644
--- /dev/null
+++ b/src/ArrayFire/Internal/Util.hs
@@ -0,0 +1,31 @@
+{-# LINE 1 "src/ArrayFire/Internal/Util.hsc" #-}
+{-# LANGUAGE CPP #-}
+module ArrayFire.Internal.Util where
+
+import ArrayFire.Internal.Defines
+import Foreign.Ptr
+import Foreign.C.Types
+
+
+foreign import ccall unsafe "af_print_array"
+    af_print_array :: AFArray -> IO AFErr
+foreign import ccall unsafe "af_print_array_gen"
+    af_print_array_gen :: Ptr CChar -> AFArray -> CInt -> IO AFErr
+foreign import ccall unsafe "af_save_array"
+    af_save_array :: Ptr CInt -> Ptr CChar -> AFArray -> Ptr CChar -> CBool -> IO AFErr
+foreign import ccall unsafe "af_read_array_index"
+    af_read_array_index :: Ptr AFArray -> Ptr CChar -> CUInt -> IO AFErr
+foreign import ccall unsafe "af_read_array_key"
+    af_read_array_key :: Ptr AFArray -> Ptr CChar -> Ptr CChar -> IO AFErr
+foreign import ccall unsafe "af_read_array_key_check"
+    af_read_array_key_check :: Ptr CInt -> Ptr CChar -> Ptr CChar -> IO AFErr
+foreign import ccall unsafe "af_array_to_string"
+    af_array_to_string :: Ptr (Ptr CChar) -> Ptr CChar -> AFArray -> CInt -> CBool -> IO AFErr
+foreign import ccall unsafe "af_example_function"
+    af_example_function :: Ptr AFArray -> AFArray -> AFSomeEnum -> IO AFErr
+foreign import ccall unsafe "af_get_version"
+    af_get_version :: Ptr CInt -> Ptr CInt -> Ptr CInt -> IO AFErr
+foreign import ccall unsafe "af_get_revision"
+    af_get_revision :: IO (Ptr CChar)
+foreign import ccall unsafe "af_get_size_of"
+    af_get_size_of :: Ptr CSize -> AFDtype -> IO AFErr
diff --git a/src/ArrayFire/Internal/Vision.hs b/src/ArrayFire/Internal/Vision.hs
new file mode 100644
--- /dev/null
+++ b/src/ArrayFire/Internal/Vision.hs
@@ -0,0 +1,31 @@
+{-# LINE 1 "src/ArrayFire/Internal/Vision.hsc" #-}
+{-# LANGUAGE CPP #-}
+module ArrayFire.Internal.Vision where
+
+import ArrayFire.Internal.Defines
+import Foreign.Ptr
+import Foreign.C.Types
+
+
+foreign import ccall unsafe "af_fast"
+    af_fast :: Ptr AFFeatures -> AFArray -> Float -> CUInt -> CBool -> Float -> CUInt -> IO AFErr
+foreign import ccall unsafe "af_harris"
+    af_harris :: Ptr AFFeatures -> AFArray -> CUInt -> Float -> Float -> CUInt -> Float -> IO AFErr
+foreign import ccall unsafe "af_orb"
+    af_orb :: Ptr AFFeatures -> Ptr AFArray -> AFArray -> Float -> CUInt -> Float -> CUInt -> CBool -> IO AFErr
+foreign import ccall unsafe "af_sift"
+    af_sift :: Ptr AFFeatures -> Ptr AFArray -> AFArray -> CUInt -> Float -> Float -> Float -> CBool -> Float -> Float -> IO AFErr
+foreign import ccall unsafe "af_gloh"
+    af_gloh :: Ptr AFFeatures -> Ptr AFArray -> AFArray -> CUInt -> Float -> Float -> Float -> CBool -> Float -> Float -> IO AFErr
+foreign import ccall unsafe "af_hamming_matcher"
+    af_hamming_matcher :: Ptr AFArray -> Ptr AFArray -> AFArray -> AFArray -> DimT -> CUInt -> IO AFErr
+foreign import ccall unsafe "af_nearest_neighbour"
+    af_nearest_neighbour :: Ptr AFArray -> Ptr AFArray -> AFArray -> AFArray -> DimT -> CUInt -> AFMatchType -> IO AFErr
+foreign import ccall unsafe "af_match_template"
+    af_match_template :: Ptr AFArray -> AFArray -> AFArray -> AFMatchType -> IO AFErr
+foreign import ccall unsafe "af_susan"
+    af_susan :: Ptr AFFeatures -> AFArray -> CUInt -> Float -> Float -> Float -> CUInt -> IO AFErr
+foreign import ccall unsafe "af_dog"
+    af_dog :: Ptr AFArray -> AFArray -> CInt -> CInt -> IO AFErr
+foreign import ccall unsafe "af_homography"
+    af_homography :: Ptr AFArray -> Ptr CInt -> AFArray -> AFArray -> AFArray -> AFArray -> AFHomographyType -> Float -> CUInt -> AFDtype -> IO AFErr
diff --git a/src/ArrayFire/LAPACK.hs b/src/ArrayFire/LAPACK.hs
--- a/src/ArrayFire/LAPACK.hs
+++ b/src/ArrayFire/LAPACK.hs
@@ -220,21 +220,6 @@
 inverse a m =
   a `op1` (\x y  -> af_inverse x y (toMatProp m))
 
--- | Pseudo-inverse
---
--- Not implemented in /3.6.4/
---
--- [ArrayFire Docs](http://arrayfire.org/docs/group__lapack__factor__func__p_inv.htm)
---
--- pinverse
---   :: AFType a
---   => Array a
---   -> Double
---   -> MatProp
---   -> Array a
--- pinverse a d m =
---   op1 a (\x y  -> af_pinverse x y d (toMatProp m))
-
 -- | Find the rank of the input matrix
 --
 -- [ArrayFire Docs](http://arrayfire.org/docs/group__lapack__factor__func__rank.htm)
diff --git a/src/ArrayFire/Random.hs b/src/ArrayFire/Random.hs
--- a/src/ArrayFire/Random.hs
+++ b/src/ArrayFire/Random.hs
@@ -240,7 +240,7 @@
           ptr
   where
     n = fromIntegral (length dims)
-    typ = afType (Proxy @ a)
+    typ = afType (Proxy @a)
 
 rand
   :: forall a . AFType a
@@ -260,7 +260,7 @@
         ptr
       where
         n = fromIntegral (length dims)
-        typ = afType (Proxy @ a)
+        typ = afType (Proxy @a)
 
 -- | Generate random 'Array'
 --
diff --git a/src/ArrayFire/Vision.hs b/src/ArrayFire/Vision.hs
--- a/src/ArrayFire/Vision.hs
+++ b/src/ArrayFire/Vision.hs
@@ -360,4 +360,4 @@
                   (,) <$> do fromIntegral <$> peek outPtrI
                       <*> do Array <$> newForeignPtr af_release_array_finalizer arrayPtr
     where
-      dtype = afType (Proxy @ a)
+      dtype = afType (Proxy @a)
diff --git a/test/ArrayFire/AlgorithmSpec.hs b/test/ArrayFire/AlgorithmSpec.hs
--- a/test/ArrayFire/AlgorithmSpec.hs
+++ b/test/ArrayFire/AlgorithmSpec.hs
@@ -63,7 +63,7 @@
       A.product (A.vector @Double 10 [1..]) 0 `shouldBe` 3628800.0
       A.product (A.vector @(A.Complex Double) 10 (repeat (1 A.:+ 1))) 0 `shouldBe` A.scalar (0.0 A.:+ 32.0)
       A.product (A.vector @(A.Complex Float) 10 (repeat (1 A.:+ 1))) 0 `shouldBe` A.scalar (0.0 A.:+ 32.0)
-      A.product (A.vector @A.CBool 10 (repeat 1)) 0 `shouldBe` 10  -- FIXME: This is a bug, should be 0
+      A.product (A.vector @A.CBool 10 (repeat 1)) 0 `shouldBe` 1 -- FIXED in 3.8.2, vector product along 0-axis is 1 for vector size 10 of all 1's.
       A.product (A.vector @A.CBool 10 (repeat 0)) 0 `shouldBe` 0
     it "Should product a default value to replace NaN" $ do
       A.productNaN (A.vector @Float 10 [1..]) 0 1.0 `shouldBe` 3628800.0
@@ -100,7 +100,7 @@
     it "Should get sum all elements" $ do
       A.sumAll (A.vector @Int 5 (repeat 2)) `shouldBe` (10,0)
       A.sumAll (A.vector @Double 5 (repeat 2)) `shouldBe` (10.0,0)
-      -- A.sumAll (A.vector @A.CBool 3800 (repeat 1)) `shouldBe` (3800,0) -- causes strange behavior
+      A.sumAll (A.vector @A.CBool 3800 (repeat 1)) `shouldBe` (3800,0)
       A.sumAll (A.vector @(A.Complex Double) 5 (repeat (2 A.:+ 0))) `shouldBe` (10.0,0)
     it "Should get sum all elements" $ do
       A.sumNaNAll (A.vector @Double 2 [10, acos 2]) 1 `shouldBe` (11.0,0)
diff --git a/test/ArrayFire/StatisticsSpec.hs b/test/ArrayFire/StatisticsSpec.hs
--- a/test/ArrayFire/StatisticsSpec.hs
+++ b/test/ArrayFire/StatisticsSpec.hs
@@ -20,7 +20,7 @@
     it "Should find the variance" $ do
       var (vector @Double 8 [1..8]) False 0
         `shouldBe`
-           6.0
+           5.25
     it "Should find the weighted variance" $ do
       varWeighted (vector @Double 8 [1..]) (vector @Double 8 (repeat 1)) 0
         `shouldBe`
diff --git a/test/ArrayFire/UtilSpec.hs b/test/ArrayFire/UtilSpec.hs
--- a/test/ArrayFire/UtilSpec.hs
+++ b/test/ArrayFire/UtilSpec.hs
@@ -15,23 +15,23 @@
 spec =
   describe "Util spec" $ do
     it "Should get size of" $ do
-      A.getSizeOf (Proxy @ Int) `shouldBe` 8
-      A.getSizeOf (Proxy @ Int64) `shouldBe` 8
-      A.getSizeOf (Proxy @ Int32) `shouldBe` 4
-      A.getSizeOf (Proxy @ Int16) `shouldBe` 2
-      A.getSizeOf (Proxy @ Word) `shouldBe` 8
-      A.getSizeOf (Proxy @ Word64) `shouldBe` 8
-      A.getSizeOf (Proxy @ Word32) `shouldBe` 4
-      A.getSizeOf (Proxy @ Word16) `shouldBe` 2
-      A.getSizeOf (Proxy @ Word8) `shouldBe` 1
-      A.getSizeOf (Proxy @ CBool) `shouldBe` 1
-      A.getSizeOf (Proxy @ Double) `shouldBe` 8
-      A.getSizeOf (Proxy @ Float) `shouldBe` 4
-      A.getSizeOf (Proxy @ (Complex Float)) `shouldBe` 8
-      A.getSizeOf (Proxy @ (Complex Double)) `shouldBe` 16
+      A.getSizeOf (Proxy @Int) `shouldBe` 8
+      A.getSizeOf (Proxy @Int64) `shouldBe` 8
+      A.getSizeOf (Proxy @Int32) `shouldBe` 4
+      A.getSizeOf (Proxy @Int16) `shouldBe` 2
+      A.getSizeOf (Proxy @Word) `shouldBe` 8
+      A.getSizeOf (Proxy @Word64) `shouldBe` 8
+      A.getSizeOf (Proxy @Word32) `shouldBe` 4
+      A.getSizeOf (Proxy @Word16) `shouldBe` 2
+      A.getSizeOf (Proxy @Word8) `shouldBe` 1
+      A.getSizeOf (Proxy @CBool) `shouldBe` 1
+      A.getSizeOf (Proxy @Double) `shouldBe` 8
+      A.getSizeOf (Proxy @Float) `shouldBe` 4
+      A.getSizeOf (Proxy @(Complex Float)) `shouldBe` 8
+      A.getSizeOf (Proxy @(Complex Double)) `shouldBe` 16
     it "Should get version" $ do
       x <- A.getVersion
-      x `shouldBe` (3,6,4)
+      x `shouldBe` (3,8,2)
     it "Should get revision" $ do
       x <- A.getRevision
       x `shouldSatisfy` (not . null)
