class_docstr: LoFTR transformer module from: https://arxiv.org/pdf/2104.00680.pdf
  Canonical implementations at: https://github.com/zju3dv/LoFTR/blob/master/src/loftr/loftr_module/transformer.py
class_docstr_tok: ["LoFTR","transformer","module","from",":","https",":","\/\/arxiv.org\/pdf\/2104.00680.pdf","Canonical","implementations","at",":","https",":","\/\/github.com\/zju3dv\/LoFTR\/blob\/master\/src\/loftr\/loftr_module\/transformer.py"]
docstr: Args:
      left_features (torch.Tensor): [N, S1, D]
      right_features (torch.Tensor): [N, S2, D]
      left_mask (torch.Tensor): [N, S1] (optional)
      right_mask (torch.Tensor): [N, S2] (optional)
  Returns:
      left_features (torch.Tensor): [N, S1, D]
      right_features (torch.Tensor): [N, S2, D]
docstr_tok: ["Args",":","left_features","(","torch.Tensor",")",":","[","N",",","S1",",","D","]","right_features","(","torch.Tensor",")",":","[","N",",","S2",",","D","]","left_mask","(","torch.Tensor",")",":","[","N",",","S1","]","(","optional",")","right_mask","(","torch.Tensor",")",":","[","N",",","S2","]","(","optional",")","Returns",":","left_features","(","torch.Tensor",")",":","[","N",",","S1",",","D","]","right_features","(","torch.Tensor",")",":","[","N",",","S2",",","D","]"]
code: def forward(
      self,
      left_features: Tensor,
      right_features: Tensor,
      left_mask: Optional[Tensor] = None,
      right_mask: Optional[Tensor] = None,
  ) -> Tuple[Tensor, Tensor]:
      """
      Args:
          left_features (torch.Tensor): [N, S1, D]
          right_features (torch.Tensor): [N, S2, D]
          left_mask (torch.Tensor): [N, S1] (optional)
          right_mask (torch.Tensor): [N, S2] (optional)
      Returns:
          left_features (torch.Tensor): [N, S1, D]
          right_features (torch.Tensor): [N, S2, D]
      """
  
      torch._assert(
          left_features.shape[2] == right_features.shape[2],
          f"left_features and right_features should have the same embedding dimensions. left_features: {left_features.shape[2]} right_features: {right_features.shape[2]}",
      )
  
      for idx, layer in enumerate(self.layers):
          attention_direction = self.attention_directions[idx]
  
          if attention_direction == "self":
              left_features = layer(
                  left_features, left_features, left_mask, left_mask
              )
              right_features = layer(
                  right_features, right_features, right_mask, right_mask
              )
  
          elif attention_direction == "cross":
              left_features = layer(
                  left_features, right_features, left_mask, right_mask
              )
              right_features = layer(
                  right_features, left_features, right_mask, left_mask
              )
  
      return left_features, right_features
  
imports: import math
  from functools import partial
  from typing import Callable, Dict, Iterable, List, Optional, Tuple
  import numpy
  import torch
  import torch.nn
  import torch.nn.functional
  import torchvision.models.optical_flow.raft
  from torch import Tensor
  from torchvision.models._api import register_model, Weights, WeightsEnum
  from torchvision.models._utils import handle_legacy_interface
  from torchvision.models.optical_flow._utils import grid_sample, make_coords_grid, upsample_flow
  from torchvision.ops import Conv2dNormActivation
  from torchvision.prototype.transforms._presets import StereoMatching
label_desc: Use image node_id 2 for calling the LocalFeatureTransformer obj's underlying member method code with example usage: obj.forward(left_features, right_features, left_mask, right_mask) and returns: left_features,  right_features