

import argparse
import json

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

from transformers import ViTImageProcessor, ViTMSNConfig, ViTMSNModel
from transformers.image_utils import IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD


torch.set_grad_enabled(False)






def        snake_case__		(    lowerCamelCase_     ,				lowerCamelCase_=False		):
							A      :					Optional[Any]      		=					[]
							for i in range(config.num_hidden_layers		):
														# encoder layers: output projection, 2 feedforward neural networks and 2 layernorms
														rename_keys.append((F'module.blocks.{i}.norm1.weight', F'vit.encoder.layer.{i}.layernorm_before.weight')		)
														rename_keys.append((F'module.blocks.{i}.norm1.bias', F'vit.encoder.layer.{i}.layernorm_before.bias')		)
														rename_keys.append(
														    (F'module.blocks.{i}.attn.proj.weight', F'vit.encoder.layer.{i}.attention.output.dense.weight')		)
														rename_keys.append((F'module.blocks.{i}.attn.proj.bias', F'vit.encoder.layer.{i}.attention.output.dense.bias')		)
														rename_keys.append((F'module.blocks.{i}.norm2.weight', F'vit.encoder.layer.{i}.layernorm_after.weight')		)
														rename_keys.append((F'module.blocks.{i}.norm2.bias', F'vit.encoder.layer.{i}.layernorm_after.bias')		)
														rename_keys.append((F'module.blocks.{i}.mlp.fc1.weight', F'vit.encoder.layer.{i}.intermediate.dense.weight')		)
														rename_keys.append((F'module.blocks.{i}.mlp.fc1.bias', F'vit.encoder.layer.{i}.intermediate.dense.bias')		)
														rename_keys.append((F'module.blocks.{i}.mlp.fc2.weight', F'vit.encoder.layer.{i}.output.dense.weight')		)
														rename_keys.append((F'module.blocks.{i}.mlp.fc2.bias', F'vit.encoder.layer.{i}.output.dense.bias')		)

							# projection layer + position embeddings
							rename_keys.extend(
							    [
							        ('''module.cls_token''', '''vit.embeddings.cls_token'''),
							        ('''module.patch_embed.proj.weight''', '''vit.embeddings.patch_embeddings.projection.weight'''),
							        ('''module.patch_embed.proj.bias''', '''vit.embeddings.patch_embeddings.projection.bias'''),
							        ('''module.pos_embed''', '''vit.embeddings.position_embeddings'''),
							    ]		)

							if base_model:
														# layernorm + pooler
														rename_keys.extend(
														    [
														        ('''module.norm.weight''', '''layernorm.weight'''),
														        ('''module.norm.bias''', '''layernorm.bias'''),
														    ]		)

														# if just the base model, we should remove "vit" from all keys that start with "vit"
														A      :					int      		=					[(pair[0], pair[1][4:]) if pair[1].startswith('''vit'''		) else pair for pair in rename_keys]
							else:
														# layernorm + classification head
														rename_keys.extend(
														    [
														        ('''norm.weight''', '''vit.layernorm.weight'''),
														        ('''norm.bias''', '''vit.layernorm.bias'''),
														        ('''head.weight''', '''classifier.weight'''),
														        ('''head.bias''', '''classifier.bias'''),
														    ]		)

							return rename_keys






def        snake_case__		(    lowerCamelCase_     ,				lowerCamelCase_     ,				lowerCamelCase_=False		):
							for i in range(config.num_hidden_layers		):
														if base_model:
																					A      :					int      		=					''''''
														else:
																					A      :					Tuple      		=					'''vit.'''
														# read in weights + bias of input projection layer (in timm, this is a single matrix + bias)
														A      :					Union[str, Any]      		=					state_dict.pop(F'module.blocks.{i}.attn.qkv.weight'		)
														A      :					Union[str, Any]      		=					state_dict.pop(F'module.blocks.{i}.attn.qkv.bias'		)
														# next, add query, keys and values (in that order) to the state dict
														A      :					Optional[Any]      		=					in_proj_weight[
														    : config.hidden_size, :
														]
														A      :					List[str]      		=					in_proj_bias[: config.hidden_size]
														A      :					Optional[Any]      		=					in_proj_weight[
														    config.hidden_size : config.hidden_size * 2, :
														]
														A      :					Any      		=					in_proj_bias[
														    config.hidden_size : config.hidden_size * 2
														]
														A      :					Union[str, Any]      		=					in_proj_weight[
														    -config.hidden_size :, :
														]
														A      :					List[str]      		=					in_proj_bias[-config.hidden_size :]






def        snake_case__		(    lowerCamelCase_		):
							A      :					str      		=					['''head.weight''', '''head.bias''']
							for k in ignore_keys:
														state_dict.pop(lowerCamelCase_     ,				lowerCamelCase_		)






def        snake_case__		(    lowerCamelCase_		):
							# projection head is used in the self-supervised pre-training in MSN,
							# for downstream task it's not needed.
							A      :					Dict      		=					[
							    '''module.fc.fc1.weight''',
							    '''module.fc.fc1.bias''',
							    '''module.fc.bn1.weight''',
							    '''module.fc.bn1.bias''',
							    '''module.fc.bn1.running_mean''',
							    '''module.fc.bn1.running_var''',
							    '''module.fc.bn1.num_batches_tracked''',
							    '''module.fc.fc2.weight''',
							    '''module.fc.fc2.bias''',
							    '''module.fc.bn2.weight''',
							    '''module.fc.bn2.bias''',
							    '''module.fc.bn2.running_mean''',
							    '''module.fc.bn2.running_var''',
							    '''module.fc.bn2.num_batches_tracked''',
							    '''module.fc.fc3.weight''',
							    '''module.fc.fc3.bias''',
							]
							for k in ignore_keys:
														state_dict.pop(lowerCamelCase_     ,				lowerCamelCase_		)






def        snake_case__		(    lowerCamelCase_     ,				lowerCamelCase_     ,				lowerCamelCase_		):
							A      :					Optional[int]      		=					dct.pop(lowerCamelCase_		)
							A      :					Any      		=					val






def        snake_case__		(    lowerCamelCase_     ,				lowerCamelCase_		):
							A      :					Tuple      		=					ViTMSNConfig()
							A      :					Optional[int]      		=					1000

							A      :					Dict      		=					'''datasets/huggingface/label-files'''
							A      :					Any      		=					'''imagenet-1k-id2label.json'''
							A      :					Tuple      		=					json.load(open(hf_hub_download(lowerCamelCase_     ,				lowerCamelCase_		)     ,				'''r'''		)		)
							A      :					Union[str, Any]      		=					{int(lowerCamelCase_		): v for k, v in idalabel.items()}
							A      :					Dict      		=					idalabel
							A      :					Union[str, Any]      		=					{v: k for k, v in idalabel.items()}

							if "s16" in checkpoint_url:
														A      :					Optional[int]      		=					384
														A      :					Tuple      		=					1536
														A      :					Optional[Any]      		=					6
							elif "l16" in checkpoint_url:
														A      :					Optional[int]      		=					1024
														A      :					Optional[int]      		=					4096
														A      :					Union[str, Any]      		=					24
														A      :					Optional[Any]      		=					16
														A      :					int      		=					0.1
							elif "b4" in checkpoint_url:
														A      :					Optional[int]      		=					4
							elif "l7" in checkpoint_url:
														A      :					int      		=					7
														A      :					Any      		=					1024
														A      :					str      		=					4096
														A      :					int      		=					24
														A      :					str      		=					16
														A      :					List[Any]      		=					0.1

							A      :					Tuple      		=					ViTMSNModel(lowerCamelCase_		)

							A      :					Optional[Any]      		=					torch.hub.load_state_dict_from_url(lowerCamelCase_     ,				map_location='''cpu'''		)['''target_encoder''']

							A      :					Dict      		=					ViTImageProcessor(size=config.image_size		)

							remove_projection_head(lowerCamelCase_		)
							A      :					List[str]      		=					create_rename_keys(lowerCamelCase_     ,				base_model=lowerCamelCase_		)

							for src, dest in rename_keys:
														rename_key(lowerCamelCase_     ,				lowerCamelCase_     ,				lowerCamelCase_		)
							read_in_q_k_v(lowerCamelCase_     ,				lowerCamelCase_     ,				base_model=lowerCamelCase_		)

							model.load_state_dict(lowerCamelCase_		)
							model.eval()

							A      :					Any      		=					'''http://images.cocodataset.org/val2017/000000039769.jpg'''

							A      :					str      		=					Image.open(requests.get(lowerCamelCase_     ,				stream=lowerCamelCase_		).raw		)
							A      :					Union[str, Any]      		=					ViTImageProcessor(
							    size=config.image_size     ,				image_mean=lowerCamelCase_     ,				image_std=lowerCamelCase_		)
							A      :					Optional[Any]      		=					image_processor(images=lowerCamelCase_     ,				return_tensors='''pt'''		)

							# forward pass
							torch.manual_seed(2		)
							A      :					Optional[Any]      		=					model(**lowerCamelCase_		)
							A      :					Optional[int]      		=					outputs.last_hidden_state

							# The following Colab Notebook was used to generate these outputs:
							# https://colab.research.google.com/gist/sayakpaul/3672419a04f5997827503fd84079bdd1/scratchpad.ipynb
							if "s16" in checkpoint_url:
														A      :					List[str]      		=					torch.tensor([[-1.0_915, -1.4_876, -1.1_809]]		)
							elif "b16" in checkpoint_url:
														A      :					Dict      		=					torch.tensor([[14.2_889, -18.9_045, 11.7_281]]		)
							elif "l16" in checkpoint_url:
														A      :					Tuple      		=					torch.tensor([[41.5_028, -22.8_681, 45.6_475]]		)
							elif "b4" in checkpoint_url:
														A      :					Optional[int]      		=					torch.tensor([[-4.3_868, 5.2_932, -0.4_137]]		)
							else:
														A      :					Optional[Any]      		=					torch.tensor([[-0.1_792, -0.6_465, 2.4_263]]		)

							# verify logits
							assert torch.allclose(last_hidden_state[:, 0, :3]     ,				lowerCamelCase_     ,				atol=1E-4		)

							print(F'Saving model to {pytorch_dump_folder_path}'		)
							model.save_pretrained(lowerCamelCase_		)

							print(F'Saving image processor to {pytorch_dump_folder_path}'		)
							image_processor.save_pretrained(lowerCamelCase_		)


if __name__ == "__main__":
		lowercase			:				Dict   =     argparse.ArgumentParser()
		# Required parameters
		parser.add_argument(
		    "--checkpoint_url",
		    default="https://dl.fbaipublicfiles.com/msn/vits16_800ep.pth.tar",
		    type=str,
		    help="URL of the checkpoint you'd like to convert.",
		)
		parser.add_argument(
		    "--pytorch_dump_folder_path", default=None, type=str, help="Path to the output PyTorch model directory."
		)

		lowercase			:				Dict   =     parser.parse_args()
		convert_vit_msn_checkpoint(args.checkpoint_url, args.pytorch_dump_folder_path)









lowercase			:				Dict   =     [sum(int(c, 10) ** 2 for c in i.__str__()) for i in range(10_00_00)]






def        snake_case__		(    lowerCamelCase_		):
							A      :					List[str]      		=					0
							while number:
														# Increased Speed Slightly by checking every 5 digits together.
														sum_of_digits_squared += DIGITS_SQUARED[number % 100000]
														number //= 100000

							return sum_of_digits_squared


# There are 2 Chains made,
# One ends with 89 with the chain member 58 being the one which when declared first,
# there will be the least number of iterations for all the members to be checked.

# The other one ends with 1 and has only one element 1.

# So 58 and 1 are chosen to be declared at the starting.

# Changed dictionary to an array to quicken the solution
lowercase			:				list[bool | None]   =     [None] * 10_00_00_00
lowercase			:				int   =     True
lowercase			:				Tuple   =     False






def        snake_case__		(    lowerCamelCase_		):

							if CHAINS[number - 1] is not None:
														return CHAINS[number - 1]  # type: ignore

							A      :					int      		=					chain(next_number(lowerCamelCase_		)		)
							A      :					Dict      		=					number_chain

							while number < 10000000:
														A      :					Any      		=					number_chain
														number *= 10

							return number_chain






def        snake_case__		(    lowerCamelCase_ = 10000000		):
							for i in range(1     ,				lowerCamelCase_		):
														if CHAINS[i] is None:
																					chain(i + 1		)

							return CHAINS[:number].count(lowerCamelCase_		)


if __name__ == "__main__":
		import doctest

		doctest.testmod()
		print(F"{solution() = }")






