code: def forward(
      model: Model[Ints1d, OutT], ids: Ints1d, is_train: bool
  ) -> Tuple[OutT, Callable]:
      vectors = cast(Floats2d, model.get_param("E"))
      nV = vectors.shape[0]
      nO = vectors.shape[1]
      if len(ids) == 0:
          output: Floats2d = model.ops.alloc2f(
              0, nO, dtype=vectors.dtype
          )
      else:
          ids = model.ops.as_contig(ids, dtype="uint64")
          nN = ids.shape[0]
          seed: int = model.attrs["seed"]
          keys = model.ops.hash(ids, seed) % nV
          output = model.ops.gather_add(vectors, keys)
          drop_mask = None
          if is_train:
              dropout: Optional[float] = model.attrs.get("dropout_rate")
              drop_mask = cast(
                  Floats1d, model.ops.get_dropout_mask((nO,), dropout)
              )
              if drop_mask is not None:
                  output *= drop_mask
  
      def backprop(d_vectors: OutT) -> Ints1d:
          if drop_mask is not None:
              d_vectors *= drop_mask
          dE = model.ops.alloc2f(*vectors.shape)
          keysT = model.ops.as_contig(keys.T, dtype="i")
          for i in range(keysT.shape[0]):
              model.ops.scatter_add(dE, keysT[i], d_vectors)
          model.inc_grad("E", dE)
          dX = model.ops.alloc1i(nN)
          return dX
  
      return output, backprop
  
file_path: thinc/thinc/layers/hashembed.py
imports: from typing import Any, Callable, Dict, Optional, Tuple, TypeVar, Union, cast
  from ..config import registry
  from ..initializers import uniform_init
  from ..model import Model
  from ..types import Floats1d, Floats2d, Ints1d, Ints2d
  from ..util import partial
  from .array_getitem import ints_getitem
  from .chain import chain
label_desc: Use image node_id 2 for calling a global function with example usage: forward(model, ids, is_train) and returns: output,  backprop, dX