docstr: Args:
      x: [N, L, C]
      source: [N, S, C]
      x_mask: [N, L] (optional)
      source_mask: [N, S] (optional)
docstr_tok: ["Args",":","x",":","[","N",",","L",",","C","]","source",":","[","N",",","S",",","C","]","x_mask",":","[","N",",","L","]","(","optional",")","source_mask",":","[","N",",","S","]","(","optional",")"]
code: def forward(
      self,
      x: Tensor,
      source: Tensor,
      x_mask: Optional[Tensor] = None,
      source_mask: Optional[Tensor] = None,
  ) -> Tensor:
      """
      Args:
          x: [N, L, C]
          source: [N, S, C]
          x_mask: [N, L] (optional)
          source_mask: [N, S] (optional)
      """
      bs = x.size(0)
      query, key, value = x, source, source
  
      # multi-head attention
      query = self.q_proj(query).view(
          bs, -1, self.nhead, self.dim
      )  # [N, L, (H, D)]
      key = self.k_proj(key).view(
          bs, -1, self.nhead, self.dim
      )  # [N, S, (H, D)]
      value = self.v_proj(value).view(bs, -1, self.nhead, self.dim)
      message = self.attention(
          query, key, value, q_mask=x_mask, kv_mask=source_mask
      )  # [N, L, (H, D)]
      message = self.merge(
          message.view(bs, -1, self.nhead * self.dim)
      )  # [N, L, C]
      message = self.norm1(message)
  
      # feed-forward network
      message = self.mlp(torch.cat([x, message], dim=2))
      message = self.norm2(message)
  
      return x + message
  
file_path: kornia/kornia/feature/loftr/loftr_module/transformer.py
imports: from __future__ import annotations
  import copy
  from typing import Any, Literal, Optional
  import torch
  from torch import nn
  from kornia.core import Module, Tensor
  from .linear_attention import FullAttention, LinearAttention
label_desc: Use image node_id 2 for calling the LoFTREncoderLayer obj's underlying member method code with example usage: obj.forward(x, source, x_mask, source_mask) and returns: unknown