




import random
import unittest

import numpy as np

import transformers
from transformers import is_flax_available, is_torch_available
from transformers.testing_utils import is_pt_flax_cross_test, require_flax


if is_flax_available():
     import os

     import jax.numpy as jnp
     from jax import jit

     from transformers import AutoTokenizer, FlaxAutoModelForCausalLM
     from transformers.modeling_flax_pytorch_utils import load_flax_weights_in_pytorch_model

     lowerCAmelCase_					    = """0.12"""  # assumed parallelism: 8


if is_torch_available():
     import torch



def      __lowerCAmelCase			(					UpperCamelCase	,      UpperCamelCase	,      UpperCamelCase=None      )     ->	Any:







  if rng is None:
    lowerCAmelCase__				:  Tuple		       =     random.Random()

  lowerCAmelCase__				:  List[str]		       =     1
  for dim in shape:
    total_dims *= dim

  lowerCAmelCase__				:  Dict		       =     []
  for _ in range(__UpperCAmelCase      ):
    values.append(rng.randint(0	,      vocab_size - 1      )      )

  lowerCAmelCase__				:  Optional[int]		       =     np.array(__UpperCAmelCase	,      dtype=jnp.intaa      ).reshape(__UpperCAmelCase      )

  return output



def      __lowerCAmelCase			(					UpperCamelCase	,      UpperCamelCase=None      )     ->	Dict:
  lowerCAmelCase__				:  str		       =     ids_tensor(__UpperCAmelCase	,      vocab_size=2	,      rng=__UpperCAmelCase      )
  # make sure that at least one token is attended to for each batch
  lowerCAmelCase__				:  List[str]		       =     1
  return attn_mask






@require_flax
class  _lowerCAmelCase     :
      A__		     =		None
      A__		     =		()

      def 	__magic_name__(   self		):
        lowerCAmelCase__       ,			lowerCAmelCase__				:  Optional[Any]		       =     self.model_tester.prepare_config_and_inputs_for_common()

        # cut to half length & take max batch_size 3
        lowerCAmelCase__				:  Tuple		       =     2
        lowerCAmelCase__				:  int		       =     inputs['''input_ids'''].shape[-1] // 2
        lowerCAmelCase__				:  List[Any]		       =     inputs['''input_ids'''][:max_batch_size, :sequence_length]

        lowerCAmelCase__				:  Optional[Any]		       =     jnp.ones_like(__UpperCAmelCase		)
        lowerCAmelCase__				:  Tuple		       =     attention_mask[:max_batch_size, :sequence_length]

        # generate max 5 tokens
        lowerCAmelCase__				:  Optional[int]		       =     input_ids.shape[-1] + 5
        if config.eos_token_id is not None and config.pad_token_id is None:
          # hack to allow generate for models such as GPT2 as is done in `generate()`
          lowerCAmelCase__				:  List[str]		       =     config.eos_token_id
        return config, input_ids, attention_mask, max_length

      @is_pt_flax_cross_test
      def 	__magic_name__(   self		):
        lowerCAmelCase__       ,			lowerCAmelCase__       ,			lowerCAmelCase__       ,			lowerCAmelCase__				:  Optional[int]		       =     self._get_input_ids_and_config()
        lowerCAmelCase__				:  Any		       =     False
        lowerCAmelCase__				:  Dict		       =     max_length
        lowerCAmelCase__				:  Tuple		       =     0

        for model_class in self.all_generative_model_classes:
          lowerCAmelCase__				:  Dict		       =     model_class(__UpperCAmelCase		)

          lowerCAmelCase__				:  str		       =     model_class.__name__[4:]  # Skip the "Flax" at the beginning
          lowerCAmelCase__				:  List[Any]		       =     getattr(__UpperCAmelCase      ,				__UpperCAmelCase		)
          lowerCAmelCase__				:  Tuple		       =     pt_model_class(__UpperCAmelCase		).eval()
          lowerCAmelCase__				:  Optional[int]		       =     load_flax_weights_in_pytorch_model(__UpperCAmelCase      ,				flax_model.params		)

          lowerCAmelCase__				:  Optional[int]		       =     flax_model.generate(__UpperCAmelCase		).sequences
          lowerCAmelCase__				:  Union[str, Any]		       =     pt_model.generate(torch.tensor(__UpperCAmelCase      ,				dtype=torch.long		)		)

          if flax_generation_outputs.shape[-1] > pt_generation_outputs.shape[-1]:
            lowerCAmelCase__				:  str		       =     flax_generation_outputs[:, : pt_generation_outputs.shape[-1]]

          self.assertListEqual(pt_generation_outputs.numpy().tolist()      ,				flax_generation_outputs.tolist()		)

      def 	__magic_name__(   self		):
        lowerCAmelCase__       ,			lowerCAmelCase__       ,			lowerCAmelCase__       ,			lowerCAmelCase__				:  Optional[int]		       =     self._get_input_ids_and_config()
        lowerCAmelCase__				:  Any		       =     False
        lowerCAmelCase__				:  Any		       =     max_length

        for model_class in self.all_generative_model_classes:
          lowerCAmelCase__				:  Dict		       =     model_class(__UpperCAmelCase		)

          lowerCAmelCase__				:  Union[str, Any]		       =     model.generate(__UpperCAmelCase		).sequences
          self.assertEqual(generation_outputs.shape[-1]      ,				__UpperCAmelCase		)

          lowerCAmelCase__				:  Tuple		       =     jit(model.generate		)
          lowerCAmelCase__				:  str		       =     jit_generate(__UpperCAmelCase		).sequences

          self.assertListEqual(generation_outputs.tolist()      ,				jit_generation_outputs.tolist()		)

      def 	__magic_name__(   self		):
        lowerCAmelCase__       ,			lowerCAmelCase__       ,			lowerCAmelCase__       ,			lowerCAmelCase__				:  Union[str, Any]		       =     self._get_input_ids_and_config()
        lowerCAmelCase__				:  List[str]		       =     True
        lowerCAmelCase__				:  Optional[int]		       =     max_length

        for model_class in self.all_generative_model_classes:
          lowerCAmelCase__				:  List[str]		       =     model_class(__UpperCAmelCase		)

          lowerCAmelCase__				:  str		       =     model.generate(__UpperCAmelCase		).sequences
          self.assertEqual(generation_outputs.shape[-1]      ,				__UpperCAmelCase		)

          lowerCAmelCase__				:  List[str]		       =     jit(model.generate		)
          lowerCAmelCase__				:  int		       =     jit_generate(__UpperCAmelCase		).sequences

          self.assertListEqual(generation_outputs.tolist()      ,				jit_generation_outputs.tolist()		)

      def 	__magic_name__(   self		):
        lowerCAmelCase__       ,			lowerCAmelCase__       ,			lowerCAmelCase__       ,			lowerCAmelCase__				:  List[str]		       =     self._get_input_ids_and_config()
        lowerCAmelCase__				:  Optional[int]		       =     False
        lowerCAmelCase__				:  Optional[int]		       =     max_length
        lowerCAmelCase__				:  Optional[Any]		       =     2

        for model_class in self.all_generative_model_classes:
          lowerCAmelCase__				:  str		       =     model_class(__UpperCAmelCase		)

          lowerCAmelCase__				:  List[Any]		       =     model.generate(__UpperCAmelCase		).sequences
          self.assertEqual(generation_outputs.shape[-1]      ,				__UpperCAmelCase		)

          lowerCAmelCase__				:  Optional[Any]		       =     jit(model.generate		)
          lowerCAmelCase__				:  Union[str, Any]		       =     jit_generate(__UpperCAmelCase		).sequences

          self.assertListEqual(generation_outputs.tolist()      ,				jit_generation_outputs.tolist()		)

      def 	__magic_name__(   self		):
        lowerCAmelCase__       ,			lowerCAmelCase__       ,			lowerCAmelCase__       ,			lowerCAmelCase__				:  Optional[Any]		       =     self._get_input_ids_and_config()
        lowerCAmelCase__				:  Tuple		       =     False
        lowerCAmelCase__				:  Optional[int]		       =     max_length
        lowerCAmelCase__				:  Tuple		       =     2
        lowerCAmelCase__				:  Tuple		       =     2

        for model_class in self.all_generative_model_classes:
          lowerCAmelCase__				:  List[Any]		       =     model_class(__UpperCAmelCase		)

          lowerCAmelCase__				:  Union[str, Any]		       =     model.generate(__UpperCAmelCase		).sequences
          self.assertEqual(generation_outputs.shape[0]      ,				input_ids.shape[0] * config.num_return_sequences		)

      def 	__magic_name__(   self		):
        lowerCAmelCase__       ,			lowerCAmelCase__       ,			lowerCAmelCase__       ,			lowerCAmelCase__				:  List[Any]		       =     self._get_input_ids_and_config()
        lowerCAmelCase__				:  Optional[Any]		       =     True
        lowerCAmelCase__				:  List[str]		       =     max_length
        lowerCAmelCase__				:  Optional[Any]		       =     0.8
        lowerCAmelCase__				:  Any		       =     10
        lowerCAmelCase__				:  List[str]		       =     0.3
        lowerCAmelCase__				:  List[Any]		       =     1
        lowerCAmelCase__				:  Optional[int]		       =     8
        lowerCAmelCase__				:  Any		       =     9

        for model_class in self.all_generative_model_classes:
          lowerCAmelCase__				:  List[str]		       =     model_class(__UpperCAmelCase		)

          lowerCAmelCase__				:  Dict		       =     model.generate(__UpperCAmelCase		).sequences
          self.assertEqual(generation_outputs.shape[-1]      ,				__UpperCAmelCase		)

          lowerCAmelCase__				:  List[Any]		       =     jit(model.generate		)
          lowerCAmelCase__				:  List[str]		       =     jit_generate(__UpperCAmelCase		).sequences

          self.assertListEqual(generation_outputs.tolist()      ,				jit_generation_outputs.tolist()		)

      def 	__magic_name__(   self		):
        lowerCAmelCase__       ,			lowerCAmelCase__       ,			lowerCAmelCase__       ,			lowerCAmelCase__				:  int		       =     self._get_input_ids_and_config()
        lowerCAmelCase__				:  Tuple		       =     max_length
        lowerCAmelCase__				:  Tuple		       =     1
        lowerCAmelCase__				:  Optional[Any]		       =     8
        lowerCAmelCase__				:  int		       =     9

        for model_class in self.all_generative_model_classes:
          lowerCAmelCase__				:  Tuple		       =     model_class(__UpperCAmelCase		)

          lowerCAmelCase__				:  Optional[int]		       =     model.generate(__UpperCAmelCase		).sequences
          self.assertEqual(generation_outputs.shape[-1]      ,				__UpperCAmelCase		)

          lowerCAmelCase__				:  Dict		       =     jit(model.generate		)
          lowerCAmelCase__				:  List[str]		       =     jit_generate(__UpperCAmelCase		).sequences

          self.assertListEqual(generation_outputs.tolist()      ,				jit_generation_outputs.tolist()		)

      def 	__magic_name__(   self		):
        lowerCAmelCase__       ,			lowerCAmelCase__       ,			lowerCAmelCase__       ,			lowerCAmelCase__				:  Tuple		       =     self._get_input_ids_and_config()
        lowerCAmelCase__				:  int		       =     max_length
        lowerCAmelCase__				:  int		       =     2
        lowerCAmelCase__				:  Optional[int]		       =     1
        lowerCAmelCase__				:  Any		       =     8
        lowerCAmelCase__				:  List[Any]		       =     9

        for model_class in self.all_generative_model_classes:
          lowerCAmelCase__				:  Union[str, Any]		       =     model_class(__UpperCAmelCase		)

          lowerCAmelCase__				:  List[str]		       =     model.generate(__UpperCAmelCase		).sequences
          self.assertEqual(generation_outputs.shape[-1]      ,				__UpperCAmelCase		)

          lowerCAmelCase__				:  List[Any]		       =     jit(model.generate		)
          lowerCAmelCase__				:  Any		       =     jit_generate(__UpperCAmelCase		).sequences

          self.assertListEqual(generation_outputs.tolist()      ,				jit_generation_outputs.tolist()		)

      def 	__magic_name__(   self		):
        lowerCAmelCase__       ,			lowerCAmelCase__       ,			lowerCAmelCase__       ,			lowerCAmelCase__				:  Optional[int]		       =     self._get_input_ids_and_config()

        # pad attention mask on the left
        lowerCAmelCase__				:  Dict		       =     attention_mask.at[(0, 0)].set(0		)

        lowerCAmelCase__				:  List[str]		       =     False
        lowerCAmelCase__				:  Union[str, Any]		       =     max_length

        for model_class in self.all_generative_model_classes:
          lowerCAmelCase__				:  List[Any]		       =     model_class(__UpperCAmelCase		)

          lowerCAmelCase__				:  List[Any]		       =     model.generate(__UpperCAmelCase      ,				attention_mask=__UpperCAmelCase		).sequences
          self.assertEqual(generation_outputs.shape[-1]      ,				__UpperCAmelCase		)

          lowerCAmelCase__				:  Union[str, Any]		       =     jit(model.generate		)
          lowerCAmelCase__				:  Union[str, Any]		       =     jit_generate(__UpperCAmelCase      ,				attention_mask=__UpperCAmelCase		).sequences

          self.assertListEqual(generation_outputs.tolist()      ,				jit_generation_outputs.tolist()		)

      def 	__magic_name__(   self		):
        lowerCAmelCase__       ,			lowerCAmelCase__       ,			lowerCAmelCase__       ,			lowerCAmelCase__				:  List[Any]		       =     self._get_input_ids_and_config()

        # pad attention mask on the left
        lowerCAmelCase__				:  str		       =     attention_mask.at[(0, 0)].set(0		)

        lowerCAmelCase__				:  Dict		       =     True
        lowerCAmelCase__				:  Dict		       =     max_length

        for model_class in self.all_generative_model_classes:
          lowerCAmelCase__				:  List[Any]		       =     model_class(__UpperCAmelCase		)

          lowerCAmelCase__				:  Optional[int]		       =     model.generate(__UpperCAmelCase      ,				attention_mask=__UpperCAmelCase		).sequences
          self.assertEqual(generation_outputs.shape[-1]      ,				__UpperCAmelCase		)

          lowerCAmelCase__				:  Any		       =     jit(model.generate		)
          lowerCAmelCase__				:  List[Any]		       =     jit_generate(__UpperCAmelCase      ,				attention_mask=__UpperCAmelCase		).sequences

          self.assertListEqual(generation_outputs.tolist()      ,				jit_generation_outputs.tolist()		)







      def 	__magic_name__(   self		):
        lowerCAmelCase__       ,			lowerCAmelCase__       ,			lowerCAmelCase__       ,			lowerCAmelCase__				:  List[str]		       =     self._get_input_ids_and_config()

        # pad attention mask on the left
        lowerCAmelCase__				:  Optional[Any]		       =     attention_mask.at[(0, 0)].set(0		)

        lowerCAmelCase__				:  Any		       =     2
        lowerCAmelCase__				:  Any		       =     max_length

        for model_class in self.all_generative_model_classes:
          lowerCAmelCase__				:  Any		       =     model_class(__UpperCAmelCase		)

          lowerCAmelCase__				:  Union[str, Any]		       =     model.generate(__UpperCAmelCase      ,				attention_mask=__UpperCAmelCase		).sequences
          self.assertEqual(generation_outputs.shape[-1]      ,				__UpperCAmelCase		)

          lowerCAmelCase__				:  str		       =     jit(model.generate		)
          lowerCAmelCase__				:  Any		       =     jit_generate(__UpperCAmelCase      ,				attention_mask=__UpperCAmelCase		).sequences

          self.assertListEqual(generation_outputs.tolist()      ,				jit_generation_outputs.tolist()		)






@require_flax
class  _lowerCAmelCase     (  unittest.TestCase	):

      def 	__magic_name__(   self		):
        lowerCAmelCase__				:  List[str]		       =     AutoTokenizer.from_pretrained('''hf-internal-testing/tiny-bert'''		)
        lowerCAmelCase__				:  Any		       =     FlaxAutoModelForCausalLM.from_pretrained('''hf-internal-testing/tiny-bert-flax-only'''		)

        lowerCAmelCase__				:  Union[str, Any]		       =     '''Hello world'''
        lowerCAmelCase__				:  List[Any]		       =     tokenizer(__UpperCAmelCase      ,				return_tensors='''np'''		).input_ids

        # typos are quickly detected (the correct argument is `do_sample`)
        with self.assertRaisesRegex(__UpperCAmelCase      ,				'''do_samples'''		):
          model.generate(__UpperCAmelCase      ,				do_samples=__UpperCAmelCase		)

        # arbitrary arguments that will not be used anywhere are also not accepted
        with self.assertRaisesRegex(__UpperCAmelCase      ,				'''foo'''		):
          lowerCAmelCase__				:  Any		       =     {'''foo''': '''bar'''}
          model.generate(__UpperCAmelCase      ,				**__UpperCAmelCase		)







from collections import Counter
from timeit import timeit



def      __lowerCAmelCase			(					UpperCamelCase = ""	,      )     ->	bool:
  return sum(c % 2 for c in Counter(input_str.replace(''' '''	,      ''''''      ).lower()      ).values()      ) < 2



def      __lowerCAmelCase			(					UpperCamelCase = ""      )     ->	bool:
  if len(UpperCamelCase      ) == 0:
    return True
  lowerCAmelCase__				:  str		       =     input_str.replace(''' '''	,      ''''''      ).lower()
  # character_freq_dict: Stores the frequency of every character in the input string
  lowerCAmelCase__				:  dict[str, int]		       =     {}

  for character in lower_case_input_str:
    lowerCAmelCase__				:  int		       =     character_freq_dict.get(UpperCamelCase	,      0      ) + 1
  lowerCAmelCase__				:  Any		       =     0

  for character_count in character_freq_dict.values():
    if character_count % 2:
      odd_char += 1
  if odd_char > 1:
    return False
  return True



def      __lowerCAmelCase			(					UpperCamelCase = ""      )     ->	None:
  print('''\nFor string = '''	,      UpperCamelCase	,      ''':'''      )
  print(
      '''> can_string_be_rearranged_as_palindrome_counter()'''	,      '''\tans ='''	,      can_string_be_rearranged_as_palindrome_counter(UpperCamelCase      )	,      '''\ttime ='''	,      timeit(
          '''z.can_string_be_rearranged_as_palindrome_counter(z.check_str)'''	,      setup='''import __main__ as z'''	,      )	,      '''seconds'''	,      )
  print(
      '''> can_string_be_rearranged_as_palindrome()'''	,      '''\tans ='''	,      can_string_be_rearranged_as_palindrome(UpperCamelCase      )	,      '''\ttime ='''	,      timeit(
          '''z.can_string_be_rearranged_as_palindrome(z.check_str)'''	,      setup='''import __main__ as z'''	,      )	,      '''seconds'''	,      )


if __name__ == "__main__":
     lowerCAmelCase_					    = input(
         """Enter string to determine if it can be rearranged as a palindrome or not: """
     ).strip()
     benchmark(check_str)
     lowerCAmelCase_					    = can_string_be_rearranged_as_palindrome_counter(check_str)
     print(F"""{check_str} can {"" if status else "not "}be rearranged as a palindrome""")

