code: def test_parallel_conv1d_stack(
      stacked_layers: Union[None, list], dropout: float
  ) -> None:
      # make repeatable
      torch.manual_seed(RANDOM_SEED)
  
      # setup synthetic input tensor for test
      input = torch.randn(
          [BATCH_SIZE, SEQ_SIZE, HIDDEN_SIZE], dtype=torch.float32
      )
  
      parallel_conv1d_stack = ParallelConv1DStack(
          in_channels=HIDDEN_SIZE,
          out_channels=NUM_FILTERS,
          max_sequence_length=SEQ_SIZE,
          stacked_layers=stacked_layers,
          default_num_filters=NUM_FILTERS,
          default_dropout=dropout,
      )
  
      # check for correct stack formation
      if stacked_layers is None:
          assert len(parallel_conv1d_stack.stack) == 3
          for i in range(len(parallel_conv1d_stack.stack)):
              assert (
                  len(parallel_conv1d_stack.stack[i].parallel_layers)
                  == 4
              )
      else:
          # spot check custom layer specification
          assert len(parallel_conv1d_stack.stack) == len(stacked_layers)
          assert (
              len(parallel_conv1d_stack.stack[0].parallel_layers) == 3
          )
          assert (
              parallel_conv1d_stack.stack[0]
              .parallel_layers[2]
              .kernel_size
              == TEST_FILTER_SIZE0
          )
          assert (
              len(parallel_conv1d_stack.stack[1].parallel_layers) == 4
          )
          assert (
              parallel_conv1d_stack.stack[1]
              .parallel_layers[3]
              .kernel_size
              == TEST_FILTER_SIZE1
          )
  
      # generate output tensor
      out_tensor = parallel_conv1d_stack(input)
  
      # check for correct output class
      assert isinstance(out_tensor, torch.Tensor)
  
      # check output shape
      assert out_tensor.size() == (
          BATCH_SIZE,
          *parallel_conv1d_stack.output_shape,
      )
  
      # check for parameter updates
      target = torch.randn(parallel_conv1d_stack.output_shape)
      _, tpc, upc, not_updated = check_module_parameters_updated(
          parallel_conv1d_stack, (input,), target
      )
      if dropout == 0:
          # all trainable parameters should be updated
          assert tpc == upc, (
              f"All parameter not updated. Parameters not updated: {not_updated}"
              f"\nModule structure:\n{parallel_conv1d_stack}"
          )
      else:
          # with specified config and random seed, non-zero dropout update parameter count could take different values
          assert (tpc == upc) or (upc == 5), (
              f"All parameter not updated. Parameters not updated: {not_updated}"
              f"\nModule structure:\n{parallel_conv1d_stack}"
          )
  
file_path: ludwig/tests/ludwig/modules/test_convolutional_modules.py
imports: from typing import Callable, Dict, List, Optional, Tuple, Union
  import pytest
  import torch
  from ludwig.modules.convolutional_modules import Conv1DLayer, Conv1DStack, Conv2DLayer, Conv2DLayerFixedPadding, Conv2DStack, ParallelConv1D, ParallelConv1DStack, ResNet, ResNetBlock, ResNetBlockLayer, ResNetBottleneckBlock
  from ludwig.utils.image_utils import get_img_output_shape
  from tests.integration_tests.parameter_update_utils import check_module_parameters_updated
label_desc: Use image node_id 5 for calling a global function with example usage: test_parallel_conv1d_stack(stacked_layers, dropout) without return types