






import argparse
import json
from pathlib import Path

import requests
import torch
from huggingface_hub import cached_download, hf_hub_download, hf_hub_url
from PIL import Image

from transformers import DetaConfig, DetaForObjectDetection, DetaImageProcessor, SwinConfig
from transformers.utils import logging


logging.set_verbosity_info()
__UpperCAmelCase							:   int							=  logging.get_logger(__name__)


def 					lowercase_ (    __snake_case     :							Tuple      )     -> str:





				'''simple docstring'''


				snake_case__      :List[str]         =   SwinConfig(
				    embed_dim=1_92	,	depths=(2, 2, 18, 2)	,	num_heads=(6, 12, 24, 48)	,	window_size=12	,	out_features=["stage2", "stage3", "stage4"]	,	)

				snake_case__      :Optional[int]         =   DetaConfig(
				    backbone_config=_lowerCamelCase	,	num_queries=9_00	,	encoder_ffn_dim=20_48	,	decoder_ffn_dim=20_48	,	num_feature_levels=5	,	assign_first_stage=_lowerCamelCase	,	with_box_refine=_lowerCamelCase	,	two_stage=_lowerCamelCase	,	)

				# set labels
				snake_case__      :List[str]         =   "huggingface/label-files"
				if "o365" in model_name:
								snake_case__      :Optional[Any]         =   3_66
								snake_case__      :List[str]         =   "object365-id2label.json"
				else:
								snake_case__      :List[Any]         =   91
								snake_case__      :Any         =   "coco-detection-id2label.json"

				snake_case__      :Union[str, Any]         =   num_labels
				snake_case__      :Tuple         =   json.load(open(cached_download(hf_hub_url(_lowerCamelCase	,	_lowerCamelCase	,	repo_type="dataset"      )      )	,	"r"      )      )
				snake_case__      :List[Any]         =   {int(_lowerCamelCase      ): v for k, v in idalabel.items()}
				snake_case__      :str         =   idalabel
				snake_case__      :Any         =   {v: k for k, v in idalabel.items()}

				return config


def 					lowercase_ (    __snake_case     :							Any      )     -> Dict:





				'''simple docstring'''


				snake_case__      :str         =   []

				# stem
				# fmt: off
				rename_keys.append(("backbone.0.body.patch_embed.proj.weight", "model.backbone.model.embeddings.patch_embeddings.projection.weight")      )
				rename_keys.append(("backbone.0.body.patch_embed.proj.bias", "model.backbone.model.embeddings.patch_embeddings.projection.bias")      )
				rename_keys.append(("backbone.0.body.patch_embed.norm.weight", "model.backbone.model.embeddings.norm.weight")      )
				rename_keys.append(("backbone.0.body.patch_embed.norm.bias", "model.backbone.model.embeddings.norm.bias")      )
				# stages
				for i in range(len(config.backbone_config.depths      )      ):
								for j in range(config.backbone_config.depths[i]      ):
												rename_keys.append((F'backbone.0.body.layers.{i}.blocks.{j}.norm1.weight', F'model.backbone.model.encoder.layers.{i}.blocks.{j}.layernorm_before.weight')      )
												rename_keys.append((F'backbone.0.body.layers.{i}.blocks.{j}.norm1.bias', F'model.backbone.model.encoder.layers.{i}.blocks.{j}.layernorm_before.bias')      )
												rename_keys.append((F'backbone.0.body.layers.{i}.blocks.{j}.attn.relative_position_bias_table', F'model.backbone.model.encoder.layers.{i}.blocks.{j}.attention.self.relative_position_bias_table')      )
												rename_keys.append((F'backbone.0.body.layers.{i}.blocks.{j}.attn.relative_position_index', F'model.backbone.model.encoder.layers.{i}.blocks.{j}.attention.self.relative_position_index')      )
												rename_keys.append((F'backbone.0.body.layers.{i}.blocks.{j}.attn.proj.weight', F'model.backbone.model.encoder.layers.{i}.blocks.{j}.attention.output.dense.weight')      )
												rename_keys.append((F'backbone.0.body.layers.{i}.blocks.{j}.attn.proj.bias', F'model.backbone.model.encoder.layers.{i}.blocks.{j}.attention.output.dense.bias')      )
												rename_keys.append((F'backbone.0.body.layers.{i}.blocks.{j}.norm2.weight', F'model.backbone.model.encoder.layers.{i}.blocks.{j}.layernorm_after.weight')      )
												rename_keys.append((F'backbone.0.body.layers.{i}.blocks.{j}.norm2.bias', F'model.backbone.model.encoder.layers.{i}.blocks.{j}.layernorm_after.bias')      )
												rename_keys.append((F'backbone.0.body.layers.{i}.blocks.{j}.mlp.fc1.weight', F'model.backbone.model.encoder.layers.{i}.blocks.{j}.intermediate.dense.weight')      )
												rename_keys.append((F'backbone.0.body.layers.{i}.blocks.{j}.mlp.fc1.bias', F'model.backbone.model.encoder.layers.{i}.blocks.{j}.intermediate.dense.bias')      )
												rename_keys.append((F'backbone.0.body.layers.{i}.blocks.{j}.mlp.fc2.weight', F'model.backbone.model.encoder.layers.{i}.blocks.{j}.output.dense.weight')      )
												rename_keys.append((F'backbone.0.body.layers.{i}.blocks.{j}.mlp.fc2.bias', F'model.backbone.model.encoder.layers.{i}.blocks.{j}.output.dense.bias')      )

								if i < 3:
												rename_keys.append((F'backbone.0.body.layers.{i}.downsample.reduction.weight', F'model.backbone.model.encoder.layers.{i}.downsample.reduction.weight')      )
												rename_keys.append((F'backbone.0.body.layers.{i}.downsample.norm.weight', F'model.backbone.model.encoder.layers.{i}.downsample.norm.weight')      )
												rename_keys.append((F'backbone.0.body.layers.{i}.downsample.norm.bias', F'model.backbone.model.encoder.layers.{i}.downsample.norm.bias')      )

				rename_keys.append(("backbone.0.body.norm1.weight", "model.backbone.model.hidden_states_norms.stage2.weight")      )
				rename_keys.append(("backbone.0.body.norm1.bias", "model.backbone.model.hidden_states_norms.stage2.bias")      )
				rename_keys.append(("backbone.0.body.norm2.weight", "model.backbone.model.hidden_states_norms.stage3.weight")      )
				rename_keys.append(("backbone.0.body.norm2.bias", "model.backbone.model.hidden_states_norms.stage3.bias")      )
				rename_keys.append(("backbone.0.body.norm3.weight", "model.backbone.model.hidden_states_norms.stage4.weight")      )
				rename_keys.append(("backbone.0.body.norm3.bias", "model.backbone.model.hidden_states_norms.stage4.bias")      )

				# transformer encoder
				for i in range(config.encoder_layers      ):
								rename_keys.append((F'transformer.encoder.layers.{i}.self_attn.sampling_offsets.weight', F'model.encoder.layers.{i}.self_attn.sampling_offsets.weight')      )
								rename_keys.append((F'transformer.encoder.layers.{i}.self_attn.sampling_offsets.bias', F'model.encoder.layers.{i}.self_attn.sampling_offsets.bias')      )
								rename_keys.append((F'transformer.encoder.layers.{i}.self_attn.attention_weights.weight', F'model.encoder.layers.{i}.self_attn.attention_weights.weight')      )
								rename_keys.append((F'transformer.encoder.layers.{i}.self_attn.attention_weights.bias', F'model.encoder.layers.{i}.self_attn.attention_weights.bias')      )
								rename_keys.append((F'transformer.encoder.layers.{i}.self_attn.value_proj.weight', F'model.encoder.layers.{i}.self_attn.value_proj.weight')      )
								rename_keys.append((F'transformer.encoder.layers.{i}.self_attn.value_proj.bias', F'model.encoder.layers.{i}.self_attn.value_proj.bias')      )
								rename_keys.append((F'transformer.encoder.layers.{i}.self_attn.output_proj.weight', F'model.encoder.layers.{i}.self_attn.output_proj.weight')      )
								rename_keys.append((F'transformer.encoder.layers.{i}.self_attn.output_proj.bias', F'model.encoder.layers.{i}.self_attn.output_proj.bias')      )
								rename_keys.append((F'transformer.encoder.layers.{i}.norm1.weight', F'model.encoder.layers.{i}.self_attn_layer_norm.weight')      )
								rename_keys.append((F'transformer.encoder.layers.{i}.norm1.bias', F'model.encoder.layers.{i}.self_attn_layer_norm.bias')      )
								rename_keys.append((F'transformer.encoder.layers.{i}.linear1.weight', F'model.encoder.layers.{i}.fc1.weight')      )
								rename_keys.append((F'transformer.encoder.layers.{i}.linear1.bias', F'model.encoder.layers.{i}.fc1.bias')      )
								rename_keys.append((F'transformer.encoder.layers.{i}.linear2.weight', F'model.encoder.layers.{i}.fc2.weight')      )
								rename_keys.append((F'transformer.encoder.layers.{i}.linear2.bias', F'model.encoder.layers.{i}.fc2.bias')      )
								rename_keys.append((F'transformer.encoder.layers.{i}.norm2.weight', F'model.encoder.layers.{i}.final_layer_norm.weight')      )
								rename_keys.append((F'transformer.encoder.layers.{i}.norm2.bias', F'model.encoder.layers.{i}.final_layer_norm.bias')      )

				# transformer decoder
				for i in range(config.decoder_layers      ):
								rename_keys.append((F'transformer.decoder.layers.{i}.cross_attn.sampling_offsets.weight', F'model.decoder.layers.{i}.encoder_attn.sampling_offsets.weight')      )
								rename_keys.append((F'transformer.decoder.layers.{i}.cross_attn.sampling_offsets.bias', F'model.decoder.layers.{i}.encoder_attn.sampling_offsets.bias')      )
								rename_keys.append((F'transformer.decoder.layers.{i}.cross_attn.attention_weights.weight', F'model.decoder.layers.{i}.encoder_attn.attention_weights.weight')      )
								rename_keys.append((F'transformer.decoder.layers.{i}.cross_attn.attention_weights.bias', F'model.decoder.layers.{i}.encoder_attn.attention_weights.bias')      )
								rename_keys.append((F'transformer.decoder.layers.{i}.cross_attn.value_proj.weight', F'model.decoder.layers.{i}.encoder_attn.value_proj.weight')      )
								rename_keys.append((F'transformer.decoder.layers.{i}.cross_attn.value_proj.bias', F'model.decoder.layers.{i}.encoder_attn.value_proj.bias')      )
								rename_keys.append((F'transformer.decoder.layers.{i}.cross_attn.output_proj.weight', F'model.decoder.layers.{i}.encoder_attn.output_proj.weight')      )
								rename_keys.append((F'transformer.decoder.layers.{i}.cross_attn.output_proj.bias', F'model.decoder.layers.{i}.encoder_attn.output_proj.bias')      )
								rename_keys.append((F'transformer.decoder.layers.{i}.norm1.weight', F'model.decoder.layers.{i}.encoder_attn_layer_norm.weight')      )
								rename_keys.append((F'transformer.decoder.layers.{i}.norm1.bias', F'model.decoder.layers.{i}.encoder_attn_layer_norm.bias')      )
								rename_keys.append((F'transformer.decoder.layers.{i}.self_attn.out_proj.weight', F'model.decoder.layers.{i}.self_attn.out_proj.weight')      )
								rename_keys.append((F'transformer.decoder.layers.{i}.self_attn.out_proj.bias', F'model.decoder.layers.{i}.self_attn.out_proj.bias')      )
								rename_keys.append((F'transformer.decoder.layers.{i}.norm2.weight', F'model.decoder.layers.{i}.self_attn_layer_norm.weight')      )
								rename_keys.append((F'transformer.decoder.layers.{i}.norm2.bias', F'model.decoder.layers.{i}.self_attn_layer_norm.bias')      )
								rename_keys.append((F'transformer.decoder.layers.{i}.linear1.weight', F'model.decoder.layers.{i}.fc1.weight')      )
								rename_keys.append((F'transformer.decoder.layers.{i}.linear1.bias', F'model.decoder.layers.{i}.fc1.bias')      )
								rename_keys.append((F'transformer.decoder.layers.{i}.linear2.weight', F'model.decoder.layers.{i}.fc2.weight')      )
								rename_keys.append((F'transformer.decoder.layers.{i}.linear2.bias', F'model.decoder.layers.{i}.fc2.bias')      )
								rename_keys.append((F'transformer.decoder.layers.{i}.norm3.weight', F'model.decoder.layers.{i}.final_layer_norm.weight')      )
								rename_keys.append((F'transformer.decoder.layers.{i}.norm3.bias', F'model.decoder.layers.{i}.final_layer_norm.bias')      )

				# fmt: on

				return rename_keys


def 					lowercase_ (    __snake_case     :							Any	,	__snake_case     :							List[Any]	,	__snake_case     :							Optional[int]      )     -> List[Any]:





				'''simple docstring'''


				snake_case__      :Dict         =   dct.pop(_lowerCamelCase      )
				snake_case__      :List[Any]         =   val


def 					lowercase_ (    __snake_case     :							Dict	,	__snake_case     :							Union[str, Any]      )     -> Optional[int]:





				'''simple docstring'''


				snake_case__      :str         =   [int(backbone_config.embed_dim * 2**i      ) for i in range(len(backbone_config.depths      )      )]
				for i in range(len(backbone_config.depths      )      ):
								snake_case__      :List[Any]         =   num_features[i]
								for j in range(backbone_config.depths[i]      ):
												# fmt: off
												# read in weights + bias of input projection layer (in original implementation, this is a single matrix + bias)
												snake_case__      :Optional[Any]         =   state_dict.pop(F'backbone.0.body.layers.{i}.blocks.{j}.attn.qkv.weight'      )
												snake_case__      :str         =   state_dict.pop(F'backbone.0.body.layers.{i}.blocks.{j}.attn.qkv.bias'      )
												# next, add query, keys and values (in that order) to the state dict
												snake_case__      :List[str]         =   in_proj_weight[:dim, :]
												snake_case__      :Tuple         =   in_proj_bias[: dim]
												snake_case__      :Dict         =   in_proj_weight[
												    dim : dim * 2, :
												]
												snake_case__      :Tuple         =   in_proj_bias[
												    dim : dim * 2
												]
												snake_case__      :List[Any]         =   in_proj_weight[
												    -dim :, :
												]
												snake_case__      :Dict         =   in_proj_bias[-dim :]
												# fmt: on


def 					lowercase_ (    __snake_case     :							List[str]	,	__snake_case     :							Union[str, Any]      )     -> Any:





				'''simple docstring'''


				snake_case__      :str         =   config.d_model
				for i in range(config.decoder_layers      ):
								# read in weights + bias of input projection layer of self-attention
								snake_case__      :Any         =   state_dict.pop(F'transformer.decoder.layers.{i}.self_attn.in_proj_weight'      )
								snake_case__      :Any         =   state_dict.pop(F'transformer.decoder.layers.{i}.self_attn.in_proj_bias'      )
								# next, add query, keys and values (in that order) to the state dict
								snake_case__      :Any         =   in_proj_weight[:hidden_size, :]
								snake_case__      :str         =   in_proj_bias[:hidden_size]
								snake_case__      :Any         =   in_proj_weight[
								    hidden_size : hidden_size * 2, :
								]
								snake_case__      :Dict         =   in_proj_bias[hidden_size : hidden_size * 2]
								snake_case__      :Union[str, Any]         =   in_proj_weight[-hidden_size:, :]
								snake_case__      :Tuple         =   in_proj_bias[-hidden_size:]


def 					lowercase_ (    )     -> Any:





				'''simple docstring'''


				snake_case__      :Any         =   "http://images.cocodataset.org/val2017/000000039769.jpg"
				snake_case__      :Dict         =   Image.open(requests.get(_lowerCamelCase	,	stream=_lowerCamelCase      ).raw      )

				return im


@torch.no_grad()
def 					lowercase_ (    __snake_case     :							Union[str, Any]	,	__snake_case     :							List[str]	,	__snake_case     :							str      )     -> Optional[Any]:





				'''simple docstring'''


				snake_case__      :Union[str, Any]         =   get_deta_config(_lowerCamelCase      )

				# load original state dict
				if model_name == "deta-swin-large":
								snake_case__      :Dict         =   hf_hub_download(repo_id="nielsr/deta-checkpoints"	,	filename="adet_swin_ft.pth"      )
				elif model_name == "deta-swin-large-o365":
								snake_case__      :Union[str, Any]         =   hf_hub_download(repo_id="jozhang97/deta-swin-l-o365"	,	filename="deta_swin_pt_o365.pth"      )
				else:
								raise ValueError(F'Model name {model_name} not supported'      )

				snake_case__      :str         =   torch.load(_lowerCamelCase	,	map_location="cpu"      )["model"]

				# original state dict
				for name, param in state_dict.items():
								print(_lowerCamelCase	,	param.shape      )

				# rename keys
				snake_case__      :Tuple         =   create_rename_keys(_lowerCamelCase      )
				for src, dest in rename_keys:
								rename_key(_lowerCamelCase	,	_lowerCamelCase	,	_lowerCamelCase      )
				read_in_swin_q_k_v(_lowerCamelCase	,	config.backbone_config      )
				read_in_decoder_q_k_v(_lowerCamelCase	,	_lowerCamelCase      )

				# fix some prefixes
				for key in state_dict.copy().keys():
								if "transformer.decoder.class_embed" in key or "transformer.decoder.bbox_embed" in key:
												snake_case__      :Optional[int]         =   state_dict.pop(_lowerCamelCase      )
												snake_case__      :List[Any]         =   val
								if "input_proj" in key:
												snake_case__      :Union[str, Any]         =   state_dict.pop(_lowerCamelCase      )
												snake_case__      :Optional[int]         =   val
								if "level_embed" in key or "pos_trans" in key or "pix_trans" in key or "enc_output" in key:
												snake_case__      :List[Any]         =   state_dict.pop(_lowerCamelCase      )
												snake_case__      :Tuple         =   val

    # finally, create HuggingFace model and load state dict
				snake_case__      :Dict         =   DetaForObjectDetection(_lowerCamelCase      )
				model.load_state_dict(_lowerCamelCase      )
				model.eval()

				snake_case__      :Union[str, Any]         =   "cuda" if torch.cuda.is_available() else "cpu"
				model.to(_lowerCamelCase      )

				# load image processor
				snake_case__      :Dict         =   DetaImageProcessor(format="coco_detection"      )

				# verify our conversion on image
				snake_case__      :List[str]         =   prepare_img()
				snake_case__      :List[str]         =   processor(images=_lowerCamelCase	,	return_tensors="pt"      )
				snake_case__      :Dict         =   encoding["pixel_values"]
				snake_case__      :str         =   model(pixel_values.to(_lowerCamelCase      )      )

				# verify logits
				print("Logits:"	,	outputs.logits[0, :3, :3]      )
				print("Boxes:"	,	outputs.pred_boxes[0, :3, :3]      )
				if model_name == "deta-swin-large":
								snake_case__      :str         =   torch.tensor(
								    [[-7.6_3_0_8, -2.8_4_8_5, -5.3_7_3_7], [-7.2_0_3_7, -4.5_5_0_5, -4.8_0_2_7], [-7.2_9_4_3, -4.2_6_1_1, -4.6_6_1_7]]      )
								snake_case__      :Dict         =   torch.tensor([[0.4_9_8_7, 0.4_9_6_9, 0.9_9_9_9], [0.2_5_4_9, 0.5_4_9_8, 0.4_8_0_5], [0.5_4_9_8, 0.2_7_5_7, 0.0_5_6_9]]      )
				elif model_name == "deta-swin-large-o365":
								snake_case__      :Union[str, Any]         =   torch.tensor(
								    [[-8.0_1_2_2, -3.5_7_2_0, -4.9_7_1_7], [-8.1_5_4_7, -3.6_8_8_6, -4.6_3_8_9], [-7.6_6_1_0, -3.6_1_9_4, -5.0_1_3_4]]      )
								snake_case__      :int         =   torch.tensor([[0.2_5_2_3, 0.5_5_4_9, 0.4_8_8_1], [0.7_7_1_5, 0.4_1_4_9, 0.4_6_0_1], [0.5_5_0_3, 0.2_7_5_3, 0.0_5_7_5]]      )
				assert torch.allclose(outputs.logits[0, :3, :3]	,	expected_logits.to(_lowerCamelCase      )	,	atol=1e-4      )
				assert torch.allclose(outputs.pred_boxes[0, :3, :3]	,	expected_boxes.to(_lowerCamelCase      )	,	atol=1e-4      )
				print("Everything ok!"      )

				if pytorch_dump_folder_path:
								# Save model and processor
								logger.info(F'Saving PyTorch model and processor to {pytorch_dump_folder_path}...'      )
								Path(_lowerCamelCase      ).mkdir(exist_ok=_lowerCamelCase      )
								model.save_pretrained(_lowerCamelCase      )
								processor.save_pretrained(_lowerCamelCase      )

				# Push to hub
				if push_to_hub:
								print("Pushing model and processor to hub..."      )
								model.push_to_hub(F'jozhang97/{model_name}'      )
								processor.push_to_hub(F'jozhang97/{model_name}'      )


if __name__ == "__main__":
	__UpperCAmelCase							:   List[str]							=  argparse.ArgumentParser()

	parser.add_argument(
	    "--model_name",
	    type=str,
	    default="deta-swin-large",
	    choices=["deta-swin-large", "deta-swin-large-o365"],
	    help="Name of the model you'd like to convert.",
	)
	parser.add_argument(
	    "--pytorch_dump_folder_path",
	    default=None,
	    type=str,
	    help="Path to the folder to output PyTorch model.",
	)
	parser.add_argument(
	    "--push_to_hub", action="store_true", help="Whether or not to push the converted model to the 🤗 hub."
	)
	__UpperCAmelCase							:   Optional[Any]							=  parser.parse_args()
	convert_deta_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.push_to_hub)







from __future__ import annotations

import math





def 					lowercase_ (    __snake_case     :							int	,	__snake_case     :							int	,	__snake_case     :							bool	,	__snake_case     :							list[int]	,	__snake_case     :							float      )     -> int:





				'''simple docstring'''


				if depth < 0:
								raise ValueError("Depth cannot be less than 0"      )

				if len(__snake_case      ) == 0:
								raise ValueError("Scores cannot be empty"      )

				if depth == height:
								return scores[node_index]

				if is_max:
								return max(
								    minimax(depth + 1	,	node_index * 2	,	__snake_case	,	__snake_case	,	__snake_case      )	,	minimax(depth + 1	,	node_index * 2 + 1	,	__snake_case	,	__snake_case	,	__snake_case      )	,	)

				return min(
				    minimax(depth + 1	,	node_index * 2	,	__snake_case	,	__snake_case	,	__snake_case      )	,	minimax(depth + 1	,	node_index * 2 + 1	,	__snake_case	,	__snake_case	,	__snake_case      )	,	)





def 					lowercase_ (    )     -> None:





				'''simple docstring'''


				snake_case__      :List[Any]         =   [90, 23, 6, 33, 21, 65, 1_23, 3_44_23]
				snake_case__      :int         =   math.log(len(__snake_case      )	,	2      )
				print("Optimal value : "	,	end=""      )
				print(minimax(0	,	0	,	__snake_case	,	__snake_case	,	__snake_case      )      )


if __name__ == "__main__":
	import doctest

	doctest.testmod()
	main()