class_docstr: Implement CrossentropySoftmaxArgmax1HotWithBias on the gpu.
code: def gpu_kernels(self, node, nodename):
      dtype_x = node.inputs[0].dtype
      dtype_b = node.inputs[1].dtype
      dtype_y_idx = node.inputs[2].dtype
      work_x = work_dtype(dtype_x)
      work_b = work_dtype(dtype_b)
      load_x = load_w(dtype_x)
      load_b = load_w(dtype_b)
      write_x = write_w(dtype_x)
      write_b = write_w(dtype_b)
      flags = Kernel.get_flags(dtype_x, dtype_b, dtype_y_idx)
      type_x = gpuarray.dtype_to_ctype(dtype_x)
      type_b = gpuarray.dtype_to_ctype(dtype_b)
      work_x = gpuarray.dtype_to_ctype(work_x)
      type_y_idx = gpuarray.dtype_to_ctype(dtype_y_idx)
      kname = "k_xent_sm_1hot_bias"
      k_var = "k_xent_sm_1hot_bias_" + nodename
      if node.inputs[0].type.context.kind != b"cuda":
          f = ""
      else:
          f = "" if dtype_x == "float64" else "f"
      params = [
          gpuarray.SIZE,
          gpuarray.SIZE,
          gpuarray.GpuArray,
          gpuarray.SIZE,
          gpuarray.SSIZE,
          gpuarray.SSIZE,
          gpuarray.GpuArray,
          gpuarray.SIZE,
          gpuarray.SSIZE,
          gpuarray.GpuArray,
          gpuarray.SIZE,
          gpuarray.SSIZE,
          gpuarray.GpuArray,
          gpuarray.SIZE,
          gpuarray.SSIZE,
          gpuarray.GpuArray,
          gpuarray.SIZE,
          gpuarray.SSIZE,
          gpuarray.SSIZE,
          gpuarray.GpuArray,
          gpuarray.SIZE,
          gpuarray.SSIZE,
      ]
      sio = StringIO()
      print(
          """#include "cluda.h"
  
          KERNEL void %(kname)s(const ga_size M, const ga_size N,
              GLOBAL_MEM const %(type_x)s* x_data, const ga_size offset_x, const ga_ssize xs0, const ga_ssize xs1,
              GLOBAL_MEM const %(type_b)s* b, const ga_size offset_b, const ga_ssize bs0,
              GLOBAL_MEM const %(type_y_idx)s* y_idx_data, const ga_size offset_y_idx, const ga_ssize y_idxs0,
              GLOBAL_MEM %(type_x)s* nll_data, const ga_size offset_nll, const ga_ssize nlls0,
              GLOBAL_MEM %(type_x)s* sm_data, const ga_size offset_sm, const ga_ssize sms0, const ga_ssize sms1,
              GLOBAL_MEM %(type_y_idx)s* am_data, const ga_size offset_am, const ga_ssize ams0 GA_DECL_SHARED_PARAM(%(work_x)s, per_thread_values))
          {
            x_data = (GLOBAL_MEM const %(type_x)s *)(((GLOBAL_MEM char *)x_data)+offset_x);
            b = (GLOBAL_MEM const %(type_b)s *)(((GLOBAL_MEM char *)b)+offset_b);
            y_idx_data = (GLOBAL_MEM const %(type_y_idx)s *)(((GLOBAL_MEM char *)y_idx_data)+offset_y_idx);
            nll_data = (GLOBAL_MEM %(type_x)s *)(((GLOBAL_MEM char *)nll_data)+offset_nll);
            sm_data = (GLOBAL_MEM %(type_x)s *)(((GLOBAL_MEM char *)sm_data)+offset_sm);
            am_data = (GLOBAL_MEM %(type_y_idx)s *)(((GLOBAL_MEM char *)am_data)+offset_am);
            for (ga_int row = GID_0; row < M; row += GDIM_0){
              GLOBAL_MEM const %(type_x)s* x = x_data + xs0 * row;
              GLOBAL_MEM %(type_x)s* sm = sm_data + sms0 * row;
              GA_DECL_SHARED_BODY(%(work_x)s, per_thread_values);
              LOCAL_MEM %(work_x)s row_max, sum, sum_inv;
              LOCAL_MEM ga_int row_max_threadIdx;
              %(work_x)s per_thread_row_max, per_thread_sum;
              ga_int per_thread_row_max_j;
              // COMPUTE ROW MAX AND ARGMAX
              // compute separate per-thread maximums and argmaxes
              per_thread_row_max = NAN;
              per_thread_row_max_j = 0;
              for (ga_int j = LID_0; j < N; j += LDIM_0)
              {
                %(work_x)s row_ij = %(load_x)s(x[j * xs1]) + %(load_b)s(b[j * bs0]);
                per_thread_row_max_j = (row_ij > per_thread_row_max) ? j : per_thread_row_max_j;
                per_thread_row_max = fmax%(f)s(row_ij, per_thread_row_max);
              }
              per_thread_values[LID_0] = per_thread_row_max;
              local_barrier();
              if (LID_0 == 0) {
                row_max = NAN;
                row_max_threadIdx = 0;
                for (ga_int j = 0; j < LDIM_0; j++)
                {
                  %(work_x)s per_thread_max = per_thread_values[j];
                  row_max_threadIdx = (per_thread_max > row_max) ? j : row_max_threadIdx;
                  row_max = fmax%(f)s(per_thread_max, row_max);
                }
              }
              local_barrier();
              // The thread with the highest max writes out which of its
              // values was the winner.
              if (LID_0 == row_max_threadIdx) am_data[row * ams0] = per_thread_row_max_j;
              // COMPUTE SOFTMAX
              per_thread_sum = 0.0;
              for (ga_int j = LID_0; j < N; j += LDIM_0)
              {
                %(work_x)s row_ij = %(load_x)s(x[j * xs1]) + %(load_b)s(b[j * bs0]);
                %(work_x)s sm_ij = exp%(f)s(row_ij - row_max);
                per_thread_sum += sm_ij;
                sm[j * sms1] = %(write_x)s(sm_ij);
              }
              per_thread_values[LID_0] = per_thread_sum;
              local_barrier();
              if (LID_0 == 0) {
                sum = 0.0;
                for (ga_int j = 0; j < LDIM_0; j++) {
                  sum += per_thread_values[j];
                }
                sum_inv = 1.0 / sum;
              }
              local_barrier();
              for (ga_int j = LID_0; j < N; j += LDIM_0) {
                sm[j * sms1] = %(write_x)s(%(load_x)s(sm[j * sms1]) * sum_inv);
              }
              if (LID_0 == 0) {
                const %(type_y_idx)s y_idx = (ga_int)y_idx_data[row * y_idxs0];
                if ((y_idx >= N || y_idx < 0)) {
                  // raise some suspicion.
                  nll_data[row * nlls0] = %(write_x)s(0.0);
                } else {
                  nll_data[row * nlls0] = %(write_x)s(
                     - %(load_x)s(x[y_idx * xs1])
                     - %(load_b)s(b[y_idx * bs0])
                     + row_max + log%(f)s(sum));
                }
              }
            }
          }
          """
          % locals(),
          file=sio,
      )
  
      return [
          Kernel(
              code=sio.getvalue(),
              name=kname,
              params=params,
              flags=flags,
              objvar=k_var,
          )
      ]
  
imports: from __future__ import absolute_import, print_function, division
  import numpy
  from theano import Op, Apply
  from six import StringIO
  from .basic_ops import as_gpuarray_variable, GpuKernelBase, Kernel, gpuarray_helper_inc_dir, infer_context_name
  from .type import GpuArrayType
  from .fp16_help import work_dtype, load_w, write_w
label_desc: Use image node_id 4 for calling the GpuCrossentropySoftmaxArgmax1HotWithBias obj's underlying member method code with example usage: obj.gpu_kernels(node, nodename) and returns: list