class_docstr: Contextual Block Conformer encoder module.
  
  Args:
      input_size: input dim
      output_size: dimension of attention
      attention_heads: the number of heads of multi head attention
      linear_units: the number of units of position-wise feed forward
      num_blocks: the number of decoder blocks
      dropout_rate: dropout rate
      attention_dropout_rate: dropout rate in attention
      positional_dropout_rate: dropout rate after adding positional encoding
      input_layer: input layer type
      pos_enc_class: PositionalEncoding or ScaledPositionalEncoding
      normalize_before: whether to use layer_norm before the first block
      concat_after: whether to concat attention layer's input and output
          if True, additional linear will be applied.
          i.e. x -> x + linear(concat(x, att(x)))
          if False, no additional linear will be applied.
          i.e. x -> x + att(x)
      positionwise_layer_type: linear of conv1d
      positionwise_conv_kernel_size: kernel size of positionwise conv1d layer
      padding_idx: padding_idx for input_layer=embed
      block_size: block size for contextual block processing
      hop_Size: hop size for block processing
      look_ahead: look-ahead size for block_processing
      init_average: whether to use average as initial context (otherwise max values)
      ctx_pos_enc: whether to use positional encoding to the context vectors
docstr: Embed positions in tensor.
  
  Args:
      xs_pad: input tensor (B, L, D)
      ilens: input length (B)
      prev_states: Not to be used now.
  Returns:
      position embedded tensor and mask
docstr_tok: ["Embed","positions","in","tensor",".","Args",":","xs_pad",":","input","tensor","(","B",",","L",",","D",")","ilens",":","input","length","(","B",")","prev_states",":","Not","to","be","used","now",".","Returns",":","position","embedded","tensor","and","mask"]
code: def forward_train(
      self,
      xs_pad: torch.Tensor,
      ilens: torch.Tensor,
      prev_states: torch.Tensor = None,
  ) -> Tuple[torch.Tensor, torch.Tensor, Optional[torch.Tensor]]:
      """Embed positions in tensor.
  
      Args:
          xs_pad: input tensor (B, L, D)
          ilens: input length (B)
          prev_states: Not to be used now.
      Returns:
          position embedded tensor and mask
      """
      masks = (~make_pad_mask(ilens)[:, None, :]).to(xs_pad.device)
  
      if isinstance(self.embed, Conv2dSubsamplingWOPosEnc):
          xs_pad, masks = self.embed(xs_pad, masks)
      elif self.embed is not None:
          xs_pad = self.embed(xs_pad)
  
      # create empty output container
      total_frame_num = xs_pad.size(1)
      ys_pad = xs_pad.new_zeros(xs_pad.size())
  
      past_size = self.block_size - self.hop_size - self.look_ahead
  
      # block_size could be 0 meaning infinite
      # apply usual encoder for short sequence
      if self.block_size == 0 or total_frame_num <= self.block_size:
          xs_pad, masks, _, _, _, _, _ = self.encoders(
              self.pos_enc(xs_pad), masks, False, None, None
          )
          if self.normalize_before:
              xs_pad = self.after_norm(xs_pad)
  
          olens = masks.squeeze(1).sum(1)
          return xs_pad, olens, None
  
      # start block processing
      cur_hop = 0
      block_num = math.ceil(
          float(total_frame_num - past_size - self.look_ahead)
          / float(self.hop_size)
      )
      bsize = xs_pad.size(0)
      addin = xs_pad.new_zeros(
          bsize, block_num, xs_pad.size(-1)
      )  # additional context embedding vecctors
  
      # first step
      if self.init_average:  # initialize with average value
          addin[:, 0, :] = xs_pad.narrow(
              1, cur_hop, self.block_size
          ).mean(1)
      else:  # initialize with max value
          addin[:, 0, :] = xs_pad.narrow(
              1, cur_hop, self.block_size
          ).max(1)
      cur_hop += self.hop_size
      # following steps
      while cur_hop + self.block_size < total_frame_num:
          if self.init_average:  # initialize with average value
              addin[:, cur_hop // self.hop_size, :] = xs_pad.narrow(
                  1, cur_hop, self.block_size
              ).mean(1)
          else:  # initialize with max value
              addin[:, cur_hop // self.hop_size, :] = xs_pad.narrow(
                  1, cur_hop, self.block_size
              ).max(1)
          cur_hop += self.hop_size
      # last step
      if (
          cur_hop < total_frame_num
          and cur_hop // self.hop_size < block_num
      ):
          if self.init_average:  # initialize with average value
              addin[:, cur_hop // self.hop_size, :] = xs_pad.narrow(
                  1, cur_hop, total_frame_num - cur_hop
              ).mean(1)
          else:  # initialize with max value
              addin[:, cur_hop // self.hop_size, :] = xs_pad.narrow(
                  1, cur_hop, total_frame_num - cur_hop
              ).max(1)
  
      if self.ctx_pos_enc:
          addin = self.pos_enc(addin)
  
      xs_pad = self.pos_enc(xs_pad)
  
      # set up masks
      mask_online = xs_pad.new_zeros(
          xs_pad.size(0),
          block_num,
          self.block_size + 2,
          self.block_size + 2,
      )
      mask_online.narrow(2, 1, self.block_size + 1).narrow(
          3, 0, self.block_size + 1
      ).fill_(1)
  
      xs_chunk = xs_pad.new_zeros(
          bsize, block_num, self.block_size + 2, xs_pad.size(-1)
      )
  
      # fill the input
      # first step
      left_idx = 0
      block_idx = 0
      xs_chunk[:, block_idx, 1 : self.block_size + 1] = xs_pad.narrow(
          -2, left_idx, self.block_size
      )
      left_idx += self.hop_size
      block_idx += 1
      # following steps
      while (
          left_idx + self.block_size < total_frame_num
          and block_idx < block_num
      ):
          xs_chunk[
              :, block_idx, 1 : self.block_size + 1
          ] = xs_pad.narrow(-2, left_idx, self.block_size)
          left_idx += self.hop_size
          block_idx += 1
      # last steps
      last_size = total_frame_num - left_idx
      xs_chunk[:, block_idx, 1 : last_size + 1] = xs_pad.narrow(
          -2, left_idx, last_size
      )
  
      # fill the initial context vector
      xs_chunk[:, 0, 0] = addin[:, 0]
      xs_chunk[:, 1:, 0] = addin[:, 0 : block_num - 1]
      xs_chunk[:, :, self.block_size + 1] = addin
  
      # forward
      ys_chunk, mask_online, _, _, _, _, _ = self.encoders(
          xs_chunk, mask_online, False, xs_chunk
      )
  
      # copy output
      # first step
      offset = self.block_size - self.look_ahead - self.hop_size + 1
      left_idx = 0
      block_idx = 0
      cur_hop = self.block_size - self.look_ahead
      ys_pad[:, left_idx:cur_hop] = ys_chunk[
          :, block_idx, 1 : cur_hop + 1
      ]
      left_idx += self.hop_size
      block_idx += 1
      # following steps
      while (
          left_idx + self.block_size < total_frame_num
          and block_idx < block_num
      ):
          ys_pad[:, cur_hop : cur_hop + self.hop_size] = ys_chunk[
              :, block_idx, offset : offset + self.hop_size
          ]
          cur_hop += self.hop_size
          left_idx += self.hop_size
          block_idx += 1
      ys_pad[:, cur_hop:total_frame_num] = ys_chunk[
          :, block_idx, offset : last_size + 1, :
      ]
  
      if self.normalize_before:
          ys_pad = self.after_norm(ys_pad)
  
      olens = masks.squeeze(1).sum(1)
      return ys_pad, olens, None
  
imports: import math
  from typing import Optional, Tuple
  import torch
  from typeguard import check_argument_types
  from espnet2.asr.encoder.abs_encoder import AbsEncoder
  from espnet.nets.pytorch_backend.conformer.contextual_block_encoder_layer import ContextualBlockEncoderLayer
  from espnet.nets.pytorch_backend.conformer.convolution import ConvolutionModule
  from espnet.nets.pytorch_backend.nets_utils import get_activation, make_pad_mask
  from espnet.nets.pytorch_backend.transformer.attention import MultiHeadedAttention
  from espnet.nets.pytorch_backend.transformer.embedding import StreamPositionalEncoding
  from espnet.nets.pytorch_backend.transformer.layer_norm import LayerNorm
  from espnet.nets.pytorch_backend.transformer.multi_layer_conv import Conv1dLinear, MultiLayeredConv1d
  from espnet.nets.pytorch_backend.transformer.positionwise_feed_forward import PositionwiseFeedForward
  from espnet.nets.pytorch_backend.transformer.repeat import repeat
  from espnet.nets.pytorch_backend.transformer.subsampling_without_posenc import Conv2dSubsamplingWOPosEnc
label_desc: Use image node_id 4 for calling the ContextualBlockConformerEncoder obj's underlying member method code with example usage: obj.forward_train(xs_pad, ilens, prev_states) and returns: ys_pad,  olens,  None, xs_pad,  olens,  None