def _test_pool3d_single_case(
        self,
        cpu_only,
        pool_type,
        shape,
        kernel,
        stride,
        padding,
        average_pooling_count_excludes_padding,
    ):
        """

        Args:
            cpu_only:
            pool_type:
            shape:
            kernel:
            stride:
            padding:
            average_pooling_count_excludes_padding:

        Returns: True if success, False if skipped, Str if error

        """
        test_case = (
            "Test case:: pool_type: %s, shape: %s, kernel: %s, stride: %s, padding: %s, average_pooling_count_excludes_padding: %s"
            % (
                pool_type,
                shape,
                kernel,
                stride,
                padding,
                average_pooling_count_excludes_padding,
            )
        )
        input_features = [("data", datatypes.Array(*shape))]
        output_features = [("output", None)]
        builder = neural_network.NeuralNetworkBuilder(
            input_features, output_features, disable_rank5_shape_mapping=True
        )
        padding_mode = padding[0]
        padding_values = padding[1]
        builder.add_pooling3d(
            name="pooling3d",
            input_name="data",
            output_name="output",
            pooling_type=pool_type,
            kernel_depth=kernel[0],
            kernel_height=kernel[1],
            kernel_width=kernel[2],
            stride_depth=stride[0],
            stride_height=stride[1],
            stride_width=stride[2],
            padding_mode=padding_mode,
            custom_padding_front=padding_values[4],
            custom_padding_back=padding_values[5],
            custom_padding_top=padding_values[2],
            custom_padding_bottom=padding_values[3],
            custom_padding_left=padding_values[0],
            custom_padding_right=padding_values[1],
            average_pooling_count_excludes_padding=average_pooling_count_excludes_padding,
        )

        # Expected output
        input = np.random.rand(*shape)
        torch_input = torch.from_numpy(np.reshape(input, shape))

        # Padding
        if padding_mode == "CUSTOM":
            torch_padding = torch.nn.ConstantPad3d(padding_values, 0)
        elif padding_mode == "VALID":
            torch_padding = torch.nn.ConstantPad3d(0, 0)
        elif padding_mode == "SAME":
            padding_list = []
            # torch.nn.ConstantPad3d wants (left, right, top, bottom, front, back)
            # but our shape, kernel, and stride are (depth, height, width).
            total_paddings = aggregated_pad(
                pad_type=padding_mode.lower(),
                kernel_shape=kernel,
                input_shape=shape[2:],
                strides=stride,
            )
            total_paddings = list(total_paddings)
            total_paddings.reverse()
            for p in total_paddings:
                before = int(math.floor(float(p) / 2.0))
                after = int(math.ceil(float(p) / 2.0))
                padding_list.append(before)
                padding_list.append(after)

            torch_padding = torch.nn.ConstantPad3d(tuple(padding_list), 0)
            padding_values = padding_list[:]
        else:
            assert False

        # Validate output shape
        for i in range(3):
            try:
                IOS14SingleLayerTests._validate_pooling_dimension(
                    shape[i + 2],
                    kernel[i],
                    stride[i],
                    padding_values[6 - i - 2],
                    padding_values[6 - i - 1],
                )
            except ValueError:
                return False

        # Pooling type
        # Average pooling
        if pool_type == "AVERAGE":
            # torch.nn.AvgPool3d only accepts a single integer for padding, so we normally
            # create a pooling layer first which allows us to fully specify the
            # before and after padding in all three dimensions.
            #
            # However, when we use a padding layer, torch.nn.AvgPool3d doesn't
            # know what is padding and what isn't, which means that its
            # `count_include_pad` parameter has no effect.
            #
            # Therefore, we can only test average_pooling_count_excludes_padding=True
            # when padding is homogeneous.
            is_padding_homogeneous = all(p == padding_values[0] for p in padding_values)
            if average_pooling_count_excludes_padding:
                if not is_padding_homogeneous:
                    return False
                else:
                    # padding is homogeneous
                    torch_model = torch.nn.AvgPool3d(
                        kernel,
                        stride=stride,
                        padding=padding_values[0],
                        count_include_pad=not average_pooling_count_excludes_padding,
                    )
            else:
                # average_pooling_count_excludes_padding == False
                torch_pool = torch.nn.AvgPool3d(
                    kernel,
                    stride=stride,
                    count_include_pad=not average_pooling_count_excludes_padding,
                )
                torch_model = torch.nn.Sequential(torch_padding, torch_pool)
        # Max pooling
        else:
            torch_pool = torch.nn.MaxPool3d(kernel, stride=stride)
            torch_model = torch.nn.Sequential(torch_padding, torch_pool)

        try:
            expected = torch_model(torch_input).numpy()
            self._test_model(
                builder.spec, {"data": input}, {"output": expected}, useCPUOnly=cpu_only
            )
            return True
        except AssertionError as e:
            print(e)
            return "test_case: %s, error: %s" % (test_case, e)


        Args:
            cpu_only:
            pool_type:
            shape:
            kernel:
            stride:
            padding:
            average_pooling_count_excludes_padding:

        Returns: True if success, False if skipped, Str if error

        
coremltools/test/neural_network/test_numpy_nn_layers.py