





"""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   lowercase_					(  snake_case__				):
       snake_case__					:				torch.FloatTensor



class   lowercase_					(  snake_case__					,snake_case__				):

       @register_to_config
       def __init__(      self ,       __SCREAMING_SNAKE_CASE = None ,       __SCREAMING_SNAKE_CASE = 3 ,       __SCREAMING_SNAKE_CASE = 3 ,       __SCREAMING_SNAKE_CASE = False ,       __SCREAMING_SNAKE_CASE = "positional" ,       __SCREAMING_SNAKE_CASE = 0 ,       __SCREAMING_SNAKE_CASE = True ,       __SCREAMING_SNAKE_CASE = ("DownBlock2D", "AttnDownBlock2D", "AttnDownBlock2D", "AttnDownBlock2D") ,       __SCREAMING_SNAKE_CASE = ("AttnUpBlock2D", "AttnUpBlock2D", "AttnUpBlock2D", "UpBlock2D") ,       __SCREAMING_SNAKE_CASE = (224, 448, 672, 896) ,       __SCREAMING_SNAKE_CASE = 2 ,       __SCREAMING_SNAKE_CASE = 1 ,       __SCREAMING_SNAKE_CASE = 1 ,       __SCREAMING_SNAKE_CASE = "conv" ,       __SCREAMING_SNAKE_CASE = "conv" ,       __SCREAMING_SNAKE_CASE = "silu" ,       __SCREAMING_SNAKE_CASE = 8 ,       __SCREAMING_SNAKE_CASE = 32 ,       __SCREAMING_SNAKE_CASE = 1e-5 ,       __SCREAMING_SNAKE_CASE = "default" ,       __SCREAMING_SNAKE_CASE = True ,       __SCREAMING_SNAKE_CASE = None ,       __SCREAMING_SNAKE_CASE = None ,       ):






        '''simple docstring'''

        super().__init__()

        snake_case__     				=					sample_size
        snake_case__     				=					block_out_channels[0] * 4

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

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

        snake_case__     				=					TimestepEmbedding(__lowerCAmelCase ,       __lowerCAmelCase  )

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

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

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

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

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

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

         snake_case__     				=					i == len(__lowerCAmelCase  ) - 1

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

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

       def 		_SCREAMING_SNAKE_CASE(      self ,       __SCREAMING_SNAKE_CASE ,       __SCREAMING_SNAKE_CASE ,       __SCREAMING_SNAKE_CASE = None ,       __SCREAMING_SNAKE_CASE = True ,       ):






        '''simple docstring'''

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

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

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

        snake_case__     				=					self.time_proj(__lowerCAmelCase  )

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

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

         snake_case__     				=					self.class_embedding(__lowerCAmelCase  ).to(dtype=self.dtype  )
         snake_case__     				=					emb + class_emb

        # 2. pre-process
        snake_case__     				=					sample
        snake_case__     				=					self.conv_in(__lowerCAmelCase  )

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

         down_block_res_samples += res_samples

        # 4. mid
        snake_case__     				=					self.mid_block(__lowerCAmelCase ,       __lowerCAmelCase  )

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

         if hasattr(__lowerCAmelCase ,       "skip_conv"  ):
          snake_case__     				=					upsample_block(__lowerCAmelCase ,       __lowerCAmelCase ,       __lowerCAmelCase ,       __lowerCAmelCase  )
         else:
          snake_case__     				=					upsample_block(__lowerCAmelCase ,       __lowerCAmelCase ,       __lowerCAmelCase  )

        # 6. post-process
        snake_case__     				=					self.conv_norm_out(__lowerCAmelCase  )
        snake_case__     				=					self.conv_act(__lowerCAmelCase  )
        snake_case__     				=					self.conv_out(__lowerCAmelCase  )

        if skip_sample is not None:
         sample += skip_sample

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

        if not return_dict:
         return (sample,)

        return UNetaDOutput(sample=__lowerCAmelCase  )







'''simple docstring'''





from __future__ import annotations

# Define the Gravitational Constant G and the function
a		:	Union[str, Any]       =      6.6743e-11  # unit of G : m^3 * kg^-1 * s^-2





def UpperCAmelCase    (       UpperCAmelCase_   ,	UpperCAmelCase_   ,	UpperCAmelCase_   ,	UpperCAmelCase_						):
    _a				:							Dict							       =      mass_a * mass_a

    if (force, mass_a, mass_a, distance).count(0						) != 1:
        raise ValueError("""One and only one argument must be 0"""						)
    if force < 0:
        raise ValueError("""Gravitational force can not be negative"""						)
    if distance < 0:
        raise ValueError("""Distance can not be negative"""						)
    if mass_a < 0 or mass_a < 0:
        raise ValueError("""Mass can not be negative"""						)
    if force == 0:
        _a				:							Optional[int]							       =      GRAVITATIONAL_CONSTANT * product_of_mass / (distance**2)
        return {"force": force}
    elif mass_a == 0:
        _a				:							Any							       =      (force) * (distance**2) / (GRAVITATIONAL_CONSTANT * mass_a)
        return {"mass_1": mass_a}
    elif mass_a == 0:
        _a				:							Union[str, Any]							       =      (force) * (distance**2) / (GRAVITATIONAL_CONSTANT * mass_a)
        return {"mass_2": mass_a}
    elif distance == 0:
        _a				:							Optional[Any]							       =      (GRAVITATIONAL_CONSTANT * product_of_mass / (force)) ** 0.5
        return {"distance": distance}
    raise ValueError("""One and only one argument must be 0"""						)


# Run doctest
if __name__ == "__main__":
  import doctest

  doctest.testmod()


