def gen_function_call(
    backend_spec,
    func_name,
    inputs,
    outputs,
    start_indices,
    end_indices,
    dim=0,
    indent="  ",
    output_shape_def=None,
):
    """Generates function call.

    Parameters
    ----------
    backend_spec: dataclass
        Backend specification.
    func_name : str
        Function neame
    inputs : List[Tensor]
        Input tensors.
    outputs : List[Tensor]
        Output tensors.
    start_indices : List[List[int]]
        each input has its own list of indices
    end_indices : List[List[int]]
        Each input has its own list of indices
    dim : int
        Specify the concat dim if we concat outputs of all inputs, by default 0.
    indent : str, optional
        Indent for template, by default "  ".
    output_shape_def: jinja2.Template
      output shape template, by default None.

    Returns
    -------
    str
        Rendered function call.
    """
    assert len(inputs) == len(start_indices) == len(end_indices)
    x = inputs[0]
    y = outputs[0]

    input_names = ",\n        ".join([i._attrs["name"] for i in inputs])

    input_shape_defs = []
    input_shape_names = []
    start_indices_defs = []
    start_indices_names = []
    end_indices_defs = []
    end_indices_names = []

    for idx, (i, s_indices, e_indices) in enumerate(
        zip(inputs, start_indices, end_indices)
    ):
        input_shape_name = "{}_shape".format(i._attrs["name"])
        s_indices_name = "{}_slice_start_indices_{}".format(i._attrs["name"], idx)
        e_indices_name = "{}_slice_end_indices_{}".format(i._attrs["name"], idx)
        if input_shape_name not in input_shape_names:
            dims = ", ".join([dim._attrs["name"] for dim in i._attrs["shape"]])
            one_shape_def = INPUT_SHAPE_DEF_TEMPLATE.render(
                indent="      ", input_shape_name=input_shape_name, input_dims=dims
            )
            input_shape_defs.append(one_shape_def)

        s_indices_str = ", ".join([str(i) for i in s_indices])
        one_s_indices_def = INPUT_INDICES_DEF_TEMPLATE.render(
            indent="      ",
            input_indices_name=s_indices_name,
            input_indices=s_indices_str,
        )
        start_indices_defs.append(one_s_indices_def)

        e_indices_str = ", ".join([str(i) for i in e_indices])
        one_e_indices_def = INPUT_INDICES_DEF_TEMPLATE.render(
            indent="      ",
            input_indices_name=e_indices_name,
            input_indices=e_indices_str,
        )
        end_indices_defs.append(one_e_indices_def)

        input_shape_names.append(input_shape_name)
        start_indices_names.append(s_indices_name)
        end_indices_names.append(e_indices_name)

    if output_shape_def is None:
        y_dim_refs = ", ".join(["&" + dim._attrs["name"] for dim in y._attrs["shape"]])
        output_shape_def = DEFAULT_OUTPUT_SHAPE_DEF_TEMPLATE.render(
            indent=indent, output_name=y._attrs["name"], output_dim_refs=y_dim_refs
        )

    return FUNC_CALL_TEMPLATE.render(
        indent=indent,
        func_name=func_name,
        output_name=y._attrs["name"],
        output_ptr=y._attrs["name"],
        output_shape_def=output_shape_def,
        inputs=input_names,
        input_shape_defs="".join(input_shape_defs),
        input_shapes=", ".join(input_shape_names),
        start_indices_defs="".join(start_indices_defs),
        slice_start_indices=", ".join(start_indices_names),
        end_indices_defs="".join(end_indices_defs),
        slice_end_indices=", ".join(end_indices_names),
        scatter_dim=dim,
        rank=len(x._attrs["shape"]),
        num_inputs=len(inputs),
    )
Generates function call.

    Parameters
    ----------
    backend_spec: dataclass
        Backend specification.
    func_name : str
        Function neame
    inputs : List[Tensor]
        Input tensors.
    outputs : List[Tensor]
        Output tensors.
    start_indices : List[List[int]]
        each input has its own list of indices
    end_indices : List[List[int]]
        Each input has its own list of indices
    dim : int
        Specify the concat dim if we concat outputs of all inputs, by default 0.
    indent : str, optional
        Indent for template, by default "  ".
    output_shape_def: jinja2.Template
      output shape template, by default None.

    Returns
    -------
    str
        Rendered function call.
    
python/aitemplate/backend/common/tensor/slice_common.py