


'''simple docstring'''



from dataclasses import dataclass
from typing import Optional, Tuple, Union

import torch
import torch.nn as nn

from ..configuration_utils import ConfigMixin, register_to_config
from ..utils import BaseOutput
from .embeddings import GaussianFourierProjection, TimestepEmbedding, Timesteps
from .modeling_utils import ModelMixin
from .unet_ad_blocks import UNetMidBlockaD, get_down_block, get_up_block



@dataclass
class       a							(						_a			):


     """simple docstring"""






     SCREAMING_SNAKE_CASE			:					torch.FloatTensor



class       a							(						_a      ,    _a			):


     """simple docstring"""






     @register_to_config
     def __init__(							self	:						List[Any]				,					snake_case	:						Optional[Union[int, Tuple[int, int]]] = None				,					snake_case	:						int = 3				,					snake_case	:						int = 3				,					snake_case	:						bool = False				,					snake_case	:						str = "positional"				,					snake_case	:						int = 0				,					snake_case	:						bool = True				,					snake_case	:						Tuple[str] = ("DownBlock2D", "AttnDownBlock2D", "AttnDownBlock2D", "AttnDownBlock2D")				,					snake_case	:						Tuple[str] = ("AttnUpBlock2D", "AttnUpBlock2D", "AttnUpBlock2D", "UpBlock2D")				,					snake_case	:						Tuple[int] = (224, 448, 672, 896)				,					snake_case	:						int = 2				,					snake_case	:						float = 1				,					snake_case	:						int = 1				,					snake_case	:						str = "conv"				,					snake_case	:						str = "conv"				,					snake_case	:						str = "silu"				,					snake_case	:						Optional[int] = 8				,					snake_case	:						int = 32				,					snake_case	:						float = 1E-5				,					snake_case	:						str = "default"				,					snake_case	:						bool = True				,					snake_case	:						Optional[str] = None				,					snake_case	:						Optional[int] = None				,					)		->				Optional[Any]:
          super().__init__()

          __UpperCAmelCase      :					int    				=     sample_size
          __UpperCAmelCase      :					Dict    				=     block_out_channels[0] * 4

          # Check inputs
          if len(_snake_case     ) != len(_snake_case     ):
               raise ValueError(
                   f'Must provide the same number of `down_block_types` as `up_block_types`. `down_block_types`: {down_block_types}. `up_block_types`: {up_block_types}.'     )

          if len(_snake_case     ) != len(_snake_case     ):
               raise ValueError(
                   f'Must provide the same number of `block_out_channels` as `down_block_types`. `block_out_channels`: {block_out_channels}. `down_block_types`: {down_block_types}.'     )

          # input
          __UpperCAmelCase      :					int    				=     nn.Convad(_snake_case				,					block_out_channels[0]				,					kernel_size=3				,					padding=(1, 1)     )

          # time
          if time_embedding_type == "fourier":
               __UpperCAmelCase      :					List[str]    				=     GaussianFourierProjection(embedding_size=block_out_channels[0]				,					scale=16     )
               __UpperCAmelCase      :					Union[str, Any]    				=     2 * block_out_channels[0]
          elif time_embedding_type == "positional":
               __UpperCAmelCase      :					List[str]    				=     Timesteps(block_out_channels[0]				,					_snake_case				,					_snake_case     )
               __UpperCAmelCase      :					Optional[Any]    				=     block_out_channels[0]

          __UpperCAmelCase      :					List[Any]    				=     TimestepEmbedding(_snake_case				,					_snake_case     )

          # class embedding
          if class_embed_type is None and num_class_embeds is not None:
               __UpperCAmelCase      :					List[Any]    				=     nn.Embedding(_snake_case				,					_snake_case     )
          elif class_embed_type == "timestep":
               __UpperCAmelCase      :					List[str]    				=     TimestepEmbedding(_snake_case				,					_snake_case     )
          elif class_embed_type == "identity":
               __UpperCAmelCase      :					str    				=     nn.Identity(_snake_case				,					_snake_case     )
          else:
               __UpperCAmelCase      :					Optional[int]    				=     None

          __UpperCAmelCase      :					int    				=     nn.ModuleList([]     )
          __UpperCAmelCase      :					Optional[int]    				=     None
          __UpperCAmelCase      :					str    				=     nn.ModuleList([]     )

          # down
          __UpperCAmelCase      :					List[str]    				=     block_out_channels[0]
          for i, down_block_type in enumerate(_snake_case     ):
               __UpperCAmelCase      :					List[Any]    				=     output_channel
               __UpperCAmelCase      :					Tuple    				=     block_out_channels[i]
               __UpperCAmelCase      :					List[Any]    				=     i == len(_snake_case     ) - 1

               __UpperCAmelCase      :					Any    				=     get_down_block(
                   _snake_case				,					num_layers=_snake_case				,					in_channels=_snake_case				,					out_channels=_snake_case				,					temb_channels=_snake_case				,					add_downsample=not is_final_block				,					resnet_eps=_snake_case				,					resnet_act_fn=_snake_case				,					resnet_groups=_snake_case				,					attention_head_dim=attention_head_dim if attention_head_dim is not None else output_channel				,					downsample_padding=_snake_case				,					resnet_time_scale_shift=_snake_case				,					downsample_type=_snake_case				,					)
               self.down_blocks.append(_snake_case     )

          # mid
          __UpperCAmelCase      :					Tuple    				=     UNetMidBlockaD(
              in_channels=block_out_channels[-1]				,					temb_channels=_snake_case				,					resnet_eps=_snake_case				,					resnet_act_fn=_snake_case				,					output_scale_factor=_snake_case				,					resnet_time_scale_shift=_snake_case				,					attention_head_dim=attention_head_dim if attention_head_dim is not None else block_out_channels[-1]				,					resnet_groups=_snake_case				,					add_attention=_snake_case				,					)

          # up
          __UpperCAmelCase      :					int    				=     list(reversed(_snake_case     )     )
          __UpperCAmelCase      :					Tuple    				=     reversed_block_out_channels[0]
          for i, up_block_type in enumerate(_snake_case     ):
               __UpperCAmelCase      :					int    				=     output_channel
               __UpperCAmelCase      :					Optional[int]    				=     reversed_block_out_channels[i]
               __UpperCAmelCase      :					Optional[Any]    				=     reversed_block_out_channels[min(i + 1				,					len(_snake_case     ) - 1     )]

               __UpperCAmelCase      :					Union[str, Any]    				=     i == len(_snake_case     ) - 1

               __UpperCAmelCase      :					int    				=     get_up_block(
                   _snake_case				,					num_layers=layers_per_block + 1				,					in_channels=_snake_case				,					out_channels=_snake_case				,					prev_output_channel=_snake_case				,					temb_channels=_snake_case				,					add_upsample=not is_final_block				,					resnet_eps=_snake_case				,					resnet_act_fn=_snake_case				,					resnet_groups=_snake_case				,					attention_head_dim=attention_head_dim if attention_head_dim is not None else output_channel				,					resnet_time_scale_shift=_snake_case				,					upsample_type=_snake_case				,					)
               self.up_blocks.append(_snake_case     )
               __UpperCAmelCase      :					List[Any]    				=     output_channel

          # out
          __UpperCAmelCase      :					Union[str, Any]    				=     norm_num_groups if norm_num_groups is not None else min(block_out_channels[0] // 4				,					32     )
          __UpperCAmelCase      :					Optional[Any]    				=     nn.GroupNorm(num_channels=block_out_channels[0]				,					num_groups=_snake_case				,					eps=_snake_case     )
          __UpperCAmelCase      :					List[str]    				=     nn.SiLU()
          __UpperCAmelCase      :					int    				=     nn.Convad(block_out_channels[0]				,					_snake_case				,					kernel_size=3				,					padding=1     )






     def 					lowerCamelCase__					(							self	:						str				,					snake_case	:						torch.FloatTensor				,					snake_case	:						Union[torch.Tensor, float, int]				,					snake_case	:						Optional[torch.Tensor] = None				,					snake_case	:						bool = True				,					)		->				Optional[Any]:


          if self.config.center_input_sample:
               __UpperCAmelCase      :					List[str]    				=     2 * sample - 1.0

          # 1. time
          __UpperCAmelCase      :					Any    				=     timestep
          if not torch.is_tensor(_snake_case     ):
               __UpperCAmelCase      :					int    				=     torch.tensor([timesteps]				,					dtype=torch.long				,					device=sample.device     )
          elif torch.is_tensor(_snake_case     ) and len(timesteps.shape     ) == 0:
               __UpperCAmelCase      :					Tuple    				=     timesteps[None].to(sample.device     )

          # broadcast to batch dimension in a way that's compatible with ONNX/Core ML
          __UpperCAmelCase      :					Any    				=     timesteps * torch.ones(sample.shape[0]				,					dtype=timesteps.dtype				,					device=timesteps.device     )

          __UpperCAmelCase      :					str    				=     self.time_proj(_snake_case     )

          # timesteps does not contain any weights and will always return f32 tensors
          # but time_embedding might actually be running in fp16. so we need to cast here.
          # there might be better ways to encapsulate this.
          __UpperCAmelCase      :					List[Any]    				=     t_emb.to(dtype=self.dtype     )
          __UpperCAmelCase      :					Dict    				=     self.time_embedding(_snake_case     )

          if self.class_embedding is not None:
               if class_labels is None:
                    raise ValueError('''class_labels should be provided when doing class conditioning'''     )

               if self.config.class_embed_type == "timestep":
                    __UpperCAmelCase      :					int    				=     self.time_proj(_snake_case     )

               __UpperCAmelCase      :					Any    				=     self.class_embedding(_snake_case     ).to(dtype=self.dtype     )
               __UpperCAmelCase      :					Dict    				=     emb + class_emb

          # 2. pre-process
          __UpperCAmelCase      :					Tuple    				=     sample
          __UpperCAmelCase      :					Union[str, Any]    				=     self.conv_in(_snake_case     )

          # 3. down
          __UpperCAmelCase      :					Tuple    				=     (sample,)
          for downsample_block in self.down_blocks:
               if hasattr(_snake_case				,					'''skip_conv'''     ):
                    __UpperCAmelCase				,  __UpperCAmelCase				,  __UpperCAmelCase      :					Tuple    				=     downsample_block(
                        hidden_states=_snake_case				,					temb=_snake_case				,					skip_sample=_snake_case     )
               else:
                    __UpperCAmelCase				,  __UpperCAmelCase      :					str    				=     downsample_block(hidden_states=_snake_case				,					temb=_snake_case     )

               down_block_res_samples += res_samples

          # 4. mid
          __UpperCAmelCase      :					Optional[int]    				=     self.mid_block(_snake_case				,					_snake_case     )

          # 5. up
          __UpperCAmelCase      :					Any    				=     None
          for upsample_block in self.up_blocks:
               __UpperCAmelCase      :					List[str]    				=     down_block_res_samples[-len(upsample_block.resnets     ) :]
               __UpperCAmelCase      :					Optional[int]    				=     down_block_res_samples[: -len(upsample_block.resnets     )]

               if hasattr(_snake_case				,					'''skip_conv'''     ):
                    __UpperCAmelCase				,  __UpperCAmelCase      :					Dict    				=     upsample_block(_snake_case				,					_snake_case				,					_snake_case				,					_snake_case     )
               else:
                    __UpperCAmelCase      :					str    				=     upsample_block(_snake_case				,					_snake_case				,					_snake_case     )

        # 6. post-process
          __UpperCAmelCase      :					Any    				=     self.conv_norm_out(_snake_case     )
          __UpperCAmelCase      :					int    				=     self.conv_act(_snake_case     )
          __UpperCAmelCase      :					Optional[int]    				=     self.conv_out(_snake_case     )

          if skip_sample is not None:
               sample += skip_sample

          if self.config.time_embedding_type == "fourier":
               __UpperCAmelCase      :					Union[str, Any]    				=     timesteps.reshape((sample.shape[0], *([1] * len(sample.shape[1:]     )))     )
               __UpperCAmelCase      :					Any    				=     sample / timesteps

          if not return_dict:
               return (sample,)

          return UNetaDOutput(sample=_snake_case     )





def   A		(__A  :       float  ,							__A  :       int = 2			)  -> float:







     """simple docstring"""


     return round((float(__A			) * 9 / 5) + 32  ,							__A			)


def   A		(__A  :       float  ,							__A  :       int = 2			)  -> float:







     """simple docstring"""


     return round(float(__A			) + 273.15  ,							__A			)


def   A		(__A  :       float  ,							__A  :       int = 2			)  -> float:







     """simple docstring"""


     return round((float(__A			) * 9 / 5) + 491.67  ,							__A			)


def   A		(__A  :       float  ,							__A  :       int = 2			)  -> float:







     """simple docstring"""


     return round((float(__A			) - 32) * 5 / 9  ,							__A			)


def   A		(__A  :       float  ,							__A  :       int = 2			)  -> float:







     """simple docstring"""


     return round(((float(__A			) - 32) * 5 / 9) + 273.15  ,							__A			)


def   A		(__A  :       float  ,							__A  :       int = 2			)  -> float:







     """simple docstring"""


     return round(float(__A			) + 459.67  ,							__A			)


def   A		(__A  :       float  ,							__A  :       int = 2			)  -> float:







     """simple docstring"""


     return round(float(__A			) - 273.15  ,							__A			)


def   A		(__A  :       float  ,							__A  :       int = 2			)  -> float:







     """simple docstring"""


     return round(((float(__A			) - 273.15) * 9 / 5) + 32  ,							__A			)


def   A		(__A  :       float  ,							__A  :       int = 2			)  -> float:







     """simple docstring"""


     return round((float(__A			) * 9 / 5)  ,							__A			)


def   A		(__A  :       float  ,							__A  :       int = 2			)  -> float:







     """simple docstring"""


     return round((float(__A			) - 491.67) * 5 / 9  ,							__A			)


def   A		(__A  :       float  ,							__A  :       int = 2			)  -> float:







     """simple docstring"""


     return round(float(__A			) - 459.67  ,							__A			)


def   A		(__A  :       float  ,							__A  :       int = 2			)  -> float:







     """simple docstring"""


     return round((float(__A			) * 5 / 9)  ,							__A			)


def   A		(__A  :       float  ,							__A  :       int = 2			)  -> float:







     """simple docstring"""


     return round((float(__A			) * 1.25 + 273.15)  ,							__A			)


def   A		(__A  :       float  ,							__A  :       int = 2			)  -> float:







     """simple docstring"""


     return round((float(__A			) * 2.25 + 32)  ,							__A			)


def   A		(__A  :       float  ,							__A  :       int = 2			)  -> float:







     """simple docstring"""


     return round((float(__A			) * 1.25)  ,							__A			)


def   A		(__A  :       float  ,							__A  :       int = 2			)  -> float:







     """simple docstring"""


     return round((float(__A			) * 2.25 + 32 + 459.67)  ,							__A			)


if __name__ == "__main__":
    import doctest

    doctest.testmod()






