import torch.nn as nn from .mossformer_m import MossFormerM from .utils import select_norm class ComputationBlock(nn.Module): """Computation block for dual-path processing. Arguments --------- out_channels : int Dimensionality of model output. norm : str Normalization type. skip_around_intra : bool Skip connection around the intra layer. Example --------- >>> comp_block = Computation_Block(64) >>> x = torch.randn(10, 64, 100) >>> x = comp_block(x) >>> x.shape torch.Size([10, 64, 100]) """ def __init__( self, num_blocks, out_channels, norm="ln", skip_around_intra=True, ): super(ComputationBlock, self).__init__() ##Default MossFormer model self.intra_mdl = MossFormerM(num_blocks=num_blocks, d_model=out_channels) self.skip_around_intra = skip_around_intra # Norm self.norm = norm if norm is not None: self.intra_norm = select_norm(norm, out_channels, 3) def forward(self, x): """Returns the output tensor. Arguments --------- x : torch.Tensor Input tensor of dimension [B, N, S]. Return --------- out: torch.Tensor Output tensor of dimension [B, N, S]. where, B = Batchsize, N = number of filters S = sequence time index """ # [B, S, N] intra = x.permute(0, 2, 1).contiguous() intra = self.intra_mdl(intra) # [B, N, S] intra = intra.permute(0, 2, 1).contiguous() if self.norm is not None: intra = self.intra_norm(intra) # [B, N, S] if self.skip_around_intra: intra = intra + x return intra