



from math import pi, sqrt, tan
def 							UpperCAmelCase__		(				_SCREAMING_SNAKE_CASE   :	Union[str, Any]				)->float:





      if side_length < 0:
            raise ValueError('''surface_area_cube() only accepts non-negative values'''				)
      return 6 * side_length**2
def 							UpperCAmelCase__		(				_SCREAMING_SNAKE_CASE   :	int     ,				_SCREAMING_SNAKE_CASE   :	Dict     ,				_SCREAMING_SNAKE_CASE   :	str				)->float:





      if length < 0 or breadth < 0 or height < 0:
            raise ValueError('''surface_area_cuboid() only accepts non-negative values'''				)
      return 2 * ((length * breadth) + (breadth * height) + (length * height))
def 							UpperCAmelCase__		(				_SCREAMING_SNAKE_CASE   :	Optional[int]				)->float:





      if radius < 0:
            raise ValueError('''surface_area_sphere() only accepts non-negative values'''				)
      return 4 * pi * radius**2
def 							UpperCAmelCase__		(				_SCREAMING_SNAKE_CASE   :	Dict				)->float:





      if radius < 0:
            raise ValueError('''surface_area_hemisphere() only accepts non-negative values'''				)
      return 3 * pi * radius**2
def 							UpperCAmelCase__		(				_SCREAMING_SNAKE_CASE   :	List[str]     ,				_SCREAMING_SNAKE_CASE   :	Optional[Any]				)->float:





      if radius < 0 or height < 0:
            raise ValueError('''surface_area_cone() only accepts non-negative values'''				)
      return pi * radius * (radius + (height**2 + radius**2) ** 0.5)
def 							UpperCAmelCase__		(				_SCREAMING_SNAKE_CASE   :	List[str]     ,				_SCREAMING_SNAKE_CASE   :	List[Any]     ,				_SCREAMING_SNAKE_CASE   :	Union[str, Any]				)->float:





      if radius_a < 0 or radius_a < 0 or height < 0:
            raise ValueError(
                '''surface_area_conical_frustum() only accepts non-negative values'''				)
      _lowerCAmelCase 			=  (height**2 + (radius_a - radius_a) ** 2) ** 0.5
      return pi * ((slant_height * (radius_a + radius_a)) + radius_a**2 + radius_a**2)
def 							UpperCAmelCase__		(				_SCREAMING_SNAKE_CASE   :	Optional[int]     ,				_SCREAMING_SNAKE_CASE   :	Any				)->float:





      if radius < 0 or height < 0:
            raise ValueError('''surface_area_cylinder() only accepts non-negative values'''				)
      return 2 * pi * radius * (height + radius)
def 							UpperCAmelCase__		(				_SCREAMING_SNAKE_CASE   :	int     ,				_SCREAMING_SNAKE_CASE   :	Optional[int]				)->float:





      if torus_radius < 0 or tube_radius < 0:
            raise ValueError('''surface_area_torus() only accepts non-negative values'''				)
      if torus_radius < tube_radius:
            raise ValueError(
                '''surface_area_torus() does not support spindle or self intersecting tori'''				)
      return 4 * pow(__snake_case     ,				2				) * torus_radius * tube_radius
def 							UpperCAmelCase__		(				_SCREAMING_SNAKE_CASE   :	Dict     ,				_SCREAMING_SNAKE_CASE   :	int				)->float:





      if length < 0 or width < 0:
            raise ValueError('''area_rectangle() only accepts non-negative values'''				)
      return length * width
def 							UpperCAmelCase__		(				_SCREAMING_SNAKE_CASE   :	str				)->float:





      if side_length < 0:
            raise ValueError('''area_square() only accepts non-negative values'''				)
      return side_length**2
def 							UpperCAmelCase__		(				_SCREAMING_SNAKE_CASE   :	Optional[int]     ,				_SCREAMING_SNAKE_CASE   :	Optional[Any]				)->float:





      if base < 0 or height < 0:
            raise ValueError('''area_triangle() only accepts non-negative values'''				)
      return (base * height) / 2
def 							UpperCAmelCase__		(				_SCREAMING_SNAKE_CASE   :	Optional[Any]     ,				_SCREAMING_SNAKE_CASE   :	Optional[int]     ,				_SCREAMING_SNAKE_CASE   :	List[Any]				)->float:





      if sidea < 0 or sidea < 0 or sidea < 0:
            raise ValueError('''area_triangle_three_sides() only accepts non-negative values'''				)
      elif sidea + sidea < sidea or sidea + sidea < sidea or sidea + sidea < sidea:
            raise ValueError('''Given three sides do not form a triangle'''				)
      _lowerCAmelCase 			=  (sidea + sidea + sidea) / 2
      _lowerCAmelCase 			=  sqrt(
          semi_perimeter
          * (semi_perimeter - sidea)
          * (semi_perimeter - sidea)
          * (semi_perimeter - sidea)				)
      return area
def 							UpperCAmelCase__		(				_SCREAMING_SNAKE_CASE   :	Union[str, Any]     ,				_SCREAMING_SNAKE_CASE   :	Any				)->float:





      if base < 0 or height < 0:
            raise ValueError('''area_parallelogram() only accepts non-negative values'''				)
      return base * height
def 							UpperCAmelCase__		(				_SCREAMING_SNAKE_CASE   :	Union[str, Any]     ,				_SCREAMING_SNAKE_CASE   :	int     ,				_SCREAMING_SNAKE_CASE   :	List[str]				)->float:





      if basea < 0 or basea < 0 or height < 0:
            raise ValueError('''area_trapezium() only accepts non-negative values'''				)
      return 1 / 2 * (basea + basea) * height
def 							UpperCAmelCase__		(				_SCREAMING_SNAKE_CASE   :	str				)->float:





      if radius < 0:
            raise ValueError('''area_circle() only accepts non-negative values'''				)
      return pi * radius**2
def 							UpperCAmelCase__		(				_SCREAMING_SNAKE_CASE   :	int     ,				_SCREAMING_SNAKE_CASE   :	List[str]				)->float:





      if radius_x < 0 or radius_y < 0:
            raise ValueError('''area_ellipse() only accepts non-negative values'''				)
      return pi * radius_x * radius_y
def 							UpperCAmelCase__		(				_SCREAMING_SNAKE_CASE   :	List[str]     ,				_SCREAMING_SNAKE_CASE   :	int				)->float:





      if diagonal_a < 0 or diagonal_a < 0:
            raise ValueError('''area_rhombus() only accepts non-negative values'''				)
      return 1 / 2 * diagonal_a * diagonal_a
def 							UpperCAmelCase__		(				_SCREAMING_SNAKE_CASE   :	Dict     ,				_SCREAMING_SNAKE_CASE   :	Union[str, Any]				)->float:





      if not isinstance(__snake_case     ,				__snake_case				) or sides < 3:
            raise ValueError(
                '''area_reg_polygon() only accepts integers greater than or \
equal to three as number of sides'''				)
      elif length < 0:
            raise ValueError(
                '''area_reg_polygon() only accepts non-negative values as \
length of a side'''				)
      return (sides * length**2) / (4 * tan(pi / sides				))
      return (sides * length**2) / (4 * tan(pi / sides				))


if __name__ == "__main__":
    import doctest

    doctest.testmod(verbose=True)  # verbose so we can see methods missing tests

    print("[DEMO] Areas of various geometric shapes: \n")
    print(F"""Rectangle: {area_rectangle(1_0, 2_0) = }""")
    print(F"""Square: {area_square(1_0) = }""")
    print(F"""Triangle: {area_triangle(1_0, 1_0) = }""")
    print(F"""Triangle: {area_triangle_three_sides(5, 1_2, 1_3) = }""")
    print(F"""Parallelogram: {area_parallelogram(1_0, 2_0) = }""")
    print(F"""Rhombus: {area_rhombus(1_0, 2_0) = }""")
    print(F"""Trapezium: {area_trapezium(1_0, 2_0, 3_0) = }""")
    print(F"""Circle: {area_circle(2_0) = }""")
    print(F"""Ellipse: {area_ellipse(1_0, 2_0) = }""")
    print("\nSurface Areas of various geometric shapes: \n")
    print(F"""Cube: {surface_area_cube(2_0) = }""")
    print(F"""Cuboid: {surface_area_cuboid(1_0, 2_0, 3_0) = }""")
    print(F"""Sphere: {surface_area_sphere(2_0) = }""")
    print(F"""Hemisphere: {surface_area_hemisphere(2_0) = }""")
    print(F"""Cone: {surface_area_cone(1_0, 2_0) = }""")
    print(F"""Conical Frustum: {surface_area_conical_frustum(1_0, 2_0, 3_0) = }""")
    print(F"""Cylinder: {surface_area_cylinder(1_0, 2_0) = }""")
    print(F"""Torus: {surface_area_torus(2_0, 1_0) = }""")
    print(F"""Equilateral Triangle: {area_reg_polygon(3, 1_0) = }""")
    print(F"""Square: {area_reg_polygon(4, 1_0) = }""")
    print(F"""Reqular Pentagon: {area_reg_polygon(5, 1_0) = }""")











import functools
import gc
import inspect

import torch

from .imports import is_npu_available, is_xpu_available
def 							UpperCAmelCase__		(				*_SCREAMING_SNAKE_CASE   :	Tuple				)->List[Any]:
      if not isinstance(_SCREAMING_SNAKE_CASE     ,				_SCREAMING_SNAKE_CASE				):
            _lowerCAmelCase 			=  list(_SCREAMING_SNAKE_CASE				)
      for i in range(len(_SCREAMING_SNAKE_CASE				)				):
            _lowerCAmelCase 			=  None
      gc.collect()
      if is_xpu_available():
            torch.xpu.empty_cache()
      elif is_npu_available():
            torch.npu.empty_cache()
      else:
            torch.cuda.empty_cache()
      return objects
def 							UpperCAmelCase__		(				_SCREAMING_SNAKE_CASE   :	Exception				)->bool:
      _lowerCAmelCase 			=  [
          '''CUDA out of memory.''',  # CUDA OOM
          '''cuDNN error: CUDNN_STATUS_NOT_SUPPORTED.''',  # CUDNN SNAFU
          '''DefaultCPUAllocator: can\'t allocate memory''',  # CPU OOM
      ]
      if isinstance(_SCREAMING_SNAKE_CASE     ,				_SCREAMING_SNAKE_CASE				) and len(exception.args				) == 1:
            return any(err in exception.args[0] for err in _statements				)
      return False


def 							UpperCAmelCase__		(				_SCREAMING_SNAKE_CASE   :	callable = None     ,				_SCREAMING_SNAKE_CASE   :	int = 1_2_8				)->Optional[int]:
      if function is None:
            return functools.partial(_SCREAMING_SNAKE_CASE     ,				starting_batch_size=_SCREAMING_SNAKE_CASE				)

      _lowerCAmelCase 			=  starting_batch_size

      def decorator(*_SCREAMING_SNAKE_CASE   :	Optional[int]     ,				**_SCREAMING_SNAKE_CASE   :	Optional[Any]				):
            nonlocal batch_size
            gc.collect()
            if is_xpu_available():
                  torch.xpu.empty_cache()
            elif is_npu_available():
                  torch.npu.empty_cache()
            else:
                  torch.cuda.empty_cache()
            _lowerCAmelCase 			=  list(inspect.signature(_SCREAMING_SNAKE_CASE				).parameters.keys()				)
            # Guard against user error
            if len(_SCREAMING_SNAKE_CASE				) < (len(_SCREAMING_SNAKE_CASE				) + 1):
                  _lowerCAmelCase 			=  ''', '''.join([f'''{arg}={value}''' for arg, value in zip(params[1:]     ,				args[1:]				)]				)
                  raise TypeError(
                      f'''Batch size was passed into `{function.__name__}` as the first argument when called.'''
                      f'''Remove this as the decorator already does so: `{function.__name__}({arg_str})`'''				)
            while True:
                  if batch_size == 0:
                        raise RuntimeError('''No executable batch size found, reached zero.'''				)
                  try:
                        return function(_SCREAMING_SNAKE_CASE     ,				*_SCREAMING_SNAKE_CASE     ,				**_SCREAMING_SNAKE_CASE				)
                  except Exception as e:
                        if should_reduce_batch_size(_SCREAMING_SNAKE_CASE				):
                              gc.collect()
                              if is_xpu_available():
                                    torch.xpu.empty_cache()
                              elif is_npu_available():
                                    torch.npu.empty_cache()
                              else:
                                    torch.cuda.empty_cache()
                              batch_size //= 2
                        else:
                              raise

      return decorator