


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_							(					lowerCAmelCase__					):



					'''simple docstring'''







					__UpperCAmelCase							  =					42
					__UpperCAmelCase							  =					42




class 						lowerCamelCase_							(					nn.Module					):



					'''simple docstring'''







					__UpperCAmelCase							  =					42
					__UpperCAmelCase							  =					(16, 32, 96, 256)
					__UpperCAmelCase							  =					jnp.floataa






					def A   (					self    ) ->      int:







								'''simple docstring'''

								__lowercase			       = nn.Conv(
								    self.block_out_channels[0]			,							kernel_size=(3, 3)			,							padding=((1, 1), (1, 1))			,							dtype=self.dtype			,							)

								__lowercase			       = []
								for i in range(len(self.block_out_channels    ) - 1    ):
											__lowercase			       = self.block_out_channels[i]
											__lowercase			       = self.block_out_channels[i + 1]
											__lowercase			       = nn.Conv(
											    snake_case_			,							kernel_size=(3, 3)			,							padding=((1, 1), (1, 1))			,							dtype=self.dtype			,							)
											blocks.append(snake_case_    )
											__lowercase			       = nn.Conv(
											    snake_case_			,							kernel_size=(3, 3)			,							strides=(2, 2)			,							padding=((1, 1), (1, 1))			,							dtype=self.dtype			,							)
											blocks.append(snake_case_    )
								__lowercase			       = blocks

								__lowercase			       = 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			,							snake_case_    ) ->      Tuple:







								'''simple docstring'''

								__lowercase			       = self.conv_in(snake_case_    )
								__lowercase			       = nn.silu(snake_case_    )

								for block in self.blocks:
											__lowercase			       = block(snake_case_    )
											__lowercase			       = nn.silu(snake_case_    )

								__lowercase			       = self.conv_out(snake_case_    )

								return embedding




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



					'''simple docstring'''







					__UpperCAmelCase							  =					32
					__UpperCAmelCase							  =					4
					__UpperCAmelCase							  =					(
					    "CrossAttnDownBlock2D",
					    "CrossAttnDownBlock2D",
					    "CrossAttnDownBlock2D",
					    "DownBlock2D",
					)
					__UpperCAmelCase							  =					False
					__UpperCAmelCase							  =					(320, 640, 1_280, 1_280)
					__UpperCAmelCase							  =					2
					__UpperCAmelCase							  =					8
					__UpperCAmelCase							  =					None
					__UpperCAmelCase							  =					1_280
					__UpperCAmelCase							  =					0.0
					__UpperCAmelCase							  =					False
					__UpperCAmelCase							  =					jnp.floataa
					__UpperCAmelCase							  =					True
					__UpperCAmelCase							  =					0
					__UpperCAmelCase							  =					"rgb"
					__UpperCAmelCase							  =					(16, 32, 96, 256)






					def A   (					self			,							snake_case_    ) ->      FrozenDict:







								'''simple docstring'''

								__lowercase			       = (1, self.in_channels, self.sample_size, self.sample_size)
								__lowercase			       = jnp.zeros(snake_case_			,							dtype=jnp.floataa    )
								__lowercase			       = jnp.ones((1,)			,							dtype=jnp.intaa    )
								__lowercase			       = jnp.zeros((1, 1, self.cross_attention_dim)			,							dtype=jnp.floataa    )
								__lowercase			       = (1, 3, self.sample_size * 8, self.sample_size * 8)
								__lowercase			       = jnp.zeros(snake_case_			,							dtype=jnp.floataa    )

								__lowercase       ,			__lowercase			       = jax.random.split(snake_case_    )
								__lowercase			       = {'''params''': params_rng, '''dropout''': dropout_rng}

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






					def A   (					self    ) ->      str:







								'''simple docstring'''

								__lowercase			       = self.block_out_channels
								__lowercase			       = 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.
								__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(snake_case_			,							dtype=self.dtype    )

								__lowercase			       = FlaxControlNetConditioningEmbedding(
								    conditioning_embedding_channels=block_out_channels[0]			,							block_out_channels=self.conditioning_embedding_out_channels			,							)

								__lowercase			       = self.only_cross_attention
								if isinstance(snake_case_			,							snake_case_    ):
											__lowercase			       = (only_cross_attention,) * len(self.down_block_types    )

								if isinstance(snake_case_			,							snake_case_    ):
											__lowercase			       = (num_attention_heads,) * len(self.down_block_types    )

								# down
								__lowercase			       = []
								__lowercase			       = []

								__lowercase			       = block_out_channels[0]

								__lowercase			       = nn.Conv(
								    snake_case_			,							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(snake_case_    )

								for i, down_block_type in enumerate(self.down_block_types    ):
											__lowercase			       = output_channel
											__lowercase			       = block_out_channels[i]
											__lowercase			       = i == len(snake_case_    ) - 1

											if down_block_type == "CrossAttnDownBlock2D":
														__lowercase			       = 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]			,							dtype=self.dtype			,							)
											else:
														__lowercase			       = 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_    )

											for _ in range(self.layers_per_block    ):
														__lowercase			       = nn.Conv(
														    snake_case_			,							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(snake_case_    )

											if not is_final_block:
														__lowercase			       = nn.Conv(
														    snake_case_			,							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(snake_case_    )

								__lowercase			       = down_blocks
								__lowercase			       = controlnet_down_blocks

								# mid
								__lowercase			       = block_out_channels[-1]
								__lowercase			       = FlaxUNetMidBlockaDCrossAttn(
								    in_channels=snake_case_			,							dropout=self.dropout			,							num_attention_heads=num_attention_heads[-1]			,							use_linear_projection=self.use_linear_projection			,							dtype=self.dtype			,							)

								__lowercase			       = nn.Conv(
								    snake_case_			,							kernel_size=(1, 1)			,							padding='''VALID'''			,							kernel_init=nn.initializers.zeros_init()			,							bias_init=nn.initializers.zeros_init()			,							dtype=self.dtype			,							)






					def __call__(					self			,							snake_case_			,							snake_case_			,							snake_case_			,							snake_case_			,							snake_case_ = 1.0			,							snake_case_ = True			,							snake_case_ = False			,							) ->      Union[FlaxControlNetOutput, Tuple]:







								'''simple docstring'''

								__lowercase			       = self.controlnet_conditioning_channel_order
								if channel_order == "bgr":
											__lowercase			       = jnp.flip(snake_case_			,							axis=1    )

								# 1. time
								if not isinstance(snake_case_			,							jnp.ndarray    ):
											__lowercase			       = jnp.array([timesteps]			,							dtype=jnp.intaa    )
								elif isinstance(snake_case_			,							jnp.ndarray    ) and len(timesteps.shape    ) == 0:
											__lowercase			       = timesteps.astype(dtype=jnp.floataa    )
											__lowercase			       = jnp.expand_dims(snake_case_			,							0    )

								__lowercase			       = self.time_proj(snake_case_    )
								__lowercase			       = self.time_embedding(snake_case_    )

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

								__lowercase			       = jnp.transpose(snake_case_			,							(0, 2, 3, 1)    )
								__lowercase			       = self.controlnet_cond_embedding(snake_case_    )
								sample += controlnet_cond

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

								# 4. mid
								__lowercase			       = self.mid_block(snake_case_			,							snake_case_			,							snake_case_			,							deterministic=not train    )

								# 5. contronet blocks
								__lowercase			       = ()
								for down_block_res_sample, controlnet_block in zip(snake_case_			,							self.controlnet_down_blocks    ):
											__lowercase			       = controlnet_block(snake_case_    )
											controlnet_down_block_res_samples += (down_block_res_sample,)

								__lowercase			       = controlnet_down_block_res_samples

								__lowercase			       = self.controlnet_mid_block(snake_case_    )

								# 6. scaling
								__lowercase			       = [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=snake_case_			,							mid_block_res_sample=snake_case_    )






from maths.prime_factors import prime_factors


def 		lowercase_	(  _UpperCamelCase	):


			'''simple docstring'''







			if not isinstance(_UpperCamelCase							,      _UpperCamelCase	):
						__lowercase			       = F'Input value of [number={number}] must be an integer'
						raise TypeError(_UpperCamelCase	)
			if number < 1:
						raise ValueError('''Input must be a positive integer'''	)
			return -1 if len(prime_factors(_UpperCamelCase	)	) % 2 else 1


if __name__ == "__main__":
	import doctest

	doctest.testmod()


