code: def assert_column_equal(
      left,
      right,
      check_dtype=True,
      check_column_type="equiv",
      check_less_precise=False,
      check_exact=False,
      check_datetimelike_compat=False,
      check_categorical=True,
      check_category_order=True,
      rtol=1e-05,
      atol=1e-08,
      obj="ColumnBase",
  ):
      """
      Check that left and right columns are equal
  
      This function is intended to compare two columns and output
      any differences. Additional parameters allow varying the strictness
      of the equality checks performed.
  
      Parameters
      ----------
      left : Column
          left Column to compare
      right : Column
          right Column to compare
      check_dtype : bool, default True
          Whether to check the Column dtype is identical.
      check_column_type : bool or {'equiv'}, default 'equiv'
          Whether to check the columns class, dtype and
          inferred_type are identical. Currently it is idle,
          and similar to pandas.
      check_less_precise : bool or int, default False
          Not yet supported
      check_exact : bool, default False
          Whether to compare number exactly.
      check_datetime_like_compat : bool, default False
          Compare datetime-like which is comparable ignoring dtype.
      check_categorical : bool, default True
          Whether to compare internal Categorical exactly.
      check_category_order : bool, default True
          Whether to compare category order of internal Categoricals
      rtol : float, default 1e-5
          Relative tolerance. Only used when `check_exact` is False.
      atol : float, default 1e-8
          Absolute tolerance. Only used when `check_exact` is False.
      obj : str, default 'ColumnBase'
          Specify object name being compared, internally used to
          show appropriate assertion message.
      """
      if check_dtype is True:
          if (
              is_categorical_dtype(left)
              and is_categorical_dtype(right)
              and not check_categorical
          ):
              pass
          else:
              if type(left) != type(right) or left.dtype != right.dtype:
                  msg1 = f"{left.dtype}"
                  msg2 = f"{right.dtype}"
                  raise_assert_detail(
                      obj, "Dtypes are different", msg1, msg2
                  )
      else:
          if left.null_count == len(left) and right.null_count == len(
              right
          ):
              return True
  
      if check_datetimelike_compat:
          if np.issubdtype(left.dtype, np.datetime64):
              right = right.astype(left.dtype)
          elif np.issubdtype(right.dtype, np.datetime64):
              left = left.astype(right.dtype)
  
          if np.issubdtype(left.dtype, np.datetime64):
              if not left.equals(right):
                  raise AssertionError(
                      f"[datetimelike_compat=True] {left.values} "
                      f"is not equal to {right.values}."
                  )
              return
  
      if check_exact and check_categorical:
          if is_categorical_dtype(left) and is_categorical_dtype(right):
              left_cat = left.categories
              right_cat = right.categories
  
              if check_category_order:
                  assert_index_equal(
                      left_cat,
                      right_cat,
                      exact=check_dtype,
                      check_exact=True,
                      check_categorical=False,
                      rtol=rtol,
                      atol=atol,
                  )
                  assert_column_equal(
                      left.codes,
                      right.codes,
                      check_dtype=check_dtype,
                      check_exact=True,
                      check_categorical=False,
                      check_category_order=False,
                      rtol=rtol,
                      atol=atol,
                  )
  
              if left.ordered != right.ordered:
                  msg1 = f"{left.ordered}"
                  msg2 = f"{right.ordered}"
                  raise_assert_detail(
                      f"{obj} category",
                      "Orders are different",
                      msg1,
                      msg2,
                  )
  
      if (
          not check_dtype
          and is_categorical_dtype(left)
          and is_categorical_dtype(right)
      ):
          left = left.astype(left.categories.dtype)
          right = right.astype(right.categories.dtype)
      columns_equal = False
      if left.size == right.size == 0:
          columns_equal = True
      elif not (
          (
              not dtype_can_compare_equal_to_other(left.dtype)
              and is_numeric_dtype(right.dtype)
          )
          or (
              is_numeric_dtype(left.dtype)
              and not dtype_can_compare_equal_to_other(right.dtype)
          )
      ):
          try:
              # nulls must be in the same places for all dtypes
              columns_equal = cp.all(
                  left.isnull().values == right.isnull().values
              )
  
              if (
                  columns_equal
                  and not check_exact
                  and is_numeric_dtype(left.dtype)
              ):
                  # non-null values must be the same
                  columns_equal = cp.allclose(
                      left.apply_boolean_mask(
                          left.isnull().unary_operator("not")
                      ).values,
                      right.apply_boolean_mask(
                          right.isnull().unary_operator("not")
                      ).values,
                  )
                  if columns_equal and (
                      left.dtype.kind == right.dtype.kind == "f"
                  ):
                      columns_equal = cp.all(
                          is_nan(left).values == is_nan(right).values
                      )
              else:
                  columns_equal = left.equals(right)
          except TypeError as e:
              if (
                  str(e)
                  != "Categoricals can only compare with the same type"
              ):
                  raise e
              else:
                  columns_equal = False
              if is_categorical_dtype(left) and is_categorical_dtype(
                  right
              ):
                  left = left.astype(left.categories.dtype)
                  right = right.astype(right.categories.dtype)
      if not columns_equal:
          try:
              ldata = str(
                  [val for val in left.to_pandas(nullable=True)]
              )
              rdata = str(
                  [val for val in right.to_pandas(nullable=True)]
              )
          except NotImplementedError:
              ldata = str(
                  [val for val in left.to_pandas(nullable=False)]
              )
              rdata = str(
                  [val for val in right.to_pandas(nullable=False)]
              )
          try:
              diff = 0
              for i in range(left.size):
                  if not null_safe_scalar_equals(left[i], right[i]):
                      diff += 1
              diff = diff * 100.0 / left.size
          except BaseException:
              diff = 100.0
          raise_assert_detail(
              obj,
              f"values are different ({np.round(diff, 5)} %)",
              {ldata},
              {rdata},
          )
  
file_path: cudf/python/cudf/cudf/testing/testing.py
imports: from __future__ import annotations
  from typing import Union
  import cupy
  import numpy
  import pandas
  import cudf
  from cudf._lib.unary import is_nan
  from cudf.api.types import is_categorical_dtype, is_numeric_dtype, is_string_dtype
  from cudf.core.missing import NA, NaT
label_desc: Use image node_id 5 for calling a global function with example usage: assert_column_equal(left, right, check_dtype, check_column_type, check_less_precise, check_exact, check_datetimelike_compat, check_categorical, check_category_order, rtol, atol, obj) and returns: True