def METHOD_NAME(op, *clients, scope=None, **kwargs):
    """Register execution rules for elementwise UDFs."""
    input_type = op.input_type
    # definitions
    # Define an execution rule for elementwise operations on a
    # grouped Series
    nargs = len(input_type)
    @execute_node.register(
        ops.ElementWiseVectorizedUDF, *(itertools.repeat(SeriesGroupBy, nargs))
    )
    def execute_udf_node_groupby(op, *args, **kwargs):
        func = op.func
        groupers = [
            grouper
            for grouper in (getattr(arg, "grouper", None) for arg in args)
            if grouper is not None
        ]
        # all grouping keys must be identical
        assert all(groupers[0] == grouper for grouper in groupers[1:])
        # we're performing a scalar operation on grouped column, so
        # perform the operation directly on the underlying Series
        # and regroup after it's finished
        args = [getattr(arg, "obj", arg) for arg in args]
        groupings = get_grouping(groupers[0].groupings)
        return func(*args).groupby(groupings, group_keys=False)
    # Define an execution rule for a simple elementwise Series
    # function
    @execute_node.register(
        ops.ElementWiseVectorizedUDF, *(itertools.repeat(pd.Series, nargs))
    )
    @execute_node.register(
        ops.ElementWiseVectorizedUDF, *(itertools.repeat(object, nargs))
    )
    def execute_udf_node(op, *args, cache=None, timecontext=None, **kwargs):
        # We have rewritten op.func to be a closure enclosing
        # the kwargs, and therefore, we do not need to pass
        # kwargs here. This is true for all udf execution in this
        # file.
        # See ibis.legacy.udf.vectorized.UserDefinedFunction
        # prevent executing UDFs multiple times on different execution branches
        try:
            result = cache[(op, timecontext)]
        except KeyError:
            result = cache[(op, timecontext)] = op.func(*args)
        return result
    return scope