
'''simple docstring'''





import os
import tempfile
import unittest

import numpy as np
import torch

from diffusers.models import ModelMixin, UNetaDConditionModel
from diffusers.models.attention_processor import AttnProcessor, LoRAAttnProcessor
from diffusers.utils import (
    floats_tensor,
    logging,
    skip_mps,
    torch_device,
)
from diffusers.utils.import_utils import is_xformers_available
from diffusers.utils.testing_utils import enable_full_determinism

from .test_modeling_common import ModelTesterMixin, UNetTesterMixin


enable_full_determinism()

a__		: int  							=							logging.get_logger(__name__)





def 							snake_case				(		UpperCAmelCase   ,	UpperCAmelCase = True						)->      Optional[Any]:







      """simple docstring"""
      __A													=      {}
      for name in model.attn_processors.keys():
            __A													=      name.endswith('attn2.processor'						) and not (
                name.startswith('transformer_in'						) or 'temp_attentions' in name.split('.'						)
            )
            __A													=      model.config.cross_attention_dim if has_cross_attention else None
            if name.startswith('mid_block'						):
                  __A													=      model.config.block_out_channels[-1]
            elif name.startswith('up_blocks'						):
                  __A													=      int(name[len('up_blocks.'						)]						)
                  __A													=      list(reversed(model.config.block_out_channels						)						)[block_id]
            elif name.startswith('down_blocks'						):
                  __A													=      int(name[len('down_blocks.'						)]						)
                  __A													=      model.config.block_out_channels[block_id]
            elif name.startswith('transformer_in'						):
                  # Note that the `8 * ...` comes from: https://github.com/huggingface/diffusers/blob/7139f0e874f10b2463caa8cbd585762a309d12d6/src/diffusers/models/unet_3d_condition.py#L148
                  __A													=      8 * model.config.attention_head_dim

            __A													=      LoRAAttnProcessor(hidden_size=UpperCAmelCase   ,	cross_attention_dim=UpperCAmelCase						)
            __A													=      lora_attn_procs[name].to(model.device						)

            if mock_weights:
                  # add 1 to weights to mock trained weights
                  with torch.no_grad():
                        lora_attn_procs[name].to_q_lora.up.weight += 1
                        lora_attn_procs[name].to_k_lora.up.weight += 1
                        lora_attn_procs[name].to_v_lora.up.weight += 1
                        lora_attn_procs[name].to_out_lora.up.weight += 1

      return lora_attn_procs


@skip_mps
class 			UpperCamelCase__	(     SCREAMING_SNAKE_CASE   ,  SCREAMING_SNAKE_CASE   ,  unittest.TestCase):
 UpperCAmelCase__     :     List[str]    					=       UNetaDConditionModel
 UpperCAmelCase__     :     Dict    					=       'sample'






 @property
 def 						lowercase_    (      self	:List[Any]      )					->      List[Any]:







       '''simple docstring'''



       __A													=      4
       __A													=      4
       __A													=      4
       __A													=      (32, 32)

       __A													=      floats_tensor((batch_size, num_channels, num_frames) + sizes      ).to(_A      )
       __A													=      torch.tensor([10]      ).to(_A      )
       __A													=      floats_tensor((batch_size, 4, 32)      ).to(_A      )

       return {"sample": noise, "timestep": time_step, "encoder_hidden_states": encoder_hidden_states}






 @property
 def 						lowercase_    (      self	:int      )					->      List[Any]:







       '''simple docstring'''



       return (4, 4, 32, 32)






 @property
 def 						lowercase_    (      self	:List[str]      )					->      Any:







       '''simple docstring'''



       return (4, 4, 32, 32)






 def 						lowercase_    (      self	:Tuple      )					->      Any:







       '''simple docstring'''



       __A													=      {
           'block_out_channels': (32, 64),
           'down_block_types': (
               'CrossAttnDownBlock3D',
               'DownBlock3D',
           ),
           'up_block_types': ('UpBlock3D', 'CrossAttnUpBlock3D'),
           'cross_attention_dim': 32,
           'attention_head_dim': 8,
           'out_channels': 4,
           'in_channels': 4,
           'layers_per_block': 1,
           'sample_size': 32,
       }
       __A													=      self.dummy_input
       return init_dict, inputs_dict






 @unittest.skipIf(
     torch_device != 'cuda' or not is_xformers_available()						,					reason='XFormers attention is only available with CUDA and `xformers` installed'						,					)
 def 						lowercase_    (      self	:Tuple      )					->      str:







       '''simple docstring'''



       __A						,   __A													=      self.prepare_init_args_and_inputs_for_common()
       __A													=      self.model_class(**_A      )

       model.enable_xformers_memory_efficient_attention()

       assert (
           model.mid_block.attentions[0].transformer_blocks[0].attna.processor.__class__.__name__
           == "XFormersAttnProcessor"
       ), "xformers is not enabled"






 def 						lowercase_    (      self	:List[Any]      )					->      Any:







       '''simple docstring'''



       __A						,   __A													=      self.prepare_init_args_and_inputs_for_common()

       __A													=      32

       __A													=      self.model_class(**_A      )
       model.to(_A      )
       model.eval()

       with torch.no_grad():
             __A													=      model(**_A      )

             if isinstance(_A						,					_A      ):
                   __A													=      output.sample

       self.assertIsNotNone(_A      )
       __A													=      inputs_dict['sample'].shape
       self.assertEqual(output.shape						,					_A						,					'Input and output shapes do not match'      )






 def 						lowercase_    (      self	:Optional[int]      )					->      Dict:







       '''simple docstring'''



       __A						,   __A													=      self.prepare_init_args_and_inputs_for_common()
       __A													=      self.model_class(**_A      )
       model.to(_A      )
       model.eval()

       with torch.no_grad():
             # Warmup pass when using mps (see #372)
             if torch_device == "mps" and isinstance(_A						,					_A      ):
                   model(**self.dummy_input      )

             __A													=      model(**_A      )
             if isinstance(_A						,					_A      ):
                   __A													=      first.sample

             __A													=      model(**_A      )
             if isinstance(_A						,					_A      ):
                   __A													=      second.sample

       __A													=      first.cpu().numpy()
       __A													=      second.cpu().numpy()
       __A													=      out_a[~np.isnan(_A      )]
       __A													=      out_a[~np.isnan(_A      )]
       __A													=      np.amax(np.abs(out_a - out_a      )      )
       self.assertLessEqual(_A						,					1E-5      )






 def 						lowercase_    (      self	:Optional[Any]      )					->      Dict:







       '''simple docstring'''



       __A						,   __A													=      self.prepare_init_args_and_inputs_for_common()

       __A													=      8

       __A													=      self.model_class(**_A      )
       model.to(_A      )
       model.eval()

       model.set_attention_slice('auto'      )
       with torch.no_grad():
             __A													=      model(**_A      )
       assert output is not None

       model.set_attention_slice('max'      )
       with torch.no_grad():
             __A													=      model(**_A      )
       assert output is not None

       model.set_attention_slice(2      )
       with torch.no_grad():
             __A													=      model(**_A      )
       assert output is not None






 def 						lowercase_    (      self	:Dict      )					->      Optional[Any]:







       '''simple docstring'''



       __A						,   __A													=      self.prepare_init_args_and_inputs_for_common()

       __A													=      8

       __A													=      self.model_class(**_A      )
       model.to(_A      )

       with torch.no_grad():
             __A													=      model(**_A      ).sample

       __A													=      create_lora_layers(_A      )

       # make sure we can set a list of attention processors
       model.set_attn_processor(_A      )
       model.to(_A      )

       # test that attn processors can be set to itself
       model.set_attn_processor(model.attn_processors      )

       with torch.no_grad():
             __A													=      model(**_A						,					cross_attention_kwargs={'scale': 0.0}      ).sample
             __A													=      model(**_A						,					cross_attention_kwargs={'scale': 0.5}      ).sample
             __A													=      model(**_A						,					cross_attention_kwargs={'scale': 0.5}      ).sample

       assert (samplea - samplea).abs().max() < 3E-3
       assert (samplea - samplea).abs().max() < 3E-3

       # sample 2 and sample 3 should be different
       assert (samplea - samplea).abs().max() > 3E-3






 def 						lowercase_    (      self	:List[str]      )					->      Any:







       '''simple docstring'''



       __A						,   __A													=      self.prepare_init_args_and_inputs_for_common()

       __A													=      8

       torch.manual_seed(0      )
       __A													=      self.model_class(**_A      )
       model.to(_A      )

       with torch.no_grad():
             __A													=      model(**_A      ).sample

       __A													=      create_lora_layers(_A      )
       model.set_attn_processor(_A      )

       with torch.no_grad():
             __A													=      model(**_A						,					cross_attention_kwargs={'scale': 0.5}      ).sample

       with tempfile.TemporaryDirectory() as tmpdirname:
             model.save_attn_procs(_A      )
             self.assertTrue(os.path.isfile(os.path.join(_A						,					'pytorch_lora_weights.bin'      )      )      )
             torch.manual_seed(0      )
             __A													=      self.model_class(**_A      )
             new_model.to(_A      )
             new_model.load_attn_procs(_A      )

       with torch.no_grad():
             __A													=      new_model(**_A						,					cross_attention_kwargs={'scale': 0.5}      ).sample

       assert (sample - new_sample).abs().max() < 1E-3

       # LoRA and no LoRA should NOT be the same
       assert (sample - old_sample).abs().max() > 1E-4






 def 						lowercase_    (      self	:Tuple      )					->      str:







       '''simple docstring'''



       __A						,   __A													=      self.prepare_init_args_and_inputs_for_common()

       __A													=      8

       torch.manual_seed(0      )
       __A													=      self.model_class(**_A      )
       model.to(_A      )

       with torch.no_grad():
             __A													=      model(**_A      ).sample

       __A													=      create_lora_layers(_A      )
       model.set_attn_processor(_A      )

       with torch.no_grad():
             __A													=      model(**_A						,					cross_attention_kwargs={'scale': 0.5}      ).sample

       with tempfile.TemporaryDirectory() as tmpdirname:
             model.save_attn_procs(_A						,					safe_serialization=_A      )
             self.assertTrue(os.path.isfile(os.path.join(_A						,					'pytorch_lora_weights.safetensors'      )      )      )
             torch.manual_seed(0      )
             __A													=      self.model_class(**_A      )
             new_model.to(_A      )
             new_model.load_attn_procs(_A      )

       with torch.no_grad():
             __A													=      new_model(**_A						,					cross_attention_kwargs={'scale': 0.5}      ).sample

       assert (sample - new_sample).abs().max() < 3E-3

       # LoRA and no LoRA should NOT be the same
       assert (sample - old_sample).abs().max() > 1E-4






 def 						lowercase_    (      self	:Any      )					->      Tuple:







       '''simple docstring'''



       __A						,   __A													=      self.prepare_init_args_and_inputs_for_common()

       __A													=      8

       torch.manual_seed(0      )
       __A													=      self.model_class(**_A      )
       model.to(_A      )

       __A													=      create_lora_layers(_A						,					mock_weights=_A      )
       model.set_attn_processor(_A      )
       # Saving as torch, properly reloads with directly filename
       with tempfile.TemporaryDirectory() as tmpdirname:
             model.save_attn_procs(_A      )
             self.assertTrue(os.path.isfile(os.path.join(_A						,					'pytorch_lora_weights.bin'      )      )      )
             torch.manual_seed(0      )
             __A													=      self.model_class(**_A      )
             new_model.to(_A      )
             new_model.load_attn_procs(_A						,					weight_name='pytorch_lora_weights.bin'      )






 def 						lowercase_    (      self	:Any      )					->      Union[str, Any]:







       '''simple docstring'''



       __A						,   __A													=      self.prepare_init_args_and_inputs_for_common()

       __A													=      8

       torch.manual_seed(0      )
       __A													=      self.model_class(**_A      )
       model.to(_A      )

       __A													=      create_lora_layers(_A						,					mock_weights=_A      )
       model.set_attn_processor(_A      )
       # Saving as torch, properly reloads with directly filename
       with tempfile.TemporaryDirectory() as tmpdirname:
             model.save_attn_procs(_A      )
             self.assertTrue(os.path.isfile(os.path.join(_A						,					'pytorch_lora_weights.bin'      )      )      )
             torch.manual_seed(0      )
             __A													=      self.model_class(**_A      )
             new_model.to(_A      )
             with self.assertRaises(_A      ) as e:
                   new_model.load_attn_procs(_A						,					use_safetensors=_A      )
             self.assertIn('Error no file named pytorch_lora_weights.safetensors'						,					str(e.exception      )      )






 def 						lowercase_    (      self	:List[Any]      )					->      str:







       '''simple docstring'''



       __A						,   __A													=      self.prepare_init_args_and_inputs_for_common()

       __A													=      8

       torch.manual_seed(0      )
       __A													=      self.model_class(**_A      )
       model.to(_A      )

       with torch.no_grad():
             __A													=      model(**_A      ).sample

       __A													=      create_lora_layers(_A      )
       model.set_attn_processor(_A      )

       with torch.no_grad():
             __A													=      model(**_A						,					cross_attention_kwargs={'scale': 0.0}      ).sample

       model.set_attn_processor(AttnProcessor()      )

       with torch.no_grad():
             __A													=      model(**_A      ).sample

       assert (sample - new_sample).abs().max() < 1E-4
       assert (sample - old_sample).abs().max() < 3E-3






 @unittest.skipIf(
     torch_device != 'cuda' or not is_xformers_available()						,					reason='XFormers attention is only available with CUDA and `xformers` installed'						,					)
 def 						lowercase_    (      self	:Tuple      )					->      Dict:







       '''simple docstring'''



       __A						,   __A													=      self.prepare_init_args_and_inputs_for_common()

       __A													=      4

       torch.manual_seed(0      )
       __A													=      self.model_class(**_A      )
       model.to(_A      )
       __A													=      create_lora_layers(_A      )
       model.set_attn_processor(_A      )

       # default
       with torch.no_grad():
             __A													=      model(**_A      ).sample

             model.enable_xformers_memory_efficient_attention()
             __A													=      model(**_A      ).sample

             model.disable_xformers_memory_efficient_attention()
             __A													=      model(**_A      ).sample

       assert (sample - on_sample).abs().max() < 1E-4
       assert (sample - off_sample).abs().max() < 1E-4






 def 						lowercase_    (      self	:str      )					->      Union[str, Any]:







       '''simple docstring'''



       __A						,   __A													=      self.prepare_init_args_and_inputs_for_common()
       __A													=      32

       __A													=      self.model_class(**_A      )
       model.to(_A      )
       model.eval()

       with torch.no_grad():
             __A													=      model(**_A      )[0]

       model.enable_forward_chunking()
       with torch.no_grad():
             __A													=      model(**_A      )[0]

       self.assertEqual(output.shape						,					output_a.shape						,					'Shape doesn\'t match'      )
       assert np.abs(output.cpu() - output_a.cpu()      ).max() < 1E-2


# (todo: sayakpaul) implement SLOW tests.










from __future__ import annotations

from string import ascii_letters






def 	lowerCamelCase_       (			_a      ,  _a      ,  _a = None			):




		"""simple docstring"""






		lowerCAmelCase__  :     List[Any]       	=   alphabet or ascii_letters

		# The final result string
		lowerCAmelCase__  :     Optional[Any]       	=   ''''''

		for character in input_string:
				if character not in alpha:
						# Append without encryption if character is not in the alphabet
						result += character
				else:
						# Get the index of the new key and make sure it isn't too large
						lowerCAmelCase__  :     int       	=   (alpha.index(_a			) + key) % len(_a			)

						# Append the encoded character to the alphabet
						result += alpha[new_key]

		return result






def 	lowerCamelCase_       (			_a      ,  _a      ,  _a = None			):




		"""simple docstring"""






		key *= -1

		return encrypt(_a      ,  _a      ,  _a			)






def 	lowerCamelCase_       (			_a      ,  _a = None			):




		"""simple docstring"""






		lowerCAmelCase__  :     Optional[Any]       	=   alphabet or ascii_letters

		# To store data on all the combinations
		lowerCAmelCase__  :     Optional[int]       	=   {}

		# Cycle through each combination
		for key in range(1      ,  len(_a			) + 1			):
				# Decrypt the message and store the result in the data
				lowerCAmelCase__  :     Optional[int]       	=   decrypt(_a      ,  _a      ,  _a			)

		return brute_force_data


if __name__ == "__main__":
		while True:
				print(f'''\n{"-" * 10}\n Menu\n{"-" * 10}''')
				print(*['''1.Encrypt''', '''2.Decrypt''', '''3.BruteForce''', '''4.Quit'''], sep='''\n''')

				# get user input
				lowerCamelCase		=						input('''\nWhat would you like to do?: ''').strip() or '''4'''

				# run functions based on what the user chose
				if choice not in ("1", "2", "3", "4"):
						print('''Invalid choice, please enter a valid choice''')
				elif choice == "1":
						lowerCamelCase		=						input('''Please enter the string to be encrypted: ''')
						lowerCamelCase		=						int(input('''Please enter off-set: ''').strip())

						print(encrypt(input_string, key))
				elif choice == "2":
						lowerCamelCase		=						input('''Please enter the string to be decrypted: ''')
						lowerCamelCase		=						int(input('''Please enter off-set: ''').strip())

						print(decrypt(input_string, key))
				elif choice == "3":
						lowerCamelCase		=						input('''Please enter the string to be decrypted: ''')
						lowerCamelCase		=						brute_force(input_string)

						for key, value in brute_force_data.items():
								print(f'''Key: {key} | Message: {value}''')

				elif choice == "4":
						print('''Goodbye.''')
						break




