 foreign import ccall "wrapper"
     doAutoRelease   :: (Ptr () -> IO ()) -> IO (FunPtr (Ptr () -> IO ()))
 
--- |
--- Copy data between host and device
---
-memcpy :: DevicePtr -> DevicePtr -> Integer -> CopyDirection -> IO (Maybe String)
-memcpy dst src bytes dir =  nothingIfOk `fmap` cudaMemcpy dst src bytes dir
-
-{# fun unsafe cudaMemcpy
-    { withDevicePtr* `DevicePtr'     ,
-      withDevicePtr* `DevicePtr'     ,
-      cIntConv       `Integer'       ,
-      cFromEnum      `CopyDirection' } -> `Status' cToEnum #}
-
--- |
--- Copy data between host and device asynchronously
---
-memcpyAsync :: DevicePtr -> DevicePtr -> Integer -> CopyDirection -> Stream -> IO (Maybe String)
-memcpyAsync dst src bytes dir stream =  nothingIfOk `fmap` cudaMemcpyAsync dst src bytes dir stream
-
-{# fun unsafe cudaMemcpyAsync
-    { withDevicePtr* `DevicePtr'     ,
-      withDevicePtr* `DevicePtr'     ,
-      cIntConv       `Integer'       ,
-      cFromEnum      `CopyDirection' ,
-      cIntConv       `Stream'        } -> `Status' cToEnum #}
-
--- |
--- Initialize device memory to a given value
+
+-- |
+-- Initialise device memory to a given value
 --
 memset                  :: DevicePtr -> Integer -> Int -> IO (Maybe String)
 memset ptr bytes symbol =  nothingIfOk `fmap` cudaMemset ptr symbol bytes

--------------------------------------------------------------------------------

-- |
-- A reference to data stored on the device
--
newtype DevicePtr = DevicePtr (ForeignPtr ())


-- function may pad the allocation to ensure corresponding pointers in each row
-- meet coalescing requirements. The actual allocation width is returned.
--
malloc2D :: (Integer, Integer)          -- ^ allocation (width,height) in bytes
         -> IO (Either String (DevicePtr,Integer))
malloc2D (width,height) =  do
    (rv,ptr,pitch) <- cudaMallocPitch width height
    case rv of
        Success -> doAutoRelease free_ >>= \fp ->
