






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     _a							(	UpperCAmelCase__     ):






  """simple docstring"""





  A_						       = 42
  A_						       = 42




class     _a							(	nn.Module     ):






  """simple docstring"""





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




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

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

     UpperCamelCase_						=  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		,		_UpperCAmelCase			)      ->			Any:
     UpperCamelCase_						=  self.conv_in(_UpperCAmelCase			)
     UpperCamelCase_						=  nn.silu(_UpperCAmelCase			)

     for block in self.blocks:
        UpperCamelCase_						=  block(_UpperCAmelCase			)
        UpperCamelCase_						=  nn.silu(_UpperCAmelCase			)

     UpperCamelCase_						=  self.conv_out(_UpperCAmelCase			)

     return embedding




@flax_register_to_config
class     _a							(	nn.Module    ,							UpperCAmelCase__    ,							UpperCAmelCase__     ):






  """simple docstring"""





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




  def  _UpperCAmelCase  (  self		,		_UpperCAmelCase			)      ->			FrozenDict:
     # init input tensors
     UpperCamelCase_						=  (1, self.in_channels, self.sample_size, self.sample_size)
     UpperCamelCase_						=  jnp.zeros(_UpperCAmelCase		,		dtype=jnp.floataa			)
     UpperCamelCase_						=  jnp.ones((1,)		,		dtype=jnp.intaa			)
     UpperCamelCase_						=  jnp.zeros((1, 1, self.cross_attention_dim)		,		dtype=jnp.floataa			)
     UpperCamelCase_						=  (1, 3, self.sample_size * 8, self.sample_size * 8)
     UpperCamelCase_						=  jnp.zeros(_UpperCAmelCase		,		dtype=jnp.floataa			)

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

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




  def  _UpperCAmelCase  (  self			)      ->			List[str]:
     UpperCamelCase_						=  self.block_out_channels
     UpperCamelCase_						=  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.
     UpperCamelCase_						=  self.num_attention_heads or self.attention_head_dim

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

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

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

     UpperCamelCase_						=  self.only_cross_attention
     if isinstance(_UpperCAmelCase		,		_UpperCAmelCase			):
        UpperCamelCase_						=  (only_cross_attention,) * len(self.down_block_types			)

     if isinstance(_UpperCAmelCase		,		_UpperCAmelCase			):
        UpperCamelCase_						=  (num_attention_heads,) * len(self.down_block_types			)

     # down
     UpperCamelCase_						=  []
     UpperCamelCase_						=  []

     UpperCamelCase_						=  block_out_channels[0]

     UpperCamelCase_						=  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			):
        UpperCamelCase_						=  output_channel
        UpperCamelCase_						=  block_out_channels[i]
        UpperCamelCase_						=  i == len(_UpperCAmelCase			) - 1

        if down_block_type == "CrossAttnDownBlock2D":
           UpperCamelCase_						=  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:
           UpperCamelCase_						=  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			):
           UpperCamelCase_						=  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:
           UpperCamelCase_						=  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			)

     UpperCamelCase_						=  down_blocks
     UpperCamelCase_						=  controlnet_down_blocks

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

     UpperCamelCase_						=  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		,		_UpperCAmelCase		,		_UpperCAmelCase		,		_UpperCAmelCase		,		_UpperCAmelCase		,		_UpperCAmelCase = 1.0		,		_UpperCAmelCase = True		,		_UpperCAmelCase = False		,		)      ->			Union[FlaxControlNetOutput, Tuple]:
     UpperCamelCase_						=  self.controlnet_conditioning_channel_order
     if channel_order == "bgr":
        UpperCamelCase_						=  jnp.flip(_UpperCAmelCase		,		axis=1			)

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

     UpperCamelCase_						=  self.time_proj(_UpperCAmelCase			)
     UpperCamelCase_						=  self.time_embedding(_UpperCAmelCase			)

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

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

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

     # 4. mid
     UpperCamelCase_						=  self.mid_block(_UpperCAmelCase		,		_UpperCAmelCase		,		_UpperCAmelCase		,		deterministic=not train			)

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

     UpperCamelCase_						=  controlnet_down_block_res_samples

     UpperCamelCase_						=  self.controlnet_mid_block(_UpperCAmelCase			)

     # 6. scaling
     UpperCamelCase_						=  [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 __future__ import annotations

from sys import maxsize
from typing import Generic, TypeVar

snake_case__   :						List[str]													=   TypeVar("""T""")






def      _snake_case     (__lowercase):
   return (position - 1) // 2






def      _snake_case     (__lowercase):
   return (2 * position) + 1






def      _snake_case     (__lowercase):
   return (2 * position) + 2


class     _a							(	Generic[T]     ):






  """simple docstring"""





  def __init__(  self			)      ->			None:
     UpperCamelCase_						=  []
     UpperCamelCase_						=  {}
     UpperCamelCase_						=  0




  def __len__(  self			)      ->			int:
     return self.elements




  def __repr__(  self			)      ->			str:
     return str(self.heap			)




  def  _UpperCAmelCase  (  self			)      ->			bool:
     # Check if the priority queue is empty
     return self.elements == 0




  def  _UpperCAmelCase  (  self		,		_UpperCAmelCase		,		_UpperCAmelCase			)      ->			None:
     # Add an element with given priority to the queue
     self.heap.append((elem, weight)			)
     UpperCamelCase_						=  self.elements
     self.elements += 1
     self._bubble_up(_UpperCAmelCase			)




  def  _UpperCAmelCase  (  self			)      ->			T:
     # Remove and return the element with lowest weight (highest priority)
     if self.elements > 1:
        self._swap_nodes(0		,		self.elements - 1			)
     UpperCamelCase_		,   UpperCamelCase_						=  self.heap.pop()
     del self.position_map[elem]
     self.elements -= 1
     if self.elements > 0:
        UpperCamelCase_		,   UpperCamelCase_						=  self.heap[0]
        self._bubble_down(_UpperCAmelCase			)
     return elem




  def  _UpperCAmelCase  (  self		,		_UpperCAmelCase		,		_UpperCAmelCase			)      ->			None:
     # Update the weight of the given key
     UpperCamelCase_						=  self.position_map[elem]
     UpperCamelCase_						=  (elem, weight)
     if position > 0:
        UpperCamelCase_						=  get_parent_position(_UpperCAmelCase			)
        UpperCamelCase_		,   UpperCamelCase_						=  self.heap[parent_position]
        if parent_weight > weight:
           self._bubble_up(_UpperCAmelCase			)
        else:
           self._bubble_down(_UpperCAmelCase			)
     else:
        self._bubble_down(_UpperCAmelCase			)




  def  _UpperCAmelCase  (  self		,		_UpperCAmelCase			)      ->			None:
     # Place a node at the proper position (upward movement) [to be used internally
     # only]
     UpperCamelCase_						=  self.position_map[elem]
     if curr_pos == 0:
        return None
     UpperCamelCase_						=  get_parent_position(_UpperCAmelCase			)
     UpperCamelCase_		,   UpperCamelCase_						=  self.heap[curr_pos]
     UpperCamelCase_		,   UpperCamelCase_						=  self.heap[parent_position]
     if parent_weight > weight:
        self._swap_nodes(_UpperCAmelCase		,		_UpperCAmelCase			)
        return self._bubble_up(_UpperCAmelCase			)
     return None




  def  _UpperCAmelCase  (  self		,		_UpperCAmelCase			)      ->			None:
     # Place a node at the proper position (downward movement) [to be used
     # internally only]
     UpperCamelCase_						=  self.position_map[elem]
     UpperCamelCase_		,   UpperCamelCase_						=  self.heap[curr_pos]
     UpperCamelCase_						=  get_child_left_position(_UpperCAmelCase			)
     UpperCamelCase_						=  get_child_right_position(_UpperCAmelCase			)
     if child_left_position < self.elements and child_right_position < self.elements:
        UpperCamelCase_		,   UpperCamelCase_						=  self.heap[child_left_position]
        UpperCamelCase_		,   UpperCamelCase_						=  self.heap[child_right_position]
        if child_right_weight < child_left_weight and child_right_weight < weight:
           self._swap_nodes(_UpperCAmelCase		,		_UpperCAmelCase			)
           return self._bubble_down(_UpperCAmelCase			)
     if child_left_position < self.elements:
        UpperCamelCase_		,   UpperCamelCase_						=  self.heap[child_left_position]
        if child_left_weight < weight:
           self._swap_nodes(_UpperCAmelCase		,		_UpperCAmelCase			)
           return self._bubble_down(_UpperCAmelCase			)
     else:
        return None
     if child_right_position < self.elements:
        UpperCamelCase_		,   UpperCamelCase_						=  self.heap[child_right_position]
        if child_right_weight < weight:
           self._swap_nodes(_UpperCAmelCase		,		_UpperCAmelCase			)
           return self._bubble_down(_UpperCAmelCase			)
     return None




  def  _UpperCAmelCase  (  self		,		_UpperCAmelCase		,		_UpperCAmelCase			)      ->			None:
     # Swap the nodes at the given positions
     UpperCamelCase_						=  self.heap[nodea_pos][0]
     UpperCamelCase_						=  self.heap[nodea_pos][0]
     UpperCamelCase_		,   UpperCamelCase_						=  (
         self.heap[nodea_pos],
         self.heap[nodea_pos],
     )
     UpperCamelCase_						=  nodea_pos
     UpperCamelCase_						=  nodea_pos




class     _a							(	Generic[T]     ):






  """simple docstring"""





  def __init__(  self			)      ->			None:
     UpperCamelCase_						=  {}
     UpperCamelCase_						=  0




  def __repr__(  self			)      ->			str:
     return str(self.connections			)




  def __len__(  self			)      ->			int:
     return self.nodes




  def  _UpperCAmelCase  (  self		,		_UpperCAmelCase			)      ->			None:
     # Add a node in the graph if it is not in the graph
     if node not in self.connections:
        UpperCamelCase_						=  {}
        self.nodes += 1




  def  _UpperCAmelCase  (  self		,		_UpperCAmelCase		,		_UpperCAmelCase		,		_UpperCAmelCase			)      ->			None:
     # Add an edge between 2 nodes in the graph
     self.add_node(_UpperCAmelCase			)
     self.add_node(_UpperCAmelCase			)
     UpperCamelCase_						=  weight
     UpperCamelCase_						=  weight






def      _snake_case     (__lowercase     ,   ):
   UpperCamelCase_						=  {node: maxsize for node in graph.connections}
   UpperCamelCase_						=  {node: None for node in graph.connections}

   UpperCamelCase_						=  MinPriorityQueue()
   for node, weight in dist.items():
      priority_queue.push(__lowercase     ,   __lowercase)

   if priority_queue.is_empty():
      return dist, parent

   # initialization
   UpperCamelCase_						=  priority_queue.extract_min()
   UpperCamelCase_						=  0
   for neighbour in graph.connections[node]:
      if dist[neighbour] > dist[node] + graph.connections[node][neighbour]:
         UpperCamelCase_						=  dist[node] + graph.connections[node][neighbour]
         priority_queue.update_key(__lowercase     ,   dist[neighbour])
         UpperCamelCase_						=  node

    # running prim's algorithm
   while not priority_queue.is_empty():
      UpperCamelCase_						=  priority_queue.extract_min()
      for neighbour in graph.connections[node]:
         if dist[neighbour] > dist[node] + graph.connections[node][neighbour]:
            UpperCamelCase_						=  dist[node] + graph.connections[node][neighbour]
            priority_queue.update_key(__lowercase     ,   dist[neighbour])
            UpperCamelCase_						=  node
   return dist, parent





