class_docstr: Implement SoftmaxWithBias on the gpu.
code: def c_code(self, node, nodename, inp, out, sub):
      dtype_x = node.inputs[0].dtype
      dtype_b = node.inputs[1].dtype
      dtype_z = node.outputs[0].dtype
      work_x = work_dtype(dtype_x)
      itemsize_x = np.dtype(dtype_x).itemsize
      itemsize_b = np.dtype(dtype_b).itemsize
      itemsize_z = np.dtype(dtype_z).itemsize
      typecode = pygpu.gpuarray.dtype_to_typecode(node.outputs[0].dtype)
      x, b = inp
      (z,) = out
      fail = sub["fail"]
      ctx = sub["params"]
      err_check = (
          """
              if (err != GA_NO_ERROR) {
                  PyErr_Format(PyExc_RuntimeError, fmt_str, msg);
                  %(fail)s;
              }
          """
          % locals()
      )
      return (
          """
          if (PyGpuArray_NDIM(%(x)s) != 2)
          {
              PyErr_SetString(PyExc_ValueError, "rank error input");
              %(fail)s;
          }
          if (PyGpuArray_NDIM(%(b)s) != 1)
          {
              PyErr_SetString(PyExc_ValueError, "rank error for the bias");
              %(fail)s;
          }
          if ((PyGpuArray_DIMS(%(x)s)[1] !=
              PyGpuArray_DIMS(%(b)s)[0]))
          {
              PyErr_Format(PyExc_ValueError,
                           "number of columns in x (%%ld)"
                           " does not match length of b (%%ld)",
                           (long int)PyGpuArray_DIMS(%(x)s)[1],
                           (long int)PyGpuArray_DIMS(%(b)s)[0]);
              %(fail)s;
          }
          if ((NULL == %(z)s)
              || (PyGpuArray_DIMS(%(z)s)[0] !=
                  PyGpuArray_DIMS(%(x)s)[0])
              || (PyGpuArray_DIMS(%(z)s)[1] !=
                  PyGpuArray_DIMS(%(x)s)[1]))
          {
              Py_XDECREF(%(z)s);
              %(z)s = pygpu_empty(2, PyGpuArray_DIMS(%(x)s),
                                  %(typecode)s, GA_C_ORDER,
                                  %(ctx)s, Py_None);
              if (!%(z)s) {
                  %(fail)s
              }
          }
          {
              size_t n_blocks[3] = {std::min(PyGpuArray_DIMS(%(x)s)[0], (size_t)(32*1024)), 1, 1};
  //TODO, detect the maximum number of thread per block.
              size_t threads_per_block[3] = {std::min(PyGpuArray_DIMS(%(x)s)[1], (size_t)256), 1, 1}; // TODO: Read GA_CTX_PROP_MAXLSIZE0
              size_t shmem_sz = PyGpuArray_DIMS(%(x)s)[1] *
                                       2 * sizeof(npy_%(work_x)s);
              ssize_t stride_X0 = PyGpuArray_STRIDES(%(x)s)[0] / %(itemsize_x)s;
              ssize_t stride_X1 = PyGpuArray_STRIDES(%(x)s)[1] / %(itemsize_x)s;
              ssize_t stride_B0 = PyGpuArray_STRIDES(%(b)s)[0] / %(itemsize_b)s;
              ssize_t stride_Z0 = PyGpuArray_STRIDES(%(z)s)[0] / %(itemsize_z)s;
              ssize_t stride_Z1 = PyGpuArray_STRIDES(%(z)s)[1] / %(itemsize_z)s;
              const char *fmt_str, *msg;
              void *kernel_params[] = {
                  (void *)&PyGpuArray_DIMS(%(x)s)[0],
                  (void *)&PyGpuArray_DIMS(%(x)s)[1],
                  (void *)%(x)s->ga.data, (void *)&%(x)s->ga.offset,
                  (void *)&stride_X0, (void *)&stride_X1,
                  (void *)%(b)s->ga.data, (void *)&%(b)s->ga.offset,
                  (void *)&stride_B0,
                  (void *)%(z)s->ga.data, (void *)&%(z)s->ga.offset,
                  (void *)&stride_Z0, (void *)&stride_Z1};
              int err = GA_NO_ERROR;
              if (PyGpuArray_DIMS(%(x)s)[0] > 0)
              {
                if(shmem_sz < (32 * 1024 - 500)){
                  err = GpuKernel_call(&kSoftmaxWithBias_%(nodename)s, 3,
                                       n_blocks, threads_per_block, shmem_sz,
                                       kernel_params);
                  fmt_str = "gpuarray error: kSoftmaxWithBias_%(nodename)s: %%s";
                  msg = GpuKernel_error(&kSoftmaxWithBias_%(nodename)s, err);
                }else{
                  err = GpuKernel_call(&kSoftmaxWithBias_fixed_shared%(nodename)s,
                                       3, n_blocks, threads_per_block,
                                       threads_per_block[0] * sizeof(npy_%(work_x)s),
                                       kernel_params);
                  fmt_str = "gpuarray error: kSoftmaxWithBias_fixed_shared%(nodename)s: %%s";
                  msg = GpuKernel_error(&kSoftmaxWithBias_fixed_shared%(nodename)s, err);
                }
                %(err_check)s
              }
          }
          assert(%(z)s);
          """
          % locals()
      )
  
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 5 for calling the GpuSoftmaxWithBias obj's underlying member method code with example usage: obj.c_code(node, nodename, inp, out, sub) and returns: unknown