


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


UpperCAmelCase__  							="CompVis/stable-diffusion-v1-1"
UpperCAmelCase__  							="CompVis/stable-diffusion-v1-2"
UpperCAmelCase__  							="CompVis/stable-diffusion-v1-3"
UpperCAmelCase__  							="CompVis/stable-diffusion-v1-4"





class    lowerCamelCase__						(		_a    ):
      def __init__(		self	:	List[Any]      ,       A_	:	AutoencoderKL      ,       A_	:	CLIPTextModel      ,       A_	:	CLIPTokenizer      ,       A_	:	UNetaDConditionModel      ,       A_	:	Union[DDIMScheduler, PNDMScheduler, LMSDiscreteScheduler]      ,       A_	:	StableDiffusionSafetyChecker      ,       A_	:	CLIPImageProcessor      ,       A_	:	bool = True      ,       ):






       '''simple docstring'''


       super()._init_()

       __lowercase									=	StableDiffusionPipeline.from_pretrained(A_							)
       __lowercase									=	StableDiffusionPipeline.from_pretrained(A_							)
       __lowercase									=	StableDiffusionPipeline.from_pretrained(A_							)
       __lowercase									=	StableDiffusionPipeline(
           vae=A_      ,       text_encoder=A_      ,       tokenizer=A_      ,       unet=A_      ,       scheduler=A_      ,       safety_checker=A_      ,       feature_extractor=A_      ,       requires_safety_checker=A_      ,       )

       self.register_modules(pipelinea=self.pipea      ,       pipelinea=self.pipea      ,       pipelinea=self.pipea      ,       pipelinea=self.pipea							)
      @property
      def SCREAMING_SNAKE_CASE_	(		self	:	List[Any]							):






       '''simple docstring'''


       return {k: getattr(self      ,       A_							) for k in self.config.keys() if not k.startswith("""_"""							)}
      def SCREAMING_SNAKE_CASE_	(		self	:	List[Any]      ,       A_	:	Optional[Union[str, int]] = "auto"							):






       '''simple docstring'''


       if slice_size == "auto":
        # half the attention head size is usually a good trade-off between
        # speed and memory
        __lowercase									=	self.unet.config.attention_head_dim // 2
       self.unet.set_attention_slice(A_							)
      def SCREAMING_SNAKE_CASE_	(		self	:	List[str]							):






       '''simple docstring'''


       self.enable_attention_slicing(A_							)
      @torch.no_grad()
      def SCREAMING_SNAKE_CASE_	(		self	:	List[Any]      ,       A_	:	Union[str, List[str]]      ,       A_	:	int = 5_1_2      ,       A_	:	int = 5_1_2      ,       A_	:	int = 5_0      ,       A_	:	float = 7.5      ,       A_	:	Optional[Union[str, List[str]]] = None      ,       A_	:	Optional[int] = 1      ,       A_	:	float = 0.0      ,       A_	:	Optional[torch.Generator] = None      ,       A_	:	Optional[torch.FloatTensor] = None      ,       A_	:	Optional[str] = "pil"      ,       A_	:	bool = True      ,       A_	:	Optional[Callable[[int, int, torch.FloatTensor], None]] = None      ,       A_	:	int = 1      ,       **A_	:	Tuple      ,       ):






       '''simple docstring'''


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






       '''simple docstring'''


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






       '''simple docstring'''


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






       '''simple docstring'''


       return self.pipea(
           prompt=A_      ,       height=A_      ,       width=A_      ,       num_inference_steps=A_      ,       guidance_scale=A_      ,       negative_prompt=A_      ,       num_images_per_prompt=A_      ,       eta=A_      ,       generator=A_      ,       latents=A_      ,       output_type=A_      ,       return_dict=A_      ,       callback=A_      ,       callback_steps=A_      ,       **A_      ,       )






      @torch.no_grad()
      def SCREAMING_SNAKE_CASE_	(		self	:	Tuple      ,       A_	:	Union[str, List[str]]      ,       A_	:	int = 5_1_2      ,       A_	:	int = 5_1_2      ,       A_	:	int = 5_0      ,       A_	:	float = 7.5      ,       A_	:	Optional[Union[str, List[str]]] = None      ,       A_	:	Optional[int] = 1      ,       A_	:	float = 0.0      ,       A_	:	Optional[torch.Generator] = None      ,       A_	:	Optional[torch.FloatTensor] = None      ,       A_	:	Optional[str] = "pil"      ,       A_	:	bool = True      ,       A_	:	Optional[Callable[[int, int, torch.FloatTensor], None]] = None      ,       A_	:	int = 1      ,       **A_	:	List[Any]      ,       ):






       '''simple docstring'''


       __lowercase									=	'cuda' if torch.cuda.is_available() else 'cpu'
       self.to(A_							)

       # 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
       __lowercase									=	self.textaimg_sda_a(
           prompt=A_      ,       height=A_      ,       width=A_      ,       num_inference_steps=A_      ,       guidance_scale=A_      ,       negative_prompt=A_      ,       num_images_per_prompt=A_      ,       eta=A_      ,       generator=A_      ,       latents=A_      ,       output_type=A_      ,       return_dict=A_      ,       callback=A_      ,       callback_steps=A_      ,       **A_      ,       )

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

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

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

       # 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]]							)




"""simple docstring"""

import os

import numpy
import onnx


def lowerCAmelCase_      (				UpperCamelCase__	: Optional[int]				,   UpperCamelCase__	: List[str] ):






 """simple docstring"""







 __lowercase									=	a.name
 __lowercase									=	b.name

 __lowercase									=	""""""
 __lowercase									=	""""""

 __lowercase									=	a == b

 __lowercase									=	name_a
 __lowercase									=	name_b

 return res


def lowerCAmelCase_      (				UpperCamelCase__	: Union[str, Any]				,   UpperCamelCase__	: str				,   UpperCamelCase__	: Dict ):






 """simple docstring"""







 for i, input_name in enumerate(node_proto.input ):
  if input_name == name:
   node_proto.input.insert(UpperCamelCase__				,   UpperCamelCase__ )
   node_proto.input.pop(i + 1 )

 if node_proto.op_type == "If":
  _graph_replace_input_with(node_proto.attribute[0].g				,   UpperCamelCase__				,   UpperCamelCase__ )
  _graph_replace_input_with(node_proto.attribute[1].g				,   UpperCamelCase__				,   UpperCamelCase__ )
 if node_proto.op_type == "Loop":
  _graph_replace_input_with(node_proto.attribute[0].g				,   UpperCamelCase__				,   UpperCamelCase__ )


def lowerCAmelCase_      (				UpperCamelCase__	: Optional[Any]				,   UpperCamelCase__	: Optional[int]				,   UpperCamelCase__	: str ):






 """simple docstring"""







 for n in graph_proto.node:
  _node_replace_input_with(UpperCamelCase__				,   UpperCamelCase__				,   UpperCamelCase__ )


def lowerCAmelCase_      (				UpperCamelCase__	: Tuple				,   UpperCamelCase__	: str				,   UpperCamelCase__	: Any ):






 """simple docstring"""







 __lowercase									=	list(model.graph.initializer )
 __lowercase									=	list(model_without_ext.graph.initializer )
 for i, ref_i in ind_to_replace:
  assert inits_with_data[i].name == inits[i].name
  assert inits_with_data[ref_i].name == inits[ref_i].name
  assert i > ref_i

  __lowercase									=	inits[i].name
  __lowercase									=	inits[ref_i].name

  model_without_ext.graph.initializer.remove(inits[i] )

  # for n in model.graph.node:
  _graph_replace_input_with(model_without_ext.graph				,   UpperCamelCase__				,   UpperCamelCase__ )


def lowerCAmelCase_      (				UpperCamelCase__	: List[Any] ):






 """simple docstring"""







 __lowercase									=	os.path.dirname(UpperCamelCase__ )
 __lowercase									=	os.path.basename(UpperCamelCase__ )

 __lowercase									=	onnx.load(os.path.join(UpperCamelCase__				,   UpperCamelCase__ ) )

 __lowercase									=	list(model.graph.initializer )

 __lowercase									=	set()
 __lowercase									=	{}
 __lowercase									=	[]

 __lowercase									=	0

 for i in range(len(UpperCamelCase__ ) ):
  if i in dup_set:
   continue

  for j in range(i + 1				,   len(UpperCamelCase__ ) ):
   if j in dup_set:
    continue
   if _is_equal_tensor_proto(inits[i]				,   inits[j] ):
    dup_set.add(UpperCamelCase__ )
    dup_set.add(UpperCamelCase__ )

    __lowercase									=	inits[j].data_type
    __lowercase									=	numpy.prod(inits[j].dims )
    if dtype == 1:
     mem_size *= 4
    elif dtype == 6:
     mem_size *= 4
    elif dtype == 7 or dtype == 11:
     mem_size *= 8
    else:
     print("""unexpected data type: """				,   UpperCamelCase__ )
    total_reduced_size += mem_size

    __lowercase									=	inits[i].name
    __lowercase									=	inits[j].name

    if name_i in dup_map:
     dup_map[name_i].append(UpperCamelCase__ )
    else:
     __lowercase									=	[name_j]
    ind_to_replace.append((j, i) )

 print("""total reduced size: """				,   total_reduced_size / 1024 / 1024 / 1024				,   """GB""" )

 __lowercase									=	sorted(UpperCamelCase__ )
 _remove_dup_initializers_from_model(UpperCamelCase__				,   UpperCamelCase__				,   UpperCamelCase__ )

 __lowercase									=	"""optimized_""" + model_file_name
 __lowercase									=	os.path.join(UpperCamelCase__				,   UpperCamelCase__ )
 onnx.save(UpperCamelCase__				,   UpperCamelCase__ )

 return new_model
