






import random
import timeit
from functools import wraps
from typing import Callable, Optional

from ..configuration_utils import PretrainedConfig
from ..models.auto.modeling_tf_auto import TF_MODEL_MAPPING, TF_MODEL_WITH_LM_HEAD_MAPPING
from ..utils import is_pyanvml_available, is_tf_available, logging
from .benchmark_utils import (
    Benchmark,
    Memory,
    MemorySummary,
    measure_peak_memory_cpu,
    start_memory_tracing,
    stop_memory_tracing,
)


if is_tf_available():
 import tensorflow as tf
 from tensorflow.python.framework.errors_impl import ResourceExhaustedError

 from .benchmark_args_tf import TensorFlowBenchmarkArguments

if is_pyanvml_available():
 import pyanvml.pyanvml as nvml

lowerCamelCase      :       Any    =						logging.get_logger(__name__)





def    __lowerCAmelCase   (    __snake_case       ,			__snake_case							):
     def run_func(__snake_case							):
          @wraps(__snake_case							)
          def run_in_eager_mode(*__snake_case       ,			**__snake_case							):
               return func(*__snake_case       ,			**__snake_case							)

          @wraps(__snake_case							)
          @tf.function(experimental_compile=__snake_case							)
          def run_in_graph_mode(*__snake_case       ,			**__snake_case							):
               return func(*__snake_case       ,			**__snake_case							)

          if do_eager_mode is True:
               if use_xla is not False:
                    raise ValueError(
                        "Cannot run model in XLA, if `args.eager_mode` is set to `True`. Please set `args.eager_mode=False`."							)
               return run_in_eager_mode
          else:
               return run_in_graph_mode

     return run_func





def    __lowerCAmelCase   (    __snake_case       ,			__snake_case       ,			__snake_case							):
     __lowerCAmelCase             =       random.Random()
     __lowerCAmelCase             =       [rng.randint(0       ,			vocab_size - 1							) for i in range(batch_size * sequence_length							)]
     return tf.constant(__snake_case       ,			shape=(batch_size, sequence_length)       ,			dtype=tf.intaa							)



class 				_UpperCamelCase      (a_      ):
      snake_case_	=				42
      snake_case_	=				42
      snake_case_	=				"TensorFlow"


      @property
      def 			__UpperCAmelCase		(						self						)->						List[Any]:
           return tf.__version__


      def 			__UpperCAmelCase		(						self       ,    __UpperCamelCase       ,    __UpperCamelCase       ,    __UpperCamelCase						)->						float:
           # initialize GPU on separate process
           __lowerCAmelCase             =       self.args.strategy
           if strategy is None:
                raise ValueError("A device strategy has to be initialized before using TensorFlow."						)
           __lowerCAmelCase             =       self._prepare_inference_func(__UpperCamelCase       ,    __UpperCamelCase       ,    __UpperCamelCase						)
           return self._measure_speed(_inference						)


      def 			__UpperCAmelCase		(						self       ,    __UpperCamelCase       ,    __UpperCamelCase       ,    __UpperCamelCase						)->						float:
           __lowerCAmelCase             =       self.args.strategy
           if strategy is None:
                raise ValueError("A device strategy has to be initialized before using TensorFlow."						)
           __lowerCAmelCase             =       self._prepare_train_func(__UpperCamelCase       ,    __UpperCamelCase       ,    __UpperCamelCase						)
           return self._measure_speed(_train						)


      def 			__UpperCAmelCase		(						self       ,    __UpperCamelCase       ,    __UpperCamelCase       ,    __UpperCamelCase						)->						[Memory, Optional[MemorySummary]]:
           # initialize GPU on separate process
           if self.args.is_gpu:
                tf.config.experimental.set_memory_growth(self.args.gpu_list[self.args.device_idx]       ,    __UpperCamelCase						)
           __lowerCAmelCase             =       self.args.strategy
           if strategy is None:
                raise ValueError("A device strategy has to be initialized before using TensorFlow."						)
           __lowerCAmelCase             =       self._prepare_inference_func(__UpperCamelCase       ,    __UpperCamelCase       ,    __UpperCamelCase						)
           return self._measure_memory(_inference						)


      def 			__UpperCAmelCase		(						self       ,    __UpperCamelCase       ,    __UpperCamelCase       ,    __UpperCamelCase						)->						[Memory, Optional[MemorySummary]]:
           if self.args.is_gpu:
                tf.config.experimental.set_memory_growth(self.args.gpu_list[self.args.device_idx]       ,    __UpperCamelCase						)
           __lowerCAmelCase             =       self.args.strategy
           if strategy is None:
                raise ValueError("A device strategy has to be initialized before using TensorFlow."						)

           __lowerCAmelCase             =       self._prepare_train_func(__UpperCamelCase       ,    __UpperCamelCase       ,    __UpperCamelCase						)
           return self._measure_memory(_train						)


      def 			__UpperCAmelCase		(						self       ,    __UpperCamelCase       ,    __UpperCamelCase       ,    __UpperCamelCase						)->						Callable[[], None]:
           __lowerCAmelCase             =       self.config_dict[model_name]

           if self.args.fpaa:
                raise NotImplementedError("Mixed precision is currently not supported."						)

           __lowerCAmelCase             =       (
               hasattr(__UpperCamelCase       ,    "architectures"						)
               and isinstance(config.architectures       ,    __UpperCamelCase						)
               and len(config.architectures						) > 0
           )
           if not self.args.only_pretrain_model and has_model_class_in_config:
                try:
                     __lowerCAmelCase             =       "TF" + config.architectures[0]  # prepend 'TF' for tensorflow model
                     __lowerCAmelCase             =       __import__("transformers"       ,    fromlist=[model_class]						)
                     __lowerCAmelCase             =       getattr(__UpperCamelCase       ,    __UpperCamelCase						)
                     __lowerCAmelCase             =       model_cls(__UpperCamelCase						)
                except ImportError:
                     raise ImportError(
                         F"""{model_class} does not exist. If you just want to test the pretrained model, you might want to"""
                         " set `--only_pretrain_model` or `args.only_pretrain_model=True`."						)
           else:
                __lowerCAmelCase             =       TF_MODEL_MAPPING[config.__class__](__UpperCamelCase						)

           # encoder-decoder has vocab size saved differently
           __lowerCAmelCase             =       config.vocab_size if hasattr(__UpperCamelCase       ,    "vocab_size"						) else config.encoder.vocab_size
           __lowerCAmelCase             =       random_input_ids(__UpperCamelCase       ,    __UpperCamelCase       ,    __UpperCamelCase						)

           @run_with_tf_optimizations(self.args.eager_mode       ,    self.args.use_xla						)
           def encoder_decoder_forward():
                return model(__UpperCamelCase       ,    decoder_input_ids=__UpperCamelCase       ,    training=__UpperCamelCase						)

           @run_with_tf_optimizations(self.args.eager_mode       ,    self.args.use_xla						)
           def encoder_forward():
                return model(__UpperCamelCase       ,    training=__UpperCamelCase						)

           __lowerCAmelCase             =       encoder_decoder_forward if config.is_encoder_decoder else encoder_forward

           return _inference


      def 			__UpperCAmelCase		(						self       ,    __UpperCamelCase       ,    __UpperCamelCase       ,    __UpperCamelCase						)->						Callable[[], None]:
           __lowerCAmelCase             =       self.config_dict[model_name]

           if self.args.eager_mode is not False:
                raise ValueError("Training cannot be done in eager mode. Please make sure that `args.eager_mode = False`."						)

           if self.args.fpaa:
                raise NotImplementedError("Mixed precision is currently not supported."						)

           __lowerCAmelCase             =       (
               hasattr(__UpperCamelCase       ,    "architectures"						)
               and isinstance(config.architectures       ,    __UpperCamelCase						)
               and len(config.architectures						) > 0
           )
           if not self.args.only_pretrain_model and has_model_class_in_config:
                try:
                     __lowerCAmelCase             =       "TF" + config.architectures[0]  # prepend 'TF' for tensorflow model
                     __lowerCAmelCase             =       __import__("transformers"       ,    fromlist=[model_class]						)
                     __lowerCAmelCase             =       getattr(__UpperCamelCase       ,    __UpperCamelCase						)
                     __lowerCAmelCase             =       model_cls(__UpperCamelCase						)
                except ImportError:
                     raise ImportError(
                         F"""{model_class} does not exist. If you just want to test the pretrained model, you might want to"""
                         " set `--only_pretrain_model` or `args.only_pretrain_model=True`."						)
           else:
                __lowerCAmelCase             =       TF_MODEL_WITH_LM_HEAD_MAPPING[config.__class__](__UpperCamelCase						)

           # encoder-decoder has vocab size saved differently
           __lowerCAmelCase             =       config.vocab_size if hasattr(__UpperCamelCase       ,    "vocab_size"						) else config.encoder.vocab_size
           __lowerCAmelCase             =       random_input_ids(__UpperCamelCase       ,    __UpperCamelCase       ,    __UpperCamelCase						)

           @run_with_tf_optimizations(self.args.eager_mode       ,    self.args.use_xla						)
           def encoder_decoder_train():
                __lowerCAmelCase             =       model(__UpperCamelCase       ,    decoder_input_ids=__UpperCamelCase       ,    labels=__UpperCamelCase       ,    training=__UpperCamelCase						)[0]
                __lowerCAmelCase             =       tf.gradients(__UpperCamelCase       ,    model.trainable_variables						)
                return gradients

           @run_with_tf_optimizations(self.args.eager_mode       ,    self.args.use_xla						)
           def encoder_train():
                __lowerCAmelCase             =       model(__UpperCamelCase       ,    labels=__UpperCamelCase       ,    training=__UpperCamelCase						)[0]
                __lowerCAmelCase             =       tf.gradients(__UpperCamelCase       ,    model.trainable_variables						)
                return gradients

           __lowerCAmelCase             =       encoder_decoder_train if config.is_encoder_decoder else encoder_train

           return _train


      def 			__UpperCAmelCase		(						self       ,    __UpperCamelCase						)->						float:
           with self.args.strategy.scope():
                try:
                     if self.args.is_tpu or self.args.use_xla:
                          # run additional 10 times to stabilize compilation for tpu
                          logger.info("Do inference on TPU. Running model 5 times to stabilize compilation"						)
                          timeit.repeat(__UpperCamelCase       ,    repeat=1       ,    number=5						)

                     # as written in https://docs.python.org/2/library/timeit.html#timeit.Timer.repeat, min should be taken rather than the average
                     __lowerCAmelCase             =       timeit.repeat(
                         __UpperCamelCase       ,    repeat=self.args.repeat       ,    number=1_0       ,    )

                     return min(__UpperCamelCase						) / 1_0.0
                except ResourceExhaustedError as e:
                     self.print_fn(F"""Doesn't fit on GPU. {e}"""						)


      def 			__UpperCAmelCase		(						self       ,    __UpperCamelCase						)->						[Memory, MemorySummary]:
           logger.info(
               "Note that TensorFlow allocates more memory than "
               "it might need to speed up computation. "
               "The memory reported here corresponds to the memory "
               "reported by `nvidia-smi`, which can vary depending "
               "on total available memory on the GPU that is used."						)
           with self.args.strategy.scope():
                try:
                     if self.args.trace_memory_line_by_line:
                          if not self.args.eager_mode:
                               raise ValueError(
                                   "`args.eager_mode` is set to `False`. Make sure to run model in eager mode to measure memory"
                                   " consumption line by line."						)
                          __lowerCAmelCase             =       start_memory_tracing("transformers"						)

                     if self.args.is_tpu:
                          # tpu
                          raise NotImplementedError(
                              "Memory Benchmarking is currently not implemented for TPU. Please disable memory benchmarking"
                              " with `args.memory=False`"						)
                     elif self.args.is_gpu:
                          # gpu
                          if not is_pyanvml_available():
                               logger.warning(
                                   "py3nvml not installed, we won't log GPU memory usage. "
                                   "Install py3nvml (pip install py3nvml) to log information about GPU."						)
                               __lowerCAmelCase             =       "N/A"
                          else:
                               logger.info(
                                   "Measuring total GPU usage on GPU device. Make sure to not have additional processes"
                                   " running on the same GPU."						)
                               # init nvml
                               nvml.nvmlInit()
                               func()
                               __lowerCAmelCase             =       nvml.nvmlDeviceGetHandleByIndex(self.args.device_idx						)
                               __lowerCAmelCase             =       nvml.nvmlDeviceGetMemoryInfo(__UpperCamelCase						)
                               __lowerCAmelCase             =       meminfo.used
                               __lowerCAmelCase             =       Memory(__UpperCamelCase						)
                               # shutdown nvml
                               nvml.nvmlShutdown()
                     else:
                          # cpu
                          if self.args.trace_memory_line_by_line:
                               logger.info(
                                   "When enabling line by line tracing, the max peak memory for CPU is inaccurate in"
                                   " TensorFlow."						)
                               __lowerCAmelCase             =       None
                          else:
                               __lowerCAmelCase             =       measure_peak_memory_cpu(__UpperCamelCase						)
                               __lowerCAmelCase             =       Memory(__UpperCamelCase						) if isinstance(__UpperCamelCase       ,    __UpperCamelCase						) else memory_bytes
                     if self.args.trace_memory_line_by_line:
                          __lowerCAmelCase             =       stop_memory_tracing(__UpperCamelCase						)
                          if memory is None:
                               __lowerCAmelCase             =       summary.total
                     else:
                          __lowerCAmelCase             =       None

                     return memory, summary
                except ResourceExhaustedError as e:
                     self.print_fn(F"""Doesn't fit on GPU. {e}"""						)
                     return "N/A", None














import itertools
import string
from collections.abc import Generator, Iterable





def    __lowerCAmelCase   (    __snake_case       ,			__snake_case							):
     __lowerCAmelCase             =       iter(__snake_case							)
     while True:
          __lowerCAmelCase             =       tuple(itertools.islice(__snake_case       ,			__snake_case							)							)
          if not chunk:
               return
          yield chunk





def    __lowerCAmelCase   (    __snake_case							):
     __lowerCAmelCase             =       "".join([c.upper() for c in dirty if c in string.ascii_letters]							)
     __lowerCAmelCase             =       ""

     if len(__snake_case							) < 2:
          return dirty

     for i in range(len(__snake_case							) - 1							):
          clean += dirty[i]

          if dirty[i] == dirty[i + 1]:
               clean += "X"

     clean += dirty[-1]

     if len(__snake_case							) & 1:
          clean += "X"

     return clean





def    __lowerCAmelCase   (    __snake_case							):
     # I and J are used interchangeably to allow
     # us to use a 5x5 table (25 letters)
     __lowerCAmelCase             =       "ABCDEFGHIKLMNOPQRSTUVWXYZ"
     # we're using a list instead of a '2d' array because it makes the math
     # for setting up the table and doing the actual encoding/decoding simpler
     __lowerCAmelCase             =       []

     # copy key chars into the table if they are in `alphabet` ignoring duplicates
     for char in key.upper():
          if char not in table and char in alphabet:
               table.append(__snake_case							)

    # fill the rest of the table in with the remaining alphabet chars
     for char in alphabet:
          if char not in table:
               table.append(__snake_case							)

     return table





def    __lowerCAmelCase   (    __snake_case       ,			__snake_case							):
     __lowerCAmelCase             =       generate_table(__snake_case							)
     __lowerCAmelCase             =       prepare_input(__snake_case							)
     __lowerCAmelCase             =       ""

     # https://en.wikipedia.org/wiki/Playfair_cipher#Description
     for chara, chara in chunker(__snake_case       ,			2							):
          __lowerCAmelCase      ,			__lowerCAmelCase             =       divmod(table.index(__snake_case							)       ,			5							)
          __lowerCAmelCase      ,			__lowerCAmelCase             =       divmod(table.index(__snake_case							)       ,			5							)

          if rowa == rowa:
               ciphertext += table[rowa * 5 + (cola + 1) % 5]
               ciphertext += table[rowa * 5 + (cola + 1) % 5]
          elif cola == cola:
               ciphertext += table[((rowa + 1) % 5) * 5 + cola]
               ciphertext += table[((rowa + 1) % 5) * 5 + cola]
          else:  # rectangle
               ciphertext += table[rowa * 5 + cola]
               ciphertext += table[rowa * 5 + cola]

     return ciphertext





def    __lowerCAmelCase   (    __snake_case       ,			__snake_case							):
     __lowerCAmelCase             =       generate_table(__snake_case							)
     __lowerCAmelCase             =       ""

     # https://en.wikipedia.org/wiki/Playfair_cipher#Description
     for chara, chara in chunker(__snake_case       ,			2							):
          __lowerCAmelCase      ,			__lowerCAmelCase             =       divmod(table.index(__snake_case							)       ,			5							)
          __lowerCAmelCase      ,			__lowerCAmelCase             =       divmod(table.index(__snake_case							)       ,			5							)

          if rowa == rowa:
               plaintext += table[rowa * 5 + (cola - 1) % 5]
               plaintext += table[rowa * 5 + (cola - 1) % 5]
          elif cola == cola:
               plaintext += table[((rowa - 1) % 5) * 5 + cola]
               plaintext += table[((rowa - 1) % 5) * 5 + cola]
          else:  # rectangle
               plaintext += table[rowa * 5 + cola]
               plaintext += table[rowa * 5 + cola]

     return plaintext






