    def from_two_input_lists_jagged_tensor(
        cls, inputs1: List[torch.Tensor], inputs2: List[torch.Tensor]
    ) -> List["TensorSpec"]:
        """
        This function is useful when we expect multiple dynamic dims.

        The parent graph can receive two sets of inputs:
        1. with min dynamic dim values,
        2. with max dynamic dim values.

        After FX splitter logic is applied and lowerable subgraph sample inputs
        are inferred, we make two assumptions:
        1. two lists of inferred inputs will differ at dynamic dimensions,
        2. the difference numbers will be the dynamic ranges, i.e. min and max.

        TODO: The assumptions above are not ideal, and, in theory, we should do
        symbolic shape propagation using something like SymPy.
        """
        if len(inputs1) != len(inputs2):
            raise ValueError(
                f"Different number of inputs: {len(inputs1)} vs {len(inputs2)}"
            )

        result: List[TensorSpec] = []
        dynamic_dict = {}
        num_dynamic = 0
        for t1, t2 in zip(inputs1, inputs2):
            if t1.dtype != t2.dtype:
                raise ValueError(f"Different types: {t1.dtype} vs {t2.dtype}")
            if len(t1.shape) != len(t2.shape):
                raise ValueError(
                    f"Different tensor sizes: {len(t1.shape)} vs {len(t2.shape)}"
                )
            shape: List[IntVar] = []
            for _, (d1, d2) in enumerate(zip(t1.shape, t2.shape)):
                if d1 == d2:
                    shape.append(IntImm(d1))
                else:
                    dynamic_range = [min(d1, d2), max(d1, d2)]
                    tuple_range = tuple(dynamic_range)
                    dynamic_name = dynamic_dict.get(tuple_range, None)
                    # The rule here we record the dynamic range+dynamic name in a dict
                    # and extract it if it exists. If not, we will create the pair and append
                    # the pair to the dict
                    if dynamic_name:
                        shape.append(IntVar(dynamic_range, dynamic_name))
                    else:
                        if num_dynamic == 0:
                            shape.append(IntVar(dynamic_range, "batch_size"))
                            dynamic_dict[tuple_range] = "batch_size"
                        else:
                            shape.append(
                                IntVar(
                                    dynamic_range,
                                    f"batch_size_{num_dynamic}",
                                )
                            )
                            dynamic_dict[tuple_range] = f"batch_size_{num_dynamic}"
                        num_dynamic = num_dynamic + 1
            result.append(TensorSpec(shape, t1.dtype))

        return result
This function is useful when we expect multiple dynamic dims.

The parent graph can receive two sets of inputs:
1. with min dynamic dim values,
2. with max dynamic dim values.

After FX splitter logic is applied and lowerable subgraph sample inputs
are inferred, we make two assumptions:
1. two lists of inferred inputs will differ at dynamic dimensions,
2. the difference numbers will be the dynamic ranges, i.e. min and max.

TODO: The assumptions above are not ideal, and, in theory, we should do
symbolic shape propagation using something like SymPy.
fx2ait/fx2ait/tensor_spec.py