



"""simple docstring"""





import sys
from collections.abc import Mapping
from typing import TYPE_CHECKING, Dict, Optional

import numpy as np
import pyarrow as pa

from .. import config
from ..utils.logging import get_logger
from ..utils.py_utils import map_nested
from .formatting import TensorFormatter


if TYPE_CHECKING:
						import jax
						import jaxlib

lowercase  							=					get_logger()

lowercase  							=					None




class 			lowercase__			(      TensorFormatter[Mapping, '''jax.Array''', Mapping]    ):
							'''simple docstring'''







							def __init__(  self	,       snake_case=None	,       snake_case=None	,       **snake_case						)			->							str:
									super().__init__(features=__A						)
									import jax
									from jaxlib.xla_client import Device

									if isinstance(__A	,       __A						):
											raise ValueError(
											    f'Expected {device} to be a `str` not {type(__A						)}, as `jaxlib.xla_extension.Device` '
											    'is not serializable neither with `pickle` nor with `dill`. Instead you can surround '
											    'the device with `str()` to get its string identifier that will be internally mapped '
											    'to the actual `jaxlib.xla_extension.Device`.'						)
									_UpperCAmelCase							 =		device if isinstance(__A	,       __A						) else str(jax.devices()[0]						)
									# using global variable since `jaxlib.xla_extension.Device` is not serializable neither
									# with `pickle` nor with `dill`, so we need to use a global variable instead
									global DEVICE_MAPPING
									if DEVICE_MAPPING is None:
											_UpperCAmelCase							 =		self._map_devices_to_str()
									if self.device not in list(DEVICE_MAPPING.keys()						):
											logger.warning(
											    f'Device with string identifier {self.device} not listed among the available '
											    f'devices: {list(DEVICE_MAPPING.keys()						)}, so falling back to the default '
											    f'device: {str(jax.devices()[0]						)}.'						)
											_UpperCAmelCase							 =		str(jax.devices()[0]						)
									_UpperCAmelCase							 =		jnp_array_kwargs






							@staticmethod
							def        lowerCamelCase_   (  )			->							str:
									import jax

									return {str(__A						): device for device in jax.devices()}






							def        lowerCamelCase_   (  self	,       snake_case						)			->							Optional[int]:
									import jax
									import jax.numpy as jnp

									if isinstance(__A	,       __A						) and column:
											if all(
											    isinstance(__A	,       jax.Array						) and x.shape == column[0].shape and x.dtype == column[0].dtype for x in column						):
													return jnp.stack(__A	,       axis=0						)
									return column






							def        lowerCamelCase_   (  self	,       snake_case						)			->							List[str]:
									import jax
									import jax.numpy as jnp

									if isinstance(__A	,       (str, bytes, type(__A						))						):
											return value
									elif isinstance(__A	,       (np.character, np.ndarray)						) and np.issubdtype(value.dtype	,       np.character						):
											return value.tolist()

									_UpperCAmelCase							 =		{}

									if isinstance(__A	,       (np.number, np.ndarray)						) and np.issubdtype(value.dtype	,       np.integer						):
											# the default int precision depends on the jax config
											# see https://jax.readthedocs.io/en/latest/notebooks/Common_Gotchas_in_JAX.html#double-64bit-precision
											if jax.config.jax_enable_xaa:
													_UpperCAmelCase							 =		{"dtype": jnp.intaa}
											else:
													_UpperCAmelCase							 =		{"dtype": jnp.intaa}
									elif isinstance(__A	,       (np.number, np.ndarray)						) and np.issubdtype(value.dtype	,       np.floating						):
											_UpperCAmelCase							 =		{"dtype": jnp.floataa}
									elif config.PIL_AVAILABLE and "PIL" in sys.modules:
											import PIL.Image

											if isinstance(__A	,       PIL.Image.Image						):
													_UpperCAmelCase							 =		np.asarray(__A						)

        # using global variable since `jaxlib.xla_extension.Device` is not serializable neither
        # with `pickle` nor with `dill`, so we need to use a global variable instead
									global DEVICE_MAPPING
									if DEVICE_MAPPING is None:
											_UpperCAmelCase							 =		self._map_devices_to_str()

									with jax.default_device(DEVICE_MAPPING[self.device]						):
											# calling jnp.array on a np.ndarray does copy the data
											# see https://github.com/google/jax/issues/4486
											return jnp.array(__A	,       **{**default_dtype, **self.jnp_array_kwargs}						)






							def        lowerCamelCase_   (  self	,       snake_case						)			->							List[Any]:
									import jax

									# support for torch, tf, jax etc.
									if config.TORCH_AVAILABLE and "torch" in sys.modules:
											import torch

											if isinstance(__A	,       torch.Tensor						):
													return self._tensorize(data_struct.detach().cpu().numpy()[()]						)
									if hasattr(__A	,       '__array__'						) and not isinstance(__A	,       jax.Array						):
											_UpperCAmelCase							 =		data_struct.__array__()
									# support for nested types like struct of list of struct
									if isinstance(__A	,       np.ndarray						):
											if data_struct.dtype == object:  # jax arrays cannot be instantied from an array of objects
													return self._consolidate([self.recursive_tensorize(__A						) for substruct in data_struct]						)
									elif isinstance(__A	,       (list, tuple)						):
											return self._consolidate([self.recursive_tensorize(__A						) for substruct in data_struct]						)
									return self._tensorize(__A						)






							def        lowerCamelCase_   (  self	,       snake_case						)			->							List[Any]:
									return map_nested(self._recursive_tensorize	,       __A	,       map_list=__A						)






							def        lowerCamelCase_   (  self	,       snake_case						)			->							Any:
									_UpperCAmelCase							 =		self.numpy_arrow_extractor().extract_row(__A						)
									_UpperCAmelCase							 =		self.python_features_decoder.decode_row(__A						)
									return self.recursive_tensorize(__A						)






							def        lowerCamelCase_   (  self	,       snake_case						)			->							str:
									_UpperCAmelCase							 =		self.numpy_arrow_extractor().extract_column(__A						)
									_UpperCAmelCase							 =		self.python_features_decoder.decode_column(__A	,       pa_table.column_names[0]						)
									_UpperCAmelCase							 =		self.recursive_tensorize(__A						)
									_UpperCAmelCase							 =		self._consolidate(__A						)
									return column






							def        lowerCamelCase_   (  self	,       snake_case						)			->							Dict:
									_UpperCAmelCase							 =		self.numpy_arrow_extractor().extract_batch(__A						)
									_UpperCAmelCase							 =		self.python_features_decoder.decode_batch(__A						)
									_UpperCAmelCase							 =		self.recursive_tensorize(__A						)
									for column_name in batch:
											_UpperCAmelCase							 =		self._consolidate(batch[column_name]						)
									return batch







"""simple docstring"""





def 	UpperCAmelCase     (		A	:						int       ):

		'''simple docstring'''


		_UpperCAmelCase							 =		abs(A       )
		_UpperCAmelCase							 =		0
		while n > 0:
				res += n % 10
				n //= 10
		return res




def 	UpperCAmelCase     (		A	:						int       ):

		'''simple docstring'''


		_UpperCAmelCase							 =		abs(A       )
		return n if n < 10 else n % 10 + sum_of_digits(n // 10       )




def 	UpperCAmelCase     (		A	:						int       ):

		'''simple docstring'''


		return sum(int(A       ) for c in str(abs(A       )       )       )




def 	UpperCAmelCase     (		):

		'''simple docstring'''


		from collections.abc import Callable
		from timeit import timeit

		def benchmark_a_function(A	:						Callable     ,				A	:						int       ) -> None:
				_UpperCAmelCase							 =		f'{func.__name__}({value})'
				_UpperCAmelCase							 =		timeit(f'__main__.{call}'     ,				setup='import __main__'       )
				print(f'{call:56} = {func(A       )} -- {timing:.4f} seconds'       )

		for value in (26_2144, 1125_8999_0684_2624, 126_7650_6002_2822_9401_4967_0320_5376):
				for func in (sum_of_digits, sum_of_digits_recursion, sum_of_digits_compact):
						benchmark_a_function(A     ,				A       )
				print()


if __name__ == "__main__":
					import doctest

					doctest.testmod()
					benchmark()


