code: def MetropolisOpenCL(InputCL):
      import pyopencl as cl
  
      iterations = InputCL["Iterations"]
      steps = InputCL["Steps"]
      blocks = InputCL["Blocks"]
      threads = InputCL["Threads"]
      Device = InputCL["Device"]
      RNG = InputCL["RNG"]
      ValueType = InputCL["ValueType"]
      TestType = InputCL["IfThen"]
      Seeds = InputCL["Seeds"]
  
      Marsaglia, Computing, Test = DictionariesAPI()
  
      # Initialisation des variables en les CASTant correctement
      Id = 0
      HasXPU = False
      for platform in cl.get_platforms():
          for device in platform.get_devices():
              if Id == Device:
                  XPU = device
                  print("CPU/GPU selected: ", device.name.lstrip())
                  HasXPU = True
              Id += 1
              # print(Id)
  
      if not HasXPU:
          print(
              "No XPU #%i found in all of %i devices, sorry..."
              % (Device, Id - 1)
          )
          sys.exit()
  
      # Je cree le contexte et la queue pour son execution
      try:
          ctx = cl.Context(devices=[XPU])
          queue = cl.CommandQueue(
              ctx,
              properties=cl.command_queue_properties.PROFILING_ENABLE,
          )
      except Exception:
          print("Crash during context creation")
  
      # Je recupere les flag possibles pour les buffers
      mf = cl.mem_flags
  
      circle = numpy.zeros(blocks * threads).astype(numpy.uint64)
      circleCL = cl.Buffer(
          ctx, mf.WRITE_ONLY | mf.COPY_HOST_PTR, hostbuf=circle
      )
  
      MetropolisCL = cl.Program(ctx, KernelCodeOpenCL()).build(
          options="-cl-mad-enable -cl-fast-relaxed-math -DTRNG=%i -DTYPE=%s -DTEST=%s"
          % (Marsaglia[RNG], Computing[ValueType], Test[TestType])
      )
  
      MyDuration = numpy.zeros(steps)
  
      jobs = blocks * threads
  
      iterationsCL = numpy.uint64(iterations / jobs)
      if iterations % jobs != 0:
          iterationsCL += 1
  
      for i in range(steps):
          start_time = time.time()
          if threads == 1:
              CLLaunch = MetropolisCL.MainLoopGlobal(
                  queue,
                  (blocks,),
                  None,
                  circleCL,
                  numpy.uint64(iterationsCL),
                  numpy.uint32(Seeds[0]),
                  numpy.uint32(Seeds[1]),
              )
          else:
              CLLaunch = MetropolisCL.MainLoopHybrid(
                  queue,
                  (jobs,),
                  (threads,),
                  circleCL,
                  numpy.uint64(iterationsCL),
                  numpy.uint32(Seeds[0]),
                  numpy.uint32(Seeds[1]),
              )
  
          CLLaunch.wait()
          cl.enqueue_copy(queue, circle, circleCL).wait()
  
          elapsed = time.time() - start_time
          print(
              "(Blocks/Threads)=(%i,%i) method done in %.2f s..."
              % (blocks, threads, elapsed)
          )
  
          # Elapsed method based on CLLaunch doesn't work for Beignet OpenCL
          # elapsed = 1e-9*(CLLaunch.profile.end - CLLaunch.profile.start)
  
          # print circle,numpy.mean(circle),numpy.median(circle),numpy.std(circle)
          MyDuration[i] = elapsed
          # AllPi=4./numpy.float32(iterationsCL)*circle.astype(numpy.float32)
          # MyPi[i]=numpy.median(AllPi)
          # print MyPi[i],numpy.std(AllPi),MyDuration[i]
  
      circleCL.release()
  
      OutputCL = {
          "Inside": sum(circle),
          "NewIterations": numpy.uint64(iterationsCL * jobs),
          "Duration": MyDuration,
      }
      # print(OutputCL)
      return OutputCL
  
imports: import numpy
  import sys
  import getopt
  import time
  import itertools
  from socket import gethostname
label_desc: Use image node_id 11 for calling a global function with example usage: MetropolisOpenCL(InputCL) and returns: OutputCL