



import os
import sys
import warnings
from dataclasses import dataclass, field
from io import BytesIO
from typing import TYPE_CHECKING, Any, ClassVar, Dict, List, Optional, Union

import numpy as np
import pyarrow as pa

from .. import config
from ..download.streaming_download_manager import xopen
from ..table import array_cast
from ..utils.file_utils import is_local_path
from ..utils.py_utils import first_non_null_value, no_op_if_value_is_null, string_to_dict


if TYPE_CHECKING:
  import PIL.Image

  from .features import FeatureType


a_								=       None
a_								=       """<""" if sys.byteorder == """little""" else """>"""
# Origin: https://github.com/python-pillow/Pillow/blob/698951e19e19972aeed56df686868f1329981c12/src/PIL/Image.py#L3126 minus "|i1" which values are not preserved correctly when saving and loading an image
a_								=       [
    np.dtype("""|b1"""),
    np.dtype("""|u1"""),
    np.dtype("""<u2"""),
    np.dtype(""">u2"""),
    np.dtype("""<i2"""),
    np.dtype(""">i2"""),
    np.dtype("""<u4"""),
    np.dtype(""">u4"""),
    np.dtype("""<i4"""),
    np.dtype(""">i4"""),
    np.dtype("""<f4"""),
    np.dtype(""">f4"""),
    np.dtype("""<f8"""),
    np.dtype(""">f8"""),
]



@dataclass
class 			__lowerCAmelCase  :
 lowerCAmelCase__							       =	True
 lowerCAmelCase__							       =	None
 # Automatically constructed
 lowerCAmelCase__							       =	"PIL.Image.Image"
 lowerCAmelCase__							       =	pa.struct({"""bytes""": pa.binary(), """path""": pa.string()} )
 lowerCAmelCase__							       =	field(default="""Image"""	,						init=lowerCAmelCase__	,						repr=lowerCAmelCase__ )




 def __call__(    self					):



    '''simple docstring'''
    return self.pa_type




 def 							lowerCamelCase   (    self						,					__UpperCAmelCase					):



    '''simple docstring'''
    if config.PIL_AVAILABLE:
       import PIL.Image
    else:
       raise ImportError('''To support encoding images, please install \'Pillow\'.'''					)

    if isinstance(__UpperCAmelCase						,					__UpperCAmelCase					):
       __lowerCamelCase    				=     np.array(__UpperCAmelCase					)

    if isinstance(__UpperCAmelCase						,					__UpperCAmelCase					):
       return {"path": value, "bytes": None}
    elif isinstance(__UpperCAmelCase						,					__UpperCAmelCase					):
       return {"path": None, "bytes": value}
    elif isinstance(__UpperCAmelCase						,					np.ndarray					):
       # convert the image array to PNG/TIFF bytes
       return encode_np_array(__UpperCAmelCase					)
    elif isinstance(__UpperCAmelCase						,					PIL.Image.Image					):
       # convert the PIL image to bytes (default format is PNG/TIFF)
       return encode_pil_image(__UpperCAmelCase					)
    elif value.get('''path'''					) is not None and os.path.isfile(value['''path''']					):
       # we set "bytes": None to not duplicate the data if they're already available locally
       return {"bytes": None, "path": value.get('''path'''					)}
    elif value.get('''bytes'''					) is not None or value.get('''path'''					) is not None:
       # store the image bytes, and path is used to infer the image format using the file extension
       return {"bytes": value.get('''bytes'''					), "path": value.get('''path'''					)}
    else:
       raise ValueError(
           F"""An image sample should have one of 'path' or 'bytes' but they are missing or None in {value}."""					)




 def 							lowerCamelCase   (    self						,					__UpperCAmelCase						,					__UpperCAmelCase=None					):



    '''simple docstring'''
    if not self.decode:
       raise RuntimeError('''Decoding is disabled for this feature. Please use Image(decode=True) instead.'''					)

    if config.PIL_AVAILABLE:
       import PIL.Image
    else:
       raise ImportError('''To support decoding images, please install \'Pillow\'.'''					)

    if token_per_repo_id is None:
       __lowerCamelCase    				=     {}

    __lowerCamelCase				,__lowerCamelCase    				=     value['''path'''], value['''bytes''']
    if bytes_ is None:
       if path is None:
          raise ValueError(F"""An image should have one of 'path' or 'bytes' but both are None in {value}."""					)
       else:
          if is_local_path(__UpperCAmelCase					):
             __lowerCamelCase    				=     PIL.Image.open(__UpperCAmelCase					)
          else:
             __lowerCamelCase    				=     path.split('''::'''					)[-1]
             try:
                __lowerCamelCase    				=     string_to_dict(__UpperCAmelCase						,					config.HUB_DATASETS_URL					)['''repo_id''']
                __lowerCamelCase    				=     token_per_repo_id.get(__UpperCAmelCase					)
             except ValueError:
                __lowerCamelCase    				=     None
             with xopen(__UpperCAmelCase						,					'''rb'''						,					use_auth_token=__UpperCAmelCase					) as f:
                __lowerCamelCase    				=     BytesIO(f.read()					)
             __lowerCamelCase    				=     PIL.Image.open(bytes_					)
    else:
       __lowerCamelCase    				=     PIL.Image.open(BytesIO(bytes_					)					)
    image.load()  # to avoid "Too many open files" errors
    return image




 def 							lowerCamelCase   (    self					):



    '''simple docstring'''
    from .features import Value

    return (
        self
        if self.decode
        else {
            "bytes": Value('''binary'''					),
            "path": Value('''string'''					),
        }
    )




 def 							lowerCamelCase   (    self						,					__UpperCAmelCase					):



    '''simple docstring'''
    if pa.types.is_string(storage.type					):
       __lowerCamelCase    				=     pa.array([None] * len(__UpperCAmelCase					)						,					type=pa.binary()					)
       __lowerCamelCase    				=     pa.StructArray.from_arrays([bytes_array, storage]						,					['''bytes''', '''path''']						,					mask=storage.is_null()					)
    elif pa.types.is_binary(storage.type					):
       __lowerCamelCase    				=     pa.array([None] * len(__UpperCAmelCase					)						,					type=pa.string()					)
       __lowerCamelCase    				=     pa.StructArray.from_arrays([storage, path_array]						,					['''bytes''', '''path''']						,					mask=storage.is_null()					)
    elif pa.types.is_struct(storage.type					):
       if storage.type.get_field_index('''bytes'''					) >= 0:
          __lowerCamelCase    				=     storage.field('''bytes'''					)
       else:
          __lowerCamelCase    				=     pa.array([None] * len(__UpperCAmelCase					)						,					type=pa.binary()					)
       if storage.type.get_field_index('''path'''					) >= 0:
          __lowerCamelCase    				=     storage.field('''path'''					)
       else:
          __lowerCamelCase    				=     pa.array([None] * len(__UpperCAmelCase					)						,					type=pa.string()					)
       __lowerCamelCase    				=     pa.StructArray.from_arrays([bytes_array, path_array]						,					['''bytes''', '''path''']						,					mask=storage.is_null()					)
    elif pa.types.is_list(storage.type					):
       __lowerCamelCase    				=     pa.array(
           [encode_np_array(np.array(__UpperCAmelCase					)					)['''bytes'''] if arr is not None else None for arr in storage.to_pylist()]						,					type=pa.binary()						,					)
       __lowerCamelCase    				=     pa.array([None] * len(__UpperCAmelCase					)						,					type=pa.string()					)
       __lowerCamelCase    				=     pa.StructArray.from_arrays(
           [bytes_array, path_array]						,					['''bytes''', '''path''']						,					mask=bytes_array.is_null()					)
    return array_cast(__UpperCAmelCase						,					self.pa_type					)




 def 							lowerCamelCase   (    self						,					__UpperCAmelCase					):



    '''simple docstring'''

    @no_op_if_value_is_null
    def path_to_bytes(__UpperCAmelCase					):
       with xopen(__UpperCAmelCase						,					'''rb'''					) as f:
          __lowerCamelCase    				=     f.read()
       return bytes_

    __lowerCamelCase    				=     pa.array(
        [
            (path_to_bytes(x['''path''']					) if x['''bytes'''] is None else x['''bytes''']) if x is not None else None
            for x in storage.to_pylist()
        ]						,					type=pa.binary()						,					)
    __lowerCamelCase    				=     pa.array(
        [os.path.basename(__UpperCAmelCase					) if path is not None else None for path in storage.field('''path'''					).to_pylist()]						,					type=pa.string()						,					)
    __lowerCamelCase    				=     pa.StructArray.from_arrays([bytes_array, path_array]						,					['''bytes''', '''path''']						,					mask=bytes_array.is_null()					)
    return array_cast(__UpperCAmelCase						,					self.pa_type					)





def 		a__      (		):
   if config.PIL_AVAILABLE:
      import PIL.Image
   else:
      raise ImportError('''To support encoding images, please install \'Pillow\'.'''				)

   global _IMAGE_COMPRESSION_FORMATS
   if _IMAGE_COMPRESSION_FORMATS is None:
      PIL.Image.init()
      __lowerCamelCase    				=     list(set(PIL.Image.OPEN.keys()				) & set(PIL.Image.SAVE.keys()				)				)
   return _IMAGE_COMPRESSION_FORMATS





def 		a__      (		_UpperCamelCase      :			"PIL.Image.Image"				):
   __lowerCamelCase    				=     BytesIO()
   if image.format in list_image_compression_formats():
      __lowerCamelCase    				=     image.format
   else:
      __lowerCamelCase    				=     '''PNG''' if image.mode in ['''1''', '''L''', '''LA''', '''RGB''', '''RGBA'''] else '''TIFF'''
   image.save(_UpperCamelCase			,format=_UpperCamelCase				)
   return buffer.getvalue()





def 		a__      (		_UpperCamelCase      :			"PIL.Image.Image"				):
   if hasattr(_UpperCamelCase			,'''filename'''				) and image.filename != "":
      return {"path": image.filename, "bytes": None}
   else:
      return {"path": None, "bytes": image_to_bytes(_UpperCamelCase				)}





def 		a__      (		_UpperCamelCase      :			np.ndarray				):
   if config.PIL_AVAILABLE:
      import PIL.Image
   else:
      raise ImportError('''To support encoding images, please install \'Pillow\'.'''				)

   __lowerCamelCase    				=     array.dtype
   __lowerCamelCase    				=     dtype.byteorder if dtype.byteorder != '''=''' else _NATIVE_BYTEORDER
   __lowerCamelCase    				=     dtype.kind
   __lowerCamelCase    				=     dtype.itemsize

   __lowerCamelCase    				=     None

   # Multi-channel array case (only np.dtype("|u1") is allowed)
   if array.shape[2:]:
      __lowerCamelCase    				=     np.dtype('''|u1'''				)
      if dtype_kind not in ["u", "i"]:
         raise TypeError(
             F"""Unsupported array dtype {dtype} for image encoding. Only {dest_dtype} is supported for multi-channel arrays."""				)
      if dtype is not dest_dtype:
         warnings.warn(F"""Downcasting array dtype {dtype} to {dest_dtype} to be compatible with 'Pillow'"""				)
    # Exact match
   elif dtype in _VALID_IMAGE_ARRAY_DTPYES:
      __lowerCamelCase    				=     dtype
   else:  # Downcast the type within the kind (np.can_cast(from_type, to_type, casting="same_kind") doesn't behave as expected, so do it manually)
      while dtype_itemsize >= 1:
         __lowerCamelCase    				=     dtype_byteorder + dtype_kind + str(_UpperCamelCase				)
         __lowerCamelCase    				=     np.dtype(_UpperCamelCase				)
         if dest_dtype in _VALID_IMAGE_ARRAY_DTPYES:
            warnings.warn(F"""Downcasting array dtype {dtype} to {dest_dtype} to be compatible with 'Pillow'"""				)
            break
         else:
            dtype_itemsize //= 2

   if dest_dtype is None:
      raise TypeError(
          F"""Cannot convert dtype {dtype} to a valid image dtype. Valid image dtypes: {_VALID_IMAGE_ARRAY_DTPYES}"""				)
   __lowerCamelCase    				=     PIL.Image.fromarray(array.astype(_UpperCamelCase				)				)
   return {"path": None, "bytes": image_to_bytes(_UpperCamelCase				)}





def 		a__      (		_UpperCamelCase      :			Union[List[str], List[dict], List[np.ndarray], List["PIL.Image.Image"]]				):
   if config.PIL_AVAILABLE:
      import PIL.Image
   else:
      raise ImportError('''To support encoding images, please install \'Pillow\'.'''				)

   if objs:
      __lowerCamelCase				,__lowerCamelCase    				=     first_non_null_value(_UpperCamelCase				)
      if isinstance(_UpperCamelCase			,_UpperCamelCase				):
         return [{"path": obj, "bytes": None} if obj is not None else None for obj in objs]
      if isinstance(_UpperCamelCase			,np.ndarray				):
         __lowerCamelCase    				=     no_op_if_value_is_null(_UpperCamelCase				)
         return [obj_to_image_dict_func(_UpperCamelCase				) for obj in objs]
      elif isinstance(_UpperCamelCase			,PIL.Image.Image				):
         __lowerCamelCase    				=     no_op_if_value_is_null(_UpperCamelCase				)
         return [obj_to_image_dict_func(_UpperCamelCase				) for obj in objs]
      else:
         return objs
   else:
      return objs











import argparse

import requests
import torch
from PIL import Image

from transformers import ViTMAEConfig, ViTMAEForPreTraining, ViTMAEImageProcessor





def 		a__      (		_UpperCamelCase      :			List[Any]				):
   if "cls_token" in name:
      __lowerCamelCase    				=     name.replace('''cls_token'''			,'''vit.embeddings.cls_token'''				)
   if "mask_token" in name:
      __lowerCamelCase    				=     name.replace('''mask_token'''			,'''decoder.mask_token'''				)
   if "decoder_pos_embed" in name:
      __lowerCamelCase    				=     name.replace('''decoder_pos_embed'''			,'''decoder.decoder_pos_embed'''				)
   if "pos_embed" in name and "decoder" not in name:
      __lowerCamelCase    				=     name.replace('''pos_embed'''			,'''vit.embeddings.position_embeddings'''				)
   if "patch_embed.proj" in name:
      __lowerCamelCase    				=     name.replace('''patch_embed.proj'''			,'''vit.embeddings.patch_embeddings.projection'''				)
   if "patch_embed.norm" in name:
      __lowerCamelCase    				=     name.replace('''patch_embed.norm'''			,'''vit.embeddings.norm'''				)
   if "decoder_blocks" in name:
      __lowerCamelCase    				=     name.replace('''decoder_blocks'''			,'''decoder.decoder_layers'''				)
   if "blocks" in name:
      __lowerCamelCase    				=     name.replace('''blocks'''			,'''vit.encoder.layer'''				)
   if "attn.proj" in name:
      __lowerCamelCase    				=     name.replace('''attn.proj'''			,'''attention.output.dense'''				)
   if "attn" in name:
      __lowerCamelCase    				=     name.replace('''attn'''			,'''attention.self'''				)
   if "norm1" in name:
      __lowerCamelCase    				=     name.replace('''norm1'''			,'''layernorm_before'''				)
   if "norm2" in name:
      __lowerCamelCase    				=     name.replace('''norm2'''			,'''layernorm_after'''				)
   if "mlp.fc1" in name:
      __lowerCamelCase    				=     name.replace('''mlp.fc1'''			,'''intermediate.dense'''				)
   if "mlp.fc2" in name:
      __lowerCamelCase    				=     name.replace('''mlp.fc2'''			,'''output.dense'''				)
   if "decoder_embed" in name:
      __lowerCamelCase    				=     name.replace('''decoder_embed'''			,'''decoder.decoder_embed'''				)
   if "decoder_norm" in name:
      __lowerCamelCase    				=     name.replace('''decoder_norm'''			,'''decoder.decoder_norm'''				)
   if "decoder_pred" in name:
      __lowerCamelCase    				=     name.replace('''decoder_pred'''			,'''decoder.decoder_pred'''				)
   if "norm.weight" in name and "decoder" not in name:
      __lowerCamelCase    				=     name.replace('''norm.weight'''			,'''vit.layernorm.weight'''				)
   if "norm.bias" in name and "decoder" not in name:
      __lowerCamelCase    				=     name.replace('''norm.bias'''			,'''vit.layernorm.bias'''				)

   return name





def 		a__      (		_UpperCamelCase      :			Tuple			,_UpperCamelCase      :			Dict				):
   for key in orig_state_dict.copy().keys():
      __lowerCamelCase    				=     orig_state_dict.pop(_UpperCamelCase				)

      if "qkv" in key:
         __lowerCamelCase    				=     key.split('''.'''				)
         __lowerCamelCase    				=     int(key_split[1]				)
         if "decoder_blocks" in key:
            __lowerCamelCase    				=     config.decoder_hidden_size
            __lowerCamelCase    				=     '''decoder.decoder_layers.'''
            if "weight" in key:
               __lowerCamelCase    				=     val[:dim, :]
               __lowerCamelCase    				=     val[dim : dim * 2, :]
               __lowerCamelCase    				=     val[-dim:, :]
            elif "bias" in key:
               __lowerCamelCase    				=     val[:dim]
               __lowerCamelCase    				=     val[dim : dim * 2]
               __lowerCamelCase    				=     val[-dim:]
         else:
            __lowerCamelCase    				=     config.hidden_size
            __lowerCamelCase    				=     '''vit.encoder.layer.'''
            if "weight" in key:
               __lowerCamelCase    				=     val[:dim, :]
               __lowerCamelCase    				=     val[dim : dim * 2, :]
               __lowerCamelCase    				=     val[-dim:, :]
            elif "bias" in key:
               __lowerCamelCase    				=     val[:dim]
               __lowerCamelCase    				=     val[dim : dim * 2]
               __lowerCamelCase    				=     val[-dim:]

      else:
         __lowerCamelCase    				=     val

   return orig_state_dict





def 		a__      (		_UpperCamelCase      :			Dict			,_UpperCamelCase      :			Any				):
   __lowerCamelCase    				=     ViTMAEConfig()
   if "large" in checkpoint_url:
      __lowerCamelCase    				=     10_24
      __lowerCamelCase    				=     40_96
      __lowerCamelCase    				=     24
      __lowerCamelCase    				=     16
   elif "huge" in checkpoint_url:
      __lowerCamelCase    				=     14
      __lowerCamelCase    				=     12_80
      __lowerCamelCase    				=     51_20
      __lowerCamelCase    				=     32
      __lowerCamelCase    				=     16

   __lowerCamelCase    				=     ViTMAEForPreTraining(_UpperCamelCase				)

   __lowerCamelCase    				=     torch.hub.load_state_dict_from_url(_UpperCamelCase			,map_location='''cpu'''				)['''model''']

   __lowerCamelCase    				=     ViTMAEImageProcessor(size=config.image_size				)

   __lowerCamelCase    				=     convert_state_dict(_UpperCamelCase			,_UpperCamelCase				)

   model.load_state_dict(_UpperCamelCase				)
   model.eval()

   __lowerCamelCase    				=     '''https://user-images.githubusercontent.com/11435359/147738734-196fd92f-9260-48d5-ba7e-bf103d29364d.jpg'''

   __lowerCamelCase    				=     Image.open(requests.get(_UpperCamelCase			,stream=_UpperCamelCase				).raw				)
   __lowerCamelCase    				=     ViTMAEImageProcessor(size=config.image_size				)
   __lowerCamelCase    				=     image_processor(images=_UpperCamelCase			,return_tensors='''pt'''				)

   # forward pass
   torch.manual_seed(2				)
   __lowerCamelCase    				=     model(**_UpperCamelCase				)
   __lowerCamelCase    				=     outputs.logits

   if "large" in checkpoint_url:
      __lowerCamelCase    				=     torch.tensor(
          [[-0.7_309, -0.7_128, -1.0_169], [-1.0_161, -0.9_058, -1.1_878], [-1.0_478, -0.9_411, -1.1_911]]				)
   elif "huge" in checkpoint_url:
      __lowerCamelCase    				=     torch.tensor(
          [[-1.1_599, -0.9_199, -1.2_221], [-1.1_952, -0.9_269, -1.2_307], [-1.2_143, -0.9_337, -1.2_262]]				)
   else:
      __lowerCamelCase    				=     torch.tensor(
          [[-0.9_192, -0.8_481, -1.1_259], [-1.1_349, -1.0_034, -1.2_599], [-1.1_757, -1.0_429, -1.2_726]]				)

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

   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				)


if __name__ == "__main__":
  a_								=       argparse.ArgumentParser()
  # Required parameters
  parser.add_argument(
      """--checkpoint_url""",
      default="""https://dl.fbaipublicfiles.com/mae/visualize/mae_visualize_vit_base.pth""",
      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."""
  )

  a_								=       parser.parse_args()
  convert_vit_mae_checkpoint(args.checkpoint_url, args.pytorch_dump_folder_path)






