def reduce_dict_data(frames, reducer, order=None):
    """Merge tensor dictionaries into one. Resolve conflict fields using reducer.

    Parameters
    ----------
    frames : list[dict[str, Tensor]]
        Input tensor dictionaries
    reducer : str or callable function
        One of "sum", "max", "min", "mean", "stack" or a callable function.
        If a callable function is provided, the input arguments must be a single list
        of tensors containing aggregation results from each edge type, and the
        output of function must be a single tensor.
    order : list[Int], optional
        Merge order hint. Useful for "stack" reducer.
        If provided, each integer indicates the relative order
        of the ``frames`` list. Frames are sorted according to this list
        in ascending order. Tie is not handled so make sure the order values
        are distinct.

    Returns
    -------
    dict[str, Tensor]
        Merged frame
    """
    if len(frames) == 1 and reducer != "stack":
        # Directly return the only one input. Stack reducer requires
        # modifying tensor shape.
        return frames[0]
    if callable(reducer):
        merger = reducer
    elif reducer == "stack":
        # Stack order does not matter. However, it must be consistent!
        if order:
            assert len(order) == len(frames)
            sorted_with_key = sorted(zip(frames, order), key=lambda x: x[1])
            frames = list(zip(*sorted_with_key))[0]

        def merger(flist):
            return F.stack(flist, 1)

    else:
        redfn = getattr(F, reducer, None)
        if redfn is None:
            raise DGLError(
                "Invalid cross type reducer. Must be one of "
                '"sum", "max", "min", "mean" or "stack".'
            )

        def merger(flist):
            return redfn(F.stack(flist, 0), 0) if len(flist) > 1 else flist[0]

    keys = set()
    for frm in frames:
        keys.update(frm.keys())
    ret = {}
    for k in keys:
        flist = []
        for frm in frames:
            if k in frm:
                flist.append(frm[k])
        ret[k] = merger(flist)
    return ret
Merge tensor dictionaries into one. Resolve conflict fields using reducer.

    Parameters
    ----------
    frames : list[dict[str, Tensor]]
        Input tensor dictionaries
    reducer : str or callable function
        One of "sum", "max", "min", "mean", "stack" or a callable function.
        If a callable function is provided, the input arguments must be a single list
        of tensors containing aggregation results from each edge type, and the
        output of function must be a single tensor.
    order : list[Int], optional
        Merge order hint. Useful for "stack" reducer.
        If provided, each integer indicates the relative order
        of the ``frames`` list. Frames are sorted according to this list
        in ascending order. Tie is not handled so make sure the order values
        are distinct.

    Returns
    -------
    dict[str, Tensor]
        Merged frame
    
python/dgl/heterograph.py