 -- meet coalescing requirements. The actual allocation width is returned.
 --
 malloc2D :: (Int64, Int64)              -- ^ allocation (width,height) in bytes
-         -> IO (Either String (DevicePtr (),Int64))
+         -> IO (Either String (DevicePtr a,Int64))
 malloc2D (width,height) =  do
     (rv,ptr,pitch) <- cudaMallocPitch width height
     case rv of
-        Success -> (\p -> Right (p,pitch)) `fmap` newDevicePtr ptr
+        Success -> (\p -> Right (p,pitch)) `fmap` newDevicePtr (castPtr ptr)
         _       -> return . Left . describe $ rv
 
 {# fun unsafe cudaMallocPitch

-- requirements are met. The actual allocation pitch is returned
--
malloc3D :: (Int64,Int64,Int64)         -- ^ allocation (width,height,depth) in bytes
         -> IO (Either String (DevicePtr (),Int64))
malloc3D = moduleErr "malloc3D" "not implemented yet"



-- free   :: Ptr () -> IO (Maybe String)
-- free p =  nothingIfOk `fmap` cudaFree p

free_   :: Ptr a -> IO ()
free_ p =  throwIf_ (/= Success) (describe) (cudaFree p)

{# fun unsafe cudaFree
    { castPtr `Ptr a' } -> `Status' cToEnum #}

foreign import ccall "wrapper"
    doAutoRelease   :: (Ptr a -> IO ()) -> IO (FunPtr (Ptr a -> IO ()))


-- |
-- Initialise device memory to a given value
--
memset                  :: DevicePtr a -> Int64 -> Int -> IO (Maybe String)
memset ptr bytes symbol =  nothingIfOk `fmap` cudaMemset ptr symbol bytes

{# fun unsafe cudaMemset
    { withDevicePtr* `DevicePtr a' ,
                     `Int'         ,
      cIntConv       `Int64'       } -> `Status' cToEnum #}


-- |
-- Initialise a matrix to a given value
--
memset2D :: DevicePtr a                 -- ^ The device memory
         -> (Int64,Int64)               -- ^ The (width,height) of the matrix in bytes
         -> Int64                       -- ^ The allocation pitch, as returned by 'malloc2D'
         -> Int                         -- ^ Value to set for each byte
