






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   lowerCamelCase				(nn.Module      ):







		'''simple docstring'''



		def __init__(							self    ,		_UpperCamelCase    ,		_UpperCamelCase    ,		_UpperCamelCase    ,		_UpperCamelCase = 0    ,		_UpperCamelCase = False    ,		_UpperCamelCase = 1    ,		)     ->							None:
							super().__init__()
							UpperCAmelCase_   :				Union[str, Any]						=						nn.Convad(
							    in_channels=_UpperCamelCase    ,		out_channels=_UpperCamelCase    ,		kernel_size=_UpperCamelCase    ,		padding=_UpperCamelCase    ,		bias=_UpperCamelCase    ,		dilation=_UpperCamelCase    ,		)
							UpperCAmelCase_   :				Optional[int]						=						nn.BatchNormad(_UpperCamelCase       )
							UpperCAmelCase_   :				Dict						=						nn.ReLU()



		def  __UpperCAmelCase      (							self    ,		_UpperCamelCase       )     ->							torch.Tensor:
							UpperCAmelCase_   :				List[str]						=						self.conv(_UpperCamelCase       )
							UpperCAmelCase_   :				Tuple						=						self.batch_norm(_UpperCamelCase       )
							UpperCAmelCase_   :				str						=						self.activation(_UpperCamelCase       )

							return output





class   lowerCamelCase				(nn.Module      ):







		'''simple docstring'''



		def __init__(							self    ,		_UpperCamelCase    ,		_UpperCamelCase    ,		_UpperCamelCase       )     ->							None:
							super().__init__()
							UpperCAmelCase_   :				Optional[int]						=						[
							    nn.AdaptiveAvgPoolad(_UpperCamelCase       ),
							    UperNetConvModule(_UpperCamelCase    ,		_UpperCamelCase    ,		kernel_size=1       ),
							]
							for i, layer in enumerate(self.layers       ):
												self.add_module(str(_UpperCamelCase       )    ,		_UpperCamelCase       )



		def  __UpperCAmelCase      (							self    ,		_UpperCamelCase       )     ->							torch.Tensor:
							UpperCAmelCase_   :				Optional[int]						=						input
							for layer in self.layers:
												UpperCAmelCase_   :				Any						=						layer(_UpperCamelCase       )
							return hidden_state





class   lowerCamelCase				(nn.Module      ):







		'''simple docstring'''



		def __init__(							self    ,		_UpperCamelCase    ,		_UpperCamelCase    ,		_UpperCamelCase    ,		_UpperCamelCase       )     ->							None:
							super().__init__()
							UpperCAmelCase_   :				List[Any]						=						pool_scales
							UpperCAmelCase_   :				Tuple						=						align_corners
							UpperCAmelCase_   :				List[Any]						=						in_channels
							UpperCAmelCase_   :				Optional[Any]						=						channels
							UpperCAmelCase_   :				List[str]						=						[]
							for i, pool_scale in enumerate(_UpperCamelCase       ):
												UpperCAmelCase_   :				Tuple						=						UperNetPyramidPoolingBlock(pool_scale=_UpperCamelCase    ,		in_channels=_UpperCamelCase    ,		channels=_UpperCamelCase       )
												self.blocks.append(_UpperCamelCase       )
												self.add_module(str(_UpperCamelCase       )    ,		_UpperCamelCase       )



		def  __UpperCAmelCase      (							self    ,		_UpperCamelCase       )     ->							List[torch.Tensor]:
							UpperCAmelCase_   :				Optional[int]						=						[]
							for ppm in self.blocks:
												UpperCAmelCase_   :				Any						=						ppm(_UpperCamelCase       )
												UpperCAmelCase_   :				List[str]						=						nn.functional.interpolate(
												    _UpperCamelCase    ,		size=x.size()[2:]    ,		mode='bilinear'    ,		align_corners=self.align_corners       )
												ppm_outs.append(_UpperCamelCase       )
							return ppm_outs





class   lowerCamelCase				(nn.Module      ):







		'''simple docstring'''



		def __init__(							self    ,		_UpperCamelCase    ,		_UpperCamelCase       )     ->							List[Any]:
							super().__init__()

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

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

							UpperCAmelCase_   :				Optional[int]						=						UperNetConvModule(
							    len(self.in_channels       ) * self.channels    ,		self.channels    ,		kernel_size=3    ,		padding=1    ,		)



		def  __UpperCAmelCase      (							self       )     ->							Tuple:
							self.apply(self._init_weights       )



		def  __UpperCAmelCase      (							self    ,		_UpperCamelCase       )     ->							Dict:
							if isinstance(_UpperCamelCase    ,		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  __UpperCAmelCase      (							self    ,		_UpperCamelCase       )     ->							str:
							UpperCAmelCase_   :				List[str]						=						inputs[-1]
							UpperCAmelCase_   :				Optional[int]						=						[x]
							psp_outs.extend(self.psp_modules(_UpperCamelCase       )       )
							UpperCAmelCase_   :				List[Any]						=						torch.cat(_UpperCamelCase    ,		dim=1       )
							UpperCAmelCase_   :				Tuple						=						self.bottleneck(_UpperCamelCase       )

							return output



		def  __UpperCAmelCase      (							self    ,		_UpperCamelCase       )     ->							torch.Tensor:
							# build laterals
							UpperCAmelCase_   :				Optional[int]						=						[lateral_conv(encoder_hidden_states[i]       ) for i, lateral_conv in enumerate(self.lateral_convs       )]

							laterals.append(self.psp_forward(_UpperCamelCase       )       )

							# build top-down path
							UpperCAmelCase_   :				List[Any]						=						len(_UpperCamelCase       )
							for i in range(used_backbone_levels - 1    ,		0    ,		-1       ):
												UpperCAmelCase_   :				Dict						=						laterals[i - 1].shape[2:]
												UpperCAmelCase_   :				Union[str, Any]						=						laterals[i - 1] + nn.functional.interpolate(
												    laterals[i]    ,		size=_UpperCamelCase    ,		mode='bilinear'    ,		align_corners=self.align_corners       )

							# build outputs
							UpperCAmelCase_   :				Dict						=						[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       ):
												UpperCAmelCase_   :				Tuple						=						nn.functional.interpolate(
												    fpn_outs[i]    ,		size=fpn_outs[0].shape[2:]    ,		mode='bilinear'    ,		align_corners=self.align_corners       )
							UpperCAmelCase_   :				Tuple						=						torch.cat(_UpperCamelCase    ,		dim=1       )
							UpperCAmelCase_   :				Dict						=						self.fpn_bottleneck(_UpperCamelCase       )
							UpperCAmelCase_   :				Dict						=						self.classifier(_UpperCamelCase       )

							return output





class   lowerCamelCase				(nn.Module      ):







		'''simple docstring'''



		def __init__(							self    ,		_UpperCamelCase    ,		_UpperCamelCase = 2    ,		_UpperCamelCase = 3    ,		_UpperCamelCase = 1       )     ->							None:
							super().__init__()

							UpperCAmelCase_   :				Tuple						=						config
							UpperCAmelCase_   :				Dict						=						config.auxiliary_in_channels
							UpperCAmelCase_   :				Optional[int]						=						config.auxiliary_channels
							UpperCAmelCase_   :				Any						=						config.auxiliary_num_convs
							UpperCAmelCase_   :				Optional[int]						=						config.auxiliary_concat_input
							UpperCAmelCase_   :				Union[str, Any]						=						in_index

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

							UpperCAmelCase_   :				Optional[int]						=						nn.Convad(self.channels    ,		config.num_labels    ,		kernel_size=1       )



		def  __UpperCAmelCase      (							self       )     ->							Optional[int]:
							self.apply(self._init_weights       )



		def  __UpperCAmelCase      (							self    ,		_UpperCamelCase       )     ->							List[str]:
							if isinstance(_UpperCamelCase    ,		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  __UpperCAmelCase      (							self    ,		_UpperCamelCase       )     ->							torch.Tensor:
							# just take the relevant feature maps
							UpperCAmelCase_   :				Union[str, Any]						=						encoder_hidden_states[self.in_index]
							UpperCAmelCase_   :				Dict						=						self.convs(_UpperCamelCase       )
							if self.concat_input:
												UpperCAmelCase_   :				List[str]						=						self.conv_cat(torch.cat([hidden_states, output]    ,		dim=1       )       )
							UpperCAmelCase_   :				Tuple						=						self.classifier(_UpperCamelCase       )
							return output





class   lowerCamelCase				(_snake_case      ):







		'''simple docstring'''



		_snake_case   :   Dict							=  UperNetConfig
		_snake_case   :   Optional[Any]							=  '''pixel_values'''
		_snake_case   :   Union[str, Any]							=  True



		def  __UpperCAmelCase      (							self    ,		_UpperCamelCase       )     ->							Dict:
							if isinstance(_UpperCamelCase    ,		_UpperCamelCase       ):
												module.backbone.init_weights()
												module.decode_head.init_weights()
												module.auxiliary_head.init_weights()



		def  __UpperCAmelCase      (							self       )     ->							str:
							self.backbone.init_weights()
							self.decode_head.init_weights()
							self.auxiliary_head.init_weights()



		def  __UpperCAmelCase      (							self    ,		_UpperCamelCase    ,		_UpperCamelCase=False       )     ->							Union[str, Any]:
							if isinstance(_UpperCamelCase    ,		_UpperCamelCase       ):
												UpperCAmelCase_   :				List[Any]						=						value





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

__UpperCAmelCase     							=						R'\n    Args:\n        pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, height, width)`):\n            Pixel values. Padding will be ignored by default should you provide it. Pixel values can be obtained using\n            [`AutoImageProcessor`]. See [`SegformerImageProcessor.__call__`] for details.\n        output_attentions (`bool`, *optional*):\n            Whether or not to return the attentions tensors of all attention layers in case the backbone has them. See\n            `attentions` under returned tensors for more detail.\n        output_hidden_states (`bool`, *optional*):\n            Whether or not to return the hidden states of all layers of the backbone. See `hidden_states` under\n            returned tensors for more detail.\n        return_dict (`bool`, *optional*):\n            Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple.\n'



@add_start_docstrings(
    '''UperNet framework leveraging any vision backbone e.g. for ADE20k, CityScapes.'''			,  _snake_case			,  )
class   lowerCamelCase				(_snake_case      ):







		'''simple docstring'''



		def __init__(							self    ,		_UpperCamelCase       )     ->							List[Any]:
							super().__init__(_UpperCamelCase       )

							UpperCAmelCase_   :				Any						=						AutoBackbone.from_config(config.backbone_config       )

							# Semantic segmentation head(s)
							UpperCAmelCase_   :				Any						=						UperNetHead(_UpperCamelCase    ,		in_channels=self.backbone.channels       )
							UpperCAmelCase_   :				str						=						UperNetFCNHead(_UpperCamelCase       ) 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=_UpperCamelCase    ,		config_class=_CONFIG_FOR_DOC       )
		def  __UpperCAmelCase      (							self    ,		_UpperCamelCase = None    ,		_UpperCamelCase = None    ,		_UpperCamelCase = None    ,		_UpperCamelCase = None    ,		_UpperCamelCase = None    ,		)     ->							Union[tuple, SemanticSegmenterOutput]:
							UpperCAmelCase_   :				Any						=						return_dict if return_dict is not None else self.config.use_return_dict
							UpperCAmelCase_   :				List[Any]						=						(
							    output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
							)
							UpperCAmelCase_   :				Dict						=						output_attentions if output_attentions is not None else self.config.output_attentions

							UpperCAmelCase_   :				str						=						self.backbone.forward_with_filtered_kwargs(
							    _UpperCamelCase    ,		output_hidden_states=_UpperCamelCase    ,		output_attentions=_UpperCamelCase       )
							UpperCAmelCase_   :				Union[str, Any]						=						outputs.feature_maps

							UpperCAmelCase_   :				List[Any]						=						self.decode_head(_UpperCamelCase       )
							UpperCAmelCase_   :				Any						=						nn.functional.interpolate(_UpperCamelCase    ,		size=pixel_values.shape[2:]    ,		mode='bilinear'    ,		align_corners=_UpperCamelCase       )

							UpperCAmelCase_   :				Tuple						=						None
							if self.auxiliary_head is not None:
												UpperCAmelCase_   :				Optional[int]						=						self.auxiliary_head(_UpperCamelCase       )
												UpperCAmelCase_   :				str						=						nn.functional.interpolate(
												    _UpperCamelCase    ,		size=pixel_values.shape[2:]    ,		mode='bilinear'    ,		align_corners=_UpperCamelCase       )

							UpperCAmelCase_   :				int						=						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
																	UpperCAmelCase_   :				Tuple						=						CrossEntropyLoss(ignore_index=self.config.loss_ignore_index       )
																	UpperCAmelCase_   :				Optional[int]						=						loss_fct(_UpperCamelCase    ,		_UpperCamelCase       )
																	UpperCAmelCase_   :				Dict						=						loss_fct(_UpperCamelCase    ,		_UpperCamelCase       )
																	UpperCAmelCase_   :				Dict						=						main_loss + self.config.auxiliary_loss_weight * auxiliary_loss

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

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














import argparse
import json
import os

from tensorflow.core.protobuf.saved_model_pba import SavedModel


# All paths are set with the intent you should run this script from the root of the repo with the command
# python utils/check_copies.py
__UpperCAmelCase     							=						'.'

# Internal TensorFlow ops that can be safely ignored (mostly specific to a saved model)
__UpperCAmelCase     							=						[
    'Assert',
    'AssignVariableOp',
    'EmptyTensorList',
    'MergeV2Checkpoints',
    'ReadVariableOp',
    'ResourceGather',
    'RestoreV2',
    'SaveV2',
    'ShardedFilename',
    'StatefulPartitionedCall',
    'StaticRegexFullMatch',
    'VarHandleOp',
]




def 					lowercase__				(					__snake_case   :							Union[str, Any]					,	__snake_case   :							Optional[int]					,	__snake_case   :							Union[str, Any]  ):


					'''simple docstring'''


					UpperCAmelCase_   :				Optional[Any]						=						SavedModel()
					UpperCAmelCase_   :				Optional[Any]						=						[]

					with open(os.path.join(__snake_case					,	'utils'					,	'tf_ops'					,	'onnx.json'  )  ) as f:
										UpperCAmelCase_   :				Optional[Any]						=						json.load(__snake_case  )['opsets']

					for i in range(1					,	opset + 1  ):
										onnx_ops.extend(onnx_opsets[str(__snake_case  )]  )

					with open(__snake_case					,	'rb'  ) as f:
										saved_model.ParseFromString(f.read()  )

					UpperCAmelCase_   :				List[Any]						=						set()

					# Iterate over every metagraph in case there is more than one (a saved model can contain multiple graphs)
					for meta_graph in saved_model.meta_graphs:
										# Add operations in the graph definition
										model_op_names.update(node.op for node in meta_graph.graph_def.node  )

										# Go through the functions in the graph definition
										for func in meta_graph.graph_def.library.function:
															# Add operations in each function
															model_op_names.update(node.op for node in func.node_def  )

    # Convert to list, sorted if you want
					UpperCAmelCase_   :				Optional[int]						=						sorted(__snake_case  )
					UpperCAmelCase_   :				int						=						[]

					for op in model_op_names:
										if op not in onnx_ops and op not in INTERNAL_OPS:
															incompatible_ops.append(__snake_case  )

					if strict and len(__snake_case  ) > 0:
										raise Exception(F"Found the following incompatible ops for the opset {opset}:\n" + incompatible_ops  )
					elif len(__snake_case  ) > 0:
										print(F"Found the following incompatible ops for the opset {opset}:"  )
										print(*__snake_case					,	sep='\n'  )
					else:
										print(F"The saved model {saved_model_path} can properly be converted with ONNX."  )


if __name__ == "__main__":
		__UpperCAmelCase     							=						argparse.ArgumentParser()
		parser.add_argument('--saved_model_path', help='Path of the saved model to check (the .pb file).')
		parser.add_argument(
		    '--opset', default=12, type=int, help='The ONNX opset against which the model has to be tested.'
		)
		parser.add_argument(
		    '--framework', choices=['onnx'], default='onnx', help='Frameworks against which to test the saved model.'
		)
		parser.add_argument(
		    '--strict', action='store_true', help='Whether make the checking strict (raise errors) or not (raise warnings)'
		)
		__UpperCAmelCase     							=						parser.parse_args()

		if args.framework == "onnx":
				onnx_compliancy(args.saved_model_path, args.strict, args.opset)






