code: def _make_reduce_op(tensor_reduce_fn, collective_reduce_fn):
      """Makes an op that both reduces over both positional axes and named axes.
  
      Assumes that the reducers are associative so we can rearrange the tensor and
      collective reduce's orders.
  
      Args:
        tensor_reduce_fn: A function that reduces over the dimensions of a `Tensor`.
          `tensor_reduce_fn` should take in an `axis` keyword argument.
        collective_reduce_fn: A function that reduces over named axes.
          `collective_reduce_fn` should take in a `named_axis` keyword argument.
  
      Returns:
        A reduced `Tensor`.
      """
  
      def reduce_fn(x, axis=None, named_axis=None, **kwargs):
          named_axis = canonicalize_named_axis(named_axis)
          allow_all_gather = kwargs.pop("allow_all_gather", None)
          x = tensor_reduce_fn(x, axis=axis, **kwargs)
          if allow_all_gather is None:
              collection_kwargs = {}
          else:
              collection_kwargs = {"allow_all_gather": allow_all_gather}
          return collective_reduce_fn(
              x, named_axis=named_axis, **collection_kwargs
          )
  
      return reduce_fn
  
imports: import collections
  import functools
  import tensorflow.compat.v2
  from tensorflow_probability.python.internal import custom_gradient
  from tensorflow_probability.python.internal import prefer_static
  from tensorflow_probability.python.internal import samplers
  from tensorflow.python.util import nest
label_desc: Use image node_id 2 for calling a global function with example usage: _make_reduce_op(tensor_reduce_fn, collective_reduce_fn) and returns: reduce_fn, collective_reduce_fn