'''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 	lowerCamelCase_	(TensorFormatter[Mapping, "jax.Array", Mapping]    ):
      '''simple docstring'''

      def __init__(       self						:				Any						,					A						:				List[Any]=None						,					A						:				List[str]=None						,					**A						:				List[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     :  Union[str, Any]							      =    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     :  Dict							      =    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     :  List[Any]							      =    str(jax.devices()[0]       )
             _UpperCAmelCase     :  List[str]							      =    jnp_array_kwargs




      @staticmethod
      def      _A	(       ):
             import jax

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




      def      _A	(       self						:				Optional[int]						,					A						:				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      _A	(       self						:				List[str]						,					A						:				Optional[Any]       ):
             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     :  Optional[Any]							      =    {}

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

                    if isinstance(A						,					PIL.Image.Image       ):
                           _UpperCAmelCase     :  Optional[int]							      =    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     :  int							      =    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      _A	(       self						:				Optional[int]						,					A						:				Optional[int]       ):
             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     :  List[Any]							      =    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      _A	(       self						:				List[str]						,					A						:				dict       ):
             return map_nested(self._recursive_tensorize						,					A						,					map_list=A       )




      def      _A	(       self						:				Dict						,					A						:				pa.Table       ):
             _UpperCAmelCase     :  Tuple							      =    self.numpy_arrow_extractor().extract_row(A       )
             _UpperCAmelCase     :  Optional[int]							      =    self.python_features_decoder.decode_row(A       )
             return self.recursive_tensorize(A       )




      def      _A	(       self						:				Optional[Any]						,					A						:				pa.Table       ):
             _UpperCAmelCase     :  Optional[Any]							      =    self.numpy_arrow_extractor().extract_column(A       )
             _UpperCAmelCase     :  Any							      =    self.python_features_decoder.decode_column(A						,					pa_table.column_names[0]       )
             _UpperCAmelCase     :  Union[str, Any]							      =    self.recursive_tensorize(A       )
             _UpperCAmelCase     :  List[Any]							      =    self._consolidate(A       )
             return column





      def      _A	(       self						:				List[str]						,					A						:				pa.Table       ):
             _UpperCAmelCase     :  Optional[int]							      =    self.numpy_arrow_extractor().extract_batch(A       )
             _UpperCAmelCase     :  Optional[int]							      =    self.python_features_decoder.decode_batch(A       )
             _UpperCAmelCase     :  Optional[int]							      =    self.recursive_tensorize(A       )
             for column_name in batch:
                    _UpperCAmelCase     :  Any							      =    self._consolidate(batch[column_name]       )
             return batch


'''simple docstring'''




import shutil
import tempfile
import unittest
from unittest.mock import patch

from transformers import (
    DefaultFlowCallback,
    IntervalStrategy,
    PrinterCallback,
    ProgressCallback,
    Trainer,
    TrainerCallback,
    TrainingArguments,
    is_torch_available,
)
from transformers.testing_utils import require_torch


if is_torch_available():
  from transformers.trainer import DEFAULT_CALLBACKS

  from .test_trainer import RegressionDataset, RegressionModelConfig, RegressionPreTrainedModel

class 	lowerCamelCase_	(snake_case__    ):
      '''simple docstring'''

      def __init__(       self						:				List[Any]       ):
             _UpperCAmelCase     :  Union[str, Any]							      =    []




      def      _A	(       self						:				Any						,					A						:				Union[str, Any]						,					A						:				Optional[int]						,					A						:				List[str]						,					**A						:				Tuple       ):
             self.events.append("on_init_end"       )




      def      _A	(       self						:				Any						,					A						:				str						,					A						:				List[Any]						,					A						:				List[Any]						,					**A						:				Tuple       ):
             self.events.append("on_train_begin"       )




      def      _A	(       self						:				Tuple						,					A						:				List[str]						,					A						:				Tuple						,					A						:				int						,					**A						:				List[str]       ):
             self.events.append("on_train_end"       )




      def      _A	(       self						:				Optional[Any]						,					A						:				Dict						,					A						:				Any						,					A						:				Optional[Any]						,					**A						:				List[Any]       ):
             self.events.append("on_epoch_begin"       )




      def      _A	(       self						:				Optional[Any]						,					A						:				List[Any]						,					A						:				List[str]						,					A						:				Optional[int]						,					**A						:				Optional[int]       ):
             self.events.append("on_epoch_end"       )




      def      _A	(       self						:				List[str]						,					A						:				Optional[int]						,					A						:				List[Any]						,					A						:				Union[str, Any]						,					**A						:				Any       ):
             self.events.append("on_step_begin"       )




      def      _A	(       self						:				Tuple						,					A						:				Union[str, Any]						,					A						:				int						,					A						:				Optional[int]						,					**A						:				int       ):
             self.events.append("on_step_end"       )




      def      _A	(       self						:				Optional[int]						,					A						:				Optional[Any]						,					A						:				Union[str, Any]						,					A						:				str						,					**A						:				Union[str, Any]       ):
             self.events.append("on_evaluate"       )




      def      _A	(       self						:				Optional[Any]						,					A						:				Optional[int]						,					A						:				Dict						,					A						:				List[Any]						,					**A						:				Dict       ):
             self.events.append("on_predict"       )




      def      _A	(       self						:				Dict						,					A						:				Dict						,					A						:				List[Any]						,					A						:				Dict						,					**A						:				str       ):
             self.events.append("on_save"       )




      def      _A	(       self						:				Tuple						,					A						:				Optional[Any]						,					A						:				Union[str, Any]						,					A						:				Optional[int]						,					**A						:				Dict       ):
             self.events.append("on_log"       )





      def      _A	(       self						:				Optional[int]						,					A						:				Optional[Any]						,					A						:				Tuple						,					A						:				Tuple						,					**A						:				List[str]       ):
             self.events.append("on_prediction_step"       )

@require_torch
class 	lowerCamelCase_	(unittest.TestCase    ):
      '''simple docstring'''

      def      _A	(       self						:				Optional[int]       ):
             _UpperCAmelCase     :  Optional[Any]							      =    tempfile.mkdtemp()




      def      _A	(       self						:				List[Any]       ):
             shutil.rmtree(self.output_dir       )




      def      _A	(       self						:				Union[str, Any]						,					A						:				Optional[int]=0						,					A						:				Optional[Any]=0						,					A						:				Optional[Any]=64						,					A						:				Dict=64						,					A						:				Any=None						,					A						:				Tuple=False						,					**A						:				Optional[int]       ):
             # disable_tqdm in TrainingArguments has a flaky default since it depends on the level of logging. We make sure
             # its set to False since the tests later on depend on its value.
             _UpperCAmelCase     :  str							      =    RegressionDataset(length=A       )
             _UpperCAmelCase     :  Union[str, Any]							      =    RegressionDataset(length=A       )
             _UpperCAmelCase     :  Any							      =    RegressionModelConfig(a=A						,					b=A       )
             _UpperCAmelCase     :  List[Any]							      =    RegressionPreTrainedModel(A       )

             _UpperCAmelCase     :  Dict							      =    TrainingArguments(self.output_dir						,					disable_tqdm=A						,					report_to=[]						,					**A       )
             return Trainer(
                 A						,					A						,					train_dataset=A						,					eval_dataset=A						,					callbacks=A						,					)




      def      _A	(       self						:				str						,					A						:				List[str]						,					A						:				List[str]       ):
             self.assertEqual(len(A       )						,					len(A       )       )

             # Order doesn't matter
             _UpperCAmelCase     :  Tuple							      =    sorted(A						,					key=lambda A       : cb.__name__ if isinstance(A						,					A       ) else cb.__class__.__name__       )
             _UpperCAmelCase     :  Any							      =    sorted(A						,					key=lambda A       : cb.__name__ if isinstance(A						,					A       ) else cb.__class__.__name__       )

             for cba, cba in zip(A						,					A       ):
                    if isinstance(A						,					A       ) and isinstance(A						,					A       ):
                           self.assertEqual(A						,					A       )
                    elif isinstance(A						,					A       ) and not isinstance(A						,					A       ):
                           self.assertEqual(A						,					cba.__class__       )
                    elif not isinstance(A						,					A       ) and isinstance(A						,					A       ):
                           self.assertEqual(cba.__class__						,					A       )
                    else:
                           self.assertEqual(A						,					A       )




      def      _A	(       self						:				int						,					A						:				List[str]       ):
             _UpperCAmelCase     :  List[str]							      =    ["on_init_end", "on_train_begin"]
             _UpperCAmelCase     :  str							      =    0
             _UpperCAmelCase     :  Optional[Any]							      =    len(trainer.get_eval_dataloader()       )
             _UpperCAmelCase     :  Optional[int]							      =    ["on_prediction_step"] * len(trainer.get_eval_dataloader()       ) + ["on_log", "on_evaluate"]
             for _ in range(trainer.state.num_train_epochs       ):
                    expected_events.append("on_epoch_begin"       )
                    for _ in range(A       ):
                           step += 1
                           expected_events += ["on_step_begin", "on_step_end"]
                           if step % trainer.args.logging_steps == 0:
                                  expected_events.append("on_log"       )
                           if trainer.args.evaluation_strategy == IntervalStrategy.STEPS and step % trainer.args.eval_steps == 0:
                                  expected_events += evaluation_events.copy()
                           if step % trainer.args.save_steps == 0:
                                  expected_events.append("on_save"       )
                    expected_events.append("on_epoch_end"       )
                    if trainer.args.evaluation_strategy == IntervalStrategy.EPOCH:
                           expected_events += evaluation_events.copy()
             expected_events += ["on_log", "on_train_end"]
             return expected_events




      def      _A	(       self						:				str       ):
             _UpperCAmelCase     :  Any							      =    self.get_trainer()
             _UpperCAmelCase     :  int							      =    DEFAULT_CALLBACKS.copy() + [ProgressCallback]
             self.check_callbacks_equality(trainer.callback_handler.callbacks						,					A       )

             # Callbacks passed at init are added to the default callbacks
             _UpperCAmelCase     :  Optional[int]							      =    self.get_trainer(callbacks=[MyTestTrainerCallback]       )
             expected_callbacks.append(A       )
             self.check_callbacks_equality(trainer.callback_handler.callbacks						,					A       )

             # TrainingArguments.disable_tqdm controls if use ProgressCallback or PrinterCallback
             _UpperCAmelCase     :  List[Any]							      =    self.get_trainer(disable_tqdm=A       )
             _UpperCAmelCase     :  Tuple							      =    DEFAULT_CALLBACKS.copy() + [PrinterCallback]
             self.check_callbacks_equality(trainer.callback_handler.callbacks						,					A       )




      def      _A	(       self						:				Optional[Any]       ):
             _UpperCAmelCase     :  Dict							      =    DEFAULT_CALLBACKS.copy() + [ProgressCallback]
             _UpperCAmelCase     :  Dict							      =    self.get_trainer()

             # We can add, pop, or remove by class name
             trainer.remove_callback(A       )
             expected_callbacks.remove(A       )
             self.check_callbacks_equality(trainer.callback_handler.callbacks						,					A       )

             _UpperCAmelCase     :  Optional[Any]							      =    self.get_trainer()
             _UpperCAmelCase     :  Any							      =    trainer.pop_callback(A       )
             self.assertEqual(cb.__class__						,					A       )
             self.check_callbacks_equality(trainer.callback_handler.callbacks						,					A       )

             trainer.add_callback(A       )
             expected_callbacks.insert(0						,					A       )
             self.check_callbacks_equality(trainer.callback_handler.callbacks						,					A       )

             # We can also add, pop, or remove by instance
             _UpperCAmelCase     :  Union[str, Any]							      =    self.get_trainer()
             _UpperCAmelCase     :  List[Any]							      =    trainer.callback_handler.callbacks[0]
             trainer.remove_callback(A       )
             expected_callbacks.remove(A       )
             self.check_callbacks_equality(trainer.callback_handler.callbacks						,					A       )

             _UpperCAmelCase     :  List[Any]							      =    self.get_trainer()
             _UpperCAmelCase     :  List[Any]							      =    trainer.callback_handler.callbacks[0]
             _UpperCAmelCase     :  Union[str, Any]							      =    trainer.pop_callback(A       )
             self.assertEqual(A						,					A       )
             self.check_callbacks_equality(trainer.callback_handler.callbacks						,					A       )

             trainer.add_callback(A       )
             expected_callbacks.insert(0						,					A       )
             self.check_callbacks_equality(trainer.callback_handler.callbacks						,					A       )





      def      _A	(       self						:				Optional[Any]       ):
             import warnings

             # XXX: for now ignore scatter_gather warnings in this test since it's not relevant to what's being tested
             warnings.simplefilter(action="ignore"						,					category=A       )

             _UpperCAmelCase     :  Optional[int]							      =    self.get_trainer(callbacks=[MyTestTrainerCallback]       )
             trainer.train()
             _UpperCAmelCase     :  Union[str, Any]							      =    trainer.callback_handler.callbacks[-2].events
             self.assertEqual(A						,					self.get_expected_events(A       )       )

             # Independent log/save/eval
             _UpperCAmelCase     :  Tuple							      =    self.get_trainer(callbacks=[MyTestTrainerCallback]						,					logging_steps=5       )
             trainer.train()
             _UpperCAmelCase     :  int							      =    trainer.callback_handler.callbacks[-2].events
             self.assertEqual(A						,					self.get_expected_events(A       )       )

             _UpperCAmelCase     :  List[str]							      =    self.get_trainer(callbacks=[MyTestTrainerCallback]						,					save_steps=5       )
             trainer.train()
             _UpperCAmelCase     :  Tuple							      =    trainer.callback_handler.callbacks[-2].events
             self.assertEqual(A						,					self.get_expected_events(A       )       )

             _UpperCAmelCase     :  int							      =    self.get_trainer(callbacks=[MyTestTrainerCallback]						,					eval_steps=5						,					evaluation_strategy="steps"       )
             trainer.train()
             _UpperCAmelCase     :  Optional[int]							      =    trainer.callback_handler.callbacks[-2].events
             self.assertEqual(A						,					self.get_expected_events(A       )       )

             _UpperCAmelCase     :  Optional[int]							      =    self.get_trainer(callbacks=[MyTestTrainerCallback]						,					evaluation_strategy="epoch"       )
             trainer.train()
             _UpperCAmelCase     :  int							      =    trainer.callback_handler.callbacks[-2].events
             self.assertEqual(A						,					self.get_expected_events(A       )       )

             # A bit of everything
             _UpperCAmelCase     :  int							      =    self.get_trainer(
                 callbacks=[MyTestTrainerCallback]						,					logging_steps=3						,					save_steps=10						,					eval_steps=5						,					evaluation_strategy="steps"						,					)
             trainer.train()
             _UpperCAmelCase     :  Optional[int]							      =    trainer.callback_handler.callbacks[-2].events
             self.assertEqual(A						,					self.get_expected_events(A       )       )

             # warning should be emitted for duplicated callbacks
             with patch("transformers.trainer_callback.logger.warning"       ) as warn_mock:
                    _UpperCAmelCase     :  Optional[Any]							      =    self.get_trainer(
                        callbacks=[MyTestTrainerCallback, MyTestTrainerCallback]						,					)
                    assert str(A       ) in warn_mock.call_args[0][0]

