
# 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							:List[Any]										=    get_logger()

SCREAMING_SNAKE_CASE							:Optional[dict]										=    None





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




	'''simple docstring'''





	def __init__(	self :			Tuple							,A :			str=None							,A :			int=None							,**A :			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`."			)
					__A             =			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:
									__A             =			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]			)}.'''			)
									__A             =			str(jax.devices()[0]			)
					__A             =			jnp_array_kwargs






	@staticmethod
	def     UpperCamelCase_  (	):
					import jax

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






	def     UpperCamelCase_  (	self :			Any							,A :			Any			):
					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     UpperCamelCase_  (	self :			List[str]							,A :			Tuple			):
					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()

					__A             =			{}

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

									if isinstance(A							,PIL.Image.Image			):
													__A             =			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:
									__A             =			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     UpperCamelCase_  (	self :			Tuple							,A :			str			):
					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			):
									__A             =			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     UpperCamelCase_  (	self :			Union[str, Any]							,A :			dict			):
					return map_nested(self._recursive_tensorize							,A							,map_list=A			)






	def     UpperCamelCase_  (	self :			Union[str, Any]							,A :			pa.Table			):
					__A             =			self.numpy_arrow_extractor().extract_row(A			)
					__A             =			self.python_features_decoder.decode_row(A			)
					return self.recursive_tensorize(A			)






	def     UpperCamelCase_  (	self :			Dict							,A :			pa.Table			):
					__A             =			self.numpy_arrow_extractor().extract_column(A			)
					__A             =			self.python_features_decoder.decode_column(A							,pa_table.column_names[0]			)
					__A             =			self.recursive_tensorize(A			)
					__A             =			self._consolidate(A			)
					return column







	def     UpperCamelCase_  (	self :			Optional[Any]							,A :			pa.Table			):
					__A             =			self.numpy_arrow_extractor().extract_batch(A			)
					__A             =			self.python_features_decoder.decode_batch(A			)
					__A             =			self.recursive_tensorize(A			)
					for column_name in batch:
									__A             =			self._consolidate(batch[column_name]			)
					return batch


# Copyright 2023 The HuggingFace Inc. team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import torch

from ..models.auto import AutoModelForSequenceClassification, AutoTokenizer
from .base import PipelineTool





class 							UpperCAmelCase				(  __SCREAMING_SNAKE_CASE  ):




	'''simple docstring'''





	snake_case_    =					"facebook/bart-large-mnli"
	snake_case_    =					(
	    "This is a tool that classifies an English text using provided labels. It takes two inputs: `text`, which "
	    "should be the text to classify, and `labels`, which should be the list of labels to use for classification. "
	    "It returns the most likely label in the list of provided `labels` for the input text."
	)
	snake_case_    =					"text_classifier"
	snake_case_    =					AutoTokenizer
	snake_case_    =					AutoModelForSequenceClassification

	snake_case_    =					["text", ["text"]]
	snake_case_    =					["text"]






	def     UpperCamelCase_  (	self :			str			):
					super().setup()
					__A             =			self.model.config
					__A             =			-1
					for idx, label in config.idalabel.items():
									if label.lower().startswith("entail"			):
													__A             =			int(A			)
					if self.entailment_id == -1:
									raise ValueError("Could not determine the entailment ID from the model config, please pass it at init."			)






	def     UpperCamelCase_  (	self :			int							,A :			Optional[Any]							,A :			Dict			):
					__A             =			labels
					return self.pre_processor(
					    [text] * len(A			)							,[f'''This example is {label}''' for label in labels]							,return_tensors="pt"							,padding="max_length"							,)







	def     UpperCamelCase_  (	self :			Union[str, Any]							,A :			Tuple			):
					__A             =			outputs.logits
					__A             =			torch.argmax(logits[:, 2]			).item()
					return self._labels[label_id]
