Yes, there absolutely is - you can profile the individual PyOpenCL events run on the Device, and you can also profile the overall program on the Host.
PyOpenCL events are returned by copying memory to the device, running a kernel on the device, and copying memory back from the device.
Here is an example of profiling a Device event:
event = cl.enqueue_copy(queue, np_array, cl_array)
event.wait()
print (event.profile.end-event.profile.start)*1e-9
Here is an example of profiling on the host:
from time import time, strftime, gmtime
start_time = time()
# ... do some stuff like the above ^
end_time = time()
print strftime('%H:%M:%S', gmtime(end_time - start_time))
I haven't seen a more comprehensive way to profile a PyOpenCL program. Hope that helps though!