





from typing import List, Optional, Tuple, Union

import torch
from torch import nn
from torch.nn import CrossEntropyLoss

from ... import AutoBackbone
from ...modeling_outputs import SemanticSegmenterOutput
from ...modeling_utils import PreTrainedModel
from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, replace_return_docstrings
from ...utils.backbone_utils import BackboneMixin
from .configuration_upernet import UperNetConfig


UpperCAmelCase_							=				[
    """openmmlab/upernet-convnext-tiny""",
    # See all UperNet models at https://huggingface.co/models?filter=upernet
]

# General docstring
UpperCAmelCase_							=				"""UperNetConfig"""
class     UpperCamelCase__					(     nn.Module				):






		'''simple docstring'''






		def __init__(							self,   snake_case__,   snake_case__,   snake_case__,   snake_case__ = 0,   snake_case__ = False,   snake_case__ = 1,   )       -> None:






									"""simple docstring"""
									super().__init__()
									lowercase_	:   Optional[Any]  				=     nn.Convad(
									    in_channels=snake_case__,   out_channels=snake_case__,   kernel_size=snake_case__,   padding=snake_case__,   bias=snake_case__,   dilation=snake_case__,   )
									lowercase_	:   Union[str, Any]  				=     nn.BatchNormad(snake_case__  )
									lowercase_	:   Union[str, Any]  				=     nn.ReLU()






		def 						snake_case__				(							self,   snake_case__  )       -> torch.Tensor:






									"""simple docstring"""
									lowercase_	:   Tuple  				=     self.conv(snake_case__  )
									lowercase_	:   Optional[Any]  				=     self.batch_norm(snake_case__  )
									lowercase_	:   Tuple  				=     self.activation(snake_case__  )

									return output




class     UpperCamelCase__					(     nn.Module				):






		'''simple docstring'''






		def __init__(							self,   snake_case__,   snake_case__,   snake_case__  )       -> None:






									"""simple docstring"""
									super().__init__()
									lowercase_	:   Union[str, Any]  				=     [
									    nn.AdaptiveAvgPoolad(snake_case__  ),
									    UperNetConvModule(snake_case__,   snake_case__,   kernel_size=1  ),
									]
									for i, layer in enumerate(self.layers  ):
																self.add_module(str(snake_case__  ),   snake_case__  )






		def 						snake_case__				(							self,   snake_case__  )       -> torch.Tensor:






									"""simple docstring"""
									lowercase_	:   Tuple  				=     input
									for layer in self.layers:
																lowercase_	:   Optional[int]  				=     layer(snake_case__  )
									return hidden_state




class     UpperCamelCase__					(     nn.Module				):






		'''simple docstring'''






		def __init__(							self,   snake_case__,   snake_case__,   snake_case__,   snake_case__  )       -> None:






									"""simple docstring"""
									super().__init__()
									lowercase_	:   Optional[Any]  				=     pool_scales
									lowercase_	:   Union[str, Any]  				=     align_corners
									lowercase_	:   Tuple  				=     in_channels
									lowercase_	:   Dict  				=     channels
									lowercase_	:   Optional[Any]  				=     []
									for i, pool_scale in enumerate(snake_case__  ):
																lowercase_	:   Tuple  				=     UperNetPyramidPoolingBlock(pool_scale=snake_case__,   in_channels=snake_case__,   channels=snake_case__  )
																self.blocks.append(snake_case__  )
																self.add_module(str(snake_case__  ),   snake_case__  )






		def 						snake_case__				(							self,   snake_case__  )       -> List[torch.Tensor]:






									"""simple docstring"""
									lowercase_	:   List[str]  				=     []
									for ppm in self.blocks:
																lowercase_	:   Tuple  				=     ppm(snake_case__  )
																lowercase_	:   List[str]  				=     nn.functional.interpolate(
																    snake_case__,   size=x.size()[2:],   mode="""bilinear""",   align_corners=self.align_corners  )
																ppm_outs.append(snake_case__  )
									return ppm_outs




class     UpperCamelCase__					(     nn.Module				):






		'''simple docstring'''






		def __init__(							self,   snake_case__,   snake_case__  )       -> Any:






									"""simple docstring"""
									super().__init__()

									lowercase_	:   Tuple  				=     config
									lowercase_	:   int  				=     config.pool_scales  # e.g. (1, 2, 3, 6)
									lowercase_	:   Optional[int]  				=     in_channels
									lowercase_	:   Dict  				=     config.hidden_size
									lowercase_	:   List[Any]  				=     False
									lowercase_	:   str  				=     nn.Convad(self.channels,   config.num_labels,   kernel_size=1  )

									# PSP Module
									lowercase_	:   Optional[int]  				=     UperNetPyramidPoolingModule(
									    self.pool_scales,   self.in_channels[-1],   self.channels,   align_corners=self.align_corners,   )
									lowercase_	:   str  				=     UperNetConvModule(
									    self.in_channels[-1] + len(self.pool_scales  ) * self.channels,   self.channels,   kernel_size=3,   padding=1,   )
									# FPN Module
									lowercase_	:   str  				=     nn.ModuleList()
									lowercase_	:   Any  				=     nn.ModuleList()
									for in_channels in self.in_channels[:-1]:  # skip the top layer
																lowercase_	:   List[str]  				=     UperNetConvModule(snake_case__,   self.channels,   kernel_size=1  )
																lowercase_	:   Dict  				=     UperNetConvModule(self.channels,   self.channels,   kernel_size=3,   padding=1  )
																self.lateral_convs.append(snake_case__  )
																self.fpn_convs.append(snake_case__  )

									lowercase_	:   int  				=     UperNetConvModule(
									    len(self.in_channels  ) * self.channels,   self.channels,   kernel_size=3,   padding=1,   )






		def 						snake_case__				(							self  )       -> int:






									"""simple docstring"""
									self.apply(self._init_weights  )






		def 						snake_case__				(							self,   snake_case__  )       -> List[str]:






									"""simple docstring"""
									if isinstance(snake_case__,   nn.Convad  ):
																module.weight.data.normal_(mean=0.0,   std=self.config.initializer_range  )
																if module.bias is not None:
																							module.bias.data.zero_()






		def 						snake_case__				(							self,   snake_case__  )       -> List[Any]:






									"""simple docstring"""
									lowercase_	:   Tuple  				=     inputs[-1]
									lowercase_	:   List[str]  				=     [x]
									psp_outs.extend(self.psp_modules(snake_case__  )  )
									lowercase_	:   str  				=     torch.cat(snake_case__,   dim=1  )
									lowercase_	:   Optional[Any]  				=     self.bottleneck(snake_case__  )

									return output






		def 						snake_case__				(							self,   snake_case__  )       -> torch.Tensor:






									"""simple docstring"""
									# build laterals
									lowercase_	:   List[str]  				=     [lateral_conv(encoder_hidden_states[i]  ) for i, lateral_conv in enumerate(self.lateral_convs  )]

									laterals.append(self.psp_forward(snake_case__  )  )

									# build top-down path
									lowercase_	:   Optional[Any]  				=     len(snake_case__  )
									for i in range(used_backbone_levels - 1,   0,   -1  ):
																lowercase_	:   List[Any]  				=     laterals[i - 1].shape[2:]
																lowercase_	:   Tuple  				=     laterals[i - 1] + nn.functional.interpolate(
																    laterals[i],   size=snake_case__,   mode="""bilinear""",   align_corners=self.align_corners  )

									# build outputs
									lowercase_	:   List[Any]  				=     [self.fpn_convs[i](laterals[i]  ) for i in range(used_backbone_levels - 1  )]
									# append psp feature
									fpn_outs.append(laterals[-1]  )

									for i in range(used_backbone_levels - 1,   0,   -1  ):
																lowercase_	:   Union[str, Any]  				=     nn.functional.interpolate(
																    fpn_outs[i],   size=fpn_outs[0].shape[2:],   mode="""bilinear""",   align_corners=self.align_corners  )
									lowercase_	:   Dict  				=     torch.cat(snake_case__,   dim=1  )
									lowercase_	:   List[str]  				=     self.fpn_bottleneck(snake_case__  )
									lowercase_	:   Any  				=     self.classifier(snake_case__  )

									return output




class     UpperCamelCase__					(     nn.Module				):






		'''simple docstring'''






		def __init__(							self,   snake_case__,   snake_case__ = 2,   snake_case__ = 3,   snake_case__ = 1  )       -> None:






									"""simple docstring"""
									super().__init__()

									lowercase_	:   Optional[int]  				=     config
									lowercase_	:   int  				=     config.auxiliary_in_channels
									lowercase_	:   str  				=     config.auxiliary_channels
									lowercase_	:   Dict  				=     config.auxiliary_num_convs
									lowercase_	:   str  				=     config.auxiliary_concat_input
									lowercase_	:   int  				=     in_index

									lowercase_	:   Tuple  				=     (kernel_size // 2) * dilation
									lowercase_	:   Union[str, Any]  				=     []
									convs.append(
									    UperNetConvModule(
									        self.in_channels,   self.channels,   kernel_size=snake_case__,   padding=snake_case__,   dilation=snake_case__  )  )
									for i in range(self.num_convs - 1  ):
																convs.append(
																    UperNetConvModule(
																        self.channels,   self.channels,   kernel_size=snake_case__,   padding=snake_case__,   dilation=snake_case__  )  )
									if self.num_convs == 0:
																lowercase_	:   int  				=     nn.Identity()
									else:
																lowercase_	:   Dict  				=     nn.Sequential(*snake_case__  )
									if self.concat_input:
																lowercase_	:   Dict  				=     UperNetConvModule(
																    self.in_channels + self.channels,   self.channels,   kernel_size=snake_case__,   padding=kernel_size // 2  )

									lowercase_	:   Any  				=     nn.Convad(self.channels,   config.num_labels,   kernel_size=1  )






		def 						snake_case__				(							self  )       -> Union[str, Any]:






									"""simple docstring"""
									self.apply(self._init_weights  )






		def 						snake_case__				(							self,   snake_case__  )       -> Optional[int]:






									"""simple docstring"""
									if isinstance(snake_case__,   nn.Convad  ):
																module.weight.data.normal_(mean=0.0,   std=self.config.initializer_range  )
																if module.bias is not None:
																							module.bias.data.zero_()






		def 						snake_case__				(							self,   snake_case__  )       -> torch.Tensor:






									"""simple docstring"""
									# just take the relevant feature maps
									lowercase_	:   Union[str, Any]  				=     encoder_hidden_states[self.in_index]
									lowercase_	:   Union[str, Any]  				=     self.convs(snake_case__  )
									if self.concat_input:
																lowercase_	:   Any  				=     self.conv_cat(torch.cat([hidden_states, output],   dim=1  )  )
									lowercase_	:   Tuple  				=     self.classifier(snake_case__  )
									return output




class     UpperCamelCase__					(     lowerCamelCase__				):






		'''simple docstring'''






		__a       :       Dict       =	UperNetConfig
		__a       :       Union[str, Any]       =	"""pixel_values"""
		__a       :       str       =	True






		def 						snake_case__				(							self,   snake_case__  )       -> Tuple:






									"""simple docstring"""
									if isinstance(snake_case__,   snake_case__  ):
																module.backbone.init_weights()
																module.decode_head.init_weights()
																module.auxiliary_head.init_weights()






		def 						snake_case__				(							self  )       -> Optional[Any]:






									"""simple docstring"""
									self.backbone.init_weights()
									self.decode_head.init_weights()
									self.auxiliary_head.init_weights()






		def 						snake_case__				(							self,   snake_case__,   snake_case__=False  )       -> Optional[Any]:






									"""simple docstring"""
									if isinstance(snake_case__,   snake_case__  ):
																lowercase_	:   Optional[Any]  				=     value




UpperCAmelCase_							=				r"""
    Parameters:
    This model is a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) sub-class. Use
    it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage and
    behavior.
        config ([`UperNetConfig`]): Model configuration class with all the parameters of the model.
            Initializing with a config file does not load the weights associated with the model, only the
            configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights.
"""

UpperCAmelCase_							=				r"""
    Args:
        pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, height, width)`):
            Pixel values. Padding will be ignored by default should you provide it. Pixel values can be obtained using
            [`AutoImageProcessor`]. See [`SegformerImageProcessor.__call__`] for details.
        output_attentions (`bool`, *optional*):
            Whether or not to return the attentions tensors of all attention layers in case the backbone has them. See
            `attentions` under returned tensors for more detail.
        output_hidden_states (`bool`, *optional*):
            Whether or not to return the hidden states of all layers of the backbone. See `hidden_states` under
            returned tensors for more detail.
        return_dict (`bool`, *optional*):
            Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple.
"""
@add_start_docstrings(
    """UperNet framework leveraging any vision backbone e.g. for ADE20k, CityScapes."""				, lowerCamelCase__				, )
class     UpperCamelCase__					(     lowerCamelCase__				):






		'''simple docstring'''






		def __init__(							self,   snake_case__  )       -> Union[str, Any]:






									"""simple docstring"""
									super().__init__(snake_case__  )

									lowercase_	:   Tuple  				=     AutoBackbone.from_config(config.backbone_config  )

									# Semantic segmentation head(s)
									lowercase_	:   Any  				=     UperNetHead(snake_case__,   in_channels=self.backbone.channels  )
									lowercase_	:   Dict  				=     UperNetFCNHead(snake_case__  ) if config.use_auxiliary_head else None

									# Initialize weights and apply final processing
									self.post_init()






		@add_start_docstrings_to_model_forward(UPERNET_INPUTS_DOCSTRING.format("""batch_size, sequence_length"""  )  )
		@replace_return_docstrings(output_type=snake_case__,   config_class=_CONFIG_FOR_DOC  )
		def 						snake_case__				(							self,   snake_case__ = None,   snake_case__ = None,   snake_case__ = None,   snake_case__ = None,   snake_case__ = None,   )       -> Union[tuple, SemanticSegmenterOutput]:






									"""simple docstring"""
									lowercase_	:   Tuple  				=     return_dict if return_dict is not None else self.config.use_return_dict
									lowercase_	:   Optional[int]  				=     (
									    output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
									)
									lowercase_	:   str  				=     output_attentions if output_attentions is not None else self.config.output_attentions

									lowercase_	:   Union[str, Any]  				=     self.backbone.forward_with_filtered_kwargs(
									    snake_case__,   output_hidden_states=snake_case__,   output_attentions=snake_case__  )
									lowercase_	:   Tuple  				=     outputs.feature_maps

									lowercase_	:   Tuple  				=     self.decode_head(snake_case__  )
									lowercase_	:   Optional[int]  				=     nn.functional.interpolate(snake_case__,   size=pixel_values.shape[2:],   mode="""bilinear""",   align_corners=snake_case__  )

									lowercase_	:   Optional[Any]  				=     None
									if self.auxiliary_head is not None:
																lowercase_	:   Tuple  				=     self.auxiliary_head(snake_case__  )
																lowercase_	:   Union[str, Any]  				=     nn.functional.interpolate(
																    snake_case__,   size=pixel_values.shape[2:],   mode="""bilinear""",   align_corners=snake_case__  )

									lowercase_	:   Dict  				=     None
									if labels is not None:
																if self.config.num_labels == 1:
																							raise ValueError("""The number of labels should be greater than one"""  )
																else:
																							# compute weighted loss
																							lowercase_	:   Any  				=     CrossEntropyLoss(ignore_index=self.config.loss_ignore_index  )
																							lowercase_	:   Union[str, Any]  				=     loss_fct(snake_case__,   snake_case__  )
																							lowercase_	:   int  				=     loss_fct(snake_case__,   snake_case__  )
																							lowercase_	:   str  				=     main_loss + self.config.auxiliary_loss_weight * auxiliary_loss

									if not return_dict:
																if output_hidden_states:
																							lowercase_	:   Optional[int]  				=     (logits,) + outputs[1:]
																else:
																							lowercase_	:   Optional[Any]  				=     (logits,) + outputs[2:]
																return ((loss,) + output) if loss is not None else output

									return SemanticSegmenterOutput(
									    loss=snake_case__,   logits=snake_case__,   hidden_states=outputs.hidden_states,   attentions=outputs.attentions,   )






UpperCAmelCase_							=				{"""a""": ["""c""", """b"""], """b""": ["""d""", """e"""], """c""": [], """d""": [], """e""": []}
UpperCAmelCase_							=				["""a""", """b""", """c""", """d""", """e"""]





def  __magic_name__  (				lowercase				,       lowercase				,       lowercase				)				-> Union[str, Any]:

							"""simple docstring"""



							lowercase_	:   Tuple  				=     start
							# add current to visited
							visited.append(lowercase				)
							lowercase_	:   Any  				=     edges[current]
							for neighbor in neighbors:
														# if neighbor not in visited, visit
														if neighbor not in visited:
																					lowercase_	:   List[str]  				=     topological_sort(lowercase				,       lowercase				,       lowercase				)
    # if all neighbors visited add current to sort
							sort.append(lowercase				)
							# if all vertices haven't been visited select a new one to visit
							if len(lowercase				) != len(lowercase				):
														for vertice in vertices:
																					if vertice not in visited:
																												lowercase_	:   Optional[Any]  				=     topological_sort(lowercase				,       lowercase				,       lowercase				)
    # return sort
							return sort


if __name__ == "__main__":
							UpperCAmelCase_							=				topological_sort("""a""", [], [])
							print(sort)