


import random
from typing import List, Optional, Union

import numpy as np
import torch

from ..state import AcceleratorState
from .constants import CUDA_DISTRIBUTED_TYPES
from .dataclasses import DistributedType, RNGType
from .imports import is_npu_available, is_tpu_available, is_xpu_available


if is_tpu_available(check_device=False):
						import torch_xla.core.xla_model as xm


def 	_UpperCamelCase							(				lowercase__   ,	lowercase__ = False				):





						if device_specific:
												seed += AcceleratorState().process_index
						random.seed(_lowerCamelCase				)
						np.random.seed(_lowerCamelCase				)
						torch.manual_seed(_lowerCamelCase				)
						if is_xpu_available():
												torch.xpu.manual_seed_all(_lowerCamelCase				)
						elif is_npu_available():
												torch.npu.manual_seed_all(_lowerCamelCase				)
						else:
												torch.cuda.manual_seed_all(_lowerCamelCase				)
						# ^^ safe to call this function even if cuda is not available
						if is_tpu_available():
												xm.set_rng_state(_lowerCamelCase				)


def 	_UpperCamelCase							(				lowercase__ = None   ,	lowercase__ = None				):





						if rng_type == RNGType.TORCH:
												__SCREAMING_SNAKE_CASE						:					Optional[Any]		      =		torch.get_rng_state()
						elif rng_type == RNGType.CUDA:
												__SCREAMING_SNAKE_CASE						:					int		      =		torch.cuda.get_rng_state()
						elif rng_type == RNGType.XLA:
												assert is_tpu_available(), "Can't synchronize XLA seeds on an environment without TPUs."
												__SCREAMING_SNAKE_CASE						:					Optional[int]		      =		torch.tensor(xm.get_rng_state()				)
						elif rng_type == RNGType.NPU:
												assert is_npu_available(), "Can't synchronize NPU seeds on an environment without NPUs."
												__SCREAMING_SNAKE_CASE						:					List[str]		      =		torch.npu.get_rng_state()
						elif rng_type == RNGType.XPU:
												assert is_xpu_available(), "Can't synchronize XPU seeds on an environment without XPUs."
												__SCREAMING_SNAKE_CASE						:					str		      =		torch.xpu.get_rng_state()
						elif rng_type == RNGType.GENERATOR:
												assert generator is not None, "Need a generator to synchronize its seed."
												__SCREAMING_SNAKE_CASE						:					List[str]		      =		generator.get_state()

						# Broadcast the rng state from device 0 to other devices
						__SCREAMING_SNAKE_CASE						:					Optional[Any]		      =		AcceleratorState()
						if state.distributed_type == DistributedType.TPU:
												__SCREAMING_SNAKE_CASE						:					int		      =		rng_state.to(xm.xla_device()				)
												xm.collective_broadcast([rng_state]				)
												xm.mark_step()
												__SCREAMING_SNAKE_CASE						:					int		      =		rng_state.cpu()
						elif (
						    state.distributed_type in CUDA_DISTRIBUTED_TYPES
						    or state.distributed_type == DistributedType.MULTI_NPU
						    or state.distributed_type == DistributedType.MULTI_XPU
						):
												__SCREAMING_SNAKE_CASE						:					Any		      =		rng_state.to(state.device				)
												torch.distributed.broadcast(_lowerCamelCase   ,	0				)
												__SCREAMING_SNAKE_CASE						:					Tuple		      =		rng_state.cpu()
						elif state.distributed_type == DistributedType.MULTI_CPU:
												torch.distributed.broadcast(_lowerCamelCase   ,	0				)

						# Set the broadcast rng state
						if rng_type == RNGType.TORCH:
												torch.set_rng_state(_lowerCamelCase				)
						elif rng_type == RNGType.CUDA:
												torch.cuda.set_rng_state(_lowerCamelCase				)
						elif rng_type == RNGType.NPU:
												torch.npu.set_rng_state(_lowerCamelCase				)
						elif rng_type == RNGType.XPU:
												torch.xpu.set_rng_state(_lowerCamelCase				)
						elif rng_type == RNGType.XLA:
												xm.set_rng_state(rng_state.item()				)
						elif rng_type == RNGType.GENERATOR:
												generator.set_state(_lowerCamelCase				)


def 	_UpperCamelCase							(				lowercase__   ,	lowercase__ = None				):





						for rng_type in rng_types:
												synchronize_rng_state(RNGType(_lowerCamelCase				)   ,	generator=_lowerCamelCase				)




from typing import Any, Callable, Dict, List, Optional, Union

import PIL.Image
import torch
from transformers import CLIPImageProcessor, CLIPTextModel, CLIPTokenizer

from diffusers import (
    AutoencoderKL,
    DDIMScheduler,
    DiffusionPipeline,
    LMSDiscreteScheduler,
    PNDMScheduler,
    StableDiffusionImgaImgPipeline,
    StableDiffusionInpaintPipelineLegacy,
    StableDiffusionPipeline,
    UNetaDConditionModel,
)
from diffusers.configuration_utils import FrozenDict
from diffusers.pipelines.stable_diffusion.safety_checker import StableDiffusionSafetyChecker
from diffusers.utils import deprecate, logging


__lowerCAmelCase     :			Tuple      =logging.get_logger(__name__)  # pylint: disable=invalid-name
class 	_lowercase				(      A__	):






				'''simple docstring'''



				SCREAMING_SNAKE_CASE__    :      Union[str, Any]      =		['''safety_checker''', '''feature_extractor''']


				def __init__(	self      :int      ,      lowerCAmelCase__      :AutoencoderKL      ,      lowerCAmelCase__      :CLIPTextModel      ,      lowerCAmelCase__      :CLIPTokenizer      ,      lowerCAmelCase__      :UNetaDConditionModel      ,      lowerCAmelCase__      :Union[DDIMScheduler, PNDMScheduler, LMSDiscreteScheduler]      ,      lowerCAmelCase__      :StableDiffusionSafetyChecker      ,      lowerCAmelCase__      :CLIPImageProcessor      ,      lowerCAmelCase__      :bool = True      ,      )		->      List[Any]:
										super().__init__()
										if hasattr(scheduler.config      ,      '''steps_offset'''     ) and scheduler.config.steps_offset != 1:
																__SCREAMING_SNAKE_CASE						:					Union[str, Any]		      =		(
																    f'''The configuration file of this scheduler: {scheduler} is outdated. `steps_offset`'''
																    f''' should be set to 1 instead of {scheduler.config.steps_offset}. Please make sure '''
																    '''to update the config accordingly as leaving `steps_offset` might led to incorrect results'''
																    ''' in future versions. If you have downloaded this checkpoint from the Hugging Face Hub,'''
																    ''' it would be very nice if you could open a Pull request for the `scheduler/scheduler_config.json`'''
																    ''' file'''
																)
																deprecate('''steps_offset!=1'''      ,      '''1.0.0'''      ,      lowerCAmelCase__      ,      standard_warn=lowerCAmelCase__     )
																__SCREAMING_SNAKE_CASE						:					Dict		      =		dict(scheduler.config     )
																__SCREAMING_SNAKE_CASE						:					Tuple		      =		1
																__SCREAMING_SNAKE_CASE						:					Dict		      =		FrozenDict(lowerCAmelCase__     )

										self.register_modules(
										    vae=lowerCAmelCase__      ,      text_encoder=lowerCAmelCase__      ,      tokenizer=lowerCAmelCase__      ,      unet=lowerCAmelCase__      ,      scheduler=lowerCAmelCase__      ,      safety_checker=lowerCAmelCase__      ,      feature_extractor=lowerCAmelCase__      ,      )
										self.register_to_config(requires_safety_checker=lowerCAmelCase__     )


				@property
				def 		__magic_name__(	self      :Union[str, Any]     )		->      Dict[str, Any]:
										return {k: getattr(self      ,      lowerCAmelCase__     ) for k in self.config.keys() if not k.startswith('''_'''     )}


				def 		__magic_name__(	self      :str      ,      lowerCAmelCase__      :Optional[Union[str, int]] = "auto"     )		->      str:
										if slice_size == "auto":
																# half the attention head size is usually a good trade-off between
																# speed and memory
																__SCREAMING_SNAKE_CASE						:					Union[str, Any]		      =		self.unet.config.attention_head_dim // 2
										self.unet.set_attention_slice(lowerCAmelCase__     )


				def 		__magic_name__(	self      :Optional[int]     )		->      Union[str, Any]:
										self.enable_attention_slicing(lowerCAmelCase__     )


				@torch.no_grad()
				def 		__magic_name__(	self      :str      ,      lowerCAmelCase__      :Union[str, List[str]]      ,      lowerCAmelCase__      :Union[torch.FloatTensor, PIL.Image.Image]      ,      lowerCAmelCase__      :Union[torch.FloatTensor, PIL.Image.Image]      ,      lowerCAmelCase__      :float = 0.8      ,      lowerCAmelCase__      :Optional[int] = 50      ,      lowerCAmelCase__      :Optional[float] = 7.5      ,      lowerCAmelCase__      :Optional[Union[str, List[str]]] = None      ,      lowerCAmelCase__      :Optional[int] = 1      ,      lowerCAmelCase__      :Optional[float] = 0.0      ,      lowerCAmelCase__      :Optional[torch.Generator] = None      ,      lowerCAmelCase__      :Optional[str] = "pil"      ,      lowerCAmelCase__      :bool = True      ,      lowerCAmelCase__      :Optional[Callable[[int, int, torch.FloatTensor], None]] = None      ,      lowerCAmelCase__      :int = 1      ,      )		->      Any:
										# For more information on how this function works, please see: https://huggingface.co/docs/diffusers/api/pipelines/stable_diffusion#diffusers.StableDiffusionImg2ImgPipeline
										return StableDiffusionInpaintPipelineLegacy(**self.components     )(
										    prompt=lowerCAmelCase__      ,      image=lowerCAmelCase__      ,      mask_image=lowerCAmelCase__      ,      strength=lowerCAmelCase__      ,      num_inference_steps=lowerCAmelCase__      ,      guidance_scale=lowerCAmelCase__      ,      negative_prompt=lowerCAmelCase__      ,      num_images_per_prompt=lowerCAmelCase__      ,      eta=lowerCAmelCase__      ,      generator=lowerCAmelCase__      ,      output_type=lowerCAmelCase__      ,      return_dict=lowerCAmelCase__      ,      callback=lowerCAmelCase__      ,      )


				@torch.no_grad()
				def 		__magic_name__(	self      :Dict      ,      lowerCAmelCase__      :Union[str, List[str]]      ,      lowerCAmelCase__      :Union[torch.FloatTensor, PIL.Image.Image]      ,      lowerCAmelCase__      :float = 0.8      ,      lowerCAmelCase__      :Optional[int] = 50      ,      lowerCAmelCase__      :Optional[float] = 7.5      ,      lowerCAmelCase__      :Optional[Union[str, List[str]]] = None      ,      lowerCAmelCase__      :Optional[int] = 1      ,      lowerCAmelCase__      :Optional[float] = 0.0      ,      lowerCAmelCase__      :Optional[torch.Generator] = None      ,      lowerCAmelCase__      :Optional[str] = "pil"      ,      lowerCAmelCase__      :bool = True      ,      lowerCAmelCase__      :Optional[Callable[[int, int, torch.FloatTensor], None]] = None      ,      lowerCAmelCase__      :int = 1      ,      **lowerCAmelCase__      :Optional[Any]      ,      )		->      Dict:
										# For more information on how this function works, please see: https://huggingface.co/docs/diffusers/api/pipelines/stable_diffusion#diffusers.StableDiffusionImg2ImgPipeline
										return StableDiffusionImgaImgPipeline(**self.components     )(
										    prompt=lowerCAmelCase__      ,      image=lowerCAmelCase__      ,      strength=lowerCAmelCase__      ,      num_inference_steps=lowerCAmelCase__      ,      guidance_scale=lowerCAmelCase__      ,      negative_prompt=lowerCAmelCase__      ,      num_images_per_prompt=lowerCAmelCase__      ,      eta=lowerCAmelCase__      ,      generator=lowerCAmelCase__      ,      output_type=lowerCAmelCase__      ,      return_dict=lowerCAmelCase__      ,      callback=lowerCAmelCase__      ,      callback_steps=lowerCAmelCase__      ,      )



				@torch.no_grad()
				def 		__magic_name__(	self      :Tuple      ,      lowerCAmelCase__      :Union[str, List[str]]      ,      lowerCAmelCase__      :int = 512      ,      lowerCAmelCase__      :int = 512      ,      lowerCAmelCase__      :int = 50      ,      lowerCAmelCase__      :float = 7.5      ,      lowerCAmelCase__      :Optional[Union[str, List[str]]] = None      ,      lowerCAmelCase__      :Optional[int] = 1      ,      lowerCAmelCase__      :float = 0.0      ,      lowerCAmelCase__      :Optional[torch.Generator] = None      ,      lowerCAmelCase__      :Optional[torch.FloatTensor] = None      ,      lowerCAmelCase__      :Optional[str] = "pil"      ,      lowerCAmelCase__      :bool = True      ,      lowerCAmelCase__      :Optional[Callable[[int, int, torch.FloatTensor], None]] = None      ,      lowerCAmelCase__      :int = 1      ,      )		->      Optional[int]:
										# For more information on how this function https://huggingface.co/docs/diffusers/api/pipelines/stable_diffusion#diffusers.StableDiffusionPipeline
										return StableDiffusionPipeline(**self.components     )(
										    prompt=lowerCAmelCase__      ,      height=lowerCAmelCase__      ,      width=lowerCAmelCase__      ,      num_inference_steps=lowerCAmelCase__      ,      guidance_scale=lowerCAmelCase__      ,      negative_prompt=lowerCAmelCase__      ,      num_images_per_prompt=lowerCAmelCase__      ,      eta=lowerCAmelCase__      ,      generator=lowerCAmelCase__      ,      latents=lowerCAmelCase__      ,      output_type=lowerCAmelCase__      ,      return_dict=lowerCAmelCase__      ,      callback=lowerCAmelCase__      ,      callback_steps=lowerCAmelCase__      ,      )
