
import argparse
import json

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

from transformers import BitImageProcessor, FocalNetConfig, FocalNetForImageClassification
from transformers.image_utils import IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD, PILImageResampling

def 		UpperCamelCase	(      lowercase_   )		->	int:


  '''simple docstring'''






  lowercase__  :   Any    		=      [2, 2, 6, 2] if """tiny""" in model_name else [2, 2, 18, 2]
  lowercase__  :   List[str]    		=      True if """large""" in model_name or """huge""" in model_name else False
  lowercase__  :   Union[str, Any]    		=      True if """large""" in model_name or """huge""" in model_name else False
  lowercase__  :   List[Any]    		=      True if """large""" in model_name or """huge""" in model_name else False

  if "large" in model_name or "xlarge" in model_name or "huge" in model_name:
    if "fl3" in model_name:
      lowercase__  :   List[str]    		=      [3, 3, 3, 3]
      lowercase__  :   List[Any]    		=      [5, 5, 5, 5]
    elif "fl4" in model_name:
      lowercase__  :   Tuple    		=      [4, 4, 4, 4]
      lowercase__  :   Optional[Any]    		=      [3, 3, 3, 3]

  if "tiny" in model_name or "small" in model_name or "base" in model_name:
    lowercase__  :   Dict    		=      [3, 3, 3, 3]
    if "lrf" in model_name:
      lowercase__  :   Any    		=      [3, 3, 3, 3]
    else:
      lowercase__  :   str    		=      [2, 2, 2, 2]

  if "tiny" in model_name:
    lowercase__  :   Dict    		=      96
  elif "small" in model_name:
    lowercase__  :   List[Any]    		=      96
  elif "base" in model_name:
    lowercase__  :   Any    		=      1_28
  elif "large" in model_name:
    lowercase__  :   Optional[int]    		=      1_92
  elif "xlarge" in model_name:
    lowercase__  :   Tuple    		=      2_56
  elif "huge" in model_name:
    lowercase__  :   int    		=      3_52

  # set label information
  lowercase__  :   Tuple    		=      """huggingface/label-files"""
  if "large" in model_name or "huge" in model_name:
    lowercase__  :   str    		=      """imagenet-22k-id2label.json"""
  else:
    lowercase__  :   Optional[Any]    		=      """imagenet-1k-id2label.json"""

  lowercase__  :   Optional[int]    		=      json.load(open(hf_hub_download(lowercase_ , lowercase_ , repo_type="""dataset"""   ) , """r"""   )   )
  lowercase__  :   Union[str, Any]    		=      {int(lowercase_   ): v for k, v in idalabel.items()}
  lowercase__  :   List[str]    		=      {v: k for k, v in idalabel.items()}

  lowercase__  :   Any    		=      FocalNetConfig(
      embed_dim=lowercase_ , depths=lowercase_ , focal_levels=lowercase_ , focal_windows=lowercase_ , use_conv_embed=lowercase_ , idalabel=lowercase_ , labelaid=lowercase_ , use_post_layernorm=lowercase_ , use_layerscale=lowercase_ , )

  return config

def 		UpperCamelCase	(      lowercase_   )		->	List[Any]:


  '''simple docstring'''






  if "patch_embed.proj" in name:
    lowercase__  :   List[str]    		=      name.replace("""patch_embed.proj""" , """embeddings.patch_embeddings.projection"""   )
  if "patch_embed.norm" in name:
    lowercase__  :   Optional[int]    		=      name.replace("""patch_embed.norm""" , """embeddings.norm"""   )
  if "layers" in name:
    lowercase__  :   List[str]    		=      """encoder.""" + name
  if "encoder.layers" in name:
    lowercase__  :   int    		=      name.replace("""encoder.layers""" , """encoder.stages"""   )
  if "downsample.proj" in name:
    lowercase__  :   Dict    		=      name.replace("""downsample.proj""" , """downsample.projection"""   )
  if "blocks" in name:
    lowercase__  :   Optional[Any]    		=      name.replace("""blocks""" , """layers"""   )
  if "modulation.f.weight" in name or "modulation.f.bias" in name:
    lowercase__  :   str    		=      name.replace("""modulation.f""" , """modulation.projection_in"""   )
  if "modulation.h.weight" in name or "modulation.h.bias" in name:
    lowercase__  :   Optional[int]    		=      name.replace("""modulation.h""" , """modulation.projection_context"""   )
  if "modulation.proj.weight" in name or "modulation.proj.bias" in name:
    lowercase__  :   List[str]    		=      name.replace("""modulation.proj""" , """modulation.projection_out"""   )

  if name == "norm.weight":
    lowercase__  :   Optional[Any]    		=      """layernorm.weight"""
  if name == "norm.bias":
    lowercase__  :   Optional[Any]    		=      """layernorm.bias"""

  if "head" in name:
    lowercase__  :   Any    		=      name.replace("""head""" , """classifier"""   )
  else:
    lowercase__  :   Optional[Any]    		=      """focalnet.""" + name

  return name

def 		UpperCamelCase	(      lowercase_ , lowercase_ , lowercase_=False   )		->	Tuple:


  '''simple docstring'''






  lowercase__  :   str    		=      {
      """focalnet-tiny""": """https://projects4jw.blob.core.windows.net/focalnet/release/classification/focalnet_tiny_srf.pth""",
      """focalnet-tiny-lrf""": """https://projects4jw.blob.core.windows.net/focalnet/release/classification/focalnet_tiny_lrf.pth""",
      """focalnet-small""": """https://projects4jw.blob.core.windows.net/focalnet/release/classification/focalnet_small_srf.pth""",
      """focalnet-small-lrf""": """https://projects4jw.blob.core.windows.net/focalnet/release/classification/focalnet_small_lrf.pth""",
      """focalnet-base""": """https://projects4jw.blob.core.windows.net/focalnet/release/classification/focalnet_base_srf.pth""",
      """focalnet-base-lrf""": """https://projects4jw.blob.core.windows.net/focalnet/release/classification/focalnet_base_lrf.pth""",
      """focalnet-large-lrf-fl3""": """https://projects4jw.blob.core.windows.net/focalnet/release/classification/focalnet_large_lrf_384.pth""",
      """focalnet-large-lrf-fl4""": """https://projects4jw.blob.core.windows.net/focalnet/release/classification/focalnet_large_lrf_384_fl4.pth""",
      """focalnet-xlarge-lrf-fl3""": """https://projects4jw.blob.core.windows.net/focalnet/release/classification/focalnet_xlarge_lrf_384.pth""",
      """focalnet-xlarge-lrf-fl4""": """https://projects4jw.blob.core.windows.net/focalnet/release/classification/focalnet_xlarge_lrf_384_fl4.pth""",
  }
  # fmt: on

  lowercase__  :   List[str]    		=      model_name_to_url[model_name]
  print("""Checkpoint URL: """ , lowercase_   )
  lowercase__  :   Union[str, Any]    		=      torch.hub.load_state_dict_from_url(lowercase_ , map_location="""cpu"""   )["""model"""]

  # rename keys
  for key in state_dict.copy().keys():
    lowercase__  :   Dict    		=      state_dict.pop(lowercase_   )
    lowercase__  :   List[Any]    		=      val

  lowercase__  :   Optional[int]    		=      get_focalnet_config(lowercase_   )
  lowercase__  :   Optional[Any]    		=      FocalNetForImageClassification(lowercase_   )
  model.eval()

  # load state dict
  model.load_state_dict(lowercase_   )

  # verify conversion
  lowercase__  :   List[str]    		=      """http://images.cocodataset.org/val2017/000000039769.jpg"""

  lowercase__  :   List[str]    		=      BitImageProcessor(
      do_resize=lowercase_ , size={"""shortest_edge""": 2_56} , resample=PILImageResampling.BILINEAR , do_center_crop=lowercase_ , crop_size=2_24 , do_normalize=lowercase_ , image_mean=lowercase_ , image_std=lowercase_ , )
  lowercase__  :   Union[str, Any]    		=      Image.open(requests.get(lowercase_ , stream=lowercase_   ).raw   )
  lowercase__  :   List[str]    		=      processor(images=lowercase_ , return_tensors="""pt"""   )

  lowercase__  :   int    		=      transforms.Compose(
      [
          transforms.Resize(2_56   ),
          transforms.CenterCrop(2_24   ),
          transforms.ToTensor(),
          transforms.Normalize(mean=[0.485, 0.456, 0.406] , std=[0.229, 0.224, 0.225]   ),
      ]   )

  lowercase__  :   Union[str, Any]    		=      image_transforms(lowercase_   ).unsqueeze(0   )

  # verify pixel_values
  assert torch.allclose(inputs.pixel_values , lowercase_ , atol=1E-4   )

  lowercase__  :   Optional[Any]    		=      model(**lowercase_   )

  lowercase__  :   int    		=      outputs.logits.argmax(-1   ).item()
  print("""Predicted class:""" , model.config.idalabel[predicted_class_idx]   )

  print("""First values of logits:""" , outputs.logits[0, :3]   )

  if model_name == "focalnet-tiny":
    lowercase__  :   List[Any]    		=      torch.tensor([0.2166, -0.4368, 0.2191]   )
  elif model_name == "focalnet-tiny-lrf":
    lowercase__  :   Optional[int]    		=      torch.tensor([1.1669, 0.0125, -0.1695]   )
  elif model_name == "focalnet-small":
    lowercase__  :   str    		=      torch.tensor([0.4917, -0.0430, 0.1341]   )
  elif model_name == "focalnet-small-lrf":
    lowercase__  :   List[str]    		=      torch.tensor([-0.2588, -0.5342, -0.2331]   )
  elif model_name == "focalnet-base":
    lowercase__  :   str    		=      torch.tensor([-0.1655, -0.4090, -0.1730]   )
  elif model_name == "focalnet-base-lrf":
    lowercase__  :   Optional[int]    		=      torch.tensor([0.5306, -0.0483, -0.3928]   )
  assert torch.allclose(outputs.logits[0, :3] , lowercase_ , atol=1E-4   )
  print("""Looks ok!"""   )

  if pytorch_dump_folder_path is not None:
    print(F'Saving model and processor of {model_name} to {pytorch_dump_folder_path}'   )
    model.save_pretrained(lowercase_   )
    processor.save_pretrained(lowercase_   )

  if push_to_hub:
    print(F'Pushing model and processor of {model_name} to the hub...'   )
    model.push_to_hub(F'{model_name}'   )
    processor.push_to_hub(F'{model_name}'   )


if __name__ == "__main__":
     lowerCamelCase__    :		Tuple          =   argparse.ArgumentParser()
     # Required parameters
     parser.add_argument(
         """--model_name""",
         default="""focalnet-tiny""",
         type=str,
         help="""Name of the FocalNet model you'd like to convert.""",
     )
     parser.add_argument(
         """--pytorch_dump_folder_path""", default=None, type=str, help="""Path to the output PyTorch model directory."""
     )
     parser.add_argument(
         """--push_to_hub""",
         action="""store_true""",
         help="""Whether to push the model and processor to the hub.""",
     )

     lowerCamelCase__    :		Any          =   parser.parse_args()
     convert_focalnet_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.push_to_hub)








from ..utils import DummyObject, requires_backends



class       _snake_case   (	metaclass=UpperCAmelCase_							):
 __lowerCAmelCase  :     int        =			['torch', 'transformers', 'onnx']


 def __init__(					self					,  *SCREAMING_SNAKE_CASE_					,  **SCREAMING_SNAKE_CASE_):


   '''simple docstring'''




   requires_backends(self					,  ["""torch""", """transformers""", """onnx"""])


 @classmethod
 def      lowercase__     (					cls					,  *SCREAMING_SNAKE_CASE_					,  **SCREAMING_SNAKE_CASE_):


   '''simple docstring'''




   requires_backends(cls					,  ["""torch""", """transformers""", """onnx"""])



 @classmethod
 def      lowercase__     (					cls					,  *SCREAMING_SNAKE_CASE_					,  **SCREAMING_SNAKE_CASE_):


   '''simple docstring'''




   requires_backends(cls					,  ["""torch""", """transformers""", """onnx"""])



class       _snake_case   (	metaclass=UpperCAmelCase_							):
 __lowerCAmelCase  :     Any        =			['torch', 'transformers', 'onnx']


 def __init__(					self					,  *SCREAMING_SNAKE_CASE_					,  **SCREAMING_SNAKE_CASE_):


   '''simple docstring'''




   requires_backends(self					,  ["""torch""", """transformers""", """onnx"""])


 @classmethod
 def      lowercase__     (					cls					,  *SCREAMING_SNAKE_CASE_					,  **SCREAMING_SNAKE_CASE_):


   '''simple docstring'''




   requires_backends(cls					,  ["""torch""", """transformers""", """onnx"""])



 @classmethod
 def      lowercase__     (					cls					,  *SCREAMING_SNAKE_CASE_					,  **SCREAMING_SNAKE_CASE_):


   '''simple docstring'''




   requires_backends(cls					,  ["""torch""", """transformers""", """onnx"""])



class       _snake_case   (	metaclass=UpperCAmelCase_							):
 __lowerCAmelCase  :     Union[str, Any]        =			['torch', 'transformers', 'onnx']


 def __init__(					self					,  *SCREAMING_SNAKE_CASE_					,  **SCREAMING_SNAKE_CASE_):


   '''simple docstring'''




   requires_backends(self					,  ["""torch""", """transformers""", """onnx"""])


 @classmethod
 def      lowercase__     (					cls					,  *SCREAMING_SNAKE_CASE_					,  **SCREAMING_SNAKE_CASE_):


   '''simple docstring'''




   requires_backends(cls					,  ["""torch""", """transformers""", """onnx"""])



 @classmethod
 def      lowercase__     (					cls					,  *SCREAMING_SNAKE_CASE_					,  **SCREAMING_SNAKE_CASE_):


   '''simple docstring'''




   requires_backends(cls					,  ["""torch""", """transformers""", """onnx"""])



class       _snake_case   (	metaclass=UpperCAmelCase_							):
 __lowerCAmelCase  :     List[Any]        =			['torch', 'transformers', 'onnx']


 def __init__(					self					,  *SCREAMING_SNAKE_CASE_					,  **SCREAMING_SNAKE_CASE_):


   '''simple docstring'''




   requires_backends(self					,  ["""torch""", """transformers""", """onnx"""])


 @classmethod
 def      lowercase__     (					cls					,  *SCREAMING_SNAKE_CASE_					,  **SCREAMING_SNAKE_CASE_):


   '''simple docstring'''




   requires_backends(cls					,  ["""torch""", """transformers""", """onnx"""])



 @classmethod
 def      lowercase__     (					cls					,  *SCREAMING_SNAKE_CASE_					,  **SCREAMING_SNAKE_CASE_):


   '''simple docstring'''




   requires_backends(cls					,  ["""torch""", """transformers""", """onnx"""])



class       _snake_case   (	metaclass=UpperCAmelCase_							):
 __lowerCAmelCase  :     Dict        =			['torch', 'transformers', 'onnx']


 def __init__(					self					,  *SCREAMING_SNAKE_CASE_					,  **SCREAMING_SNAKE_CASE_):


   '''simple docstring'''




   requires_backends(self					,  ["""torch""", """transformers""", """onnx"""])


 @classmethod
 def      lowercase__     (					cls					,  *SCREAMING_SNAKE_CASE_					,  **SCREAMING_SNAKE_CASE_):


   '''simple docstring'''




   requires_backends(cls					,  ["""torch""", """transformers""", """onnx"""])



 @classmethod
 def      lowercase__     (					cls					,  *SCREAMING_SNAKE_CASE_					,  **SCREAMING_SNAKE_CASE_):


   '''simple docstring'''




   requires_backends(cls					,  ["""torch""", """transformers""", """onnx"""])



class       _snake_case   (	metaclass=UpperCAmelCase_							):
 __lowerCAmelCase  :     List[str]        =			['torch', 'transformers', 'onnx']


 def __init__(					self					,  *SCREAMING_SNAKE_CASE_					,  **SCREAMING_SNAKE_CASE_):


   '''simple docstring'''




   requires_backends(self					,  ["""torch""", """transformers""", """onnx"""])


 @classmethod
 def      lowercase__     (					cls					,  *SCREAMING_SNAKE_CASE_					,  **SCREAMING_SNAKE_CASE_):


   '''simple docstring'''




   requires_backends(cls					,  ["""torch""", """transformers""", """onnx"""])



 @classmethod
 def      lowercase__     (					cls					,  *SCREAMING_SNAKE_CASE_					,  **SCREAMING_SNAKE_CASE_):


   '''simple docstring'''




   requires_backends(cls					,  ["""torch""", """transformers""", """onnx"""])






