






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 							snake_case_       (    __UpperCamelCase      ):

						"""simple docstring"""



						snake_case__        =      42




@flax_register_to_config
class 							snake_case_       (    nn.Module		,							__UpperCamelCase		,							__UpperCamelCase      ):

						"""simple docstring"""



						snake_case__        =      32
						snake_case__        =      4
						snake_case__        =      4
						snake_case__        =      (
						    "CrossAttnDownBlock2D",
						    "CrossAttnDownBlock2D",
						    "CrossAttnDownBlock2D",
						    "DownBlock2D",
						)
						snake_case__        =      ("UpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D")
						snake_case__        =      False
						snake_case__        =      (320, 640, 1_280, 1_280)
						snake_case__        =      2
						snake_case__        =      8
						snake_case__        =      None
						snake_case__        =      1_280
						snake_case__        =      0.0
						snake_case__        =      False
						snake_case__        =      jnp.floataa
						snake_case__        =      True
						snake_case__        =      0
						snake_case__        =      False



						def        UpperCAmelCase__					(self:					Union[str, Any] ,					__UpperCAmelCase:					jax.random.KeyArray   )    ->     FrozenDict:




											'''simple docstring'''



											__a					:						str      =					(1, self.in_channels, self.sample_size, self.sample_size)
											__a					:						Tuple      =					jnp.zeros(__UpperCAmelCase ,					dtype=jnp.floataa   )
											__a					:						Optional[int]      =					jnp.ones((1,) ,					dtype=jnp.intaa   )
											__a					:						int      =					jnp.zeros((1, 1, self.cross_attention_dim) ,					dtype=jnp.floataa   )

											__a      ,			__a					:						int      =					jax.random.split(__UpperCAmelCase   )
											__a					:						List[str]      =					{"params": params_rng, "dropout": dropout_rng}

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



						def        UpperCAmelCase__					(self:					Optional[int]   )    ->     Dict:




											'''simple docstring'''



											__a					:						Dict      =					self.block_out_channels
											__a					:						Union[str, Any]      =					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.
											__a					:						List[Any]      =					self.num_attention_heads or self.attention_head_dim

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

											# time
											__a					:						Optional[int]      =					FlaxTimesteps(
											    block_out_channels[0] ,					flip_sin_to_cos=self.flip_sin_to_cos ,					freq_shift=self.config.freq_shift   )
											__a					:						Optional[int]      =					FlaxTimestepEmbedding(__UpperCAmelCase ,					dtype=self.dtype   )

											__a					:						int      =					self.only_cross_attention
											if isinstance(__UpperCAmelCase ,					__UpperCAmelCase   ):
																__a					:						Union[str, Any]      =					(only_cross_attention,) * len(self.down_block_types   )

											if isinstance(__UpperCAmelCase ,					__UpperCAmelCase   ):
																__a					:						Optional[Any]      =					(num_attention_heads,) * len(self.down_block_types   )

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

																if down_block_type == "CrossAttnDownBlock2D":
																					__a					:						Optional[int]      =					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] ,					use_memory_efficient_attention=self.use_memory_efficient_attention ,					dtype=self.dtype ,					)
																else:
																					__a					:						Optional[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   )
											__a					:						List[str]      =					down_blocks

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

																__a					:						Union[str, Any]      =					i == len(__UpperCAmelCase   ) - 1

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

																up_blocks.append(__UpperCAmelCase   )
																__a					:						Dict      =					output_channel
											__a					:						Any      =					up_blocks

											# out
											__a					:						Tuple      =					nn.GroupNorm(num_groups=32 ,					epsilon=1E-5   )
											__a					:						List[Any]      =					nn.Conv(
											    self.out_channels ,					kernel_size=(3, 3) ,					strides=(1, 1) ,					padding=((1, 1), (1, 1)) ,					dtype=self.dtype ,					)



						def __call__(self:					List[Any] ,					__UpperCAmelCase:					Union[str, Any] ,					__UpperCAmelCase:					List[str] ,					__UpperCAmelCase:					Optional[Any] ,					__UpperCAmelCase:					int=None ,					__UpperCAmelCase:					List[str]=None ,					__UpperCAmelCase:					bool = True ,					__UpperCAmelCase:					bool = False ,					)    ->     Union[FlaxUNetaDConditionOutput, Tuple]:




											'''simple docstring'''



											if not isinstance(__UpperCAmelCase ,					jnp.ndarray   ):
																__a					:						Tuple      =					jnp.array([timesteps] ,					dtype=jnp.intaa   )
											elif isinstance(__UpperCAmelCase ,					jnp.ndarray   ) and len(timesteps.shape   ) == 0:
																__a					:						List[str]      =					timesteps.astype(dtype=jnp.floataa   )
																__a					:						Tuple      =					jnp.expand_dims(__UpperCAmelCase ,					0   )

											__a					:						Any      =					self.time_proj(__UpperCAmelCase   )
											__a					:						str      =					self.time_embedding(__UpperCAmelCase   )

											# 2. pre-process
											__a					:						str      =					jnp.transpose(__UpperCAmelCase ,					(0, 2, 3, 1)   )
											__a					:						Dict      =					self.conv_in(__UpperCAmelCase   )

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

											if down_block_additional_residuals is not None:
																__a					:						Optional[Any]      =					()

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

																__a					:						Any      =					new_down_block_res_samples

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

        # 6. post-process
											__a					:						Optional[int]      =					self.conv_norm_out(__UpperCAmelCase   )
											__a					:						Dict      =					nn.silu(__UpperCAmelCase   )
											__a					:						Union[str, Any]      =					self.conv_out(__UpperCAmelCase   )
											__a					:						Optional[int]      =					jnp.transpose(__UpperCAmelCase ,					(0, 3, 1, 2)   )

											if not return_dict:
																return (sample,)

											return FlaxUNetaDConditionOutput(sample=__UpperCAmelCase   )













from typing import Dict, Optional

import numpy as np

import datasets


UpperCAmelCase__      			=						'''
IoU is the area of overlap between the predicted segmentation and the ground truth divided by the area of union
between the predicted segmentation and the ground truth. For binary (two classes) or multi-class segmentation,
the mean IoU of the image is calculated by taking the IoU of each class and averaging them.
'''

UpperCAmelCase__      			=						'''
Args:
    predictions (`List[ndarray]`):
        List of predicted segmentation maps, each of shape (height, width). Each segmentation map can be of a different size.
    references (`List[ndarray]`):
        List of ground truth segmentation maps, each of shape (height, width). Each segmentation map can be of a different size.
    num_labels (`int`):
        Number of classes (categories).
    ignore_index (`int`):
        Index that will be ignored during evaluation.
    nan_to_num (`int`, *optional*):
        If specified, NaN values will be replaced by the number defined by the user.
    label_map (`dict`, *optional*):
        If specified, dictionary mapping old label indices to new label indices.
    reduce_labels (`bool`, *optional*, defaults to `False`):
        Whether or not to reduce all label values of segmentation maps by 1. Usually used for datasets where 0 is used for background,
        and background itself is not included in all classes of a dataset (e.g. ADE20k). The background label will be replaced by 255.

Returns:
    `Dict[str, float | ndarray]` comprising various elements:
    - *mean_iou* (`float`):
        Mean Intersection-over-Union (IoU averaged over all categories).
    - *mean_accuracy* (`float`):
        Mean accuracy (averaged over all categories).
    - *overall_accuracy* (`float`):
        Overall accuracy on all images.
    - *per_category_accuracy* (`ndarray` of shape `(num_labels,)`):
        Per category accuracy.
    - *per_category_iou* (`ndarray` of shape `(num_labels,)`):
        Per category IoU.

Examples:

    >>> import numpy as np

    >>> mean_iou = datasets.load_metric("mean_iou")

    >>> # suppose one has 3 different segmentation maps predicted
    >>> predicted_1 = np.array([[1, 2], [3, 4], [5, 255]])
    >>> actual_1 = np.array([[0, 3], [5, 4], [6, 255]])

    >>> predicted_2 = np.array([[2, 7], [9, 2], [3, 6]])
    >>> actual_2 = np.array([[1, 7], [9, 2], [3, 6]])

    >>> predicted_3 = np.array([[2, 2, 3], [8, 2, 4], [3, 255, 2]])
    >>> actual_3 = np.array([[1, 2, 2], [8, 2, 1], [3, 255, 1]])

    >>> predicted = [predicted_1, predicted_2, predicted_3]
    >>> ground_truth = [actual_1, actual_2, actual_3]

    >>> results = mean_iou.compute(predictions=predicted, references=ground_truth, num_labels=10, ignore_index=255, reduce_labels=False)
    >>> print(results) # doctest: +NORMALIZE_WHITESPACE
    {\'mean_iou\': 0.47750000000000004, \'mean_accuracy\': 0.5916666666666666, \'overall_accuracy\': 0.5263157894736842, \'per_category_iou\': array([0.   , 0.   , 0.375, 0.4  , 0.5  , 0.   , 0.5  , 1.   , 1.   , 1.   ]), \'per_category_accuracy\': array([0.        , 0.        , 0.75      , 0.66666667, 1.        , 0.        , 0.5       , 1.        , 1.        , 1.        ])}
'''

UpperCAmelCase__      			=						'''\
@software{MMSegmentation_Contributors_OpenMMLab_Semantic_Segmentation_2020,
author = {{MMSegmentation Contributors}},
license = {Apache-2.0},
month = {7},
title = {{OpenMMLab Semantic Segmentation Toolbox and Benchmark}},
url = {https://github.com/open-mmlab/mmsegmentation},
year = {2020}
}'''







def     a_   (__A				,       __A				,       __A				,       __A				,       __A = None				,       __A = False				,       )				->						Dict:



					"""simple docstring"""
					if label_map is not None:
										for old_id, new_id in label_map.items():
															__a					:						str      =					new_id

    # turn into Numpy arrays
					__a					:						Union[str, Any]      =					np.array(__A      )
					__a					:						Any      =					np.array(__A      )

					if reduce_labels:
										__a					:						Dict      =					255
										__a					:						Union[str, Any]      =					label - 1
										__a					:						int      =					255

					__a					:						Optional[Any]      =					label != ignore_index
					__a					:						int      =					np.not_equal(__A				,       __A      )
					__a					:						str      =					pred_label[mask]
					__a					:						List[str]      =					np.array(__A      )[mask]

					__a					:						Optional[int]      =					pred_label[pred_label == label]

					__a					:						Dict      =					np.histogram(__A				,       bins=__A				,       range=(0, num_labels - 1)      )[0]
					__a					:						Union[str, Any]      =					np.histogram(__A				,       bins=__A				,       range=(0, num_labels - 1)      )[0]
					__a					:						List[Any]      =					np.histogram(__A				,       bins=__A				,       range=(0, num_labels - 1)      )[0]

					__a					:						Optional[int]      =					area_pred_label + area_label - area_intersect

					return area_intersect, area_union, area_pred_label, area_label







def     a_   (__A				,       __A				,       __A				,       __A				,       __A = None				,       __A = False				,       )				->						Dict:



					"""simple docstring"""
					__a					:						Union[str, Any]      =					np.zeros((num_labels,)				,       dtype=np.floataa      )
					__a					:						List[str]      =					np.zeros((num_labels,)				,       dtype=np.floataa      )
					__a					:						Optional[Any]      =					np.zeros((num_labels,)				,       dtype=np.floataa      )
					__a					:						Optional[int]      =					np.zeros((num_labels,)				,       dtype=np.floataa      )
					for result, gt_seg_map in zip(__A				,       __A      ):
										__a      ,			__a      ,			__a      ,			__a					:						Dict      =					intersect_and_union(
										    __A				,       __A				,       __A				,       __A				,       __A				,       __A      )
										total_area_intersect += area_intersect
										total_area_union += area_union
										total_area_pred_label += area_pred_label
										total_area_label += area_label
					return total_area_intersect, total_area_union, total_area_pred_label, total_area_label







def     a_   (__A				,       __A				,       __A				,       __A				,       __A = None				,       __A = None				,       __A = False				,       )				->						Optional[int]:



					"""simple docstring"""
					__a      ,			__a      ,			__a      ,			__a					:						Optional[int]      =					total_intersect_and_union(
					    __A				,       __A				,       __A				,       __A				,       __A				,       __A      )

					# compute metrics
					__a					:						Any      =					{}

					__a					:						str      =					total_area_intersect.sum() / total_area_label.sum()
					__a					:						List[Any]      =					total_area_intersect / total_area_union
					__a					:						Union[str, Any]      =					total_area_intersect / total_area_label

					__a					:						Optional[int]      =					np.nanmean(__A      )
					__a					:						str      =					np.nanmean(__A      )
					__a					:						List[str]      =					all_acc
					__a					:						Dict      =					iou
					__a					:						Union[str, Any]      =					acc

					if nan_to_num is not None:
										__a					:						Tuple      =					{metric: np.nan_to_num(__A				,       nan=__A      ) for metric, metric_value in metrics.items()}

					return metrics




@datasets.utils.file_utils.add_start_docstrings(_DESCRIPTION		,							_KWARGS_DESCRIPTION      )
class 							snake_case_       (    datasets.Metric      ):

						"""simple docstring"""



						def        UpperCAmelCase__					(self:					List[str]   )    ->     Tuple:




											'''simple docstring'''



											return datasets.MetricInfo(
											    description=_DESCRIPTION ,					citation=_CITATION ,					inputs_description=_KWARGS_DESCRIPTION ,					features=datasets.Features(
											        # 1st Seq - height dim, 2nd - width dim
											        {
											            "predictions": datasets.Sequence(datasets.Sequence(datasets.Value("uint16"   )   )   ),
											            "references": datasets.Sequence(datasets.Sequence(datasets.Value("uint16"   )   )   ),
											        }   ) ,					reference_urls=[
											        "https://github.com/open-mmlab/mmsegmentation/blob/71c201b1813267d78764f306a297ca717827c4bf/mmseg/core/evaluation/metrics.py"
											    ] ,					)



						def        UpperCAmelCase__					(self:					Optional[int] ,					__UpperCAmelCase:					int ,					__UpperCAmelCase:					Dict ,					__UpperCAmelCase:					int ,					__UpperCAmelCase:					bool ,					__UpperCAmelCase:					Optional[int] = None ,					__UpperCAmelCase:					Optional[Dict[int, int]] = None ,					__UpperCAmelCase:					bool = False ,					)    ->     List[str]:




											'''simple docstring'''



											__a					:						str      =					mean_iou(
											    results=__UpperCAmelCase ,					gt_seg_maps=__UpperCAmelCase ,					num_labels=__UpperCAmelCase ,					ignore_index=__UpperCAmelCase ,					nan_to_num=__UpperCAmelCase ,					label_map=__UpperCAmelCase ,					reduce_labels=__UpperCAmelCase ,					)
											return iou_result





