class_docstr: Implements TopKOp on gpu
  
  Currently the output seem sorted, but we do not test it. So as on
  the CPU, we only support sorted=False for now.
class_docstr_tok: ["Implements","TopKOp","on","gpu","Currently","the","output","seem","sorted",",","but","we","do","not","test","it",".","So","as","on","the","CPU",",","we","only","support","sorted=False","for","now","."]
code: def gpu_kernels(self, node, nodename):
      # load kernel source
      device_type = node.inputs[0].type.context.kind
      kernel_ext = {b"cuda": ".cu", b"opencl": ".cl"}[device_type]
      common_ext = {b"cuda": ".cuh", b"opencl": ".h"}[device_type]
  
      # prepare "$" macros
      if device_type == b"cuda":
          ndim = node.inputs[0].ndim
          dstv_strides_code = "".join(
              "ssize_t dstv_strides_%d, " % i for i in range(ndim)
          )
          dsti_strides_code = "".join(
              "ssize_t dsti_strides_%d, " % i for i in range(ndim)
          )
          src_strides_code = "".join(
              "ssize_t src_strides_%d, " % i for i in range(ndim)
          )
          set_slice_code = """
          gidx = gid %% dims_%(i)d;
          gid /= dims_%(i)d;
          {dstv};
          {dsti};
          src = ptr_add(src, gidx*src_strides_%(i)d);\n""".format(
              dstv="dstv = ptr_add(dstv, gidx*dstv_strides_%(i)d)"
              if self.return_values
              else "",
              dsti="dsti = ptr_add(dsti, gidx*dsti_strides_%(i)d)"
              if self.return_indices
              else "",
          )
          set_slice_code = "".join(
              set_slice_code % dict(i=j) for j in range(1, ndim)
          )
          if self.return_values:
              set_slice_code += """
                  dstv = ptr_add(dstv, dstv_offset);
                  """
          if self.return_indices:
              set_slice_code += """
                  dsti = ptr_add(dsti, dsti_offset);
                  """
          set_slice_code += """
                  src = ptr_add(src, src_offset);
              """
          flags = Kernel.get_flags(node.inputs[0].dtype)
          subs = dict(
              inp_t=ga.dtype_to_ctype(node.inputs[0].dtype),
              out_t=ga.dtype_to_ctype(self.idx_dtype),
              dims="".join(
                  "size_t dims_%d, " % i for i in range(1, ndim)
              ),
              dstv="INPUT_TYPE *dstv," if self.return_values else "",
              dstv_offset="size_t dstv_offset,"
              if self.return_values
              else "",
              dsti="INDEX_TYPE *dsti," if self.return_indices else "",
              dsti_offset="size_t dsti_offset,"
              if self.return_indices
              else "",
              dstv_strides=dstv_strides_code
              if self.return_values
              else "",
              dsti_strides=dsti_strides_code
              if self.return_indices
              else "",
              src_strides=src_strides_code,
              set_slice=set_slice_code,
              write_value=int(self.return_values),
              write_index=int(self.return_indices),
              ndim=str(ndim),
          )
      elif device_type == b"opencl":
          raise NotImplementedError()
  
      # setup parameters
      param_types = [ga.SIZE] * (ndim - 1)  # dims
      for _ in range(self.return_values + self.return_indices):
          param_types.append(ga.GpuArray)  # dst*
          param_types.append(ga.SIZE)  # offset
          param_types.extend([ga.SSIZE] * ndim)  # dst*_strides
      param_types.append(ga.SIZE)  # k
      param_types.append(ga.GpuArray)  # src
      param_types.append(ga.SIZE)  # offset
      param_types.extend([ga.SSIZE] * ndim)  # src_strides
      param_types.append(ga.SIZE)  # size
  
      # load and compile kernels
      with open(
          os.path.join(
              os.path.dirname(__file__),
              "c_code",
              "topk_common" + common_ext,
          )
      ) as f:
          common_src = f.read()
  
      kernels = []
  
      def build_kernel(fname, kname, subs):
          with open(
              os.path.join(os.path.dirname(__file__), "c_code", fname)
          ) as f:
              kernel_src = f.read()
          ker = Kernel(
              code=(
                  "#include <cluda.h>\n"
                  + Template(common_src + kernel_src).substitute(**subs)
              ),
              name=kname,
              params=param_types,
              flags=flags,
              objvar=kname + nodename,
          )
          return ker
  
      subs["count_t"] = "int"
      kernels.append(
          build_kernel("topk_dense" + kernel_ext, "k_topk_dense", subs)
      )
      subs["kname"] = "k_topk_dense_large"
      kernels.append(
          build_kernel(
              "topk_dense_large" + kernel_ext,
              "k_topk_dense_large",
              subs,
          )
      )
      subs["count_t"] = "long long"
      subs["kname"] = "k_topk_dense_xlarge"
      kernels.append(
          build_kernel(
              "topk_dense_large" + kernel_ext,
              "k_topk_dense_xlarge",
              subs,
          )
      )
      return kernels
  
imports: from __future__ import absolute_import, print_function, division
  import os
  from string import Template
  import numpy
  import theano
  from theano import Apply
  from theano.tensor import as_tensor_variable
  from theano.tensor.sort import TopKOp
  from .basic_ops import GpuKernelBase, Kernel, infer_context_name, as_gpuarray_variable, gpuarray_helper_inc_dir
  from .opt import register_opt, op_lifter, register_opt2
  from .type import GpuArrayType
label_desc: Use image node_id 6 for calling the GpuTopKOp obj's underlying member method code with example usage: obj.gpu_kernels(node, nodename) and returns: kernels, ker