





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 					lowerCAmelCase							(   lowercase_					):
  __lowerCamelCase		=			42





class 					lowerCAmelCase							(   lowercase_							,							lowercase_					):







  @register_to_config
  def __init__(			self  :Tuple    ,							_lowercase  :Optional[Union[int, Tuple[int, int]]] = None    ,							_lowercase  :int = 3    ,							_lowercase  :int = 3    ,							_lowercase  :bool = False    ,							_lowercase  :str = "positional"    ,							_lowercase  :int = 0    ,							_lowercase  :bool = True    ,							_lowercase  :Tuple[str] = ("DownBlock2D", "AttnDownBlock2D", "AttnDownBlock2D", "AttnDownBlock2D")    ,							_lowercase  :Tuple[str] = ("AttnUpBlock2D", "AttnUpBlock2D", "AttnUpBlock2D", "UpBlock2D")    ,							_lowercase  :Tuple[int] = (2_24, 4_48, 6_72, 8_96)    ,							_lowercase  :int = 2    ,							_lowercase  :float = 1    ,							_lowercase  :int = 1    ,							_lowercase  :str = "conv"    ,							_lowercase  :str = "conv"    ,							_lowercase  :str = "silu"    ,							_lowercase  :Optional[int] = 8    ,							_lowercase  :int = 32    ,							_lowercase  :float = 1e-5    ,							_lowercase  :str = "default"    ,							_lowercase  :bool = True    ,							_lowercase  :Optional[str] = None    ,							_lowercase  :Optional[int] = None    ,							):






     '''simple docstring'''





     super().__init__()

     lowercase__    =  sample_size
     lowercase__    =  block_out_channels[0] * 4

     # Check inputs
     if len(_lowercase					) != len(_lowercase					):
        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(_lowercase					) != len(_lowercase					):
        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
     lowercase__    =  nn.Convad(_lowercase    ,							block_out_channels[0]    ,							kernel_size=3    ,							padding=(1, 1)					)

     # time
     if time_embedding_type == "fourier":
        lowercase__    =  GaussianFourierProjection(embedding_size=block_out_channels[0]    ,							scale=16					)
        lowercase__    =  2 * block_out_channels[0]
     elif time_embedding_type == "positional":
        lowercase__    =  Timesteps(block_out_channels[0]    ,							_lowercase    ,							_lowercase					)
        lowercase__    =  block_out_channels[0]

     lowercase__    =  TimestepEmbedding(_lowercase    ,							_lowercase					)

     # class embedding
     if class_embed_type is None and num_class_embeds is not None:
        lowercase__    =  nn.Embedding(_lowercase    ,							_lowercase					)
     elif class_embed_type == "timestep":
        lowercase__    =  TimestepEmbedding(_lowercase    ,							_lowercase					)
     elif class_embed_type == "identity":
        lowercase__    =  nn.Identity(_lowercase    ,							_lowercase					)
     else:
        lowercase__    =  None

     lowercase__    =  nn.ModuleList([]					)
     lowercase__    =  None
     lowercase__    =  nn.ModuleList([]					)

     # down
     lowercase__    =  block_out_channels[0]
     for i, down_block_type in enumerate(_lowercase					):
        lowercase__    =  output_channel
        lowercase__    =  block_out_channels[i]
        lowercase__    =  i == len(_lowercase					) - 1

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

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

     # up
     lowercase__    =  list(reversed(_lowercase					)					)
     lowercase__    =  reversed_block_out_channels[0]
     for i, up_block_type in enumerate(_lowercase					):
        lowercase__    =  output_channel
        lowercase__    =  reversed_block_out_channels[i]
        lowercase__    =  reversed_block_out_channels[min(i + 1    ,							len(_lowercase					) - 1					)]

        lowercase__    =  i == len(_lowercase					) - 1

        lowercase__    =  get_up_block(
            _lowercase    ,							num_layers=layers_per_block + 1    ,							in_channels=_lowercase    ,							out_channels=_lowercase    ,							prev_output_channel=_lowercase    ,							temb_channels=_lowercase    ,							add_upsample=not is_final_block    ,							resnet_eps=_lowercase    ,							resnet_act_fn=_lowercase    ,							resnet_groups=_lowercase    ,							attention_head_dim=attention_head_dim if attention_head_dim is not None else output_channel    ,							resnet_time_scale_shift=_lowercase    ,							upsample_type=_lowercase    ,							)
        self.up_blocks.append(_lowercase					)
        lowercase__    =  output_channel

     # out
     lowercase__    =  norm_num_groups if norm_num_groups is not None else min(block_out_channels[0] // 4    ,							32					)
     lowercase__    =  nn.GroupNorm(num_channels=block_out_channels[0]    ,							num_groups=_lowercase    ,							eps=_lowercase					)
     lowercase__    =  nn.SiLU()
     lowercase__    =  nn.Convad(block_out_channels[0]    ,							_lowercase    ,							kernel_size=3    ,							padding=1					)







  def   UpperCAmelCase     (			self  :Optional[int]    ,							_lowercase  :torch.FloatTensor    ,							_lowercase  :Union[torch.Tensor, float, int]    ,							_lowercase  :Optional[torch.Tensor] = None    ,							_lowercase  :bool = True    ,							):






     '''simple docstring'''





     if self.config.center_input_sample:
        lowercase__    =  2 * sample - 1.0

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

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

     lowercase__    =  self.time_proj(_lowercase					)

     # 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.
     lowercase__    =  t_emb.to(dtype=self.dtype					)
     lowercase__    =  self.time_embedding(_lowercase					)

     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":
           lowercase__    =  self.time_proj(_lowercase					)

        lowercase__    =  self.class_embedding(_lowercase					).to(dtype=self.dtype					)
        lowercase__    =  emb + class_emb

     # 2. pre-process
     lowercase__    =  sample
     lowercase__    =  self.conv_in(_lowercase					)

     # 3. down
     lowercase__    =  (sample,)
     for downsample_block in self.down_blocks:
        if hasattr(_lowercase    ,							"skip_conv"					):
           lowercase__   ,							lowercase__   ,							lowercase__    =  downsample_block(
               hidden_states=_lowercase    ,							temb=_lowercase    ,							skip_sample=_lowercase					)
        else:
           lowercase__   ,							lowercase__    =  downsample_block(hidden_states=_lowercase    ,							temb=_lowercase					)

        down_block_res_samples += res_samples

     # 4. mid
     lowercase__    =  self.mid_block(_lowercase    ,							_lowercase					)

     # 5. up
     lowercase__    =  None
     for upsample_block in self.up_blocks:
        lowercase__    =  down_block_res_samples[-len(upsample_block.resnets					) :]
        lowercase__    =  down_block_res_samples[: -len(upsample_block.resnets					)]

        if hasattr(_lowercase    ,							"skip_conv"					):
           lowercase__   ,							lowercase__    =  upsample_block(_lowercase    ,							_lowercase    ,							_lowercase    ,							_lowercase					)
        else:
           lowercase__    =  upsample_block(_lowercase    ,							_lowercase    ,							_lowercase					)

        # 6. post-process
     lowercase__    =  self.conv_norm_out(_lowercase					)
     lowercase__    =  self.conv_act(_lowercase					)
     lowercase__    =  self.conv_out(_lowercase					)

     if skip_sample is not None:
        sample += skip_sample

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

     if not return_dict:
        return (sample,)

     return UNetaDOutput(sample=_lowercase					)













from typing import TYPE_CHECKING

from ...utils import OptionalDependencyNotAvailable, _LazyModule, is_torch_available


_snake_case				= {"""configuration_dinat""": ["""DINAT_PRETRAINED_CONFIG_ARCHIVE_MAP""", """DinatConfig"""]}


try:
  if not is_torch_available():
    raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
  pass
else:
  _snake_case				= [
      """DINAT_PRETRAINED_MODEL_ARCHIVE_LIST""",
      """DinatForImageClassification""",
      """DinatModel""",
      """DinatPreTrainedModel""",
      """DinatBackbone""",
  ]

if TYPE_CHECKING:
  from .configuration_dinat import DINAT_PRETRAINED_CONFIG_ARCHIVE_MAP, DinatConfig

  try:
    if not is_torch_available():
      raise OptionalDependencyNotAvailable()
  except OptionalDependencyNotAvailable:
    pass
  else:
    from .modeling_dinat import (
        DINAT_PRETRAINED_MODEL_ARCHIVE_LIST,
        DinatBackbone,
        DinatForImageClassification,
        DinatModel,
        DinatPreTrainedModel,
    )

else:
  import sys

  _snake_case				= _LazyModule(__name__, globals()["""__file__"""], _import_structure, module_spec=__spec__)






