





import gc
import random
import tempfile
import unittest

import numpy as np
import torch
from PIL import Image
from transformers import CLIPTextConfig, CLIPTextModel, CLIPTokenizer

from diffusers import (
    AutoencoderKL,
    DDIMInverseScheduler,
    DDIMScheduler,
    DPMSolverMultistepInverseScheduler,
    DPMSolverMultistepScheduler,
    StableDiffusionDiffEditPipeline,
    UNetaDConditionModel,
)
from diffusers.utils import load_image, slow
from diffusers.utils.testing_utils import enable_full_determinism, floats_tensor, require_torch_gpu, torch_device

from ..pipeline_params import TEXT_GUIDED_IMAGE_INPAINTING_BATCH_PARAMS, TEXT_GUIDED_IMAGE_INPAINTING_PARAMS
from ..test_pipelines_common import PipelineLatentTesterMixin, PipelineTesterMixin


enable_full_determinism()

class       __A     (						a    ,					a    ,					unittest.TestCase    ):
				__A      =				StableDiffusionDiffEditPipeline
				__A      =				TEXT_GUIDED_IMAGE_INPAINTING_PARAMS - {"""height""", """width""", """image"""} | {"""image_latents"""}
				__A      =				TEXT_GUIDED_IMAGE_INPAINTING_BATCH_PARAMS - {"""image"""} | {"""image_latents"""}
				__A      =				frozenset(
				    []    )  # TO-DO: update image_params once pipeline is refactored with VaeImageProcessor.preprocess
				__A      =				frozenset([]    )


				def _snake_case       (		self							):
								torch.manual_seed(0							)
								lowerCamelCase	 =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   , attention_head_dim=(2, 4)   , use_linear_projection=UpperCAmelCase_   , )
								lowerCamelCase	 =DDIMScheduler(
								    beta_start=0.0_0_0_8_5   , beta_end=0.0_1_2   , beta_schedule="""scaled_linear"""   , clip_sample=UpperCAmelCase_   , set_alpha_to_one=UpperCAmelCase_   , )
								lowerCamelCase	 =DDIMInverseScheduler(
								    beta_start=0.0_0_0_8_5   , beta_end=0.0_1_2   , beta_schedule="""scaled_linear"""   , clip_sample=UpperCAmelCase_   , set_alpha_to_zero=UpperCAmelCase_   , )
								torch.manual_seed(0							)
								lowerCamelCase	 =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   , sample_size=128   , )
								torch.manual_seed(0							)
								lowerCamelCase	 =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   , hidden_act="""gelu"""   , projection_dim=512   , )
								lowerCamelCase	 =CLIPTextModel(UpperCAmelCase_							)
								lowerCamelCase	 =CLIPTokenizer.from_pretrained("""hf-internal-testing/tiny-random-clip"""							)

								lowerCamelCase	 ={
								    """unet""": unet,
								    """scheduler""": scheduler,
								    """inverse_scheduler""": inverse_scheduler,
								    """vae""": vae,
								    """text_encoder""": text_encoder,
								    """tokenizer""": tokenizer,
								    """safety_checker""": None,
								    """feature_extractor""": None,
								}

								return components


				def _snake_case       (		self   , UpperCAmelCase_   , UpperCAmelCase_=0							):
								lowerCamelCase	 =floats_tensor((1, 16, 16)   , rng=random.Random(UpperCAmelCase_							)							).to(UpperCAmelCase_							)
								lowerCamelCase	 =floats_tensor((1, 2, 4, 16, 16)   , rng=random.Random(UpperCAmelCase_							)							).to(UpperCAmelCase_							)
								if str(UpperCAmelCase_							).startswith("""mps"""							):
												lowerCamelCase	 =torch.manual_seed(UpperCAmelCase_							)
								else:
												lowerCamelCase	 =torch.Generator(device=UpperCAmelCase_							).manual_seed(UpperCAmelCase_							)
								lowerCamelCase	 ={
								    """prompt""": """a dog and a newt""",
								    """mask_image""": mask,
								    """image_latents""": latents,
								    """generator""": generator,
								    """num_inference_steps""": 2,
								    """inpaint_strength""": 1.0,
								    """guidance_scale""": 6.0,
								    """output_type""": """numpy""",
								}

								return inputs


				def _snake_case       (		self   , UpperCAmelCase_   , UpperCAmelCase_=0							):
								lowerCamelCase	 =floats_tensor((1, 3, 32, 32)   , rng=random.Random(UpperCAmelCase_							)							).to(UpperCAmelCase_							)
								lowerCamelCase	 =image.cpu().permute(0   , 2   , 3   , 1							)[0]
								lowerCamelCase	 =Image.fromarray(np.uinta(UpperCAmelCase_							)							).convert("""RGB"""							)
								if str(UpperCAmelCase_							).startswith("""mps"""							):
												lowerCamelCase	 =torch.manual_seed(UpperCAmelCase_							)
								else:
												lowerCamelCase	 =torch.Generator(device=UpperCAmelCase_							).manual_seed(UpperCAmelCase_							)
								lowerCamelCase	 ={
								    """image""": image,
								    """source_prompt""": """a cat and a frog""",
								    """target_prompt""": """a dog and a newt""",
								    """generator""": generator,
								    """num_inference_steps""": 2,
								    """num_maps_per_mask""": 2,
								    """mask_encode_strength""": 1.0,
								    """guidance_scale""": 6.0,
								    """output_type""": """numpy""",
								}

								return inputs


				def _snake_case       (		self   , UpperCAmelCase_   , UpperCAmelCase_=0							):
								lowerCamelCase	 =floats_tensor((1, 3, 32, 32)   , rng=random.Random(UpperCAmelCase_							)							).to(UpperCAmelCase_							)
								lowerCamelCase	 =image.cpu().permute(0   , 2   , 3   , 1							)[0]
								lowerCamelCase	 =Image.fromarray(np.uinta(UpperCAmelCase_							)							).convert("""RGB"""							)
								if str(UpperCAmelCase_							).startswith("""mps"""							):
												lowerCamelCase	 =torch.manual_seed(UpperCAmelCase_							)
								else:
												lowerCamelCase	 =torch.Generator(device=UpperCAmelCase_							).manual_seed(UpperCAmelCase_							)
								lowerCamelCase	 ={
								    """image""": image,
								    """prompt""": """a cat and a frog""",
								    """generator""": generator,
								    """num_inference_steps""": 2,
								    """inpaint_strength""": 1.0,
								    """guidance_scale""": 6.0,
								    """decode_latents""": True,
								    """output_type""": """numpy""",
								}
								return inputs


				def _snake_case       (		self							):
								if not hasattr(self.pipeline_class   , """_optional_components"""							):
												return

								lowerCamelCase	 =self.get_dummy_components()
								lowerCamelCase	 =self.pipeline_class(**UpperCAmelCase_							)
								pipe.to(UpperCAmelCase_							)
								pipe.set_progress_bar_config(disable=UpperCAmelCase_							)

								# set all optional components to None and update pipeline config accordingly
								for optional_component in pipe._optional_components:
												setattr(UpperCAmelCase_   , UpperCAmelCase_   , UpperCAmelCase_							)
								pipe.register_modules(**{optional_component: None for optional_component in pipe._optional_components}							)

								lowerCamelCase	 =self.get_dummy_inputs(UpperCAmelCase_							)
								lowerCamelCase	 =pipe(**UpperCAmelCase_							)[0]

								with tempfile.TemporaryDirectory() as tmpdir:
												pipe.save_pretrained(UpperCAmelCase_							)
												lowerCamelCase	 =self.pipeline_class.from_pretrained(UpperCAmelCase_							)
												pipe_loaded.to(UpperCAmelCase_							)
												pipe_loaded.set_progress_bar_config(disable=UpperCAmelCase_							)

								for optional_component in pipe._optional_components:
												self.assertTrue(
												    getattr(UpperCAmelCase_   , UpperCAmelCase_							) is None   , f"""`{optional_component}` did not stay set to None after loading."""   , )

								lowerCamelCase	 =self.get_dummy_inputs(UpperCAmelCase_							)
								lowerCamelCase	 =pipe_loaded(**UpperCAmelCase_							)[0]

								lowerCamelCase	 =np.abs(output - output_loaded							).max()
								self.assertLess(UpperCAmelCase_   , 1E-4							)


				def _snake_case       (		self							):
								lowerCamelCase	 ="""cpu"""

								lowerCamelCase	 =self.get_dummy_components()
								lowerCamelCase	 =self.pipeline_class(**UpperCAmelCase_							)
								pipe.to(UpperCAmelCase_							)
								pipe.set_progress_bar_config(disable=UpperCAmelCase_							)

								lowerCamelCase	 =self.get_dummy_mask_inputs(UpperCAmelCase_							)
								lowerCamelCase	 =pipe.generate_mask(**UpperCAmelCase_							)
								lowerCamelCase	 =mask[0, -3:, -3:]

								self.assertEqual(mask.shape   , (1, 16, 16)							)
								lowerCamelCase	 =np.array([0] * 9							)
								lowerCamelCase	 =np.abs(mask_slice.flatten() - expected_slice							).max()
								self.assertLessEqual(UpperCAmelCase_   , 1E-3							)
								self.assertEqual(mask[0, -3, -4]   , 0							)


				def _snake_case       (		self							):
								lowerCamelCase	 ="""cpu"""

								lowerCamelCase	 =self.get_dummy_components()
								lowerCamelCase	 =self.pipeline_class(**UpperCAmelCase_							)
								pipe.to(UpperCAmelCase_							)
								pipe.set_progress_bar_config(disable=UpperCAmelCase_							)

								lowerCamelCase	 =self.get_dummy_inversion_inputs(UpperCAmelCase_							)
								lowerCamelCase	 =pipe.invert(**UpperCAmelCase_							).images
								lowerCamelCase	 =image[0, -1, -3:, -3:]

								self.assertEqual(image.shape   , (2, 32, 32, 3)							)
								lowerCamelCase	 =np.array(
								    [0.5_1_5_0, 0.5_1_3_4, 0.5_0_4_3, 0.5_3_7_6, 0.4_6_9_4, 0.5_1_0_5_0, 0.5_0_1_5, 0.4_4_0_7, 0.4_7_9_9]   , )
								lowerCamelCase	 =np.abs(image_slice.flatten() - expected_slice							).max()
								self.assertLessEqual(UpperCAmelCase_   , 1E-3							)


				def _snake_case       (		self							):
								super().test_inference_batch_single_identical(expected_max_diff=5E-3							)


				def _snake_case       (		self							):
								lowerCamelCase	 ="""cpu"""

								lowerCamelCase	 =self.get_dummy_components()

								lowerCamelCase	 ={"""beta_start""": 0.0_0_0_8_5, """beta_end""": 0.0_1_2, """beta_schedule""": """scaled_linear"""}
								lowerCamelCase	 =DPMSolverMultistepScheduler(**UpperCAmelCase_							)
								lowerCamelCase	 =DPMSolverMultistepInverseScheduler(**UpperCAmelCase_							)

								lowerCamelCase	 =self.pipeline_class(**UpperCAmelCase_							)
								pipe.to(UpperCAmelCase_							)
								pipe.set_progress_bar_config(disable=UpperCAmelCase_							)

								lowerCamelCase	 =self.get_dummy_inversion_inputs(UpperCAmelCase_							)
								lowerCamelCase	 =pipe.invert(**UpperCAmelCase_							).images
								lowerCamelCase	 =image[0, -1, -3:, -3:]

								self.assertEqual(image.shape   , (2, 32, 32, 3)							)
								lowerCamelCase	 =np.array(
								    [0.5_1_5_0, 0.5_1_3_4, 0.5_0_4_3, 0.5_3_7_6, 0.4_6_9_4, 0.5_1_0_5_0, 0.5_0_1_5, 0.4_4_0_7, 0.4_7_9_9]   , )
								lowerCamelCase	 =np.abs(image_slice.flatten() - expected_slice							).max()
								self.assertLessEqual(UpperCAmelCase_   , 1E-3							)




@require_torch_gpu
@slow
class       __A     (						unittest.TestCase    ):


				def _snake_case       (		self							):
								super().tearDown()
								gc.collect()
								torch.cuda.empty_cache()


				@classmethod
				def _snake_case       (		cls							):
								lowerCamelCase	 =load_image(
								    """https://huggingface.co/datasets/hf-internal-testing/diffusers-images/resolve/main/diffedit/fruit.png"""							)

								lowerCamelCase	 =raw_image.convert("""RGB"""							).resize((768, 768)							)

								lowerCamelCase	 =raw_image


				def _snake_case       (		self							):
								lowerCamelCase	 =torch.manual_seed(0							)

								lowerCamelCase	 =StableDiffusionDiffEditPipeline.from_pretrained(
								    """stabilityai/stable-diffusion-2-1"""   , safety_checker=UpperCAmelCase_   , torch_dtype=torch.floataa							)
								lowerCamelCase	 =DDIMScheduler.from_config(pipe.scheduler.config							)
								lowerCamelCase	 =DDIMInverseScheduler.from_config(pipe.scheduler.config							)
								pipe.enable_model_cpu_offload()
								pipe.set_progress_bar_config(disable=UpperCAmelCase_							)

								lowerCamelCase	 ="""a bowl of fruit"""
								lowerCamelCase	 ="""a bowl of pears"""

								lowerCamelCase	 =pipe.generate_mask(
								    image=self.raw_image   , source_prompt=UpperCAmelCase_   , target_prompt=UpperCAmelCase_   , generator=UpperCAmelCase_   , )

								lowerCamelCase	 =pipe.invert(
								    prompt=UpperCAmelCase_   , image=self.raw_image   , inpaint_strength=0.7   , generator=UpperCAmelCase_							).latents

								lowerCamelCase	 =pipe(
								    prompt=UpperCAmelCase_   , mask_image=UpperCAmelCase_   , image_latents=UpperCAmelCase_   , generator=UpperCAmelCase_   , negative_prompt=UpperCAmelCase_   , inpaint_strength=0.7   , output_type="""numpy"""   , ).images[0]

								lowerCamelCase	 =(
								    np.array(
								        load_image(
								            """https://huggingface.co/datasets/hf-internal-testing/diffusers-images/resolve/main"""
								            """/diffedit/pears.png"""							).resize((768, 768)							)							)
								    / 255
								)
								assert np.abs((expected_image - image).max()							) < 5E-1


				def _snake_case       (		self							):
								lowerCamelCase	 =torch.manual_seed(0							)

								lowerCamelCase	 =StableDiffusionDiffEditPipeline.from_pretrained(
								    """stabilityai/stable-diffusion-2-1"""   , safety_checker=UpperCAmelCase_   , torch_dtype=torch.floataa							)
								lowerCamelCase	 =DPMSolverMultistepScheduler.from_config(pipe.scheduler.config							)
								lowerCamelCase	 =DPMSolverMultistepInverseScheduler.from_config(pipe.scheduler.config							)
								pipe.enable_model_cpu_offload()
								pipe.set_progress_bar_config(disable=UpperCAmelCase_							)

								lowerCamelCase	 ="""a bowl of fruit"""
								lowerCamelCase	 ="""a bowl of pears"""

								lowerCamelCase	 =pipe.generate_mask(
								    image=self.raw_image   , source_prompt=UpperCAmelCase_   , target_prompt=UpperCAmelCase_   , generator=UpperCAmelCase_   , )

								lowerCamelCase	 =pipe.invert(
								    prompt=UpperCAmelCase_   , image=self.raw_image   , inpaint_strength=0.7   , generator=UpperCAmelCase_   , num_inference_steps=25   , ).latents

								lowerCamelCase	 =pipe(
								    prompt=UpperCAmelCase_   , mask_image=UpperCAmelCase_   , image_latents=UpperCAmelCase_   , generator=UpperCAmelCase_   , negative_prompt=UpperCAmelCase_   , inpaint_strength=0.7   , num_inference_steps=25   , output_type="""numpy"""   , ).images[0]

								lowerCamelCase	 =(
								    np.array(
								        load_image(
								            """https://huggingface.co/datasets/hf-internal-testing/diffusers-images/resolve/main"""
								            """/diffedit/pears.png"""							).resize((768, 768)							)							)
								    / 255
								)
								assert np.abs((expected_image - image).max()							) < 5E-1












from ...utils import (
    OptionalDependencyNotAvailable,
    is_torch_available,
    is_transformers_available,
    is_transformers_version,
)


try:
							if not (is_transformers_available() and is_torch_available()):
														raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
							from ...utils.dummy_torch_and_transformers_objects import KandinskyPipeline, KandinskyPriorPipeline
else:
							from .pipeline_kandinsky import KandinskyPipeline
							from .pipeline_kandinsky_imgaimg import KandinskyImgaImgPipeline
							from .pipeline_kandinsky_inpaint import KandinskyInpaintPipeline
							from .pipeline_kandinsky_prior import KandinskyPriorPipeline, KandinskyPriorPipelineOutput
							from .text_encoder import MultilingualCLIP





