






"""simple docstring"""







import gc
import os
import tempfile
import unittest

import torch
import torch.nn as nn
import torch.nn.functional as F
from transformers import CLIPTextConfig, CLIPTextModel, CLIPTokenizer

from diffusers import AutoencoderKL, DDIMScheduler, StableDiffusionPipeline, UNetaDConditionModel
from diffusers.loaders import AttnProcsLayers, LoraLoaderMixin
from diffusers.models.attention_processor import (
    Attention,
    AttnProcessor,
    AttnProcessor2_0,
    LoRAAttnProcessor,
    LoRAAttnProcessor2_0,
    LoRAXFormersAttnProcessor,
    XFormersAttnProcessor,
)
from diffusers.utils import TEXT_ENCODER_ATTN_MODULE, floats_tensor, torch_device





def 							SCREAMING_SNAKE_CASE							(   lowerCamelCase_):
					a__ 							=	{}
					for name in unet.attn_processors.keys():
										a__ 							=	None if name.endswith('''attn1.processor''') else unet.config.cross_attention_dim
										if name.startswith('''mid_block'''):
															a__ 							=	unet.config.block_out_channels[-1]
										elif name.startswith('''up_blocks'''):
															a__ 							=	int(name[len('''up_blocks.''')])
															a__ 							=	list(reversed(unet.config.block_out_channels))[block_id]
										elif name.startswith('''down_blocks'''):
															a__ 							=	int(name[len('''down_blocks.''')])
															a__ 							=	unet.config.block_out_channels[block_id]
										a__ 							=	(
										    LoRAAttnProcessor2_0 if hasattr(lowerCamelCase_			,  '''scaled_dot_product_attention''') else LoRAAttnProcessor
										)
										a__ 							=	lora_attn_processor_class(
										    hidden_size=lowerCamelCase_			,  cross_attention_dim=lowerCamelCase_)
					a__ 							=	AttnProcsLayers(lowerCamelCase_)
					return lora_attn_procs, unet_lora_layers





def 							SCREAMING_SNAKE_CASE							(   lowerCamelCase_):
					a__ 							=	{}
					a__ 							=	(
					    LoRAAttnProcessor2_0 if hasattr(lowerCamelCase_			,  '''scaled_dot_product_attention''') else LoRAAttnProcessor
					)
					for name, module in text_encoder.named_modules():
										if name.endswith(lowerCamelCase_):
															a__ 							=	lora_attn_processor_class(
															    hidden_size=module.out_proj.out_features			,  cross_attention_dim=lowerCamelCase_)
					return text_lora_attn_procs





def 							SCREAMING_SNAKE_CASE							(   lowerCamelCase_):
					a__ 							=	create_text_encoder_lora_attn_procs(lowerCamelCase_)
					a__ 							=	AttnProcsLayers(lowerCamelCase_)
					return text_encoder_lora_layers





def 							SCREAMING_SNAKE_CASE							(   lowerCamelCase_			,  lowerCamelCase_=False):
					for _, attn_proc in text_lora_attn_procs.items():
										# set up.weights
										for layer_name, layer_module in attn_proc.named_modules():
															if layer_name.endswith('''_lora'''):
																				a__ 							=	(
																				    torch.randn_like(layer_module.up.weight)
																				    if randn_weight
																				    else torch.zeros_like(layer_module.up.weight)
																				)
																				a__ 							=	torch.nn.Parameter(lowerCamelCase_)







class 							_SCREAMING_SNAKE_CASE    (	unittest.TestCase				):





							"""simple docstring"""





							def 			lowercase		( self:  Dict     ):

												'''simple docstring'''

												torch.manual_seed(0     )
												a__ 							=	UNetaDConditionModel(
												    block_out_channels=(32, 64)					,		layers_per_block=2					,		sample_size=32					,		in_channels=4					,		out_channels=4					,		down_block_types=('''DownBlock2D''', '''CrossAttnDownBlock2D''')					,		up_block_types=('''CrossAttnUpBlock2D''', '''UpBlock2D''')					,		cross_attention_dim=32					,		)
												a__ 							=	DDIMScheduler(
												    beta_start=0.0_0_0_8_5					,		beta_end=0.0_1_2					,		beta_schedule='''scaled_linear'''					,		clip_sample=__A					,		set_alpha_to_one=__A					,		steps_offset=1					,		)
												torch.manual_seed(0     )
												a__ 							=	AutoencoderKL(
												    block_out_channels=[32, 64]					,		in_channels=3					,		out_channels=3					,		down_block_types=['''DownEncoderBlock2D''', '''DownEncoderBlock2D''']					,		up_block_types=['''UpDecoderBlock2D''', '''UpDecoderBlock2D''']					,		latent_channels=4					,		)
												a__ 							=	CLIPTextConfig(
												    bos_token_id=0					,		eos_token_id=2					,		hidden_size=32					,		intermediate_size=37					,		layer_norm_eps=1e-05					,		num_attention_heads=4					,		num_hidden_layers=5					,		pad_token_id=1					,		vocab_size=1000					,		)
												a__ 							=	CLIPTextModel(__A     )
												a__ 							=	CLIPTokenizer.from_pretrained('''hf-internal-testing/tiny-random-clip'''     )

												a__							,a__ 							=	create_unet_lora_layers(__A     )
												a__ 							=	create_text_encoder_lora_layers(__A     )

												a__ 							=	{
												    '''unet''': unet,
												    '''scheduler''': scheduler,
												    '''vae''': vae,
												    '''text_encoder''': text_encoder,
												    '''tokenizer''': tokenizer,
												    '''safety_checker''': None,
												    '''feature_extractor''': None,
												}
												a__ 							=	{
												    '''unet_lora_layers''': unet_lora_layers,
												    '''text_encoder_lora_layers''': text_encoder_lora_layers,
												    '''unet_lora_attn_procs''': unet_lora_attn_procs,
												}
												return pipeline_components, lora_components




							def 			lowercase		( self:  Dict     ):

												'''simple docstring'''

												a__ 							=	1
												a__ 							=	10
												a__ 							=	4
												a__ 							=	(32, 32)

												a__ 							=	torch.manual_seed(0     )
												a__ 							=	floats_tensor((batch_size, num_channels) + sizes     )
												a__ 							=	torch.randint(1					,		__A					,		size=(batch_size, sequence_length)					,		generator=__A     )

												a__ 							=	{
												    '''prompt''': '''A painting of a squirrel eating a burger''',
												    '''generator''': generator,
												    '''num_inference_steps''': 2,
												    '''guidance_scale''': 6.0,
												    '''output_type''': '''numpy''',
												}

												return noise, input_ids, pipeline_inputs

												# copied from: https://colab.research.google.com/gist/sayakpaul/df2ef6e1ae6d8c10a49d859883b10860/scratchpad.ipynb




							def 			lowercase		( self:  Optional[Any]     ):

												'''simple docstring'''

												a__ 							=	77

												a__ 							=	torch.randint(2					,		56					,		size=(1, max_seq_length)					,		generator=torch.manual_seed(0     )     )

												a__ 							=	{}
												a__ 							=	inputs
												return prepared_inputs




							def 			lowercase		( self:  Union[str, Any]					,		__A:  List[Any]     ):

												'''simple docstring'''

												a__							,a__ 							=	self.get_dummy_components()
												LoraLoaderMixin.save_lora_weights(
												    save_directory=__A					,		unet_lora_layers=lora_components['''unet_lora_layers''']					,		text_encoder_lora_layers=lora_components['''text_encoder_lora_layers''']					,		)
												self.assertTrue(os.path.isfile(os.path.join(__A					,		'''pytorch_lora_weights.bin'''     )     )     )




							def 			lowercase		( self:  Tuple     ):

												'''simple docstring'''

												a__							,a__ 							=	self.get_dummy_components()
												a__ 							=	StableDiffusionPipeline(**__A     )
												a__ 							=	sd_pipe.to(__A     )
												sd_pipe.set_progress_bar_config(disable=__A     )

												a__							,a__							,a__ 							=	self.get_dummy_inputs()

												a__ 							=	sd_pipe(**__A     ).images
												a__ 							=	original_images[0, -3:, -3:, -1]

												with tempfile.TemporaryDirectory() as tmpdirname:
																	LoraLoaderMixin.save_lora_weights(
																	    save_directory=__A					,		unet_lora_layers=lora_components['''unet_lora_layers''']					,		text_encoder_lora_layers=lora_components['''text_encoder_lora_layers''']					,		)
																	self.assertTrue(os.path.isfile(os.path.join(__A					,		'''pytorch_lora_weights.bin'''     )     )     )
																	sd_pipe.load_lora_weights(__A     )

												a__ 							=	sd_pipe(**__A     ).images
												a__ 							=	lora_images[0, -3:, -3:, -1]

												# Outputs shouldn't match.
												self.assertFalse(torch.allclose(torch.from_numpy(__A     )					,		torch.from_numpy(__A     )     )     )




							def 			lowercase		( self:  str     ):

												'''simple docstring'''

												a__							,a__ 							=	self.get_dummy_components()
												a__ 							=	StableDiffusionPipeline(**__A     )
												a__ 							=	sd_pipe.to(__A     )
												sd_pipe.set_progress_bar_config(disable=__A     )

												a__							,a__							,a__ 							=	self.get_dummy_inputs()

												a__ 							=	sd_pipe(**__A     ).images
												a__ 							=	original_images[0, -3:, -3:, -1]

												with tempfile.TemporaryDirectory() as tmpdirname:
																	LoraLoaderMixin.save_lora_weights(
																	    save_directory=__A					,		unet_lora_layers=lora_components['''unet_lora_layers''']					,		text_encoder_lora_layers=lora_components['''text_encoder_lora_layers''']					,		safe_serialization=__A					,		)
																	self.assertTrue(os.path.isfile(os.path.join(__A					,		'''pytorch_lora_weights.safetensors'''     )     )     )
																	sd_pipe.load_lora_weights(__A     )

												a__ 							=	sd_pipe(**__A     ).images
												a__ 							=	lora_images[0, -3:, -3:, -1]

												# Outputs shouldn't match.
												self.assertFalse(torch.allclose(torch.from_numpy(__A     )					,		torch.from_numpy(__A     )     )     )




							def 			lowercase		( self:  str     ):

												'''simple docstring'''

												a__							,a__ 							=	self.get_dummy_components()
												a__ 							=	lora_components['''unet_lora_attn_procs''']
												a__ 							=	StableDiffusionPipeline(**__A     )
												a__ 							=	sd_pipe.to(__A     )
												sd_pipe.set_progress_bar_config(disable=__A     )

												a__							,a__							,a__ 							=	self.get_dummy_inputs()

												a__ 							=	sd_pipe(**__A     ).images
												a__ 							=	original_images[0, -3:, -3:, -1]

												with tempfile.TemporaryDirectory() as tmpdirname:
																	a__ 							=	sd_pipe.unet
																	unet.set_attn_processor(__A     )
																	unet.save_attn_procs(__A     )
																	self.assertTrue(os.path.isfile(os.path.join(__A					,		'''pytorch_lora_weights.bin'''     )     )     )
																	sd_pipe.load_lora_weights(__A     )

												a__ 							=	sd_pipe(**__A     ).images
												a__ 							=	lora_images[0, -3:, -3:, -1]

												# Outputs shouldn't match.
												self.assertFalse(torch.allclose(torch.from_numpy(__A     )					,		torch.from_numpy(__A     )     )     )




							def 			lowercase		( self:  Tuple     ):

												'''simple docstring'''

												a__							,a__ 							=	self.get_dummy_components()
												a__ 							=	StableDiffusionPipeline(**__A     )

												a__ 							=	self.get_dummy_tokens()

												# inference without lora
												a__ 							=	pipe.text_encoder(**__A     )[0]
												assert outputs_without_lora.shape == (1, 77, 32)

												# create lora_attn_procs with zeroed out up.weights
												a__ 							=	create_text_encoder_lora_attn_procs(pipe.text_encoder     )
												set_lora_up_weights(__A					,		randn_weight=__A     )

												# monkey patch
												pipe._modify_text_encoder(__A     )

												# verify that it's okay to release the text_attn_procs which holds the LoRAAttnProcessor.
												del text_attn_procs
												gc.collect()

												# inference with lora
												a__ 							=	pipe.text_encoder(**__A     )[0]
												assert outputs_with_lora.shape == (1, 77, 32)

												assert torch.allclose(
												    __A					,		__A     ), "lora_up_weight are all zero, so the lora outputs should be the same to without lora outputs"

												# create lora_attn_procs with randn up.weights
												a__ 							=	create_text_encoder_lora_attn_procs(pipe.text_encoder     )
												set_lora_up_weights(__A					,		randn_weight=__A     )

												# monkey patch
												pipe._modify_text_encoder(__A     )

												# verify that it's okay to release the text_attn_procs which holds the LoRAAttnProcessor.
												del text_attn_procs
												gc.collect()

												# inference with lora
												a__ 							=	pipe.text_encoder(**__A     )[0]
												assert outputs_with_lora.shape == (1, 77, 32)

												assert not torch.allclose(
												    __A					,		__A     ), "lora_up_weight are not zero, so the lora outputs should be different to without lora outputs"




							def 			lowercase		( self:  Union[str, Any]     ):

												'''simple docstring'''

												a__							,a__ 							=	self.get_dummy_components()
												a__ 							=	StableDiffusionPipeline(**__A     )

												a__ 							=	self.get_dummy_tokens()

												# inference without lora
												a__ 							=	pipe.text_encoder(**__A     )[0]
												assert outputs_without_lora.shape == (1, 77, 32)

												# create lora_attn_procs with randn up.weights
												a__ 							=	create_text_encoder_lora_attn_procs(pipe.text_encoder     )
												set_lora_up_weights(__A					,		randn_weight=__A     )

												# monkey patch
												pipe._modify_text_encoder(__A     )

												# verify that it's okay to release the text_attn_procs which holds the LoRAAttnProcessor.
												del text_attn_procs
												gc.collect()

												# inference with lora
												a__ 							=	pipe.text_encoder(**__A     )[0]
												assert outputs_with_lora.shape == (1, 77, 32)

												assert not torch.allclose(
												    __A					,		__A     ), "lora outputs should be different to without lora outputs"

												# remove monkey patch
												pipe._remove_text_encoder_monkey_patch()

												# inference with removed lora
												a__ 							=	pipe.text_encoder(**__A     )[0]
												assert outputs_without_lora_removed.shape == (1, 77, 32)

												assert torch.allclose(
												    __A					,		__A     ), "remove lora monkey patch should restore the original outputs"




							def 			lowercase		( self:  Dict     ):

												'''simple docstring'''

												a__							,a__ 							=	self.get_dummy_components()
												a__ 							=	StableDiffusionPipeline(**__A     )
												a__ 							=	sd_pipe.to(__A     )
												sd_pipe.set_progress_bar_config(disable=__A     )

												a__							,a__							,a__ 							=	self.get_dummy_inputs()

												with tempfile.TemporaryDirectory() as tmpdirname:
																	LoraLoaderMixin.save_lora_weights(
																	    save_directory=__A					,		unet_lora_layers=lora_components['''unet_lora_layers''']					,		text_encoder_lora_layers=lora_components['''text_encoder_lora_layers''']					,		)
																	self.assertTrue(os.path.isfile(os.path.join(__A					,		'''pytorch_lora_weights.bin'''     )     )     )
																	sd_pipe.load_lora_weights(__A     )

												a__ 							=	sd_pipe(**__A     ).images
												a__ 							=	lora_images[0, -3:, -3:, -1]

												a__ 							=	sd_pipe(**__A					,		cross_attention_kwargs={'''scale''': 0.5}     ).images
												a__ 							=	lora_images_with_scale[0, -3:, -3:, -1]

												# Outputs shouldn't match.
												self.assertFalse(
												    torch.allclose(torch.from_numpy(__A     )					,		torch.from_numpy(__A     )     )     )




							def 			lowercase		( self:  str     ):

												'''simple docstring'''

												with tempfile.TemporaryDirectory() as tmpdirname:
																	self.create_lora_weight_file(__A     )

																	a__							,a__ 							=	self.get_dummy_components()
																	a__ 							=	StableDiffusionPipeline(**__A     )
																	a__ 							=	sd_pipe.to(__A     )
																	sd_pipe.set_progress_bar_config(disable=__A     )

																	# check if vanilla attention processors are used
																	for _, module in sd_pipe.unet.named_modules():
																						if isinstance(__A					,		__A     ):
																											self.assertIsInstance(module.processor					,		(AttnProcessor, AttnProcessor2_0)     )

            # load LoRA weight file
																	sd_pipe.load_lora_weights(__A     )

																	# check if lora attention processors are used
																	for _, module in sd_pipe.unet.named_modules():
																						if isinstance(__A					,		__A     ):
																											a__ 							=	(
																											    LoRAAttnProcessor2_0 if hasattr(__A					,		'''scaled_dot_product_attention'''     ) else LoRAAttnProcessor
																											)
																											self.assertIsInstance(module.processor					,		__A     )




							@unittest.skipIf(torch_device != '''cuda'''					,		'''This test is supposed to run on GPU'''     )
							def 			lowercase		( self:  str     ):

												'''simple docstring'''

												with tempfile.TemporaryDirectory() as tmpdirname:
																	self.create_lora_weight_file(__A     )

																	a__							,a__ 							=	self.get_dummy_components()
																	a__ 							=	StableDiffusionPipeline(**__A     )
																	a__ 							=	sd_pipe.to(__A     )
																	sd_pipe.set_progress_bar_config(disable=__A     )

																	# enable XFormers
																	sd_pipe.enable_xformers_memory_efficient_attention()

																	# check if xFormers attention processors are used
																	for _, module in sd_pipe.unet.named_modules():
																						if isinstance(__A					,		__A     ):
																											self.assertIsInstance(module.processor					,		__A     )

            # load LoRA weight file
																	sd_pipe.load_lora_weights(__A     )

																	# check if lora attention processors are used
																	for _, module in sd_pipe.unet.named_modules():
																						if isinstance(__A					,		__A     ):
																											self.assertIsInstance(module.processor					,		__A     )





							@unittest.skipIf(torch_device != '''cuda'''					,		'''This test is supposed to run on GPU'''     )
							def 			lowercase		( self:  Union[str, Any]     ):

												'''simple docstring'''

												a__							,a__ 							=	self.get_dummy_components()
												a__ 							=	StableDiffusionPipeline(**__A     )
												a__ 							=	sd_pipe.to(__A     )
												sd_pipe.set_progress_bar_config(disable=__A     )

												a__							,a__							,a__ 							=	self.get_dummy_inputs()

												# enable XFormers
												sd_pipe.enable_xformers_memory_efficient_attention()

												a__ 							=	sd_pipe(**__A     ).images
												a__ 							=	original_images[0, -3:, -3:, -1]

												with tempfile.TemporaryDirectory() as tmpdirname:
																	LoraLoaderMixin.save_lora_weights(
																	    save_directory=__A					,		unet_lora_layers=lora_components['''unet_lora_layers''']					,		text_encoder_lora_layers=lora_components['''text_encoder_lora_layers''']					,		)
																	self.assertTrue(os.path.isfile(os.path.join(__A					,		'''pytorch_lora_weights.bin'''     )     )     )
																	sd_pipe.load_lora_weights(__A     )

												a__ 							=	sd_pipe(**__A     ).images
												a__ 							=	lora_images[0, -3:, -3:, -1]

												# Outputs shouldn't match.
												self.assertFalse(torch.allclose(torch.from_numpy(__A     )					,		torch.from_numpy(__A     )     )     )










"""simple docstring"""







from itertools import combinations, product





def 							SCREAMING_SNAKE_CASE							(   lowerCamelCase_			,  lowerCamelCase_			,  lowerCamelCase_			,  lowerCamelCase_):
					if xa == ya == 0 or xa == ya == 0:
										return False
					a__ 							=	xa * xa + ya * ya
					a__ 							=	xa * xa + ya * ya
					a__ 							=	(xa - xa) * (xa - xa) + (ya - ya) * (ya - ya)
					return (
					    a_square + b_square == c_square
					    or a_square + c_square == b_square
					    or b_square + c_square == a_square
					)





def 							SCREAMING_SNAKE_CASE							(   lowerCamelCase_ = 50):
					return sum(
					    1
					    for pta, pta in combinations(product(range(limit + 1)			,  repeat=2)			,  2)
					    if is_right(*lowerCamelCase_			,  *lowerCamelCase_))


if __name__ == "__main__":
	print(F'''{solution() = }''')


