"""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		(			__a      ):
      snake_case__     :  jnp.ndarray






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

      def 							A__			(		self						,			__lowerCAmelCase		):







            """simple docstring"""



            lowercase								=      (1, self.in_channels, self.sample_size, self.sample_size)
            lowercase								=      jnp.zeros(_lowerCamelCase						,			dtype=jnp.floataa		)
            lowercase								=      jnp.ones((1,)						,			dtype=jnp.intaa		)
            lowercase								=      jnp.zeros((1, 1, self.cross_attention_dim)						,			dtype=jnp.floataa		)

            lowercase				,				lowercase								=      jax.random.split(_lowerCamelCase		)
            lowercase								=      {"""params""": params_rng, """dropout""": dropout_rng}

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

      def 							A__			(		self		):







            """simple docstring"""



            lowercase								=      self.block_out_channels
            lowercase								=      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.
            lowercase								=      self.num_attention_heads or self.attention_head_dim

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

            # time
            lowercase								=      FlaxTimesteps(
                block_out_channels[0]						,			flip_sin_to_cos=self.flip_sin_to_cos						,			freq_shift=self.config.freq_shift		)
            lowercase								=      FlaxTimestepEmbedding(_lowerCamelCase						,			dtype=self.dtype		)

            lowercase								=      self.only_cross_attention
            if isinstance(_lowerCamelCase						,			_lowerCamelCase		):
                  lowercase								=      (only_cross_attention,) * len(self.down_block_types		)

            if isinstance(_lowerCamelCase						,			_lowerCamelCase		):
                  lowercase								=      (num_attention_heads,) * len(self.down_block_types		)

            # down
            lowercase								=      []
            lowercase								=      block_out_channels[0]
            for i, down_block_type in enumerate(self.down_block_types		):
                  lowercase								=      output_channel
                  lowercase								=      block_out_channels[i]
                  lowercase								=      i == len(_lowerCamelCase		) - 1

                  if down_block_type == "CrossAttnDownBlock2D":
                        lowercase								=      FlaxCrossAttnDownBlockaD(
                            in_channels=_lowerCamelCase						,			out_channels=_lowerCamelCase						,			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:
                        lowercase								=      FlaxDownBlockaD(
                            in_channels=_lowerCamelCase						,			out_channels=_lowerCamelCase						,			dropout=self.dropout						,			num_layers=self.layers_per_block						,			add_downsample=not is_final_block						,			dtype=self.dtype						,			)

                  down_blocks.append(_lowerCamelCase		)
            lowercase								=      down_blocks

            # mid
            lowercase								=      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
            lowercase								=      []
            lowercase								=      list(reversed(_lowerCamelCase		)		)
            lowercase								=      list(reversed(_lowerCamelCase		)		)
            lowercase								=      list(reversed(_lowerCamelCase		)		)
            lowercase								=      reversed_block_out_channels[0]
            for i, up_block_type in enumerate(self.up_block_types		):
                  lowercase								=      output_channel
                  lowercase								=      reversed_block_out_channels[i]
                  lowercase								=      reversed_block_out_channels[min(i + 1						,			len(_lowerCamelCase		) - 1		)]

                  lowercase								=      i == len(_lowerCamelCase		) - 1

                  if up_block_type == "CrossAttnUpBlock2D":
                        lowercase								=      FlaxCrossAttnUpBlockaD(
                            in_channels=_lowerCamelCase						,			out_channels=_lowerCamelCase						,			prev_output_channel=_lowerCamelCase						,			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:
                        lowercase								=      FlaxUpBlockaD(
                            in_channels=_lowerCamelCase						,			out_channels=_lowerCamelCase						,			prev_output_channel=_lowerCamelCase						,			num_layers=self.layers_per_block + 1						,			add_upsample=not is_final_block						,			dropout=self.dropout						,			dtype=self.dtype						,			)

                  up_blocks.append(_lowerCamelCase		)
                  lowercase								=      output_channel
            lowercase								=      up_blocks

            # out
            lowercase								=      nn.GroupNorm(num_groups=32						,			epsilon=1E-5		)
            lowercase								=      nn.Conv(
                self.out_channels						,			kernel_size=(3, 3)						,			strides=(1, 1)						,			padding=((1, 1), (1, 1))						,			dtype=self.dtype						,			)







      def __call__(		self						,			__lowerCAmelCase						,			__lowerCAmelCase						,			__lowerCAmelCase						,			__lowerCAmelCase=None						,			__lowerCAmelCase=None						,			__lowerCAmelCase = True						,			__lowerCAmelCase = False						,			):







            """simple docstring"""



            if not isinstance(_lowerCamelCase						,			jnp.ndarray		):
                  lowercase								=      jnp.array([timesteps]						,			dtype=jnp.intaa		)
            elif isinstance(_lowerCamelCase						,			jnp.ndarray		) and len(timesteps.shape		) == 0:
                  lowercase								=      timesteps.astype(dtype=jnp.floataa		)
                  lowercase								=      jnp.expand_dims(_lowerCamelCase						,			0		)

            lowercase								=      self.time_proj(_lowerCamelCase		)
            lowercase								=      self.time_embedding(_lowerCamelCase		)

            # 2. pre-process
            lowercase								=      jnp.transpose(_lowerCamelCase						,			(0, 2, 3, 1)		)
            lowercase								=      self.conv_in(_lowerCamelCase		)

            # 3. down
            lowercase								=      (sample,)
            for down_block in self.down_blocks:
                  if isinstance(_lowerCamelCase						,			_lowerCamelCase		):
                        lowercase				,				lowercase								=      down_block(_lowerCamelCase						,			_lowerCamelCase						,			_lowerCamelCase						,			deterministic=not train		)
                  else:
                        lowercase				,				lowercase								=      down_block(_lowerCamelCase						,			_lowerCamelCase						,			deterministic=not train		)
                  down_block_res_samples += res_samples

            if down_block_additional_residuals is not None:
                  lowercase								=      ()

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

                  lowercase								=      new_down_block_res_samples

            # 4. mid
            lowercase								=      self.mid_block(_lowerCamelCase						,			_lowerCamelCase						,			_lowerCamelCase						,			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:
                  lowercase								=      down_block_res_samples[-(self.layers_per_block + 1) :]
                  lowercase								=      down_block_res_samples[: -(self.layers_per_block + 1)]
                  if isinstance(_lowerCamelCase						,			_lowerCamelCase		):
                        lowercase								=      up_block(
                            _lowerCamelCase						,			temb=_lowerCamelCase						,			encoder_hidden_states=_lowerCamelCase						,			res_hidden_states_tuple=_lowerCamelCase						,			deterministic=not train						,			)
                  else:
                        lowercase								=      up_block(_lowerCamelCase						,			temb=_lowerCamelCase						,			res_hidden_states_tuple=_lowerCamelCase						,			deterministic=not train		)

        # 6. post-process
            lowercase								=      self.conv_norm_out(_lowerCamelCase		)
            lowercase								=      nn.silu(_lowerCamelCase		)
            lowercase								=      self.conv_out(_lowerCamelCase		)
            lowercase								=      jnp.transpose(_lowerCamelCase						,			(0, 3, 1, 2)		)

            if not return_dict:
                  return (sample,)

            return FlaxUNetaDConditionOutput(sample=_lowerCamelCase		)





"""simple docstring"""






def      lowerCAmelCase__			(		__magic_name__ = 1_0      )						->str:
			if not isinstance(__magic_name__			,   __magic_name__      ) or n < 0:
						raise ValueError("Invalid input"      )
			__lowercase       =       1_0**n
			__lowercase       =       2_8_4_3_3 * (pow(2			,   7_8_3_0_4_5_7			,   __magic_name__      )) + 1
			return str(number % modulus      )


if __name__ == "__main__":
					from doctest import testmod

					testmod()
					print(F"{solution(10) = }")





