code: def make_thunk(self, node, storage_map, _, _2, impl=None):
      inputs = [storage_map[v] for v in node.inputs]
      outputs = [storage_map[v] for v in node.outputs]
  
      # Initiliaze cuda context to the input's.
      with node.inputs[0].type.context:
          skcuda.misc.init()
  
      plan_input_shape = [None]
      plan = [None]
  
      def thunk():
          input_shape = inputs[0][0].shape
          s = inputs[1][0]
  
          # Since padding is not supported, assert that last dimension corresponds to
          # input forward transform size.
          assert (input_shape[1:-2] == s[:-1]).all()
          assert ((input_shape[-2] - 1) * 2 + s[-1] % 2 == s[-1]).all()
  
          # construct output shape
          # chop off the extra length-2 dimension for real/imag
          output_shape = [input_shape[0]] + list(s)
          output_shape = tuple(output_shape)
  
          z = outputs[0]
  
          # only allocate if there is no previous allocation of the
          # right size.
          if z[0] is None or z[0].shape != output_shape:
              z[0] = pygpu.zeros(
                  output_shape,
                  context=inputs[0][0].context,
                  dtype="float32",
              )
  
          input_pycuda = inputs[0][0]
          # input_pycuda is a float32 array with an extra dimension,
          # but will be interpreted by skcuda as a complex64
          # array instead.
          output_pycuda = z[0]
  
          with input_pycuda.context:
              # only initialise plan if necessary
              if plan[0] is None or plan_input_shape[0] != input_shape:
                  plan_input_shape[0] = input_shape
                  plan[0] = fft.Plan(
                      s, np.complex64, np.float32, batch=output_shape[0]
                  )
  
              # Sync GPU variables before computation
              input_pycuda.sync()
              output_pycuda.sync()
  
              fft.ifft(input_pycuda, output_pycuda, plan[0])
              # strangely enough, enabling rescaling here makes it run
              # very, very slowly, so do this rescaling manually
              # afterwards!
  
              # Sync results to ensure output contains completed computation
              pycuda.driver.Context.synchronize()
  
      thunk.inputs = inputs
      thunk.outputs = outputs
      thunk.lazy = False
  
      return thunk
  
imports: from __future__ import absolute_import, print_function, division
  import numpy
  import theano
  from theano import Op
  import theano.tensor
  from theano.gradient import DisconnectedType
  from .basic_ops import gpu_contiguous, as_gpuarray_variable, infer_context_name
  from .type import GpuArrayType
  import theano.tensor.fft
  from .opt import register_opt, op_lifter, register_opt2
label_desc: Use image node_id 3 for calling the CuIRFFTOp obj's underlying member method code with example usage: obj.make_thunk(node, storage_map, _, _2, impl) and returns: thunk