code: def test_MultiScaleBlock(self):
      seq_len = 21
      c_dim = 10
      batch_dim = 8
      fake_input = torch.rand(batch_dim, seq_len, c_dim)
      input_shape = (2, 2, 5)
  
      # Change of output dimension.
      block = MultiScaleBlock(10, 20, 2)
      output, output_shape = block(fake_input, input_shape)
      gt_shape_tensor = torch.rand(8, seq_len, 20)
      self.assertEqual(output.shape, gt_shape_tensor.shape)
      self.assertEqual(output_shape, input_shape)
  
      # Test dimension multiplication in attention
      block = MultiScaleBlock(10, 20, 2, dim_mul_in_att=True)
      output, output_shape = block(fake_input, input_shape)
      gt_shape_tensor = torch.rand(8, seq_len, 20)
      self.assertEqual(output.shape, gt_shape_tensor.shape)
      self.assertEqual(output_shape, input_shape)
  
      # Test pooling.
      block = MultiScaleBlock(10, 20, 2, stride_q=(2, 2, 1))
      output, output_shape = block(fake_input, input_shape)
      gt_shape_tensor = torch.rand(
          8, int((seq_len - 1) / 2 / 2) + 1, 20
      )
      gt_out_shape = [1, 1, 5]
      self.assertEqual(output.shape, gt_shape_tensor.shape)
      self.assertEqual(output_shape, gt_out_shape)
  
file_path: pytorchvideo/tests/test_layers_attention.py
imports: import itertools
  import unittest
  import torch
  import torch.nn
  from pytorchvideo.layers import Mlp, MultiScaleAttention, MultiScaleBlock
label_desc: Use image node_id 3 for calling the TestMLP obj's underlying member method code with example usage: obj.test_MultiScaleBlock() without return types