





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,
    FlaxDownBlockaD,
    FlaxUNetMidBlockaDCrossAttn,
)





@flax.struct.dataclass
class 			lowerCAmelCase__( __lowercase    ):






       '''simple docstring'''


       __snake_case 			=    42
       __snake_case 			=    42





class 			lowerCAmelCase__( nn.Module    ):






       '''simple docstring'''


       __snake_case 			=    42
       __snake_case 			=    (1_6, 3_2, 9_6, 2_5_6)
       __snake_case 			=    jnp.floataa




       def     UpperCamelCase_			(      self							)			->     Any:
            _SCREAMING_SNAKE_CASE       :	List[str]						    =							nn.Conv(
                self.block_out_channels[0]    ,						kernel_size=(3, 3)    ,						padding=((1, 1), (1, 1))    ,						dtype=self.dtype    ,						)

            _SCREAMING_SNAKE_CASE       :	Union[str, Any]						    =							[]
            for i in range(len(self.block_out_channels							) - 1							):
                 _SCREAMING_SNAKE_CASE       :	Any						    =							self.block_out_channels[i]
                 _SCREAMING_SNAKE_CASE       :	List[Any]						    =							self.block_out_channels[i + 1]
                 _SCREAMING_SNAKE_CASE       :	Any						    =							nn.Conv(
                     UpperCAmelCase__    ,						kernel_size=(3, 3)    ,						padding=((1, 1), (1, 1))    ,						dtype=self.dtype    ,						)
                 blocks.append(UpperCAmelCase__							)
                 _SCREAMING_SNAKE_CASE       :	Optional[Any]						    =							nn.Conv(
                     UpperCAmelCase__    ,						kernel_size=(3, 3)    ,						strides=(2, 2)    ,						padding=((1, 1), (1, 1))    ,						dtype=self.dtype    ,						)
                 blocks.append(UpperCAmelCase__							)
            _SCREAMING_SNAKE_CASE       :	Union[str, Any]						    =							blocks

            _SCREAMING_SNAKE_CASE       :	Any						    =							nn.Conv(
                self.conditioning_embedding_channels    ,						kernel_size=(3, 3)    ,						padding=((1, 1), (1, 1))    ,						kernel_init=nn.initializers.zeros_init()    ,						bias_init=nn.initializers.zeros_init()    ,						dtype=self.dtype    ,						)







       def __call__(      self    ,						__lowerCamelCase							)			->     List[str]:
            _SCREAMING_SNAKE_CASE       :	Optional[int]						    =							self.conv_in(UpperCAmelCase__							)
            _SCREAMING_SNAKE_CASE       :	Dict						    =							nn.silu(UpperCAmelCase__							)

            for block in self.blocks:
                 _SCREAMING_SNAKE_CASE       :	Any						    =							block(UpperCAmelCase__							)
                 _SCREAMING_SNAKE_CASE       :	Dict						    =							nn.silu(UpperCAmelCase__							)

            _SCREAMING_SNAKE_CASE       :	List[str]						    =							self.conv_out(UpperCAmelCase__							)

            return embedding





@flax_register_to_config
class 			lowerCAmelCase__( nn.Module  ,     __lowercase  ,     __lowercase    ):






       '''simple docstring'''


       __snake_case 			=    3_2
       __snake_case 			=    4
       __snake_case 			=    (
           "CrossAttnDownBlock2D",
           "CrossAttnDownBlock2D",
           "CrossAttnDownBlock2D",
           "DownBlock2D",
       )
       __snake_case 			=    False
       __snake_case 			=    (3_2_0, 6_4_0, 1_2_8_0, 1_2_8_0)
       __snake_case 			=    2
       __snake_case 			=    8
       __snake_case 			=    None
       __snake_case 			=    1_2_8_0
       __snake_case 			=    0.0
       __snake_case 			=    False
       __snake_case 			=    jnp.floataa
       __snake_case 			=    True
       __snake_case 			=    0
       __snake_case 			=    "rgb"
       __snake_case 			=    (1_6, 3_2, 9_6, 2_5_6)




       def     UpperCamelCase_			(      self    ,						__lowerCamelCase							)			->     Tuple:
            _SCREAMING_SNAKE_CASE       :	Optional[Any]						    =							(1, self.in_channels, self.sample_size, self.sample_size)
            _SCREAMING_SNAKE_CASE       :	List[str]						    =							jnp.zeros(UpperCAmelCase__    ,						dtype=jnp.floataa							)
            _SCREAMING_SNAKE_CASE       :	Tuple						    =							jnp.ones((1,)    ,						dtype=jnp.intaa							)
            _SCREAMING_SNAKE_CASE       :	Union[str, Any]						    =							jnp.zeros((1, 1, self.cross_attention_dim)    ,						dtype=jnp.floataa							)
            _SCREAMING_SNAKE_CASE       :	Any						    =							(1, 3, self.sample_size * 8, self.sample_size * 8)
            _SCREAMING_SNAKE_CASE       :	Tuple						    =							jnp.zeros(UpperCAmelCase__    ,						dtype=jnp.floataa							)

            _SCREAMING_SNAKE_CASE       :	Union[str, Any]						    =							jax.random.split(UpperCAmelCase__							)
            _SCREAMING_SNAKE_CASE       :	Any						    =							{'''params''': params_rng, '''dropout''': dropout_rng}

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




       def     UpperCamelCase_			(      self							)			->     Tuple:
            _SCREAMING_SNAKE_CASE       :	Optional[Any]						    =							self.block_out_channels
            _SCREAMING_SNAKE_CASE       :	int						    =							block_out_channels[0] * 4

            # 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.
            _SCREAMING_SNAKE_CASE       :	int						    =							self.num_attention_heads or self.attention_head_dim

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

            # time
            _SCREAMING_SNAKE_CASE       :	Dict						    =							FlaxTimesteps(
                block_out_channels[0]    ,						flip_sin_to_cos=self.flip_sin_to_cos    ,						freq_shift=self.config.freq_shift							)
            _SCREAMING_SNAKE_CASE       :	int						    =							FlaxTimestepEmbedding(UpperCAmelCase__    ,						dtype=self.dtype							)

            _SCREAMING_SNAKE_CASE       :	List[Any]						    =							FlaxControlNetConditioningEmbedding(
                conditioning_embedding_channels=block_out_channels[0]    ,						block_out_channels=self.conditioning_embedding_out_channels    ,						)

            _SCREAMING_SNAKE_CASE       :	Any						    =							self.only_cross_attention
            if isinstance(UpperCAmelCase__    ,						UpperCAmelCase__							):
                 _SCREAMING_SNAKE_CASE       :	Union[str, Any]						    =							(only_cross_attention,) * len(self.down_block_types							)

            if isinstance(UpperCAmelCase__    ,						UpperCAmelCase__							):
                 _SCREAMING_SNAKE_CASE       :	Optional[int]						    =							(num_attention_heads,) * len(self.down_block_types							)

            # down
            _SCREAMING_SNAKE_CASE       :	Any						    =							[]
            _SCREAMING_SNAKE_CASE       :	List[str]						    =							[]

            _SCREAMING_SNAKE_CASE       :	Any						    =							block_out_channels[0]

            _SCREAMING_SNAKE_CASE       :	int						    =							nn.Conv(
                UpperCAmelCase__    ,						kernel_size=(1, 1)    ,						padding="VALID"    ,						kernel_init=nn.initializers.zeros_init()    ,						bias_init=nn.initializers.zeros_init()    ,						dtype=self.dtype    ,						)
            controlnet_down_blocks.append(UpperCAmelCase__							)

            for i, down_block_type in enumerate(self.down_block_types							):
                 _SCREAMING_SNAKE_CASE       :	Union[str, Any]						    =							output_channel
                 _SCREAMING_SNAKE_CASE       :	Any						    =							block_out_channels[i]
                 _SCREAMING_SNAKE_CASE       :	Dict						    =							i == len(UpperCAmelCase__							) - 1

                 if down_block_type == "CrossAttnDownBlock2D":
                      _SCREAMING_SNAKE_CASE       :	Tuple						    =							FlaxCrossAttnDownBlockaD(
                          in_channels=UpperCAmelCase__    ,						out_channels=UpperCAmelCase__    ,						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]    ,						dtype=self.dtype    ,						)
                 else:
                      _SCREAMING_SNAKE_CASE       :	int						    =							FlaxDownBlockaD(
                          in_channels=UpperCAmelCase__    ,						out_channels=UpperCAmelCase__    ,						dropout=self.dropout    ,						num_layers=self.layers_per_block    ,						add_downsample=not is_final_block    ,						dtype=self.dtype    ,						)

                 down_blocks.append(UpperCAmelCase__							)

                 for _ in range(self.layers_per_block							):
                      _SCREAMING_SNAKE_CASE       :	Dict						    =							nn.Conv(
                          UpperCAmelCase__    ,						kernel_size=(1, 1)    ,						padding="VALID"    ,						kernel_init=nn.initializers.zeros_init()    ,						bias_init=nn.initializers.zeros_init()    ,						dtype=self.dtype    ,						)
                      controlnet_down_blocks.append(UpperCAmelCase__							)

                 if not is_final_block:
                      _SCREAMING_SNAKE_CASE       :	Optional[int]						    =							nn.Conv(
                          UpperCAmelCase__    ,						kernel_size=(1, 1)    ,						padding="VALID"    ,						kernel_init=nn.initializers.zeros_init()    ,						bias_init=nn.initializers.zeros_init()    ,						dtype=self.dtype    ,						)
                      controlnet_down_blocks.append(UpperCAmelCase__							)

            _SCREAMING_SNAKE_CASE       :	str						    =							down_blocks
            _SCREAMING_SNAKE_CASE       :	List[str]						    =							controlnet_down_blocks

            # mid
            _SCREAMING_SNAKE_CASE       :	str						    =							block_out_channels[-1]
            _SCREAMING_SNAKE_CASE       :	str						    =							FlaxUNetMidBlockaDCrossAttn(
                in_channels=UpperCAmelCase__    ,						dropout=self.dropout    ,						num_attention_heads=num_attention_heads[-1]    ,						use_linear_projection=self.use_linear_projection    ,						dtype=self.dtype    ,						)

            _SCREAMING_SNAKE_CASE       :	Tuple						    =							nn.Conv(
                UpperCAmelCase__    ,						kernel_size=(1, 1)    ,						padding="VALID"    ,						kernel_init=nn.initializers.zeros_init()    ,						bias_init=nn.initializers.zeros_init()    ,						dtype=self.dtype    ,						)







       def __call__(      self    ,						__lowerCamelCase    ,						__lowerCamelCase    ,						__lowerCamelCase    ,						__lowerCamelCase    ,						__lowerCamelCase = 1.0    ,						__lowerCamelCase = True    ,						__lowerCamelCase = False    ,						)			->     int:
            _SCREAMING_SNAKE_CASE       :	Tuple						    =							self.controlnet_conditioning_channel_order
            if channel_order == "bgr":
                 _SCREAMING_SNAKE_CASE       :	Dict						    =							jnp.flip(UpperCAmelCase__    ,						axis=1							)

            # 1. time
            if not isinstance(UpperCAmelCase__    ,						jnp.ndarray							):
                 _SCREAMING_SNAKE_CASE       :	Optional[int]						    =							jnp.array([timesteps]    ,						dtype=jnp.intaa							)
            elif isinstance(UpperCAmelCase__    ,						jnp.ndarray							) and len(timesteps.shape							) == 0:
                 _SCREAMING_SNAKE_CASE       :	Union[str, Any]						    =							timesteps.astype(dtype=jnp.floataa							)
                 _SCREAMING_SNAKE_CASE       :	List[Any]						    =							jnp.expand_dims(UpperCAmelCase__    ,						0							)

            _SCREAMING_SNAKE_CASE       :	Optional[Any]						    =							self.time_proj(UpperCAmelCase__							)
            _SCREAMING_SNAKE_CASE       :	Union[str, Any]						    =							self.time_embedding(UpperCAmelCase__							)

            # 2. pre-process
            _SCREAMING_SNAKE_CASE       :	Union[str, Any]						    =							jnp.transpose(UpperCAmelCase__    ,						(0, 2, 3, 1)							)
            _SCREAMING_SNAKE_CASE       :	Optional[Any]						    =							self.conv_in(UpperCAmelCase__							)

            _SCREAMING_SNAKE_CASE       :	List[Any]						    =							jnp.transpose(UpperCAmelCase__    ,						(0, 2, 3, 1)							)
            _SCREAMING_SNAKE_CASE       :	Optional[int]						    =							self.controlnet_cond_embedding(UpperCAmelCase__							)
            sample += controlnet_cond

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

            # 4. mid
            _SCREAMING_SNAKE_CASE       :	Dict						    =							self.mid_block(UpperCAmelCase__    ,						UpperCAmelCase__    ,						UpperCAmelCase__    ,						deterministic=not train							)

            # 5. contronet blocks
            _SCREAMING_SNAKE_CASE       :	List[str]						    =							()
            for down_block_res_sample, controlnet_block in zip(UpperCAmelCase__    ,						self.controlnet_down_blocks							):
                 _SCREAMING_SNAKE_CASE       :	Union[str, Any]						    =							controlnet_block(UpperCAmelCase__							)
                 controlnet_down_block_res_samples += (down_block_res_sample,)

            _SCREAMING_SNAKE_CASE       :	Optional[Any]						    =							controlnet_down_block_res_samples

            _SCREAMING_SNAKE_CASE       :	Dict						    =							self.controlnet_mid_block(UpperCAmelCase__							)

            # 6. scaling
            _SCREAMING_SNAKE_CASE       :	Tuple						    =							[sample * conditioning_scale for sample in down_block_res_samples]
            mid_block_res_sample *= conditioning_scale

            if not return_dict:
                 return (down_block_res_samples, mid_block_res_sample)

            return FlaxControlNetOutput(
                down_block_res_samples=UpperCAmelCase__    ,						mid_block_res_sample=UpperCAmelCase__							)






from PIL import Image






def     lowerCamelCase__			(__lowerCamelCase	):
     _SCREAMING_SNAKE_CASE    ,			_SCREAMING_SNAKE_CASE       :	List[str]						    =							image.size
     _SCREAMING_SNAKE_CASE       :	Tuple						    =							0
     _SCREAMING_SNAKE_CASE       :	Dict						    =							image.load()
     for i in range(__lowerCamelCase	):
          for j in range(__lowerCamelCase	):
               _SCREAMING_SNAKE_CASE       :	List[Any]						    =							pixels[j, i]
               mean += pixel
     mean //= width * height

     for j in range(__lowerCamelCase	):
          for i in range(__lowerCamelCase	):
               _SCREAMING_SNAKE_CASE       :	int						    =							255 if pixels[i, j] > mean else 0
     return image


if __name__ == "__main__":
       UpperCamelCase__      =mean_threshold(Image.open('path_to_image').convert('L'))
       image.save('output_image_path')