def METHOD_NAME(lhs_target, rhs_target, binary_op):
    name = "{}_{}_{}".format(lhs_target, binary_op, rhs_target)
    target_dict = {"u": "source node", "e": "edge", "v": "destination node"}
    lhs_str = target_dict[lhs_target]
    rhs_str = target_dict[rhs_target]
    docstring = r"""Generalized SDDMM function.
    It computes edge features by {op} {lhs} features and {rhs} features.
    Parameters
    ----------
    g : DGLGraph
        The input graph
    x : tensor
        The {lhs} features.
    y : tensor
        The {rhs} features.
    Returns
    -------
    tensor
        The result tensor.
    Notes
    -----
    This function supports autograd (computing input gradients given the output gradient). If the
    feature shape of two input operands do not match, we first broadcasts the features to a unified
    shape (note that the memory usage will not increase accordingly) and then performs the operation.
    Broadcasting follows NumPy semantics. Please see
    https://docs.scipy.org/doc/numpy/user/basics.broadcasting.html
    for more details about the NumPy broadcasting semantics.
    """.format(
        op=binary_op, lhs=lhs_str, rhs=rhs_str
    )
    def func(g, x, y):
        return gsddmm(
            g, binary_op, x, y, lhs_target=lhs_target, rhs_target=rhs_target
        )
    func.__name__ = name
    func.__doc__ = docstring
    return func