



import argparse
import json
from pathlib import Path

import requests
import torch
from huggingface_hub import hf_hub_download
from PIL import Image

from transformers import ConvNextConfig, ConvNextForImageClassification, ConvNextImageProcessor
from transformers.utils import logging


logging.set_verbosity_info()
A__       =			logging.get_logger(__name__)


def 						_UpperCAmelCase							( snake_case     ):





					"""simple docstring"""

					_lowerCAmelCase         =       ConvNextConfig()

					if "tiny" in checkpoint_url:
										_lowerCAmelCase         =       [3, 3, 9, 3]
										_lowerCAmelCase         =       [96, 1_92, 3_84, 7_68]
					if "small" in checkpoint_url:
										_lowerCAmelCase         =       [3, 3, 27, 3]
										_lowerCAmelCase         =       [96, 1_92, 3_84, 7_68]
					if "base" in checkpoint_url:
										_lowerCAmelCase         =       [3, 3, 27, 3]
										_lowerCAmelCase         =       [1_28, 2_56, 5_12, 10_24]
					if "large" in checkpoint_url:
										_lowerCAmelCase         =       [3, 3, 27, 3]
										_lowerCAmelCase         =       [1_92, 3_84, 7_68, 15_36]
					if "xlarge" in checkpoint_url:
										_lowerCAmelCase         =       [3, 3, 27, 3]
										_lowerCAmelCase         =       [2_56, 5_12, 10_24, 20_48]

					if "1k" in checkpoint_url:
										_lowerCAmelCase         =       10_00
										_lowerCAmelCase         =       '''imagenet-1k-id2label.json'''
										_lowerCAmelCase         =       (1, 10_00)
					else:
										_lowerCAmelCase         =       2_18_41
										_lowerCAmelCase         =       '''imagenet-22k-id2label.json'''
										_lowerCAmelCase         =       (1, 2_18_41)

					_lowerCAmelCase         =       '''huggingface/label-files'''
					_lowerCAmelCase         =       num_labels
					_lowerCAmelCase         =       json.load(open(hf_hub_download(_UpperCAmelCase      ,		_UpperCAmelCase      ,		repo_type="""dataset"""     )      ,		"""r"""     )     )
					_lowerCAmelCase         =       {int(_UpperCAmelCase     ): v for k, v in idalabel.items()}
					if "1k" not in checkpoint_url:
										# this dataset contains 21843 labels but the model only has 21841
										# we delete the classes as mentioned in https://github.com/google-research/big_transfer/issues/18
										del idalabel[92_05]
										del idalabel[1_50_27]
					_lowerCAmelCase         =       idalabel
					_lowerCAmelCase         =       {v: k for k, v in idalabel.items()}
					_lowerCAmelCase         =       hidden_sizes
					_lowerCAmelCase         =       depths

					return config, expected_shape


def 						_UpperCAmelCase							( snake_case     ):





					"""simple docstring"""

					if "downsample_layers.0.0" in name:
										_lowerCAmelCase         =       name.replace("""downsample_layers.0.0"""      ,		"""embeddings.patch_embeddings"""     )
					if "downsample_layers.0.1" in name:
										_lowerCAmelCase         =       name.replace("""downsample_layers.0.1"""      ,		"""embeddings.norm"""     )  # we rename to layernorm later on
					if "downsample_layers.1.0" in name:
										_lowerCAmelCase         =       name.replace("""downsample_layers.1.0"""      ,		"""stages.1.downsampling_layer.0"""     )
					if "downsample_layers.1.1" in name:
										_lowerCAmelCase         =       name.replace("""downsample_layers.1.1"""      ,		"""stages.1.downsampling_layer.1"""     )
					if "downsample_layers.2.0" in name:
										_lowerCAmelCase         =       name.replace("""downsample_layers.2.0"""      ,		"""stages.2.downsampling_layer.0"""     )
					if "downsample_layers.2.1" in name:
										_lowerCAmelCase         =       name.replace("""downsample_layers.2.1"""      ,		"""stages.2.downsampling_layer.1"""     )
					if "downsample_layers.3.0" in name:
										_lowerCAmelCase         =       name.replace("""downsample_layers.3.0"""      ,		"""stages.3.downsampling_layer.0"""     )
					if "downsample_layers.3.1" in name:
										_lowerCAmelCase         =       name.replace("""downsample_layers.3.1"""      ,		"""stages.3.downsampling_layer.1"""     )
					if "stages" in name and "downsampling_layer" not in name:
										# stages.0.0. for instance should be renamed to stages.0.layers.0.
										_lowerCAmelCase         =       name[: len("""stages.0"""     )] + '''.layers''' + name[len("""stages.0"""     ) :]
					if "stages" in name:
										_lowerCAmelCase         =       name.replace("""stages"""      ,		"""encoder.stages"""     )
					if "norm" in name:
										_lowerCAmelCase         =       name.replace("""norm"""      ,		"""layernorm"""     )
					if "gamma" in name:
										_lowerCAmelCase         =       name.replace("""gamma"""      ,		"""layer_scale_parameter"""     )
					if "head" in name:
										_lowerCAmelCase         =       name.replace("""head"""      ,		"""classifier"""     )

					return name


def 						_UpperCAmelCase							( ):





					"""simple docstring"""

					_lowerCAmelCase         =       '''http://images.cocodataset.org/val2017/000000039769.jpg'''
					_lowerCAmelCase         =       Image.open(requests.get(_UpperCAmelCase      ,		stream=_UpperCAmelCase     ).raw     )
					return im


@torch.no_grad()
def 						_UpperCAmelCase							( snake_case      ,		snake_case     ):





					"""simple docstring"""

					_lowerCAmelCase         =       get_convnext_config(_UpperCAmelCase     )
					# load original state_dict from URL
					_lowerCAmelCase         =       torch.hub.load_state_dict_from_url(_UpperCAmelCase     )['''model''']
					# rename keys
					for key in state_dict.copy().keys():
										_lowerCAmelCase         =       state_dict.pop(_UpperCAmelCase     )
										_lowerCAmelCase         =       val
					# add prefix to all keys expect classifier head
					for key in state_dict.copy().keys():
										_lowerCAmelCase         =       state_dict.pop(_UpperCAmelCase     )
										if not key.startswith("""classifier"""     ):
															_lowerCAmelCase         =       '''convnext.''' + key
										_lowerCAmelCase         =       val

					# load HuggingFace model
					_lowerCAmelCase         =       ConvNextForImageClassification(_UpperCAmelCase     )
					model.load_state_dict(_UpperCAmelCase     )
					model.eval()

					# Check outputs on an image, prepared by ConvNextImageProcessor
					_lowerCAmelCase         =       2_24 if '''224''' in checkpoint_url else 3_84
					_lowerCAmelCase         =       ConvNextImageProcessor(size=_UpperCAmelCase     )
					_lowerCAmelCase         =       image_processor(images=prepare_img()      ,		return_tensors="""pt"""     ).pixel_values

					_lowerCAmelCase         =       model(_UpperCAmelCase     ).logits

					# note: the logits below were obtained without center cropping
					if checkpoint_url == "https://dl.fbaipublicfiles.com/convnext/convnext_tiny_1k_224_ema.pth":
										_lowerCAmelCase         =       torch.tensor([-0.1_210, -0.6_605, 0.1_918]     )
					elif checkpoint_url == "https://dl.fbaipublicfiles.com/convnext/convnext_small_1k_224_ema.pth":
										_lowerCAmelCase         =       torch.tensor([-0.4_473, -0.1_847, -0.6_365]     )
					elif checkpoint_url == "https://dl.fbaipublicfiles.com/convnext/convnext_base_1k_224_ema.pth":
										_lowerCAmelCase         =       torch.tensor([0.4_525, 0.7_539, 0.0_308]     )
					elif checkpoint_url == "https://dl.fbaipublicfiles.com/convnext/convnext_base_1k_384.pth":
										_lowerCAmelCase         =       torch.tensor([0.3_561, 0.6_350, -0.0_384]     )
					elif checkpoint_url == "https://dl.fbaipublicfiles.com/convnext/convnext_large_1k_224_ema.pth":
										_lowerCAmelCase         =       torch.tensor([0.4_174, -0.0_989, 0.1_489]     )
					elif checkpoint_url == "https://dl.fbaipublicfiles.com/convnext/convnext_large_1k_384.pth":
										_lowerCAmelCase         =       torch.tensor([0.2_513, -0.1_349, -0.1_613]     )
					elif checkpoint_url == "https://dl.fbaipublicfiles.com/convnext/convnext_base_22k_224.pth":
										_lowerCAmelCase         =       torch.tensor([1.2_980, 0.3_631, -0.1_198]     )
					elif checkpoint_url == "https://dl.fbaipublicfiles.com/convnext/convnext_large_22k_224.pth":
										_lowerCAmelCase         =       torch.tensor([1.2_963, 0.1_227, 0.1_723]     )
					elif checkpoint_url == "https://dl.fbaipublicfiles.com/convnext/convnext_xlarge_22k_224.pth":
										_lowerCAmelCase         =       torch.tensor([1.7_956, 0.8_390, 0.2_820]     )
					elif checkpoint_url == "https://dl.fbaipublicfiles.com/convnext/convnext_base_22k_1k_224.pth":
										_lowerCAmelCase         =       torch.tensor([-0.2_822, -0.0_502, -0.0_878]     )
					elif checkpoint_url == "https://dl.fbaipublicfiles.com/convnext/convnext_base_22k_1k_384.pth":
										_lowerCAmelCase         =       torch.tensor([-0.5_672, -0.0_730, -0.4_348]     )
					elif checkpoint_url == "https://dl.fbaipublicfiles.com/convnext/convnext_large_22k_1k_224.pth":
										_lowerCAmelCase         =       torch.tensor([0.2_681, 0.2_365, 0.6_246]     )
					elif checkpoint_url == "https://dl.fbaipublicfiles.com/convnext/convnext_large_22k_1k_384.pth":
										_lowerCAmelCase         =       torch.tensor([-0.2_642, 0.3_931, 0.5_116]     )
					elif checkpoint_url == "https://dl.fbaipublicfiles.com/convnext/convnext_xlarge_22k_1k_224_ema.pth":
										_lowerCAmelCase         =       torch.tensor([-0.6_677, -0.1_873, -0.8_379]     )
					elif checkpoint_url == "https://dl.fbaipublicfiles.com/convnext/convnext_xlarge_22k_1k_384_ema.pth":
										_lowerCAmelCase         =       torch.tensor([-0.7_749, -0.2_967, -0.6_444]     )
					else:
										raise ValueError(F'Unknown URL: {checkpoint_url}'     )

					assert torch.allclose(logits[0, :3]      ,		_UpperCAmelCase      ,		atol=1E-3     )
					assert logits.shape == expected_shape

					Path(_UpperCAmelCase     ).mkdir(exist_ok=_UpperCAmelCase     )
					print(F'Saving model to {pytorch_dump_folder_path}'     )
					model.save_pretrained(_UpperCAmelCase     )
					print(F'Saving image processor to {pytorch_dump_folder_path}'     )
					image_processor.save_pretrained(_UpperCAmelCase     )

					print("""Pushing model to the hub..."""     )
					_lowerCAmelCase         =       '''convnext'''
					if "tiny" in checkpoint_url:
										model_name += "-tiny"
					elif "small" in checkpoint_url:
										model_name += "-small"
					elif "base" in checkpoint_url:
										model_name += "-base"
					elif "xlarge" in checkpoint_url:
										model_name += "-xlarge"
					elif "large" in checkpoint_url:
										model_name += "-large"
					if "224" in checkpoint_url:
										model_name += "-224"
					elif "384" in checkpoint_url:
										model_name += "-384"
					if "22k" in checkpoint_url and "1k" not in checkpoint_url:
										model_name += "-22k"
					if "22k" in checkpoint_url and "1k" in checkpoint_url:
										model_name += "-22k-1k"

					model.push_to_hub(
					    repo_path_or_name=Path(_UpperCAmelCase      ,		_UpperCAmelCase     )      ,		organization="""nielsr"""      ,		commit_message="""Add model"""      ,		)


if __name__ == "__main__":
	A__       =			argparse.ArgumentParser()
	# Required parameters
	parser.add_argument(
	    """--checkpoint_url""",
	    default="""https://dl.fbaipublicfiles.com/convnext/convnext_tiny_1k_224_ema.pth""",
	    type=str,
	    help="""URL of the original ConvNeXT checkpoint you\'d like to convert.""",
	)
	parser.add_argument(
	    """--pytorch_dump_folder_path""",
	    default=None,
	    type=str,
	    required=True,
	    help="""Path to the output PyTorch model directory.""",
	)

	A__       =			parser.parse_args()
	convert_convnext_checkpoint(args.checkpoint_url, args.pytorch_dump_folder_path)









"""simple docstring"""

class 							lowercase   :







				def __init__(				self :       Union[str, Any]   ,  _lowerCamelCase :       int							):



					"""simple docstring"""

					A_	:					Optional[int]						 =		data
					A_	:					int
					A_	:					Node

def 		lowercase_   (		_UpperCAmelCase						):




	"""simple docstring"""






	A_	:					List[str]						 =		0
	A_	:					List[str]						 =		x

def 		lowercase_   (		_UpperCAmelCase	,   _UpperCAmelCase						):




	"""simple docstring"""






	A_ ,			A_	:					Any						 =		find_set(_UpperCAmelCase						), find_set(_UpperCAmelCase						)
	if x == y:
		return

	elif x.rank > y.rank:
		A_	:					Optional[int]						 =		x
	else:
		A_	:					Optional[int]						 =		y
		if x.rank == y.rank:
			y.rank += 1

def 		lowercase_   (		_UpperCAmelCase						):




	"""simple docstring"""






	if x != x.parent:
		A_	:					Union[str, Any]						 =		find_set(x.parent						)
	return x.parent

def 		lowercase_   (		_UpperCAmelCase						):




	"""simple docstring"""






	A_	:					str						 =		({0, 1, 2}, {3, 4, 5})
	for s in sets:
		if node.data in s:
			return s
	A_	:					Optional[int]						 =		f"""{node.data} is not in {sets}"""
	raise ValueError(_UpperCAmelCase						)

def 		lowercase_   (		):




	"""simple docstring"""






	A_	:					Dict						 =		[Node(_UpperCAmelCase						) for i in range(6						)]
	for v in vertex:
		make_set(_UpperCAmelCase						)

	union_set(vertex[0]	,   vertex[1]						)
	union_set(vertex[1]	,   vertex[2]						)
	union_set(vertex[3]	,   vertex[4]						)
	union_set(vertex[3]	,   vertex[5]						)

	for nodea in vertex:
		for nodea in vertex:
			if find_python_set(_UpperCAmelCase						).isdisjoint(find_python_set(_UpperCAmelCase						)						):
				assert find_set(_UpperCAmelCase						) != find_set(_UpperCAmelCase						)
			else:
				assert find_set(_UpperCAmelCase						) == find_set(_UpperCAmelCase						)


if __name__ == "__main__":
		test_disjoint_set()





