



'''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__     (							_lowerCAmelCase       ):
	lowercase__      =      42






@flax_register_to_config
class 							lowercase__     (							nn.Module						, _lowerCAmelCase						, _lowerCAmelCase       ):
	lowercase__      =      32
	lowercase__      =      4
	lowercase__      =      4
	lowercase__      =      (
	    "CrossAttnDownBlock2D",
	    "CrossAttnDownBlock2D",
	    "CrossAttnDownBlock2D",
	    "DownBlock2D",
	)
	lowercase__      =      ("UpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D")
	lowercase__      =      False
	lowercase__      =      (3_20, 6_40, 12_80, 12_80)
	lowercase__      =      2
	lowercase__      =      8
	lowercase__      =      None
	lowercase__      =      12_80
	lowercase__      =      0.0
	lowercase__      =      False
	lowercase__      =      jnp.floataa
	lowercase__      =      True
	lowercase__      =      0
	lowercase__      =      False





	def      UpperCamelCase_  (			self :    List[str]			,lowerCamelCase__ :    jax.random.KeyArray			):







							'''simple docstring'''
							# init input tensors
							_UpperCamelCase :		int			    =       (1, self.in_channels, self.sample_size, self.sample_size)
							_UpperCamelCase :		List[str]			    =       jnp.zeros(_lowercase			,dtype=jnp.floataa			)
							_UpperCamelCase :		Optional[int]			    =       jnp.ones((1,)			,dtype=jnp.intaa			)
							_UpperCamelCase :		int			    =       jnp.zeros((1, 1, self.cross_attention_dim)			,dtype=jnp.floataa			)

							_UpperCamelCase    ,      _UpperCamelCase :		int			    =       jax.random.split(_lowercase			)
							_UpperCamelCase :		List[str]			    =       {'params': params_rng, 'dropout': dropout_rng}

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





	def      UpperCamelCase_  (			self :    Any			):







							'''simple docstring'''
							_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 :		str			    =       self.num_attention_heads or self.attention_head_dim

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

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

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

							if isinstance(_lowercase			,_lowercase			):
													_UpperCamelCase :		Tuple			    =       (num_attention_heads,) * len(self.down_block_types			)

							# down
							_UpperCamelCase :		Any			    =       []
							_UpperCamelCase :		List[str]			    =       block_out_channels[0]
							for i, down_block_type in enumerate(self.down_block_types			):
													_UpperCamelCase :		Tuple			    =       output_channel
													_UpperCamelCase :		int			    =       block_out_channels[i]
													_UpperCamelCase :		Any			    =       i == len(_lowercase			) - 1

													if down_block_type == "CrossAttnDownBlock2D":
																			_UpperCamelCase :		Optional[Any]			    =       FlaxCrossAttnDownBlockaD(
																			    in_channels=_lowercase			,out_channels=_lowercase			,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 :		List[Any]			    =       FlaxDownBlockaD(
																			    in_channels=_lowercase			,out_channels=_lowercase			,dropout=self.dropout			,num_layers=self.layers_per_block			,add_downsample=not is_final_block			,dtype=self.dtype			,)

													down_blocks.append(_lowercase			)
							_UpperCamelCase :		List[Any]			    =       down_blocks

							# mid
							_UpperCamelCase :		Dict			    =       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 :		Any			    =       []
							_UpperCamelCase :		List[str]			    =       list(reversed(_lowercase			)			)
							_UpperCamelCase :		Optional[Any]			    =       list(reversed(_lowercase			)			)
							_UpperCamelCase :		Optional[Any]			    =       list(reversed(_lowercase			)			)
							_UpperCamelCase :		Any			    =       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 :		Any			    =       reversed_block_out_channels[min(i + 1			,len(_lowercase			) - 1			)]

													_UpperCamelCase :		Tuple			    =       i == len(_lowercase			) - 1

													if up_block_type == "CrossAttnUpBlock2D":
																			_UpperCamelCase :		List[Any]			    =       FlaxCrossAttnUpBlockaD(
																			    in_channels=_lowercase			,out_channels=_lowercase			,prev_output_channel=_lowercase			,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 :		Tuple			    =       FlaxUpBlockaD(
																			    in_channels=_lowercase			,out_channels=_lowercase			,prev_output_channel=_lowercase			,num_layers=self.layers_per_block + 1			,add_upsample=not is_final_block			,dropout=self.dropout			,dtype=self.dtype			,)

													up_blocks.append(_lowercase			)
													_UpperCamelCase :		int			    =       output_channel
							_UpperCamelCase :		Dict			    =       up_blocks

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





	def __call__(			self :    Optional[int]			,lowerCamelCase__ :    List[Any]			,lowerCamelCase__ :    Any			,lowerCamelCase__ :    Optional[Any]			,lowerCamelCase__ :    Optional[Any]=None			,lowerCamelCase__ :    List[str]=None			,lowerCamelCase__ :    bool = True			,lowerCamelCase__ :    bool = False			,):







							'''simple docstring'''
							# 1. time
							if not isinstance(_lowercase			,jnp.ndarray			):
													_UpperCamelCase :		Any			    =       jnp.array([timesteps]			,dtype=jnp.intaa			)
							elif isinstance(_lowercase			,jnp.ndarray			) and len(timesteps.shape			) == 0:
													_UpperCamelCase :		Dict			    =       timesteps.astype(dtype=jnp.floataa			)
													_UpperCamelCase :		int			    =       jnp.expand_dims(_lowercase			,0			)

							_UpperCamelCase :		Dict			    =       self.time_proj(_lowercase			)
							_UpperCamelCase :		Optional[int]			    =       self.time_embedding(_lowercase			)

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

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

							if down_block_additional_residuals is not None:
													_UpperCamelCase :		int			    =       ()

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

													_UpperCamelCase :		List[Any]			    =       new_down_block_res_samples

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

        # 6. post-process
							_UpperCamelCase :		List[str]			    =       self.conv_norm_out(_lowercase			)
							_UpperCamelCase :		Optional[int]			    =       nn.silu(_lowercase			)
							_UpperCamelCase :		str			    =       self.conv_out(_lowercase			)
							_UpperCamelCase :		int			    =       jnp.transpose(_lowercase			,(0, 3, 1, 2)			)

							if not return_dict:
													return (sample,)

							return FlaxUNetaDConditionOutput(sample=_lowercase			)







'''simple docstring'''
class 							lowercase__     :





	def __init__(			self :    List[str]			,lowerCamelCase__ :    List[Any]			,lowerCamelCase__ :    Optional[int]			,lowerCamelCase__ :    Any			):







							'''simple docstring'''
							_UpperCamelCase :		Dict			    =       None
							_UpperCamelCase :		List[Any]			    =       None
							_UpperCamelCase :		int			    =       graph

							self._normalize_graph(lowerCamelCase__			,lowerCamelCase__			)
							_UpperCamelCase :		List[str]			    =       len(lowerCamelCase__			)
							_UpperCamelCase :		Tuple			    =       None





	def      UpperCamelCase_  (			self :    Any			,lowerCamelCase__ :    Optional[Any]			,lowerCamelCase__ :    Any			):







							'''simple docstring'''
							if sources is int:
													_UpperCamelCase :		Optional[int]			    =       [sources]
							if sinks is int:
													_UpperCamelCase :		Union[str, Any]			    =       [sinks]

							if len(lowerCamelCase__			) == 0 or len(lowerCamelCase__			) == 0:
													return

							_UpperCamelCase :		List[str]			    =       sources[0]
							_UpperCamelCase :		str			    =       sinks[0]

							# make fake vertex if there are more
							# than one source or sink
							if len(lowerCamelCase__			) > 1 or len(lowerCamelCase__			) > 1:
													_UpperCamelCase :		Dict			    =       0
													for i in sources:
																			max_input_flow += sum(self.graph[i]			)

													_UpperCamelCase :		Tuple			    =       len(self.graph			) + 1
													for room in self.graph:
																			room.insert(0			,0			)
													self.graph.insert(0			,[0] * size			)
													for i in sources:
																			_UpperCamelCase :		List[Any]			    =       max_input_flow
													_UpperCamelCase :		Tuple			    =       0

													_UpperCamelCase :		int			    =       len(self.graph			) + 1
													for room in self.graph:
																			room.append(0			)
													self.graph.append([0] * size			)
													for i in sinks:
																			_UpperCamelCase :		Optional[int]			    =       max_input_flow
													_UpperCamelCase :		Optional[int]			    =       size - 1





	def      UpperCamelCase_  (			self :    List[str]			):







							'''simple docstring'''
							if self.maximum_flow_algorithm is None:
													raise Exception('You need to set maximum flow algorithm before.'			)
							if self.source_index is None or self.sink_index is None:
													return 0

							self.maximum_flow_algorithm.execute()
							return self.maximum_flow_algorithm.getMaximumFlow()





	def      UpperCamelCase_  (			self :    Any			,lowerCamelCase__ :    Any			):







							'''simple docstring'''
							_UpperCamelCase :		str			    =       algorithm(self			)






class 							lowercase__     :





	def __init__(			self :    List[str]			,lowerCamelCase__ :    Optional[int]			):







							'''simple docstring'''
							_UpperCamelCase :		Optional[Any]			    =       flow_network
							_UpperCamelCase :		List[str]			    =       flow_network.verticesCount
							_UpperCamelCase :		List[str]			    =       flow_network.sourceIndex
							_UpperCamelCase :		Any			    =       flow_network.sinkIndex
							# it's just a reference, so you shouldn't change
							# it in your algorithms, use deep copy before doing that
							_UpperCamelCase :		List[Any]			    =       flow_network.graph
							_UpperCamelCase :		Any			    =       False





	def      UpperCamelCase_  (			self :    str			):







							'''simple docstring'''
							if not self.executed:
													self._algorithm()
													_UpperCamelCase :		Any			    =       True





	def      UpperCamelCase_  (			self :    Any			):







							'''simple docstring'''
							pass






class 							lowercase__     (							lowercase       ):





	def __init__(			self :    Union[str, Any]			,lowerCamelCase__ :    List[str]			):







							'''simple docstring'''
							super().__init__(lowerCamelCase__			)
							# use this to save your result
							_UpperCamelCase :		Tuple			    =       -1





	def      UpperCamelCase_  (			self :    Dict			):







							'''simple docstring'''
							if not self.executed:
													raise Exception('You should execute algorithm before using its result!'			)

							return self.maximum_flow






class 							lowercase__     (							lowercase       ):





	def __init__(			self :    Optional[Any]			,lowerCamelCase__ :    Dict			):







							'''simple docstring'''
							super().__init__(lowerCamelCase__			)

							_UpperCamelCase :		Dict			    =       [[0] * self.verticies_count for i in range(self.verticies_count			)]

							_UpperCamelCase :		Optional[Any]			    =       [0] * self.verticies_count
							_UpperCamelCase :		List[str]			    =       [0] * self.verticies_count





	def      UpperCamelCase_  (			self :    Union[str, Any]			):







							'''simple docstring'''
							_UpperCamelCase :		Dict			    =       self.verticies_count

							# push some substance to graph
							for nextvertex_index, bandwidth in enumerate(self.graph[self.source_index]			):
													self.preflow[self.source_index][nextvertex_index] += bandwidth
													self.preflow[nextvertex_index][self.source_index] -= bandwidth
													self.excesses[nextvertex_index] += bandwidth

							# Relabel-to-front selection rule
							_UpperCamelCase :		List[str]			    =       [
							    i
							    for i in range(self.verticies_count			)
							    if i != self.source_index and i != self.sink_index
							]

							# move through list
							_UpperCamelCase :		int			    =       0
							while i < len(lowerCamelCase__			):
													_UpperCamelCase :		List[Any]			    =       vertices_list[i]
													_UpperCamelCase :		str			    =       self.heights[vertex_index]
													self.process_vertex(lowerCamelCase__			)
													if self.heights[vertex_index] > previous_height:
																			# if it was relabeled, swap elements
																			# and start from 0 index
																			vertices_list.insert(0			,vertices_list.pop(lowerCamelCase__			)			)
																			_UpperCamelCase :		Dict			    =       0
													else:
																			i += 1

							_UpperCamelCase :		Optional[Any]			    =       sum(self.preflow[self.source_index]			)





	def      UpperCamelCase_  (			self :    Union[str, Any]			,lowerCamelCase__ :    Dict			):







							'''simple docstring'''
							while self.excesses[vertex_index] > 0:
													for neighbour_index in range(self.verticies_count			):
																			# if it's neighbour and current vertex is higher
																			if (
																			    self.graph[vertex_index][neighbour_index]
																			    - self.preflow[vertex_index][neighbour_index]
																			    > 0
																			    and self.heights[vertex_index] > self.heights[neighbour_index]
																			):
																									self.push(lowerCamelCase__			,lowerCamelCase__			)

													self.relabel(lowerCamelCase__			)





	def      UpperCamelCase_  (			self :    Tuple			,lowerCamelCase__ :    List[Any]			,lowerCamelCase__ :    List[str]			):







							'''simple docstring'''
							_UpperCamelCase :		Union[str, Any]			    =       min(
							    self.excesses[from_index]			,self.graph[from_index][to_index] - self.preflow[from_index][to_index]			,)
							self.preflow[from_index][to_index] += preflow_delta
							self.preflow[to_index][from_index] -= preflow_delta
							self.excesses[from_index] -= preflow_delta
							self.excesses[to_index] += preflow_delta





	def      UpperCamelCase_  (			self :    List[str]			,lowerCamelCase__ :    Optional[int]			):







							'''simple docstring'''
							_UpperCamelCase :		Tuple			    =       None
							for to_index in range(self.verticies_count			):
													if (
													    self.graph[vertex_index][to_index]
													    - self.preflow[vertex_index][to_index]
													    > 0
													) and (min_height is None or self.heights[to_index] < min_height):
																			_UpperCamelCase :		List[Any]			    =       self.heights[to_index]

							if min_height is not None:
													_UpperCamelCase :		Any			    =       min_height + 1


if __name__ == "__main__":
					snake_case_			:     List[str]  	=  [0]
					snake_case_			:     int  	=  [3]
					# graph = [
					#     [0, 0, 4, 6, 0, 0],
					#     [0, 0, 5, 2, 0, 0],
					#     [0, 0, 0, 0, 4, 4],
					#     [0, 0, 0, 0, 6, 6],
					#     [0, 0, 0, 0, 0, 0],
					#     [0, 0, 0, 0, 0, 0],
					# ]
					snake_case_			:     int  	=  [[0, 7, 0, 0], [0, 0, 6, 0], [0, 0, 0, 8], [9, 0, 0, 0]]

					# prepare our network
					snake_case_			:     List[Any]  	=  FlowNetwork(graph, entrances, exits)
					# set algorithm
					flow_network.set_maximum_flow_algorithm(PushRelabelExecutor)
					# and calculate
					snake_case_			:     Tuple  	=  flow_network.find_maximum_flow()

					print(F"""maximum flow is {maximum_flow}""")


