class_docstr: Fusion block of SDMGR.
  
  Args:
      input_dims (tuple(int, int)): Visual dimension and node embedding
          dimension.
      output_dim (int): Output dimension.
      mm_dim (int): Model dimension. Defaults to 1600.
      chunks (int): Number of chunks. Defaults to 20.
      rank (int): Rank number. Defaults to 15.
      shared (bool): Whether to share the project layer between visual and
          node embedding features. Defaults to False.
      dropout_input (float): Dropout rate after the first projection layer.
          Defaults to 0.
      dropout_pre_lin (float): Dropout rate before the final project layer.
          Defaults to 0.
      dropout_pre_lin (float): Dropout rate after the final project layer.
          Defaults to 0.
      pos_norm (str): The normalization position. Options are 'before_cat'
          and 'after_cat'. Defaults to 'before_cat'.
docstr: Forward function.
docstr_tok: ["Forward","function","."]
code: def forward(self, x: Tensor) -> Tensor:
      """Forward function."""
      x0 = self.linear0(x[0])
      x1 = self.linear1(x[1])
      bs = x1.size(0)
      if self.dropout_input > 0:
          x0 = F.dropout(
              x0, p=self.dropout_input, training=self.training
          )
          x1 = F.dropout(
              x1, p=self.dropout_input, training=self.training
          )
      x0_chunks = torch.split(x0, self.chunks, -1)
      x1_chunks = torch.split(x1, self.chunks, -1)
      zs = []
      for x0_c, x1_c, m0, m1 in zip(
          x0_chunks, x1_chunks, self.merge_linears0, self.merge_linears1
      ):
          m = m0(x0_c) * m1(x1_c)  # bs x split_size*rank
          m = m.view(bs, self.rank, -1)
          z = torch.sum(m, 1)
          if self.pos_norm == "before_cat":
              z = torch.sqrt(F.relu(z)) - torch.sqrt(F.relu(-z))
              z = F.normalize(z)
          zs.append(z)
      z = torch.cat(zs, 1)
      if self.pos_norm == "after_cat":
          z = torch.sqrt(F.relu(z)) - torch.sqrt(F.relu(-z))
          z = F.normalize(z)
  
      if self.dropout_pre_lin > 0:
          z = F.dropout(
              z, p=self.dropout_pre_lin, training=self.training
          )
      z = self.linear_out(z)
      if self.dropout_output > 0:
          z = F.dropout(
              z, p=self.dropout_output, training=self.training
          )
      return z
  
imports: from typing import Dict, List, Optional, Tuple, Union
  import torch
  from mmengine.model import BaseModule
  from torch import Tensor, nn
  from torch.nn import functional
  from mmocr.models.common.dictionary import Dictionary
  from mmocr.registry import MODELS, TASK_UTILS
  from mmocr.structures import KIEDataSample
label_desc: Use image node_id 2 for calling the FusionBlock obj's underlying member method code with example usage: obj.forward(x) and returns: z