class_docstr: Processes the output of both `SparseArch` (sparse_features) and `DenseArch`
  (dense_features). Returns the pairwise dot product of each sparse feature pair,
  the dot product of each sparse features with the output of the dense layer,
  and the dense layer itself (all concatenated).
  
  .. note::
      The dimensionality of the `dense_features` (D) is expected to match the
      dimensionality of the `sparse_features` so that the dot products between them
      can be computed.
  
  
  Args:
      num_sparse_features (int): F.
  
  Example::
  
      D = 3
      B = 10
      keys = ["f1", "f2"]
      F = len(keys)
      inter_arch = InteractionArch(num_sparse_features=len(keys))
  
      dense_features = torch.rand((B, D))
      sparse_features = torch.rand((B, F, D))
  
      #  B X (D + F + F choose 2)
      concat_dense = inter_arch(dense_features, sparse_features)
class_docstr_tok: ["Processes","the","output","of","both","`","SparseArch","`","(","sparse_features",")","and","`","DenseArch","`","(","dense_features",")",".","Returns","the","pairwise","dot","product","of","each","sparse","feature","pair",",","the","dot","product","of","each","sparse","features","with","the","output","of","the","dense","layer",",","and","the","dense","layer","itself","(","all","concatenated",")",".","..","note",":",":","The","dimensionality","of","the","`","dense_features","`","(","D",")","is","expected","to","match","the","dimensionality","of","the","`","sparse_features","`","so","that","the","dot","products","between","them","can","be","computed",".","Args",":","num_sparse_features","(","int",")",":","F.","Example",":",":","D","=","3","B","=","10","keys","=","[","``","f1","''",",","``","f2","''","]","F","=","len","(","keys",")","inter_arch","=","InteractionArch","(","num_sparse_features=len","(","keys",")",")","dense_features","=","torch.rand","(","(","B",",","D",")",")","sparse_features","=","torch.rand","(","(","B",",","F",",","D",")",")","#","B","X","(","D","+","F","+","F","choose","2",")","concat_dense","=","inter_arch","(","dense_features",",","sparse_features",")"]
docstr: Args:
      dense_features (torch.Tensor): an input tensor of size B X D.
      sparse_features (torch.Tensor): an input tensor of size B X F X D.
  
  Returns:
      torch.Tensor: an output tensor of size B X (D + F + F choose 2).
docstr_tok: ["Args",":","dense_features","(","torch.Tensor",")",":","an","input","tensor","of","size","B","X","D.","sparse_features","(","torch.Tensor",")",":","an","input","tensor","of","size","B","X","F","X","D.","Returns",":","torch.Tensor",":","an","output","tensor","of","size","B","X","(","D","+","F","+","F","choose","2",")","."]
code: def forward(
      self, dense_features: torch.Tensor, sparse_features: torch.Tensor
  ) -> torch.Tensor:
      """
      Args:
          dense_features (torch.Tensor): an input tensor of size B X D.
          sparse_features (torch.Tensor): an input tensor of size B X F X D.
  
      Returns:
          torch.Tensor: an output tensor of size B X (D + F + F choose 2).
      """
      if self.F <= 0:
          return dense_features
      (B, D) = dense_features.shape
  
      combined_values = torch.cat(
          (dense_features.unsqueeze(1), sparse_features), dim=1
      )
  
      # dense/sparse + sparse/sparse interaction
      # size B X (F + F choose 2)
      interactions = torch.bmm(
          combined_values, torch.transpose(combined_values, 1, 2)
      )
      interactions_flat = interactions[
          :, self.triu_indices[0], self.triu_indices[1]
      ]
  
      return torch.cat((dense_features, interactions_flat), dim=1)
  
imports: from typing import Dict, List, Optional, Tuple
  import torch
  from torch import nn
  from torchrec.datasets.utils import Batch
  from torchrec.modules.crossnet import LowRankCrossNet
  from torchrec.modules.embedding_modules import EmbeddingBagCollection
  from torchrec.modules.mlp import MLP
  from torchrec.sparse.jagged_tensor import KeyedJaggedTensor, KeyedTensor
label_desc: Use image node_id 2 for calling the InteractionArch obj's underlying member method code with example usage: obj.forward(dense_features, sparse_features) and returns: torch, dense_features