"""simple docstring"""




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

import torch
from torch import nn

from ...models.controlnet import ControlNetModel, ControlNetOutput
from ...models.modeling_utils import ModelMixin
from ...utils import logging


__lowerCAmelCase     :				List[str]    				=    logging.get_logger(__name__)

class    a_   (  __UpperCamelCase      ):




					def __init__(						self    :  Tuple	,    snake_case__    :  Union[List[ControlNetModel], Tuple[ControlNetModel]]  ):
							super().__init__()
							lowerCAmelCase__   = nn.ModuleList(snake_case__  )




					def     _SCREAMING_SNAKE_CASE    (						self    :  Dict	,    snake_case__    :  torch.FloatTensor	,    snake_case__    :  Union[torch.Tensor, float, int]	,    snake_case__    :  torch.Tensor	,    snake_case__    :  List[torch.tensor]	,    snake_case__    :  List[float]	,    snake_case__    :  Optional[torch.Tensor] = None	,    snake_case__    :  Optional[torch.Tensor] = None	,    snake_case__    :  Optional[torch.Tensor] = None	,    snake_case__    :  Optional[Dict[str, Any]] = None	,    snake_case__    :  bool = False	,    snake_case__    :  bool = True	,    ):
							for i, (image, scale, controlnet) in enumerate(zip(snake_case__	,    snake_case__	,    self.nets  )  ):
									lowerCAmelCase__ ,       lowerCAmelCase__   = controlnet(
									    snake_case__	,    snake_case__	,    snake_case__	,    snake_case__	,    snake_case__	,    snake_case__	,    snake_case__	,    snake_case__	,    snake_case__	,    snake_case__	,    snake_case__	,    )

									# merge samples
									if i == 0:
											lowerCAmelCase__ ,       lowerCAmelCase__   = down_samples, mid_sample
									else:
											lowerCAmelCase__   = [
											    samples_prev + samples_curr
											    for samples_prev, samples_curr in zip(snake_case__	,    snake_case__  )
											]
											mid_block_res_sample += mid_sample

							return down_block_res_samples, mid_block_res_sample




					def     _SCREAMING_SNAKE_CASE    (						self    :  Optional[Any]	,    snake_case__    :  Union[str, os.PathLike]	,    snake_case__    :  bool = True	,    snake_case__    :  Callable = None	,    snake_case__    :  bool = False	,    snake_case__    :  Optional[str] = None	,    ):
							lowerCAmelCase__   = 0
							lowerCAmelCase__   = save_directory
							for controlnet in self.nets:
									controlnet.save_pretrained(
									    snake_case__	,    is_main_process=snake_case__	,    save_function=snake_case__	,    safe_serialization=snake_case__	,    variant=snake_case__	,    )

									idx += 1
									lowerCAmelCase__   = model_path_to_save + F"""_{idx}"""




					@classmethod
					def     _SCREAMING_SNAKE_CASE    (						cls    :  Optional[int]	,    snake_case__    :  Optional[Union[str, os.PathLike]]	,    **snake_case__    :  List[Any]  ):
							lowerCAmelCase__   = 0
							lowerCAmelCase__   = []

							# load controlnet and append to list until no controlnet directory exists anymore
							# first controlnet has to be saved under `./mydirectory/controlnet` to be compliant with `DiffusionPipeline.from_prertained`
							# second, third, ... controlnets have to be saved under `./mydirectory/controlnet_1`, `./mydirectory/controlnet_2`, ...
							lowerCAmelCase__   = pretrained_model_path
							while os.path.isdir(snake_case__  ):
									lowerCAmelCase__   = ControlNetModel.from_pretrained(snake_case__	,    **snake_case__  )
									controlnets.append(snake_case__  )

									idx += 1
									lowerCAmelCase__   = pretrained_model_path + F"""_{idx}"""

							logger.info(F"""{len(snake_case__  )} controlnets loaded from {pretrained_model_path}."""  )

							if len(snake_case__  ) == 0:
									raise ValueError(
									    F"""No ControlNets found under {os.path.dirname(snake_case__  )}. Expected at least {pretrained_model_path + '_0'}."""  )

							return cls(snake_case__  )





"""simple docstring"""




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

import torch
from transformers import CLIPImageProcessor, CLIPTextModel, CLIPTokenizer

from diffusers import (
    AutoencoderKL,
    DDIMScheduler,
    DiffusionPipeline,
    LMSDiscreteScheduler,
    PNDMScheduler,
    StableDiffusionPipeline,
    UNetaDConditionModel,
)
from diffusers.pipelines.stable_diffusion import StableDiffusionPipelineOutput
from diffusers.pipelines.stable_diffusion.safety_checker import StableDiffusionSafetyChecker


__lowerCAmelCase     :				Dict    				=    "CompVis/stable-diffusion-v1-1"
__lowerCAmelCase     :				int    				=    "CompVis/stable-diffusion-v1-2"
__lowerCAmelCase     :				int    				=    "CompVis/stable-diffusion-v1-3"
__lowerCAmelCase     :				Union[str, Any]    				=    "CompVis/stable-diffusion-v1-4"

class    a_   (  __UpperCamelCase      ):




					def __init__(						self    :  List[Any]	,    snake_case__    :  AutoencoderKL	,    snake_case__    :  CLIPTextModel	,    snake_case__    :  CLIPTokenizer	,    snake_case__    :  UNetaDConditionModel	,    snake_case__    :  Union[DDIMScheduler, PNDMScheduler, LMSDiscreteScheduler]	,    snake_case__    :  StableDiffusionSafetyChecker	,    snake_case__    :  CLIPImageProcessor	,    snake_case__    :  bool = True	,    ):
							super()._init_()

							lowerCAmelCase__   = StableDiffusionPipeline.from_pretrained(snake_case__  )
							lowerCAmelCase__   = StableDiffusionPipeline.from_pretrained(snake_case__  )
							lowerCAmelCase__   = StableDiffusionPipeline.from_pretrained(snake_case__  )
							lowerCAmelCase__   = StableDiffusionPipeline(
							    vae=snake_case__	,    text_encoder=snake_case__	,    tokenizer=snake_case__	,    unet=snake_case__	,    scheduler=snake_case__	,    safety_checker=snake_case__	,    feature_extractor=snake_case__	,    requires_safety_checker=snake_case__	,    )

							self.register_modules(pipelinea=self.pipea	,    pipelinea=self.pipea	,    pipelinea=self.pipea	,    pipelinea=self.pipea  )




					@property
					def     _SCREAMING_SNAKE_CASE    (						self    :  Tuple  ):
							return {k: getattr(self	,    snake_case__  ) for k in self.config.keys() if not k.startswith("""_"""  )}




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




					def     _SCREAMING_SNAKE_CASE    (						self    :  int  ):
							self.enable_attention_slicing(snake_case__  )




					@torch.no_grad()
					def     _SCREAMING_SNAKE_CASE    (						self    :  int	,    snake_case__    :  Union[str, List[str]]	,    snake_case__    :  int = 512	,    snake_case__    :  int = 512	,    snake_case__    :  int = 50	,    snake_case__    :  float = 7.5	,    snake_case__    :  Optional[Union[str, List[str]]] = None	,    snake_case__    :  Optional[int] = 1	,    snake_case__    :  float = 0.0	,    snake_case__    :  Optional[torch.Generator] = None	,    snake_case__    :  Optional[torch.FloatTensor] = None	,    snake_case__    :  Optional[str] = "pil"	,    snake_case__    :  bool = True	,    snake_case__    :  Optional[Callable[[int, int, torch.FloatTensor], None]] = None	,    snake_case__    :  int = 1	,    **snake_case__    :  List[Any]	,    ):
							return self.pipea(
							    prompt=snake_case__	,    height=snake_case__	,    width=snake_case__	,    num_inference_steps=snake_case__	,    guidance_scale=snake_case__	,    negative_prompt=snake_case__	,    num_images_per_prompt=snake_case__	,    eta=snake_case__	,    generator=snake_case__	,    latents=snake_case__	,    output_type=snake_case__	,    return_dict=snake_case__	,    callback=snake_case__	,    callback_steps=snake_case__	,    **snake_case__	,    )




					@torch.no_grad()
					def     _SCREAMING_SNAKE_CASE    (						self    :  Tuple	,    snake_case__    :  Union[str, List[str]]	,    snake_case__    :  int = 512	,    snake_case__    :  int = 512	,    snake_case__    :  int = 50	,    snake_case__    :  float = 7.5	,    snake_case__    :  Optional[Union[str, List[str]]] = None	,    snake_case__    :  Optional[int] = 1	,    snake_case__    :  float = 0.0	,    snake_case__    :  Optional[torch.Generator] = None	,    snake_case__    :  Optional[torch.FloatTensor] = None	,    snake_case__    :  Optional[str] = "pil"	,    snake_case__    :  bool = True	,    snake_case__    :  Optional[Callable[[int, int, torch.FloatTensor], None]] = None	,    snake_case__    :  int = 1	,    **snake_case__    :  Tuple	,    ):
							return self.pipea(
							    prompt=snake_case__	,    height=snake_case__	,    width=snake_case__	,    num_inference_steps=snake_case__	,    guidance_scale=snake_case__	,    negative_prompt=snake_case__	,    num_images_per_prompt=snake_case__	,    eta=snake_case__	,    generator=snake_case__	,    latents=snake_case__	,    output_type=snake_case__	,    return_dict=snake_case__	,    callback=snake_case__	,    callback_steps=snake_case__	,    **snake_case__	,    )




					@torch.no_grad()
					def     _SCREAMING_SNAKE_CASE    (						self    :  Optional[int]	,    snake_case__    :  Union[str, List[str]]	,    snake_case__    :  int = 512	,    snake_case__    :  int = 512	,    snake_case__    :  int = 50	,    snake_case__    :  float = 7.5	,    snake_case__    :  Optional[Union[str, List[str]]] = None	,    snake_case__    :  Optional[int] = 1	,    snake_case__    :  float = 0.0	,    snake_case__    :  Optional[torch.Generator] = None	,    snake_case__    :  Optional[torch.FloatTensor] = None	,    snake_case__    :  Optional[str] = "pil"	,    snake_case__    :  bool = True	,    snake_case__    :  Optional[Callable[[int, int, torch.FloatTensor], None]] = None	,    snake_case__    :  int = 1	,    **snake_case__    :  Optional[Any]	,    ):
							return self.pipea(
							    prompt=snake_case__	,    height=snake_case__	,    width=snake_case__	,    num_inference_steps=snake_case__	,    guidance_scale=snake_case__	,    negative_prompt=snake_case__	,    num_images_per_prompt=snake_case__	,    eta=snake_case__	,    generator=snake_case__	,    latents=snake_case__	,    output_type=snake_case__	,    return_dict=snake_case__	,    callback=snake_case__	,    callback_steps=snake_case__	,    **snake_case__	,    )




					@torch.no_grad()
					def     _SCREAMING_SNAKE_CASE    (						self    :  List[str]	,    snake_case__    :  Union[str, List[str]]	,    snake_case__    :  int = 512	,    snake_case__    :  int = 512	,    snake_case__    :  int = 50	,    snake_case__    :  float = 7.5	,    snake_case__    :  Optional[Union[str, List[str]]] = None	,    snake_case__    :  Optional[int] = 1	,    snake_case__    :  float = 0.0	,    snake_case__    :  Optional[torch.Generator] = None	,    snake_case__    :  Optional[torch.FloatTensor] = None	,    snake_case__    :  Optional[str] = "pil"	,    snake_case__    :  bool = True	,    snake_case__    :  Optional[Callable[[int, int, torch.FloatTensor], None]] = None	,    snake_case__    :  int = 1	,    **snake_case__    :  str	,    ):
							return self.pipea(
							    prompt=snake_case__	,    height=snake_case__	,    width=snake_case__	,    num_inference_steps=snake_case__	,    guidance_scale=snake_case__	,    negative_prompt=snake_case__	,    num_images_per_prompt=snake_case__	,    eta=snake_case__	,    generator=snake_case__	,    latents=snake_case__	,    output_type=snake_case__	,    return_dict=snake_case__	,    callback=snake_case__	,    callback_steps=snake_case__	,    **snake_case__	,    )




					@torch.no_grad()
					def     _SCREAMING_SNAKE_CASE    (						self    :  Union[str, Any]	,    snake_case__    :  Union[str, List[str]]	,    snake_case__    :  int = 512	,    snake_case__    :  int = 512	,    snake_case__    :  int = 50	,    snake_case__    :  float = 7.5	,    snake_case__    :  Optional[Union[str, List[str]]] = None	,    snake_case__    :  Optional[int] = 1	,    snake_case__    :  float = 0.0	,    snake_case__    :  Optional[torch.Generator] = None	,    snake_case__    :  Optional[torch.FloatTensor] = None	,    snake_case__    :  Optional[str] = "pil"	,    snake_case__    :  bool = True	,    snake_case__    :  Optional[Callable[[int, int, torch.FloatTensor], None]] = None	,    snake_case__    :  int = 1	,    **snake_case__    :  Optional[Any]	,    ):
							lowerCAmelCase__   = """cuda""" if torch.cuda.is_available() else """cpu"""
							self.to(snake_case__  )

							# Checks if the height and width are divisible by 8 or not
							if height % 8 != 0 or width % 8 != 0:
									raise ValueError(F"""`height` and `width` must be divisible by 8 but are {height} and {width}."""  )

							# Get first result from Stable Diffusion Checkpoint v1.1
							lowerCAmelCase__   = self.textaimg_sda_a(
							    prompt=snake_case__	,    height=snake_case__	,    width=snake_case__	,    num_inference_steps=snake_case__	,    guidance_scale=snake_case__	,    negative_prompt=snake_case__	,    num_images_per_prompt=snake_case__	,    eta=snake_case__	,    generator=snake_case__	,    latents=snake_case__	,    output_type=snake_case__	,    return_dict=snake_case__	,    callback=snake_case__	,    callback_steps=snake_case__	,    **snake_case__	,    )

							# Get first result from Stable Diffusion Checkpoint v1.2
							lowerCAmelCase__   = self.textaimg_sda_a(
							    prompt=snake_case__	,    height=snake_case__	,    width=snake_case__	,    num_inference_steps=snake_case__	,    guidance_scale=snake_case__	,    negative_prompt=snake_case__	,    num_images_per_prompt=snake_case__	,    eta=snake_case__	,    generator=snake_case__	,    latents=snake_case__	,    output_type=snake_case__	,    return_dict=snake_case__	,    callback=snake_case__	,    callback_steps=snake_case__	,    **snake_case__	,    )

							# Get first result from Stable Diffusion Checkpoint v1.3
							lowerCAmelCase__   = self.textaimg_sda_a(
							    prompt=snake_case__	,    height=snake_case__	,    width=snake_case__	,    num_inference_steps=snake_case__	,    guidance_scale=snake_case__	,    negative_prompt=snake_case__	,    num_images_per_prompt=snake_case__	,    eta=snake_case__	,    generator=snake_case__	,    latents=snake_case__	,    output_type=snake_case__	,    return_dict=snake_case__	,    callback=snake_case__	,    callback_steps=snake_case__	,    **snake_case__	,    )

							# Get first result from Stable Diffusion Checkpoint v1.4
							lowerCAmelCase__   = self.textaimg_sda_a(
							    prompt=snake_case__	,    height=snake_case__	,    width=snake_case__	,    num_inference_steps=snake_case__	,    guidance_scale=snake_case__	,    negative_prompt=snake_case__	,    num_images_per_prompt=snake_case__	,    eta=snake_case__	,    generator=snake_case__	,    latents=snake_case__	,    output_type=snake_case__	,    return_dict=snake_case__	,    callback=snake_case__	,    callback_steps=snake_case__	,    **snake_case__	,    )

							# Get all result images into a single list and pass it via StableDiffusionPipelineOutput for final result
							return StableDiffusionPipelineOutput([resa[0], resa[0], resa[0], resa[0]]  )




