
"""simple docstring"""







from dataclasses import dataclass
from enum import Enum
from typing import List, Optional, Union

import numpy as np
import PIL
from PIL import Image

from ...utils import BaseOutput, is_torch_available, is_transformers_available




@dataclass
class  A__       (	A_):
		A_						:       Union[List[PIL.Image.Image], np.ndarray]
		A_						:       Optional[List[bool]]


if is_transformers_available() and is_torch_available():
							from .pipeline_semantic_stable_diffusion import SemanticStableDiffusionPipeline

from typing import Optional, Tuple, Union

import flax
import flax.linen as nn
import jax
import jax.numpy as jnp
from flax.core.frozen_dict import FrozenDict

from ..configuration_utils import ConfigMixin, flax_register_to_config
from ..utils import BaseOutput
from .embeddings_flax import FlaxTimestepEmbedding, FlaxTimesteps
from .modeling_flax_utils import FlaxModelMixin
from .unet_ad_blocks_flax import (
    FlaxCrossAttnDownBlockaD,
    FlaxCrossAttnUpBlockaD,
    FlaxDownBlockaD,
    FlaxUNetMidBlockaDCrossAttn,
    FlaxUpBlockaD,
)






@flax.struct.dataclass
class   UpperCAmelCase		(						A_ ):
   A__					:		jnp.ndarray






@flax_register_to_config
class   UpperCAmelCase		(						nn.Module       ,A_       ,A_ ):
   A__					:		int						     =     32
   A__					:		int						     =     4
   A__					:		int						     =     4
   A__					:		Tuple[str]						     =     (
       "CrossAttnDownBlock2D",
       "CrossAttnDownBlock2D",
       "CrossAttnDownBlock2D",
       "DownBlock2D",
   )
   A__					:		Tuple[str]						     =     ("UpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D")
   A__					:		Union[bool, Tuple[bool]]						     =     False
   A__					:		Tuple[int]						     =     (3_20, 6_40, 12_80, 12_80)
   A__					:		int						     =     2
   A__					:		Union[int, Tuple[int]]						     =     8
   A__					:		Optional[Union[int, Tuple[int]]]						     =     None
   A__					:		int						     =     12_80
   A__					:		float						     =     0.0
   A__					:		bool						     =     False
   A__					:		jnp.dtype						     =     jnp.floataa
   A__					:		bool						     =     True
   A__					:		int						     =     0
   A__					:		bool						     =     False



   def 				_SCREAMING_SNAKE_CASE   (self		:					Optional[int]    ,						snake_case__		:					jax.random.KeyArray )		->	FrozenDict:


          '''simple docstring'''


          snake_case       :   Dict							=      (1, self.in_channels, self.sample_size, self.sample_size)
          snake_case       :   Any							=      jnp.zeros(snake_case__    ,						dtype=jnp.floataa )
          snake_case       :   List[str]							=      jnp.ones((1,)    ,						dtype=jnp.intaa )
          snake_case       :   str							=      jnp.zeros((1, 1, self.cross_attention_dim)    ,						dtype=jnp.floataa )

          snake_case				,					snake_case       :   Optional[int]							=      jax.random.split(snake_case__ )
          snake_case       :   Union[str, Any]							=      {"params": params_rng, "dropout": dropout_rng}

          return self.init(snake_case__    ,						snake_case__    ,						snake_case__    ,						snake_case__ )["params"]



   def 				_SCREAMING_SNAKE_CASE   (self		:					str )		->	Tuple:


          '''simple docstring'''


          snake_case       :   str							=      self.block_out_channels
          snake_case       :   Optional[Any]							=      block_out_channels[0] * 4

          if self.num_attention_heads is not None:
                 raise ValueError(
                     "At the moment it is not possible to define the number of attention heads via `num_attention_heads` because of a naming issue as described in https://github.com/huggingface/diffusers/issues/2011#issuecomment-1547958131. Passing `num_attention_heads` will only be supported in diffusers v0.19." )

          # If `num_attention_heads` is not defined (which is the case for most models)
          # it will default to `attention_head_dim`. This looks weird upon first reading it and it is.
          # The reason for this behavior is to correct for incorrectly named variables that were introduced
          # when this library was created. The incorrect naming was only discovered much later in https://github.com/huggingface/diffusers/issues/2011#issuecomment-1547958131
          # Changing `attention_head_dim` to `num_attention_heads` for 40,000+ configurations is too backwards breaking
          # which is why we correct for the naming here.
          snake_case       :   Tuple							=      self.num_attention_heads or self.attention_head_dim

          # input
          snake_case       :   Tuple							=      nn.Conv(
              block_out_channels[0]    ,						kernel_size=(3, 3)    ,						strides=(1, 1)    ,						padding=((1, 1), (1, 1))    ,						dtype=self.dtype    ,						)

          # time
          snake_case       :   Union[str, Any]							=      FlaxTimesteps(
              block_out_channels[0]    ,						flip_sin_to_cos=self.flip_sin_to_cos    ,						freq_shift=self.config.freq_shift )
          snake_case       :   Dict							=      FlaxTimestepEmbedding(snake_case__    ,						dtype=self.dtype )

          snake_case       :   List[str]							=      self.only_cross_attention
          if isinstance(snake_case__    ,						snake_case__ ):
                 snake_case       :   List[Any]							=      (only_cross_attention,) * len(self.down_block_types )

          if isinstance(snake_case__    ,						snake_case__ ):
                 snake_case       :   List[Any]							=      (num_attention_heads,) * len(self.down_block_types )

          # down
          snake_case       :   List[Any]							=      []
          snake_case       :   Optional[int]							=      block_out_channels[0]
          for i, down_block_type in enumerate(self.down_block_types ):
                 snake_case       :   List[Any]							=      output_channel
                 snake_case       :   Dict							=      block_out_channels[i]
                 snake_case       :   Optional[Any]							=      i == len(snake_case__ ) - 1

                 if down_block_type == "CrossAttnDownBlock2D":
                        snake_case       :   List[Any]							=      FlaxCrossAttnDownBlockaD(
                            in_channels=snake_case__    ,						out_channels=snake_case__    ,						dropout=self.dropout    ,						num_layers=self.layers_per_block    ,						num_attention_heads=num_attention_heads[i]    ,						add_downsample=not is_final_block    ,						use_linear_projection=self.use_linear_projection    ,						only_cross_attention=only_cross_attention[i]    ,						use_memory_efficient_attention=self.use_memory_efficient_attention    ,						dtype=self.dtype    ,						)
                 else:
                        snake_case       :   Union[str, Any]							=      FlaxDownBlockaD(
                            in_channels=snake_case__    ,						out_channels=snake_case__    ,						dropout=self.dropout    ,						num_layers=self.layers_per_block    ,						add_downsample=not is_final_block    ,						dtype=self.dtype    ,						)

                 down_blocks.append(snake_case__ )
          snake_case       :   Dict							=      down_blocks

          # mid
          snake_case       :   Optional[int]							=      FlaxUNetMidBlockaDCrossAttn(
              in_channels=block_out_channels[-1]    ,						dropout=self.dropout    ,						num_attention_heads=num_attention_heads[-1]    ,						use_linear_projection=self.use_linear_projection    ,						use_memory_efficient_attention=self.use_memory_efficient_attention    ,						dtype=self.dtype    ,						)

          # up
          snake_case       :   Optional[Any]							=      []
          snake_case       :   Optional[int]							=      list(reversed(snake_case__ ) )
          snake_case       :   Dict							=      list(reversed(snake_case__ ) )
          snake_case       :   Tuple							=      list(reversed(snake_case__ ) )
          snake_case       :   Optional[Any]							=      reversed_block_out_channels[0]
          for i, up_block_type in enumerate(self.up_block_types ):
                 snake_case       :   Optional[int]							=      output_channel
                 snake_case       :   List[Any]							=      reversed_block_out_channels[i]
                 snake_case       :   Union[str, Any]							=      reversed_block_out_channels[min(i + 1    ,						len(snake_case__ ) - 1 )]

                 snake_case       :   int							=      i == len(snake_case__ ) - 1

                 if up_block_type == "CrossAttnUpBlock2D":
                        snake_case       :   Any							=      FlaxCrossAttnUpBlockaD(
                            in_channels=snake_case__    ,						out_channels=snake_case__    ,						prev_output_channel=snake_case__    ,						num_layers=self.layers_per_block + 1    ,						num_attention_heads=reversed_num_attention_heads[i]    ,						add_upsample=not is_final_block    ,						dropout=self.dropout    ,						use_linear_projection=self.use_linear_projection    ,						only_cross_attention=only_cross_attention[i]    ,						use_memory_efficient_attention=self.use_memory_efficient_attention    ,						dtype=self.dtype    ,						)
                 else:
                        snake_case       :   Optional[int]							=      FlaxUpBlockaD(
                            in_channels=snake_case__    ,						out_channels=snake_case__    ,						prev_output_channel=snake_case__    ,						num_layers=self.layers_per_block + 1    ,						add_upsample=not is_final_block    ,						dropout=self.dropout    ,						dtype=self.dtype    ,						)

                 up_blocks.append(snake_case__ )
                 snake_case       :   Optional[int]							=      output_channel
          snake_case       :   Tuple							=      up_blocks

          # out
          snake_case       :   Optional[int]							=      nn.GroupNorm(num_groups=32    ,						epsilon=1e-5 )
          snake_case       :   List[str]							=      nn.Conv(
              self.out_channels    ,						kernel_size=(3, 3)    ,						strides=(1, 1)    ,						padding=((1, 1), (1, 1))    ,						dtype=self.dtype    ,						)



   def __call__(self		:					Dict    ,						snake_case__		:					Dict    ,						snake_case__		:					Dict    ,						snake_case__		:					Optional[int]    ,						snake_case__		:					Tuple=None    ,						snake_case__		:					Union[str, Any]=None    ,						snake_case__		:					bool = True    ,						snake_case__		:					bool = False    ,						)		->	Union[FlaxUNetaDConditionOutput, Tuple]:


          '''simple docstring'''


          if not isinstance(snake_case__    ,						jnp.ndarray ):
                 snake_case       :   List[Any]							=      jnp.array([timesteps]    ,						dtype=jnp.intaa )
          elif isinstance(snake_case__    ,						jnp.ndarray ) and len(timesteps.shape ) == 0:
                 snake_case       :   Any							=      timesteps.astype(dtype=jnp.floataa )
                 snake_case       :   int							=      jnp.expand_dims(snake_case__    ,						0 )

          snake_case       :   str							=      self.time_proj(snake_case__ )
          snake_case       :   str							=      self.time_embedding(snake_case__ )

          # 2. pre-process
          snake_case       :   int							=      jnp.transpose(snake_case__    ,						(0, 2, 3, 1) )
          snake_case       :   List[Any]							=      self.conv_in(snake_case__ )

          # 3. down
          snake_case       :   Optional[int]							=      (sample,)
          for down_block in self.down_blocks:
                 if isinstance(snake_case__    ,						snake_case__ ):
                        snake_case				,					snake_case       :   List[Any]							=      down_block(snake_case__    ,						snake_case__    ,						snake_case__    ,						deterministic=not train )
                 else:
                        snake_case				,					snake_case       :   str							=      down_block(snake_case__    ,						snake_case__    ,						deterministic=not train )
                 down_block_res_samples += res_samples

          if down_block_additional_residuals is not None:
                 snake_case       :   Tuple							=      ()

                 for down_block_res_sample, down_block_additional_residual in zip(
                     snake_case__    ,						snake_case__ ):
                        down_block_res_sample += down_block_additional_residual
                        new_down_block_res_samples += (down_block_res_sample,)

                 snake_case       :   Optional[int]							=      new_down_block_res_samples

          # 4. mid
          snake_case       :   Optional[int]							=      self.mid_block(snake_case__    ,						snake_case__    ,						snake_case__    ,						deterministic=not train )

          if mid_block_additional_residual is not None:
                 sample += mid_block_additional_residual

          # 5. up
          for up_block in self.up_blocks:
                 snake_case       :   int							=      down_block_res_samples[-(self.layers_per_block + 1) :]
                 snake_case       :   Optional[Any]							=      down_block_res_samples[: -(self.layers_per_block + 1)]
                 if isinstance(snake_case__    ,						snake_case__ ):
                        snake_case       :   Optional[Any]							=      up_block(
                            snake_case__    ,						temb=snake_case__    ,						encoder_hidden_states=snake_case__    ,						res_hidden_states_tuple=snake_case__    ,						deterministic=not train    ,						)
                 else:
                        snake_case       :   Dict							=      up_block(snake_case__    ,						temb=snake_case__    ,						res_hidden_states_tuple=snake_case__    ,						deterministic=not train )

        # 6. post-process
          snake_case       :   List[str]							=      self.conv_norm_out(snake_case__ )
          snake_case       :   Any							=      nn.silu(snake_case__ )
          snake_case       :   Optional[int]							=      self.conv_out(snake_case__ )
          snake_case       :   Union[str, Any]							=      jnp.transpose(snake_case__    ,						(0, 3, 1, 2) )

          if not return_dict:
                 return (sample,)

          return FlaxUNetaDConditionOutput(sample=snake_case__ )





