code: def benchmark(self, func, gpu_args, threads, grid, times):
          
          start = drv.Event()
          end = drv.Event()
          time = []
          for _ in range(self.iterations):
              self.context.synchronize()
              start.record()
              self.run_kernel(func, gpu_args, threads, grid)
              end.record()
              self.context.synchronize()
              time.append(end.time_since(start))
          time = sorted(time)
          if times:
              return time
          else:
              if self.iterations > 4:
                  return numpy.mean(time[1:-1])
              else:
                  return numpy.mean(time)
docs: runs the kernel and measures time repeatedly, returns average time
  
          Runs the kernel and measures kernel execution time repeatedly, number of
          iterations is set during the creation of CudaFunctions. Benchmark returns
          a robust average, from all measurements the fastest and slowest runs are
          discarded and the rest is included in the returned average. The reason for
          this is to be robust against initialization artifacts and other exceptional
          cases.
  
          :param func: A PyCuda kernel compiled for this specific kernel configuration
          :type func: pycuda.driver.Function
  
          :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.
          :type gpu_args: list( pycuda.driver.DeviceAllocation, numpy.int32, ...)
  
          :param threads: A tuple listing the number of threads in each dimension of
              the thread block
          :type threads: tuple(int, int, int)
  
          :param grid: A tuple listing the number of thread blocks in each dimension
              of the grid
          :type grid: tuple(int, int)
  
          :param times: Return the execution time of all iterations.
          :type times: bool
  
          :returns: All execution times, if times=True, or a robust average for the
              kernel execution time.
          :rtype: float