 clReleaseKernel :: CLKernel -> IO Bool
 clReleaseKernel krn = wrapCheckSuccess $ raw_clReleaseKernel krn
 
+{-| Used to set the argument value for a specific argument of a kernel.
+
+A kernel object does not update the reference count for objects such as memory,
+sampler objects specified as argument values by 'clSetKernelArg', Users may not
+rely on a kernel object to retain objects specified as argument values to the
+kernel.
+
+Implementations shall not allow 'CLKernel' objects to hold reference counts to
+'CLKernel' arguments, because no mechanism is provided for the user to tell the
+kernel to release that ownership right. If the kernel holds ownership rights on
+kernel args, that would make it impossible for the user to tell with certainty
+when he may safely release user allocated resources associated with OpenCL
+objects such as the CLMem backing store used with 'CL_MEM_USE_HOST_PTR'.
+
+'clSetKernelArg' returns returns one of the following errors when fails:
+
+ * 'CL_INVALID_KERNEL' if kernel is not a valid kernel object.
+ 
+ * 'CL_INVALID_ARG_INDEX' if arg_index is not a valid argument index.
+
+ * 'CL_INVALID_ARG_VALUE' if arg_value specified is NULL for an argument that is
+not declared with the __local qualifier or vice-versa.
+
+ * 'CL_INVALID_MEM_OBJECT' for an argument declared to be a memory object when
+the specified arg_value is not a valid memory object.
+
+ * 'CL_INVALID_SAMPLER' for an argument declared to be of type sampler_t when
+the specified arg_value is not a valid sampler object.
+
+ * 'CL_INVALID_ARG_SIZE' if arg_size does not match the size of the data type
+for an argument that is not a memory object or if the argument is a memory
+object and arg_size != sizeof(cl_mem) or if arg_size is zero and the argument is
+declared with the __local qualifier or if the argument is a sampler and arg_size
+!= sizeof(cl_sampler).  
+-}
+clSetKernelArg :: Storable a => CLKernel -> CLuint -> a -> IO (Either CLError ())
+clSetKernelArg krn idx val = with val $ \pval -> do
+  errcode <- raw_clSetKernelArg krn idx (fromIntegral . sizeOf $ val) (castPtr pval)
+  if errcode == (fromIntegral . fromEnum $ CL_SUCCESS)
+    then return $ Right ()
+    else return . Left . toEnum . fromIntegral $ errcode
+
 #c
 enum CLKernelInfo {
   cL_KERNEL_FUNCTION_NAME=CL_KERNEL_FUNCTION_NAME,

  clGetProgramBuildStatus, clGetProgramBuildOptions, clGetProgramBuildLog,
  -- * Kernel Functions
  clCreateKernel, clCreateKernelsInProgram, clRetainKernel, clReleaseKernel, 
  clGetKernelFunctionName, clGetKernelNumArgs, clGetKernelReferenceCount, 
  clGetKernelContext, clGetKernelProgram
  ) where

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

import Foreign.C.Types
import Foreign.C.String( CString, withCString, newCString, peekCString )
import System.GPU.OpenCL.Types( 
  CLint, CLuint, CLulong, CLProgram, CLContext, CLKernel, CLDeviceID, 
  CLError(..), CLProgramInfo_, CLBuildStatus(..), CLBuildStatus_, 
  CLProgramBuildInfo_, CLKernelInfo_, CLKernelWorkGroupInfo_, wrapCheckSuccess, 
  wrapPError, wrapGetInfo, getCLValue, getEnumCL )

#include <CL/cl.h>

