<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def run_kernel(self, func, gpu_args, threads, grid):
 """runs the OpenCL kernel passed as 'func' :param func: An OpenCL Kernel :type func: pyopencl.Kernel :param gpu_args: A list of arguments to the kernel, order should match the order in the code. Allowed values are either variables in global memory or single values passed by value. :param threads: A tuple listing the number of work items in each dimension of the work group. :type threads: tuple(int, int, int) :param grid: A tuple listing the number of work groups in each dimension of the NDRange. :type grid: tuple(int, int) """

        global_size = (grid[0]*threads[0], grid[1]*threads[1], grid[2]*threads[2])
        local_size = threads
        event = func(self.queue, global_size, local_size, *gpu_args)
        event.wait()