code: def avg_pool2d(
      x: Union[tf.Tensor, tf.Variable],
      kernel: Union[int, Tuple[int], Tuple[int, int]],
      strides: Union[int, Tuple[int], Tuple[int, int]],
      padding: Union[str, int, List[Tuple[int, int]]],
      /,
      *,
      data_format: str = "NHWC",
      count_include_pad: bool = False,
      ceil_mode: bool = False,
      divisor_override: Optional[int] = None,
      out: Optional[Union[tf.Tensor, tf.Variable]] = None,
  ) -> Union[tf.Tensor, tf.Variable]:
      if isinstance(kernel, int):
          kernel = (kernel,) * 2
      elif len(kernel) == 1:
          kernel = (kernel[0],) * 2
  
      if isinstance(strides, int):
          strides = (strides,) * 2
      elif len(strides) == 1:
          strides = (strides[0],) * 2
  
      if data_format == "NCHW":
          x = tf.transpose(x, (0, 2, 3, 1))
      manual_padding = False
      # Have to manually pad if explicit padding is provided, or if ceil_mode is True
      if not isinstance(padding, str) or ceil_mode or count_include_pad:
          padding, pad_specific, c = _handle_manual_pad_avg_pool(
              x, kernel, strides, padding, ceil_mode, 2
          )
          x = tf.pad(x, [(0, 0), *padding, (0, 0)], constant_values=0)
          manual_padding = True
          padding = "VALID"
  
      if divisor_override is not None:
          # sum pooling then dividing by divisor_override if it is provided
          res = tf.nn.depthwise_conv2d(
              x,
              tf.ones(kernel + (x.shape[-1], 1)),
              (1,) + strides + (1,),
              padding,
          )
          res = res / divisor_override
      else:
          res = tf.nn.avg_pool2d(x, kernel, strides, padding)
  
      # removing any manual padding added because of ceil_mode or count_include_pad
      if (
          (manual_padding and not count_include_pad)
          or ceil_mode
          and not divisor_override
      ):
          if not count_include_pad:
              num_padded_values = [
                  tf.convert_to_tensor(
                      ivy.map(
                          _get_num_padded_values,
                          constant={
                              "p": pad_specific[i],
                              "n": x.shape[i + 1] - pad_specific[i],
                              "k": kernel[i],
                              "s": strides[i],
                          },
                          unique={
                              "i": tf.range(res.shape[i + 1]),
                          },
                      ),
                      dtype=res.dtype,
                  )
                  for i in range(2)
              ]
          else:
              num_padded_values = []
              for i in range(2):
                  num_pad = tf.scatter_nd(
                      tf.constant([[res.shape[i + 1] - 1]]),
                      tf.constant([c[i]], dtype=res.dtype),
                      tf.constant([res.shape[i + 1]], dtype=tf.int32),
                  )
                  num_padded_values.append(num_pad)
          num_padded_values1 = num_padded_values[0][:, None]
          num_padded_values2 = num_padded_values[1][None, :]
          num_padded_values = (
              num_padded_values1 * kernel[1]
              + num_padded_values2 * kernel[0]
              - num_padded_values1 * num_padded_values2
          )
          kernel_mul = tf.cast(tf.math.reduce_prod(kernel), res.dtype)
          res = (kernel_mul * res) / (
              kernel_mul - tf.expand_dims(num_padded_values, -1)
          )
  
      if data_format == "NCHW":
          return tf.transpose(res, (0, 3, 1, 2))
      return res
  
imports: import math
  from typing import Union, Optional, Tuple, List, Literal, Sequence, Callable
  import tensorflow
  from ivy.func_wrapper import inputs_to_ivy_arrays, output_to_native_arrays, with_unsupported_dtypes, with_supported_dtypes, with_supported_device_and_dtypes
  from ..None import backend_version
  import ivy
  from ivy.functional.ivy.layers import _handle_padding, _get_num_padded_values, _validate_max_pool_params, _depth_max_pooling_helper
  from ivy.functional.ivy.experimental.layers import _padding_ceil_mode, _get_size
label_desc: Use image node_id 7 for calling a global function with example usage: avg_pool2d() and returns: res, tf