code: def jit_groupby_apply(offsets, grouped_values, function, *args):
      """
      Main entrypoint for JIT Groupby.apply via Numba.
  
      Parameters
      ----------
      offsets : list
          A list of integers denoting the indices of the group
          boundaries in grouped_values
      grouped_values : DataFrame
          A DataFrame representing the source data
          sorted by group keys
      function : callable
          The user-defined function to execute
      """
  
      kernel, return_type = _compile_or_get(
          grouped_values,
          function,
          args,
          kernel_getter=_get_groupby_apply_kernel,
          suffix="__GROUPBY_APPLY_UDF",
      )
  
      offsets = cp.asarray(offsets)
      ngroups = len(offsets) - 1
  
      output = cudf.core.column.column_empty(ngroups, dtype=return_type)
  
      launch_args = [
          offsets,
          output,
          grouped_values.index,
      ]
      launch_args += list(
          _supported_cols_from_frame(
              grouped_values,
              supported_types=SUPPORTED_GROUPBY_NUMPY_TYPES,
          ).values()
      )
      launch_args += list(args)
  
      max_group_size = cp.diff(offsets).max()
  
      if max_group_size >= 256:
          blocklim = 256
      else:
          blocklim = ((max_group_size + 32 - 1) // 32) * 32
  
      if kernel.specialized:
          specialized = kernel
      else:
          specialized = kernel.specialize(*launch_args)
  
      # Ask the driver to give a good config
      ctx = get_context()
      # Dispatcher is specialized, so there's only one definition - get
      # it so we can get the cufunc from the code library
      (kern_def,) = specialized.overloads.values()
      grid, tpb = ctx.get_max_potential_block_size(
          func=kern_def._codelibrary.get_cufunc(),
          b2d_func=0,
          memsize=0,
          blocksizelimit=int(blocklim),
      )
  
      # Launch kernel
      with _CUDFNumbaConfig():
          specialized[ngroups, tpb](*launch_args)
  
      return output
  
file_path: cudf/python/cudf/cudf/core/udf/groupby_utils.py
imports: import cupy
  import numpy
  from numba import cuda, types
  from numba.core.errors import TypingError
  from numba.cuda.cudadrv.devices import get_context
  from numba.np import numpy_support
  import cudf.core.udf.utils
  from cudf.core.udf.groupby_typing import SUPPORTED_GROUPBY_NUMPY_TYPES, Group, GroupByJITDataFrame, GroupType
  from cudf.core.udf.templates import group_initializer_template, groupby_apply_kernel_template
  from cudf.core.udf.utils import UDFError, _all_dtypes_from_frame, _compile_or_get, _get_extensionty_size, _get_kernel, _get_udf_return_type, _supported_cols_from_frame, _supported_dtypes_from_frame
  from cudf.utils._numba import _CUDFNumbaConfig
  from cudf.utils.nvtx_annotation import _cudf_nvtx_annotate
label_desc: Use image node_id 4 for calling a global function with example usage: jit_groupby_apply(offsets, grouped_values, function) and returns: output