


"""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()

SCREAMING_SNAKE_CASE					:       Any							   =							logging.get_logger(__name__)






def 						lowercase				(	_snake_case		: List[str]	,  _snake_case		: bool = True	)	->str:
	"""simple docstring"""





	__snake_case      :		List[str]         =							{}
	for name in model.attn_processors.keys():
		__snake_case      :		str         =							name.endswith('''attn2.processor'''	) and not (
		    name.startswith('''transformer_in'''	) or '''temp_attentions''' in name.split('''.'''	)
		)
		__snake_case      :		Tuple         =							model.config.cross_attention_dim if has_cross_attention else None
		if name.startswith('''mid_block'''	):
			__snake_case      :		Dict         =							model.config.block_out_channels[-1]
		elif name.startswith('''up_blocks'''	):
			__snake_case      :		Any         =							int(name[len('''up_blocks.'''	)]	)
			__snake_case      :		List[str]         =							list(reversed(model.config.block_out_channels	)	)[block_id]
		elif name.startswith('''down_blocks'''	):
			__snake_case      :		Dict         =							int(name[len('''down_blocks.'''	)]	)
			__snake_case      :		Optional[Any]         =							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
			__snake_case      :		int         =							8 * model.config.attention_head_dim

		__snake_case      :		Tuple         =							LoRAAttnProcessor(hidden_size=_snake_case	,  cross_attention_dim=_snake_case	)
		__snake_case      :		List[str]         =							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					(				__snake_case,							__snake_case,							unittest.TestCase							):






		'''simple docstring'''

		lowerCamelCase__           =UNetaDConditionModel
		lowerCamelCase__           ='sample'



		@property
		def 							SCREAMING_SNAKE_CASE    (self   ):





			'''simple docstring'''

			__snake_case      :		str         =							4
			__snake_case      :		List[Any]         =							4
			__snake_case      :		List[str]         =							4
			__snake_case      :		Any         =							(32, 32)

			__snake_case      :		Tuple         =							floats_tensor((batch_size, num_channels, num_frames) + sizes   ).to(a_   )
			__snake_case      :		Union[str, Any]         =							torch.tensor([10]   ).to(a_   )
			__snake_case      :		str         =							floats_tensor((batch_size, 4, 32)   ).to(a_   )

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



		@property
		def 							SCREAMING_SNAKE_CASE    (self   ):





			'''simple docstring'''

			return (4, 4, 32, 32)



		@property
		def 							SCREAMING_SNAKE_CASE    (self   ):





			'''simple docstring'''

			return (4, 4, 32, 32)



		def 							SCREAMING_SNAKE_CASE    (self   ):





			'''simple docstring'''

			__snake_case      :		Any         =							{
			    '''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,
			}
			__snake_case      :		Dict         =							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 							SCREAMING_SNAKE_CASE    (self   ):





			'''simple docstring'''

			__snake_case      ,				__snake_case      :		int         =							self.prepare_init_args_and_inputs_for_common()
			__snake_case      :		Tuple         =							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 							SCREAMING_SNAKE_CASE    (self   ):





			'''simple docstring'''

			__snake_case      ,				__snake_case      :		int         =							self.prepare_init_args_and_inputs_for_common()

			__snake_case      :		Union[str, Any]         =							32

			__snake_case      :		Union[str, Any]         =							self.model_class(**a_   )
			model.to(a_   )
			model.eval()

			with torch.no_grad():
				__snake_case      :		Union[str, Any]         =							model(**a_   )

				if isinstance(a_							,			a_   ):
					__snake_case      :		Optional[Any]         =							output.sample

			self.assertIsNotNone(a_   )
			__snake_case      :		str         =							inputs_dict['''sample'''].shape
			self.assertEqual(output.shape							,			a_							,			'''Input and output shapes do not match'''   )



		def 							SCREAMING_SNAKE_CASE    (self   ):





			'''simple docstring'''

			__snake_case      ,				__snake_case      :		Optional[Any]         =							self.prepare_init_args_and_inputs_for_common()
			__snake_case      :		List[Any]         =							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   )

				__snake_case      :		Tuple         =							model(**a_   )
				if isinstance(a_							,			a_   ):
					__snake_case      :		int         =							first.sample

				__snake_case      :		str         =							model(**a_   )
				if isinstance(a_							,			a_   ):
					__snake_case      :		Optional[int]         =							second.sample

			__snake_case      :		Union[str, Any]         =							first.cpu().numpy()
			__snake_case      :		Tuple         =							second.cpu().numpy()
			__snake_case      :		int         =							out_a[~np.isnan(a_   )]
			__snake_case      :		int         =							out_a[~np.isnan(a_   )]
			__snake_case      :		Optional[int]         =							np.amax(np.abs(out_a - out_a   )   )
			self.assertLessEqual(a_							,			1E-5   )



		def 							SCREAMING_SNAKE_CASE    (self   ):





			'''simple docstring'''

			__snake_case      ,				__snake_case      :		Union[str, Any]         =							self.prepare_init_args_and_inputs_for_common()

			__snake_case      :		Optional[Any]         =							8

			__snake_case      :		Union[str, Any]         =							self.model_class(**a_   )
			model.to(a_   )
			model.eval()

			model.set_attention_slice('''auto'''   )
			with torch.no_grad():
				__snake_case      :		Any         =							model(**a_   )
			assert output is not None

			model.set_attention_slice('''max'''   )
			with torch.no_grad():
				__snake_case      :		str         =							model(**a_   )
			assert output is not None

			model.set_attention_slice(2   )
			with torch.no_grad():
				__snake_case      :		Any         =							model(**a_   )
			assert output is not None



		def 							SCREAMING_SNAKE_CASE    (self   ):





			'''simple docstring'''

			__snake_case      ,				__snake_case      :		Optional[Any]         =							self.prepare_init_args_and_inputs_for_common()

			__snake_case      :		Optional[Any]         =							8

			__snake_case      :		str         =							self.model_class(**a_   )
			model.to(a_   )

			with torch.no_grad():
				__snake_case      :		Optional[int]         =							model(**a_   ).sample

			__snake_case      :		List[str]         =							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():
				__snake_case      :		Any         =							model(**a_							,			cross_attention_kwargs={'''scale''': 0.0}   ).sample
				__snake_case      :		Dict         =							model(**a_							,			cross_attention_kwargs={'''scale''': 0.5}   ).sample
				__snake_case      :		Union[str, Any]         =							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 							SCREAMING_SNAKE_CASE    (self   ):





			'''simple docstring'''

			__snake_case      ,				__snake_case      :		Optional[Any]         =							self.prepare_init_args_and_inputs_for_common()

			__snake_case      :		Union[str, Any]         =							8

			torch.manual_seed(0   )
			__snake_case      :		Any         =							self.model_class(**a_   )
			model.to(a_   )

			with torch.no_grad():
				__snake_case      :		Any         =							model(**a_   ).sample

			__snake_case      :		List[Any]         =							create_lora_layers(a_   )
			model.set_attn_processor(a_   )

			with torch.no_grad():
				__snake_case      :		Optional[Any]         =							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   )
				__snake_case      :		Union[str, Any]         =							self.model_class(**a_   )
				new_model.to(a_   )
				new_model.load_attn_procs(a_   )

			with torch.no_grad():
				__snake_case      :		List[Any]         =							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 							SCREAMING_SNAKE_CASE    (self   ):





			'''simple docstring'''

			__snake_case      ,				__snake_case      :		str         =							self.prepare_init_args_and_inputs_for_common()

			__snake_case      :		Union[str, Any]         =							8

			torch.manual_seed(0   )
			__snake_case      :		int         =							self.model_class(**a_   )
			model.to(a_   )

			with torch.no_grad():
				__snake_case      :		Tuple         =							model(**a_   ).sample

			__snake_case      :		Dict         =							create_lora_layers(a_   )
			model.set_attn_processor(a_   )

			with torch.no_grad():
				__snake_case      :		List[Any]         =							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   )
				__snake_case      :		Optional[int]         =							self.model_class(**a_   )
				new_model.to(a_   )
				new_model.load_attn_procs(a_   )

			with torch.no_grad():
				__snake_case      :		Optional[int]         =							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 							SCREAMING_SNAKE_CASE    (self   ):





			'''simple docstring'''

			__snake_case      ,				__snake_case      :		Dict         =							self.prepare_init_args_and_inputs_for_common()

			__snake_case      :		List[Any]         =							8

			torch.manual_seed(0   )
			__snake_case      :		Dict         =							self.model_class(**a_   )
			model.to(a_   )

			__snake_case      :		Any         =							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   )
				__snake_case      :		Union[str, Any]         =							self.model_class(**a_   )
				new_model.to(a_   )
				new_model.load_attn_procs(a_							,			weight_name='''pytorch_lora_weights.bin'''   )



		def 							SCREAMING_SNAKE_CASE    (self   ):





			'''simple docstring'''

			__snake_case      ,				__snake_case      :		Tuple         =							self.prepare_init_args_and_inputs_for_common()

			__snake_case      :		List[Any]         =							8

			torch.manual_seed(0   )
			__snake_case      :		Dict         =							self.model_class(**a_   )
			model.to(a_   )

			__snake_case      :		Tuple         =							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   )
				__snake_case      :		str         =							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 							SCREAMING_SNAKE_CASE    (self   ):





			'''simple docstring'''

			__snake_case      ,				__snake_case      :		Any         =							self.prepare_init_args_and_inputs_for_common()

			__snake_case      :		List[str]         =							8

			torch.manual_seed(0   )
			__snake_case      :		str         =							self.model_class(**a_   )
			model.to(a_   )

			with torch.no_grad():
				__snake_case      :		str         =							model(**a_   ).sample

			__snake_case      :		Optional[int]         =							create_lora_layers(a_   )
			model.set_attn_processor(a_   )

			with torch.no_grad():
				__snake_case      :		Any         =							model(**a_							,			cross_attention_kwargs={'''scale''': 0.0}   ).sample

			model.set_attn_processor(AttnProcessor()   )

			with torch.no_grad():
				__snake_case      :		str         =							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 							SCREAMING_SNAKE_CASE    (self   ):





			'''simple docstring'''

			__snake_case      ,				__snake_case      :		str         =							self.prepare_init_args_and_inputs_for_common()

			__snake_case      :		int         =							4

			torch.manual_seed(0   )
			__snake_case      :		int         =							self.model_class(**a_   )
			model.to(a_   )
			__snake_case      :		Optional[int]         =							create_lora_layers(a_   )
			model.set_attn_processor(a_   )

			# default
			with torch.no_grad():
				__snake_case      :		Optional[Any]         =							model(**a_   ).sample

				model.enable_xformers_memory_efficient_attention()
				__snake_case      :		str         =							model(**a_   ).sample

				model.disable_xformers_memory_efficient_attention()
				__snake_case      :		Optional[Any]         =							model(**a_   ).sample

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



		def 							SCREAMING_SNAKE_CASE    (self   ):





			'''simple docstring'''

			__snake_case      ,				__snake_case      :		int         =							self.prepare_init_args_and_inputs_for_common()
			__snake_case      :		Any         =							32

			__snake_case      :		Union[str, Any]         =							self.model_class(**a_   )
			model.to(a_   )
			model.eval()

			with torch.no_grad():
				__snake_case      :		Union[str, Any]         =							model(**a_   )[0]

			model.enable_forward_chunking()
			with torch.no_grad():
				__snake_case      :		Optional[int]         =							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.













"""simple docstring"""





from __future__ import annotations

from PIL import Image

# Define the first generation of cells
# fmt: off
A__       :			str=						[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]







def 	lowerCAmelCase_(			SCREAMING_SNAKE_CASE       )       ->						list[int]:
    """simple docstring"""

    return [int(SCREAMING_SNAKE_CASE       ) for c in F'{ruleset:08}'[:8]]







def 	lowerCAmelCase_(			SCREAMING_SNAKE_CASE			,						SCREAMING_SNAKE_CASE			,						SCREAMING_SNAKE_CASE       )       ->						list[int]:
    """simple docstring"""

    UpperCamelCase__								=     len(cells[0]       )  # 31
    UpperCamelCase__								=     []
    for i in range(SCREAMING_SNAKE_CASE       ):
        # Get the neighbors of each cell
        # Handle neighbours outside bounds by using 0 as their value
        UpperCamelCase__								=     0 if i == 0 else cells[time][i - 1]
        UpperCamelCase__								=     0 if i == population - 1 else cells[time][i + 1]
        # Define a new cell and add it to the new generation
        UpperCamelCase__								=     7 - int(F'{left_neighbor}{cells[time][i]}{right_neighbor}'			,						2       )
        next_generation.append(rule[situation]       )
    return next_generation







def 	lowerCAmelCase_(			SCREAMING_SNAKE_CASE       )       ->						Image.Image:
    """simple docstring"""

    UpperCamelCase__								=     Image.new('RGB'			,						(len(cells[0]       ), len(SCREAMING_SNAKE_CASE       ))       )
    UpperCamelCase__								=     img.load()
    # Generates image
    for w in range(img.width       ):
        for h in range(img.height       ):
            UpperCamelCase__								=     2_55 - int(2_55 * cells[h][w]       )
            UpperCamelCase__								=     (color, color, color)
    return img


if __name__ == "__main__":
  A__       :			Optional[int]=						bin(int(input("""Rule:\n""").strip()))[2:]
  A__       :			str=						format_ruleset(int(rule_num))
  for time in range(16):
    CELLS.append(new_generation(CELLS, rule, time))
  A__       :			Tuple=						generate_image(CELLS)
  # Uncomment to save the image
  # img.save(f"rule_{rule_num}.png")
  img.show()




