

'''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 					lowercase						(  a_ ):
							_lowerCamelCase		:      jnp.ndarray



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


							def 						_snake_case							(			self    ,			_snake_case)							->				FrozenDict:
								# init input tensors
								UpperCAmelCase_		:      Dict       	=					(1, self.in_channels, self.sample_size, self.sample_size)
								UpperCAmelCase_		:      str       	=					jnp.zeros(_snake_case    ,			dtype=jnp.floataa)
								UpperCAmelCase_		:      int       	=					jnp.ones((1,)    ,			dtype=jnp.intaa)
								UpperCAmelCase_		:      List[Any]       	=					jnp.zeros((1, 1, self.cross_attention_dim)    ,			dtype=jnp.floataa)

								UpperCAmelCase_	,    UpperCAmelCase_		:      Dict       	=					jax.random.split(_snake_case)
								UpperCAmelCase_		:      List[str]       	=					{'params': params_rng, 'dropout': dropout_rng}

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


							def 						_snake_case							(			self)							->				Any:
								UpperCAmelCase_		:      Tuple       	=					self.block_out_channels
								UpperCAmelCase_		:      Dict       	=					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.
								UpperCAmelCase_		:      Any       	=					self.num_attention_heads or self.attention_head_dim

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

								# time
								UpperCAmelCase_		:      List[Any]       	=					FlaxTimesteps(
								    block_out_channels[0]    ,			flip_sin_to_cos=self.flip_sin_to_cos    ,			freq_shift=self.config.freq_shift)
								UpperCAmelCase_		:      List[str]       	=					FlaxTimestepEmbedding(_snake_case    ,			dtype=self.dtype)

								UpperCAmelCase_		:      Optional[int]       	=					self.only_cross_attention
								if isinstance(_snake_case    ,			_snake_case):
									UpperCAmelCase_		:      List[Any]       	=					(only_cross_attention,) * len(self.down_block_types)

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

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

									if down_block_type == "CrossAttnDownBlock2D":
										UpperCAmelCase_		:      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:
										UpperCAmelCase_		:      int       	=					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)
								UpperCAmelCase_		:      List[Any]       	=					down_blocks

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

									UpperCAmelCase_		:      str       	=					i == len(_snake_case) - 1

									if up_block_type == "CrossAttnUpBlock2D":
										UpperCAmelCase_		:      Dict       	=					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:
										UpperCAmelCase_		:      Optional[Any]       	=					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)
									UpperCAmelCase_		:      List[Any]       	=					output_channel
								UpperCAmelCase_		:      Any       	=					up_blocks

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





							def __call__(			self    ,			_snake_case    ,			_snake_case    ,			_snake_case    ,			_snake_case=None    ,			_snake_case=None    ,			_snake_case = True    ,			_snake_case = False    ,			)							->				Union[FlaxUNetaDConditionOutput, Tuple]:
								# 1. time
								if not isinstance(_snake_case    ,			jnp.ndarray):
									UpperCAmelCase_		:      Optional[Any]       	=					jnp.array([timesteps]    ,			dtype=jnp.intaa)
								elif isinstance(_snake_case    ,			jnp.ndarray) and len(timesteps.shape) == 0:
									UpperCAmelCase_		:      Dict       	=					timesteps.astype(dtype=jnp.floataa)
									UpperCAmelCase_		:      List[str]       	=					jnp.expand_dims(_snake_case    ,			0)

								UpperCAmelCase_		:      str       	=					self.time_proj(_snake_case)
								UpperCAmelCase_		:      List[str]       	=					self.time_embedding(_snake_case)

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

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

								if down_block_additional_residuals is not None:
									UpperCAmelCase_		:      Optional[int]       	=					()

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

									UpperCAmelCase_		:      Union[str, Any]       	=					new_down_block_res_samples

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

        # 6. post-process
								UpperCAmelCase_		:      List[Any]       	=					self.conv_norm_out(_snake_case)
								UpperCAmelCase_		:      int       	=					nn.silu(_snake_case)
								UpperCAmelCase_		:      Any       	=					self.conv_out(_snake_case)
								UpperCAmelCase_		:      Tuple       	=					jnp.transpose(_snake_case    ,			(0, 3, 1, 2))

								if not return_dict:
									return (sample,)

								return FlaxUNetaDConditionOutput(sample=_snake_case)









'''simple docstring'''


class 					lowercase						:


							def __init__(			self)							->				Dict:
								UpperCAmelCase_		:      List[str]       	=					0
								UpperCAmelCase_		:      str       	=					0
								UpperCAmelCase_		:      Union[str, Any]       	=					{}


							def 						_snake_case							(			self    ,			_snake_case)							->				Tuple:
								if vertex not in self.adjacency:
									UpperCAmelCase_		:      Tuple       	=					{}
									self.num_vertices += 1


							def 						_snake_case							(			self    ,			_snake_case    ,			_snake_case    ,			_snake_case)							->				Any:
								self.add_vertex(_snake_case)
								self.add_vertex(_snake_case)

								if head == tail:
									return

								UpperCAmelCase_		:      str       	=					weight
								UpperCAmelCase_		:      Optional[int]       	=					weight


							def 						_snake_case							(			self)							->				Union[str, Any]:
								UpperCAmelCase_		:      Dict       	=					self.get_edges()
								for edge in edges:
									UpperCAmelCase_	,    UpperCAmelCase_	,    UpperCAmelCase_		:      str       	=					edge
									edges.remove((tail, head, weight))
								for i in range(len(_snake_case)):
									UpperCAmelCase_		:      Union[str, Any]       	=					list(edges[i])

								edges.sort(key=lambda _snake_case: e[2])
								for i in range(len(_snake_case) - 1):
									if edges[i][2] >= edges[i + 1][2]:
										UpperCAmelCase_		:      Tuple       	=					edges[i][2] + 1
								for edge in edges:
									UpperCAmelCase_	,    UpperCAmelCase_	,    UpperCAmelCase_		:      List[Any]       	=					edge
									UpperCAmelCase_		:      Any       	=					weight
									UpperCAmelCase_		:      Union[str, Any]       	=					weight


							def __str__(			self)							->				str:
								UpperCAmelCase_		:      int       	=					''
								for tail in self.adjacency:
									for head in self.adjacency[tail]:
										UpperCAmelCase_		:      Dict       	=					self.adjacency[head][tail]
										string += F"""{head} -> {tail} == {weight}\n"""
								return string.rstrip('\n')


							def 						_snake_case							(			self)							->				str:
								UpperCAmelCase_		:      Optional[int]       	=					[]
								for tail in self.adjacency:
									for head in self.adjacency[tail]:
										output.append((tail, head, self.adjacency[head][tail]))
								return output


							def 						_snake_case							(			self)							->				Any:
								return self.adjacency.keys()


							@staticmethod
							def 						_snake_case							(			_snake_case=None    ,			_snake_case=None)							->				Dict:
								UpperCAmelCase_		:      List[str]       	=					Graph()
								if vertices is None:
									UpperCAmelCase_		:      Optional[Any]       	=					[]
								if edges is None:
									UpperCAmelCase_		:      int       	=					[]
								for vertex in vertices:
									g.add_vertex(_snake_case)
								for edge in edges:
									g.add_edge(*_snake_case)
								return g



							class 					lowercase						:


														def __init__(			self)							->				Dict:
															UpperCAmelCase_		:      Tuple       	=					{}
															UpperCAmelCase_		:      str       	=					{}


														def __len__(			self)							->				List[Any]:
															return len(self.parent)


														def 						_snake_case							(			self    ,			_snake_case)							->				Union[str, Any]:
															if item in self.parent:
																return self.find(_snake_case)

															UpperCAmelCase_		:      Any       	=					item
															UpperCAmelCase_		:      List[str]       	=					0
															return item


														def 						_snake_case							(			self    ,			_snake_case)							->				str:
															if item not in self.parent:
																return self.make_set(_snake_case)
															if item != self.parent[item]:
																UpperCAmelCase_		:      Dict       	=					self.find(self.parent[item])
															return self.parent[item]





														def 						_snake_case							(			self    ,			_snake_case    ,			_snake_case)							->				int:
															UpperCAmelCase_		:      List[str]       	=					self.find(_snake_case)
															UpperCAmelCase_		:      List[str]       	=					self.find(_snake_case)

															if roota == roota:
																return roota

															if self.rank[roota] > self.rank[roota]:
																UpperCAmelCase_		:      int       	=					roota
																return roota

															if self.rank[roota] < self.rank[roota]:
																UpperCAmelCase_		:      Dict       	=					roota
																return roota

															if self.rank[roota] == self.rank[roota]:
																self.rank[roota] += 1
																UpperCAmelCase_		:      Any       	=					roota
																return roota
															return None


							@staticmethod
							def 						_snake_case							(			_snake_case)							->				int:
								UpperCAmelCase_		:      Optional[Any]       	=					graph.num_vertices

								UpperCAmelCase_		:      Optional[int]       	=					Graph.UnionFind()
								UpperCAmelCase_		:      int       	=					[]
								while num_components > 1:
									UpperCAmelCase_		:      Any       	=					{}
									for vertex in graph.get_vertices():
										UpperCAmelCase_		:      Optional[Any]       	=					-1

									UpperCAmelCase_		:      List[str]       	=					graph.get_edges()
									for edge in edges:
										UpperCAmelCase_	,    UpperCAmelCase_	,    UpperCAmelCase_		:      List[str]       	=					edge
										edges.remove((tail, head, weight))
									for edge in edges:
										UpperCAmelCase_	,    UpperCAmelCase_	,    UpperCAmelCase_		:      Union[str, Any]       	=					edge
										UpperCAmelCase_		:      Any       	=					union_find.find(_snake_case)
										UpperCAmelCase_		:      Dict       	=					union_find.find(_snake_case)
										if seta != seta:
											if cheap_edge[seta] == -1 or cheap_edge[seta][2] > weight:
												UpperCAmelCase_		:      List[str]       	=					[head, tail, weight]

											if cheap_edge[seta] == -1 or cheap_edge[seta][2] > weight:
												UpperCAmelCase_		:      str       	=					[head, tail, weight]
									for vertex in cheap_edge:
										if cheap_edge[vertex] != -1:
											UpperCAmelCase_	,    UpperCAmelCase_	,    UpperCAmelCase_		:      Any       	=					cheap_edge[vertex]
											if union_find.find(_snake_case) != union_find.find(_snake_case):
												union_find.union(_snake_case    ,			_snake_case)
												mst_edges.append(cheap_edge[vertex])
												UpperCAmelCase_		:      Tuple       	=					num_components - 1
								UpperCAmelCase_		:      int       	=					Graph.build(edges=_snake_case)
								return mst






