code: def init(
      init_W: Callable,
      init_b: Callable,
      model: Model,
      X: Optional[Padded] = None,
      Y: Optional[Padded] = None,
  ) -> None:
      if X is not None:
          model.set_dim("nI", get_width(X))
      if Y is not None:
          model.set_dim("nO", get_width(Y))
      nH = int(model.get_dim("nO") / model.get_dim("dirs"))
      nI = model.get_dim("nI")
      depth = model.get_dim("depth")
      dirs = model.get_dim("dirs")
      # It's easiest to use the initializer if we alloc the weights separately
      # and then stick them all together afterwards. The order matters here:
      # we need to keep the same format that CuDNN expects.
      params = []
      # Convenience
      init_W = partial(init_W, model.ops)
      init_b = partial(init_b, model.ops)
      layer_nI = nI
      for i in range(depth):
          for j in range(dirs):
              # Input-to-gates weights and biases.
              params.append(init_W((nH, layer_nI)))
              params.append(init_W((nH, layer_nI)))
              params.append(init_W((nH, layer_nI)))
              params.append(init_W((nH, layer_nI)))
              params.append(init_b((nH,)))
              params.append(init_b((nH,)))
              params.append(init_b((nH,)))
              params.append(init_b((nH,)))
              # Hidden-to-gates weights and biases
              params.append(init_W((nH, nH)))
              params.append(init_W((nH, nH)))
              params.append(init_W((nH, nH)))
              params.append(init_W((nH, nH)))
              params.append(init_b((nH,)))
              params.append(init_b((nH,)))
              params.append(init_b((nH,)))
              params.append(init_b((nH,)))
          layer_nI = nH * dirs
      model.set_param(
          "LSTM", model.ops.xp.concatenate([p.ravel() for p in params])
      )
      model.set_param("HC0", zero_init(model.ops, (2, depth, dirs, nH)))
      size = model.get_param("LSTM").size
      expected = 4 * dirs * nH * (nH + nI) + dirs * (8 * nH)
      for _ in range(1, depth):
          expected += 4 * dirs * (nH + nH * dirs) * nH + dirs * (8 * nH)
      assert size == expected, (size, expected)
  
file_path: thinc/thinc/layers/lstm.py
imports: from functools import partial
  from typing import Callable, Optional, Tuple, cast
  from ..backends import Ops
  from ..config import registry
  from ..initializers import glorot_uniform_init, zero_init
  from ..model import Model
  from ..types import Floats1d, Floats2d, Floats4d, Padded, Ragged
  from ..util import get_width
  from .noop import noop
label_desc: Use image node_id 3 for calling a global function with example usage: init(init_W, init_b, model, X, Y) without return types