"""simple docstring"""




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 						__A							(			SCREAMING_SNAKE_CASE_		):
     _UpperCamelCase							:      jnp.ndarray







@flax_register_to_config
class 						__A							(			nn.Module   ,     SCREAMING_SNAKE_CASE_   ,     SCREAMING_SNAKE_CASE_		):
     _UpperCamelCase							:      int		 =		32
     _UpperCamelCase							:      int		 =		4
     _UpperCamelCase							:      int		 =		4
     _UpperCamelCase							:      Tuple[str]		 =		(
         "CrossAttnDownBlock2D",
         "CrossAttnDownBlock2D",
         "CrossAttnDownBlock2D",
         "DownBlock2D",
     )
     _UpperCamelCase							:      Tuple[str]		 =		("UpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D")
     _UpperCamelCase							:      Union[bool, Tuple[bool]]		 =		False
     _UpperCamelCase							:      Tuple[int]		 =		(320, 640, 1_280, 1_280)
     _UpperCamelCase							:      int		 =		2
     _UpperCamelCase							:      Union[int, Tuple[int]]		 =		8
     _UpperCamelCase							:      Optional[Union[int, Tuple[int]]]		 =		None
     _UpperCamelCase							:      int		 =		1_280
     _UpperCamelCase							:      float		 =		0.0
     _UpperCamelCase							:      bool		 =		False
     _UpperCamelCase							:      jnp.dtype		 =		jnp.floataa
     _UpperCamelCase							:      bool		 =		True
     _UpperCamelCase							:      int		 =		0
     _UpperCamelCase							:      bool		 =		False






     def    __A  (		self    ,					a__  ):
       # init input tensors
       _lowerCAmelCase						:	Optional[int]        =					(1, self.in_channels, self.sample_size, self.sample_size)
       _lowerCAmelCase						:	List[Any]        =					jnp.zeros(a__    ,					dtype=jnp.floataa  )
       _lowerCAmelCase						:	int        =					jnp.ones((1,)    ,					dtype=jnp.intaa  )
       _lowerCAmelCase						:	Tuple        =					jnp.zeros((1, 1, self.cross_attention_dim)    ,					dtype=jnp.floataa  )

       _lowerCAmelCase      ,     _lowerCAmelCase						:	Optional[int]        =					jax.random.split(a__  )
       _lowerCAmelCase						:	int        =					{"""params""": params_rng, """dropout""": dropout_rng}

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






     def    __A  (		self  ):
       _lowerCAmelCase						:	int        =					self.block_out_channels
       _lowerCAmelCase						:	Optional[int]        =					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.
       _lowerCAmelCase						:	str        =					self.num_attention_heads or self.attention_head_dim

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

       # time
       _lowerCAmelCase						:	List[Any]        =					FlaxTimesteps(
           block_out_channels[0]    ,					flip_sin_to_cos=self.flip_sin_to_cos    ,					freq_shift=self.config.freq_shift  )
       _lowerCAmelCase						:	int        =					FlaxTimestepEmbedding(a__    ,					dtype=self.dtype  )

       _lowerCAmelCase						:	List[str]        =					self.only_cross_attention
       if isinstance(a__    ,					a__  ):
         _lowerCAmelCase						:	int        =					(only_cross_attention,) * len(self.down_block_types  )

       if isinstance(a__    ,					a__  ):
         _lowerCAmelCase						:	str        =					(num_attention_heads,) * len(self.down_block_types  )

       # down
       _lowerCAmelCase						:	Tuple        =					[]
       _lowerCAmelCase						:	Union[str, Any]        =					block_out_channels[0]
       for i, down_block_type in enumerate(self.down_block_types  ):
         _lowerCAmelCase						:	Optional[Any]        =					output_channel
         _lowerCAmelCase						:	List[Any]        =					block_out_channels[i]
         _lowerCAmelCase						:	int        =					i == len(a__  ) - 1

         if down_block_type == "CrossAttnDownBlock2D":
           _lowerCAmelCase						:	Optional[int]        =					FlaxCrossAttnDownBlockaD(
               in_channels=a__    ,					out_channels=a__    ,					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:
           _lowerCAmelCase						:	List[str]        =					FlaxDownBlockaD(
               in_channels=a__    ,					out_channels=a__    ,					dropout=self.dropout    ,					num_layers=self.layers_per_block    ,					add_downsample=not is_final_block    ,					dtype=self.dtype    ,					)

         down_blocks.append(a__  )
       _lowerCAmelCase						:	str        =					down_blocks

       # mid
       _lowerCAmelCase						:	Dict        =					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
       _lowerCAmelCase						:	Union[str, Any]        =					[]
       _lowerCAmelCase						:	Tuple        =					list(reversed(a__  )  )
       _lowerCAmelCase						:	Tuple        =					list(reversed(a__  )  )
       _lowerCAmelCase						:	List[Any]        =					list(reversed(a__  )  )
       _lowerCAmelCase						:	List[Any]        =					reversed_block_out_channels[0]
       for i, up_block_type in enumerate(self.up_block_types  ):
         _lowerCAmelCase						:	Tuple        =					output_channel
         _lowerCAmelCase						:	List[str]        =					reversed_block_out_channels[i]
         _lowerCAmelCase						:	Tuple        =					reversed_block_out_channels[min(i + 1    ,					len(a__  ) - 1  )]

         _lowerCAmelCase						:	List[str]        =					i == len(a__  ) - 1

         if up_block_type == "CrossAttnUpBlock2D":
           _lowerCAmelCase						:	List[Any]        =					FlaxCrossAttnUpBlockaD(
               in_channels=a__    ,					out_channels=a__    ,					prev_output_channel=a__    ,					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:
           _lowerCAmelCase						:	Optional[Any]        =					FlaxUpBlockaD(
               in_channels=a__    ,					out_channels=a__    ,					prev_output_channel=a__    ,					num_layers=self.layers_per_block + 1    ,					add_upsample=not is_final_block    ,					dropout=self.dropout    ,					dtype=self.dtype    ,					)

         up_blocks.append(a__  )
         _lowerCAmelCase						:	Tuple        =					output_channel
       _lowerCAmelCase						:	Union[str, Any]        =					up_blocks

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






     def __call__(		self    ,					a__    ,					a__    ,					a__    ,					a__=None    ,					a__=None    ,					a__ = True    ,					a__ = False    ,					):
       # 1. time
       if not isinstance(a__    ,					jnp.ndarray  ):
         _lowerCAmelCase						:	int        =					jnp.array([timesteps]    ,					dtype=jnp.intaa  )
       elif isinstance(a__    ,					jnp.ndarray  ) and len(timesteps.shape  ) == 0:
         _lowerCAmelCase						:	Tuple        =					timesteps.astype(dtype=jnp.floataa  )
         _lowerCAmelCase						:	Optional[Any]        =					jnp.expand_dims(a__    ,					0  )

       _lowerCAmelCase						:	List[Any]        =					self.time_proj(a__  )
       _lowerCAmelCase						:	Dict        =					self.time_embedding(a__  )

       # 2. pre-process
       _lowerCAmelCase						:	Union[str, Any]        =					jnp.transpose(a__    ,					(0, 2, 3, 1)  )
       _lowerCAmelCase						:	int        =					self.conv_in(a__  )

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

       if down_block_additional_residuals is not None:
         _lowerCAmelCase						:	int        =					()

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

         _lowerCAmelCase						:	str        =					new_down_block_res_samples

       # 4. mid
       _lowerCAmelCase						:	Union[str, Any]        =					self.mid_block(a__    ,					a__    ,					a__    ,					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:
         _lowerCAmelCase						:	str        =					down_block_res_samples[-(self.layers_per_block + 1) :]
         _lowerCAmelCase						:	Dict        =					down_block_res_samples[: -(self.layers_per_block + 1)]
         if isinstance(a__    ,					a__  ):
           _lowerCAmelCase						:	Optional[int]        =					up_block(
               a__    ,					temb=a__    ,					encoder_hidden_states=a__    ,					res_hidden_states_tuple=a__    ,					deterministic=not train    ,					)
         else:
           _lowerCAmelCase						:	Optional[int]        =					up_block(a__    ,					temb=a__    ,					res_hidden_states_tuple=a__    ,					deterministic=not train  )

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

       if not return_dict:
         return (sample,)

       return FlaxUNetaDConditionOutput(sample=a__  )





"""simple docstring"""




_a				:		Any	   =       '\n# Transformers installation\n! pip install transformers datasets\n# To install from source instead of the last release, comment the command above and uncomment the following one.\n# ! pip install git+https://github.com/huggingface/transformers.git\n'

_a				:		List[Any]	   =       [{'type': 'code', 'content': INSTALL_CONTENT}]
_a				:		Union[str, Any]	   =       {
    '{processor_class}': 'FakeProcessorClass',
    '{model_class}': 'FakeModelClass',
    '{object_class}': 'FakeObjectClass',
}




