




'''simple docstring'''





# Lint as: python3
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

_SCREAMING_SNAKE_CASE							:       Optional[Any]						=			get_logger()

_SCREAMING_SNAKE_CASE							:       Optional[dict]						=			None




class 			_snake_case		(     TensorFormatter[Mapping, "jax.Array", Mapping]							):




			def __init__( self    ,							a__=None    ,							a__=None    ,							**a__							)    ->    Tuple:

										'''simple docstring'''




										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`."							)
										snake_case_      =				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:
																	snake_case_      =				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]							)}.'							)
																	snake_case_      =				str(jax.devices()[0]							)
										snake_case_      =				jnp_array_kwargs




			@staticmethod
			def        lowerCAmelCase__    ( )    ->    Dict[str, "jaxlib.xla_extension.Device"]:

										'''simple docstring'''




										import jax

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




			def        lowerCAmelCase__    ( self    ,							a__							)    ->    Optional[int]:

										'''simple docstring'''




										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    ,							a__							)    ->    Optional[Any]:

										'''simple docstring'''




										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()

										snake_case_      =				{}

										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:
																								snake_case_      =				{"dtype": jnp.intaa}
																	else:
																								snake_case_      =				{"dtype": jnp.intaa}
										elif isinstance(a__    ,							(np.number, np.ndarray)							) and np.issubdtype(value.dtype    ,							np.floating							):
																	snake_case_      =				{"dtype": jnp.floataa}
										elif config.PIL_AVAILABLE and "PIL" in sys.modules:
																	import PIL.Image

																	if isinstance(a__    ,							PIL.Image.Image							):
																								snake_case_      =				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:
																	snake_case_      =				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    ,							a__							)    ->    Dict:

										'''simple docstring'''




										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							):
																	snake_case_      =				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    ,							a__							)    ->    Optional[Any]:

										'''simple docstring'''




										return map_nested(self._recursive_tensorize    ,							a__    ,							map_list=a__							)




			def        lowerCAmelCase__    ( self    ,							a__							)    ->    Mapping:

										'''simple docstring'''




										snake_case_      =				self.numpy_arrow_extractor().extract_row(a__							)
										snake_case_      =				self.python_features_decoder.decode_row(a__							)
										return self.recursive_tensorize(a__							)




			def        lowerCAmelCase__    ( self    ,							a__							)    ->    "jax.Array":

										'''simple docstring'''




										snake_case_      =				self.numpy_arrow_extractor().extract_column(a__							)
										snake_case_      =				self.python_features_decoder.decode_column(a__    ,							pa_table.column_names[0]							)
										snake_case_      =				self.recursive_tensorize(a__							)
										snake_case_      =				self._consolidate(a__							)
										return column




			def        lowerCAmelCase__    ( self    ,							a__							)    ->    Mapping:

										'''simple docstring'''




										snake_case_      =				self.numpy_arrow_extractor().extract_batch(a__							)
										snake_case_      =				self.python_features_decoder.decode_batch(a__							)
										snake_case_      =				self.recursive_tensorize(a__							)
										for column_name in batch:
																	snake_case_      =				self._consolidate(batch[column_name]							)
										return batch










'''simple docstring'''





import unittest

from transformers import load_tool

from .test_tools_common import ToolTesterMixin




class 			_snake_case		(     unittest.TestCase						,						lowercase_							):




			def        lowerCAmelCase__    ( self							)    ->    Optional[int]:

										'''simple docstring'''




										snake_case_      =				load_tool("text-classification"							)
										self.tool.setup()
										snake_case_      =				load_tool("text-classification"    ,							remote=a__							)




			def        lowerCAmelCase__    ( self							)    ->    str:

										'''simple docstring'''




										snake_case_      =				self.tool("That's quite cool"    ,							["positive", "negative"]							)
										self.assertEqual(a__    ,							"positive"							)




			def        lowerCAmelCase__    ( self							)    ->    Optional[int]:

										'''simple docstring'''




										snake_case_      =				self.remote_tool("That's quite cool"    ,							["positive", "negative"]							)
										self.assertEqual(a__    ,							"positive"							)




			def        lowerCAmelCase__    ( self							)    ->    int:

										'''simple docstring'''




										snake_case_      =				self.tool(text="That's quite cool"    ,							labels=["positive", "negative"]							)
										self.assertEqual(a__    ,							"positive"							)




			def        lowerCAmelCase__    ( self							)    ->    Any:

										'''simple docstring'''




										snake_case_      =				self.remote_tool(text="That's quite cool"    ,							labels=["positive", "negative"]							)
										self.assertEqual(a__    ,							"positive"							)




