code: def gather_add(
      table, indices, *, threads_per_block=128, num_blocks=128
  ):
      if table.ndim != 2:
          raise ValueError(
              f"gather_add expects table with dimensionality 2, was: {table.ndim}"
          )
      if indices.ndim != 2:
          raise ValueError(
              f"gather_add expects indices with dimensionality 2, was: {indices.ndim}"
          )
      _is_float_array(table)
      indices = indices.astype("int32")
      _check_indices(indices, table.shape[0])
  
      B = indices.shape[0]
      K = indices.shape[1]
      T = table.shape[0]
      O = table.shape[1]
  
      out = _alloc((B, O), dtype=table.dtype, zeros=True)
      if table.dtype == "float32":
          gather_add_kernel_float(
              (num_blocks,),
              (threads_per_block,),
              (out, table, indices, T, O, B, K),
          )
      else:
          gather_add_kernel_double(
              (num_blocks,),
              (threads_per_block,),
              (out, table, indices, T, O, B, K),
          )
      return out
  
imports: import operator
  import re
  from collections import defaultdict
  from functools import reduce
  from pathlib import Path
  from typing import Callable, Optional, Tuple
  import numpy
  from ..compat import cupy, has_cupy_gpu
label_desc: Use image node_id 6 for calling a global function with example usage: gather_add(table, indices) and returns: out