



import os
from pickle import UnpicklingError
from typing import Dict, Tuple

import jax
import jax.numpy as jnp
import numpy as np
from flax.serialization import from_bytes
from flax.traverse_util import flatten_dict, unflatten_dict

import transformers

from .utils import logging


SCREAMING_SNAKE_CASE_:Optional[Any]					=						logging.get_logger(__name__)




def      __UpperCamelCase     (  _lowerCAmelCase				,					_lowerCAmelCase				,					_lowerCAmelCase				,					_lowerCAmelCase=False		)	->  Union[str, Any]:



				"""simple docstring"""






				try:
								import torch  # noqa: F401
				except ImportError:
								logger.error(
								    """Loading a PyTorch model in Flax, requires both PyTorch and Flax to be installed. Please see"""
								    """ https://pytorch.org/ and https://flax.readthedocs.io/en/latest/installation.html for installation"""
								    """ instructions."""		)
								raise

				if not is_sharded:
								A			:	List[str]										=       os.path.abspath(_lowerCAmelCase		)
								logger.info(f'''Loading PyTorch weights from {pt_path}'''		)

								A			:	Optional[int]										=       torch.load(_lowerCAmelCase				,					map_location="""cpu"""		)
								logger.info(f'''PyTorch checkpoint contains {sum(t.numel() for t in pt_state_dict.values()		):,} parameters.'''		)

								A			:	int										=       convert_pytorch_state_dict_to_flax(_lowerCAmelCase				,					_lowerCAmelCase		)
				else:
								# model is sharded and pytorch_checkpoint_path already contains the list of .pt shard files
								A			:	int										=       convert_pytorch_sharded_state_dict_to_flax(_lowerCAmelCase				,					_lowerCAmelCase		)
				return flax_state_dict




def      __UpperCamelCase     (  _lowerCAmelCase				,					_lowerCAmelCase				,					_lowerCAmelCase				,					_lowerCAmelCase				,					)	->  (Tuple[str], np.ndarray):



				"""simple docstring"""






				def is_key_or_prefix_key_in_dict(_lowerCAmelCase		) -> bool:
								return len(set(_lowerCAmelCase		) & {key, (model_prefix,) + key}		) > 0

				# layer norm
				A			:	Union[str, Any]										=       pt_tuple_key[:-1] + ("""scale""",)
				if pt_tuple_key[-1] in ["weight", "gamma"] and is_key_or_prefix_key_in_dict(_lowerCAmelCase		):
								return renamed_pt_tuple_key, pt_tensor

				# batch norm layer mean
				A			:	Optional[Any]										=       pt_tuple_key[:-1] + ("""mean""",)
				if pt_tuple_key[-1] == "running_mean" and not is_key_or_prefix_key_in_dict(_lowerCAmelCase		):
								return renamed_pt_tuple_key, pt_tensor

				# batch norm layer var
				A			:	int										=       pt_tuple_key[:-1] + ("""var""",)
				if pt_tuple_key[-1] == "running_var" and not is_key_or_prefix_key_in_dict(_lowerCAmelCase		):
								return renamed_pt_tuple_key, pt_tensor

				# embedding
				A			:	Optional[Any]										=       pt_tuple_key[:-1] + ("""embedding""",)
				if pt_tuple_key[-1] == "weight" and is_key_or_prefix_key_in_dict(_lowerCAmelCase		):
								return renamed_pt_tuple_key, pt_tensor

				# conv layer
				A			:	Optional[Any]										=       pt_tuple_key[:-1] + ("""kernel""",)
				if pt_tuple_key[-1] == "weight" and pt_tensor.ndim == 4 and not is_key_or_prefix_key_in_dict(_lowerCAmelCase		):
								A			:	str										=       pt_tensor.transpose(2				,					3				,					1				,					0		)
								return renamed_pt_tuple_key, pt_tensor

				# linear layer
				A			:	Any										=       pt_tuple_key[:-1] + ("""kernel""",)
				if pt_tuple_key[-1] == "weight" and not is_key_or_prefix_key_in_dict(_lowerCAmelCase		):
								A			:	List[str]										=       pt_tensor.T
								return renamed_pt_tuple_key, pt_tensor

				# old PyTorch layer norm weight
				A			:	Union[str, Any]										=       pt_tuple_key[:-1] + ("""weight""",)
				if pt_tuple_key[-1] == "gamma":
								return renamed_pt_tuple_key, pt_tensor

				# old PyTorch layer norm bias
				A			:	Dict										=       pt_tuple_key[:-1] + ("""bias""",)
				if pt_tuple_key[-1] == "beta":
								return renamed_pt_tuple_key, pt_tensor

				# New `weight_norm` from https://github.com/huggingface/transformers/pull/24030
				A			:	Optional[int]										=       None
				if pt_tuple_key[-3::2] == ("parametrizations", "original0"):
								A			:	Optional[int]										=       pt_tuple_key[-2] + """_g"""
				elif pt_tuple_key[-3::2] == ("parametrizations", "original1"):
								A			:	Union[str, Any]										=       pt_tuple_key[-2] + """_v"""
				if name is not None:
								A			:	Any										=       pt_tuple_key[:-3] + (name,)
								return renamed_pt_tuple_key, pt_tensor

				return pt_tuple_key, pt_tensor




def      __UpperCamelCase     (  _lowerCAmelCase				,					_lowerCAmelCase		)	->  List[str]:



				"""simple docstring"""






				A			:	Optional[Any]										=       {k: v.numpy() for k, v in pt_state_dict.items()}

				A			:	List[str]										=       flax_model.base_model_prefix

				# use params dict if the model contains batch norm layers
				if "params" in flax_model.params:
								A			:	Union[str, Any]										=       flax_model.params["""params"""]
				else:
								A			:	Any										=       flax_model.params
				A			:	Optional[int]										=       flatten_dict(_lowerCAmelCase		)

				# add batch_stats keys,values to dict
				if "batch_stats" in flax_model.params:
								A			:	Dict										=       flatten_dict(flax_model.params["""batch_stats"""]		)
								random_flax_state_dict.update(_lowerCAmelCase		)

				A			:	str										=       {}

				A			:	str										=       (model_prefix not in flax_model_params) and (
				    model_prefix in {k.split("""."""		)[0] for k in pt_state_dict.keys()}
				)
				A			:	Dict										=       (model_prefix in flax_model_params) and (
				    model_prefix not in {k.split("""."""		)[0] for k in pt_state_dict.keys()}
				)

				# Need to change some parameters name to match Flax names
				for pt_key, pt_tensor in pt_state_dict.items():
								A			:	int										=       tuple(pt_key.split("""."""		)		)

								# remove base model prefix if necessary
								A			:	Any										=       pt_tuple_key[0] == model_prefix
								if load_model_with_head_into_base_model and has_base_model_prefix:
												A			:	List[Any]										=       pt_tuple_key[1:]

								# Correctly rename weight parameters
								A			:	Tuple										=       rename_key_and_reshape_tensor(
								    _lowerCAmelCase				,					_lowerCAmelCase				,					_lowerCAmelCase				,					_lowerCAmelCase		)

								# add model prefix if necessary
								A			:	Tuple										=       (model_prefix,) + flax_key in random_flax_state_dict
								if load_base_model_into_model_with_head and require_base_model_prefix:
												A			:	Union[str, Any]										=       (model_prefix,) + flax_key

								if flax_key in random_flax_state_dict:
												if flax_tensor.shape != random_flax_state_dict[flax_key].shape:
																raise ValueError(
																    f'''PyTorch checkpoint seems to be incorrect. Weight {pt_key} was expected to be of shape '''
																    f'''{random_flax_state_dict[flax_key].shape}, but is {flax_tensor.shape}.'''		)

        # add batch stats if the model contains batchnorm layers
								if "batch_stats" in flax_model.params:
												if "mean" in flax_key[-1] or "var" in flax_key[-1]:
																A			:	List[Any]										=       jnp.asarray(_lowerCAmelCase		)
																continue
												# remove num_batches_tracked key
												if "num_batches_tracked" in flax_key[-1]:
																flax_state_dict.pop(_lowerCAmelCase				,					_lowerCAmelCase		)
																continue

												# also add unexpected weight so that warning is thrown
												A			:	int										=       jnp.asarray(_lowerCAmelCase		)

								else:
												# also add unexpected weight so that warning is thrown
												A			:	List[Any]										=       jnp.asarray(_lowerCAmelCase		)

				return unflatten_dict(_lowerCAmelCase		)




def      __UpperCamelCase     (  _lowerCAmelCase				,					_lowerCAmelCase		)	->  Dict:



				"""simple docstring"""






				import torch

				# Load the index
				A			:	List[Any]										=       {}
				for shard_file in shard_filenames:
								# load using msgpack utils
								A			:	str										=       torch.load(_lowerCAmelCase		)
								A			:	Any										=       {k: v.numpy() for k, v in pt_state_dict.items()}

								A			:	Dict										=       flax_model.base_model_prefix

								# use params dict if the model contains batch norm layers and then add batch_stats keys,values to dict
								if "batch_stats" in flax_model.params:
												A			:	str										=       flax_model.params["""params"""]

												A			:	Any										=       flatten_dict(_lowerCAmelCase		)
												random_flax_state_dict.update(flatten_dict(flax_model.params["""batch_stats"""]		)		)
								else:
												A			:	Dict										=       flax_model.params
												A			:	Optional[int]										=       flatten_dict(_lowerCAmelCase		)

								A			:	str										=       (model_prefix not in flax_model_params) and (
								    model_prefix in {k.split("""."""		)[0] for k in pt_state_dict.keys()}
								)
								A			:	Any										=       (model_prefix in flax_model_params) and (
								    model_prefix not in {k.split("""."""		)[0] for k in pt_state_dict.keys()}
								)
								# Need to change some parameters name to match Flax names
								for pt_key, pt_tensor in pt_state_dict.items():
												A			:	List[Any]										=       tuple(pt_key.split("""."""		)		)

												# remove base model prefix if necessary
												A			:	Optional[Any]										=       pt_tuple_key[0] == model_prefix
												if load_model_with_head_into_base_model and has_base_model_prefix:
																A			:	List[Any]										=       pt_tuple_key[1:]

												# Correctly rename weight parameters
												A			:	Dict										=       rename_key_and_reshape_tensor(
												    _lowerCAmelCase				,					_lowerCAmelCase				,					_lowerCAmelCase				,					_lowerCAmelCase		)
												# add model prefix if necessary
												A			:	Optional[int]										=       (model_prefix,) + flax_key in random_flax_state_dict
												if load_base_model_into_model_with_head and require_base_model_prefix:
																A			:	List[Any]										=       (model_prefix,) + flax_key

												if flax_key in random_flax_state_dict:
																if flax_tensor.shape != random_flax_state_dict[flax_key].shape:
																				raise ValueError(
																				    f'''PyTorch checkpoint seems to be incorrect. Weight {pt_key} was expected to be of shape '''
																				    f'''{random_flax_state_dict[flax_key].shape}, but is {flax_tensor.shape}.'''		)

            # add batch stats if the model contains batchnorm layers
												if "batch_stats" in flax_model.params:
																if "mean" in flax_key[-1]:
																				A			:	List[str]										=       jnp.asarray(_lowerCAmelCase		)
																				continue
																if "var" in flax_key[-1]:
																				A			:	int										=       jnp.asarray(_lowerCAmelCase		)
																				continue
																# remove num_batches_tracked key
																if "num_batches_tracked" in flax_key[-1]:
																				flax_state_dict.pop(_lowerCAmelCase				,					_lowerCAmelCase		)
																				continue

																# also add unexpected weight so that warning is thrown
																A			:	Union[str, Any]										=       jnp.asarray(_lowerCAmelCase		)

												else:
																# also add unexpected weight so that warning is thrown
																A			:	List[str]										=       jnp.asarray(_lowerCAmelCase		)
				return unflatten_dict(_lowerCAmelCase		)




def      __UpperCamelCase     (  _lowerCAmelCase				,					_lowerCAmelCase		)	->  Optional[int]:



				"""simple docstring"""






				A			:	Optional[Any]										=       os.path.abspath(_lowerCAmelCase		)
				logger.info(f'''Loading Flax weights from {flax_checkpoint_path}'''		)

				# import correct flax class
				A			:	Tuple										=       getattr(_lowerCAmelCase				,					"""Flax""" + model.__class__.__name__		)

				# load flax weight dict
				with open(_lowerCAmelCase				,					"""rb"""		) as state_f:
								try:
												A			:	Dict										=       from_bytes(_lowerCAmelCase				,					state_f.read()		)
								except UnpicklingError:
												raise EnvironmentError(f'''Unable to convert {flax_checkpoint_path} to Flax deserializable object. '''		)

				return load_flax_weights_in_pytorch_model(_lowerCAmelCase				,					_lowerCAmelCase		)




def      __UpperCamelCase     (  _lowerCAmelCase				,					_lowerCAmelCase		)	->  str:



				"""simple docstring"""






				try:
								import torch  # noqa: F401
				except ImportError:
								logger.error(
								    """Loading a Flax weights in PyTorch, requires both PyTorch and Flax to be installed. Please see"""
								    """ https://pytorch.org/ and https://flax.readthedocs.io/en/latest/installation.html for installation"""
								    """ instructions."""		)
								raise

				# check if we have bf16 weights
				A			:	Optional[Any]										=       flatten_dict(jax.tree_util.tree_map(lambda _lowerCAmelCase		: x.dtype == jnp.bfloataa				,					_lowerCAmelCase		)		).values()
				if any(_lowerCAmelCase		):
								# convert all weights to fp32 if the are bf16 since torch.from_numpy can-not handle bf16
								# and bf16 is not fully supported in PT yet.
								logger.warning(
								    """Found ``bfloat16`` weights in Flax model. Casting all ``bfloat16`` weights to ``float32`` """
								    """before loading those in PyTorch model."""		)
								A			:	Optional[int]										=       jax.tree_util.tree_map(
								    lambda _lowerCAmelCase		: params.astype(np.floataa		) if params.dtype == jnp.bfloataa else params				,					_lowerCAmelCase		)

				A			:	int										=       flatten_dict(_lowerCAmelCase		)
				A			:	Tuple										=       pt_model.state_dict()

				A			:	Union[str, Any]										=       (pt_model.base_model_prefix in flax_state) and (
				    pt_model.base_model_prefix not in {k.split("""."""		)[0] for k in pt_model_dict.keys()}
				)
				A			:	str										=       (pt_model.base_model_prefix not in flax_state) and (
				    pt_model.base_model_prefix in {k.split("""."""		)[0] for k in pt_model_dict.keys()}
				)

				# keep track of unexpected & missing keys
				A			:	Any										=       []
				A			:	List[Any]										=       set(pt_model_dict.keys()		)

				for flax_key_tuple, flax_tensor in flax_state_dict.items():
								A			:	str										=       flax_key_tuple[0] == pt_model.base_model_prefix
								A			:	Union[str, Any]										=       """.""".join((pt_model.base_model_prefix,) + flax_key_tuple		) in pt_model_dict

								# adapt flax_key to prepare for loading from/to base model only
								if load_model_with_head_into_base_model and has_base_model_prefix:
												A			:	str										=       flax_key_tuple[1:]
								elif load_base_model_into_model_with_head and require_base_model_prefix:
												A			:	List[Any]										=       (pt_model.base_model_prefix,) + flax_key_tuple

								# rename flax weights to PyTorch format
								if flax_key_tuple[-1] == "kernel" and flax_tensor.ndim == 4 and ".".join(_lowerCAmelCase		) not in pt_model_dict:
												# conv layer
												A			:	Union[str, Any]										=       flax_key_tuple[:-1] + ("""weight""",)
												A			:	List[Any]										=       jnp.transpose(_lowerCAmelCase				,					(3, 2, 0, 1)		)
								elif flax_key_tuple[-1] == "kernel" and ".".join(_lowerCAmelCase		) not in pt_model_dict:
												# linear layer
												A			:	Optional[int]										=       flax_key_tuple[:-1] + ("""weight""",)
												A			:	Tuple										=       flax_tensor.T
								elif flax_key_tuple[-1] in ["scale", "embedding"]:
												A			:	List[str]										=       flax_key_tuple[:-1] + ("""weight""",)

								# adding batch stats from flax batch norm to pt
								elif "mean" in flax_key_tuple[-1]:
												A			:	Optional[Any]										=       flax_key_tuple[:-1] + ("""running_mean""",)
								elif "var" in flax_key_tuple[-1]:
												A			:	Tuple										=       flax_key_tuple[:-1] + ("""running_var""",)

								if "batch_stats" in flax_state:
												A			:	List[str]										=       """.""".join(flax_key_tuple[1:]		)  # Remove the params/batch_stats header
								else:
												A			:	Union[str, Any]										=       """.""".join(_lowerCAmelCase		)

								# We also need to look at `pt_model_dict` and see if there are keys requiring further transformation.
								A			:	List[str]										=       {}
								# New `weight_norm` from https://github.com/huggingface/transformers/pull/24030
								for key in pt_model_dict:
												A			:	Optional[int]										=       key.split("""."""		)
												A			:	List[Any]										=       None
												if key_components[-3::2] == ["parametrizations", "original0"]:
																A			:	Optional[int]										=       key_components[-2] + """_g"""
												elif key_components[-3::2] == ["parametrizations", "original1"]:
																A			:	Any										=       key_components[-2] + """_v"""
												if name is not None:
																A			:	int										=       key_components[:-3] + [name]
																A			:	str										=       """.""".join(_lowerCAmelCase		)
																A			:	Dict										=       key

								if flax_key in special_pt_names:
												A			:	List[Any]										=       special_pt_names[flax_key]

								if flax_key in pt_model_dict:
												if flax_tensor.shape != pt_model_dict[flax_key].shape:
																raise ValueError(
																    f'''Flax checkpoint seems to be incorrect. Weight {flax_key_tuple} was expected '''
																    f'''to be of shape {pt_model_dict[flax_key].shape}, but is {flax_tensor.shape}.'''		)
												else:
																# add weight to pytorch dict
																A			:	Union[str, Any]										=       np.asarray(_lowerCAmelCase		) if not isinstance(_lowerCAmelCase				,					np.ndarray		) else flax_tensor
																A			:	Tuple										=       torch.from_numpy(_lowerCAmelCase		)
																# remove from missing keys
																missing_keys.remove(_lowerCAmelCase		)
								else:
												# weight is not expected by PyTorch model
												unexpected_keys.append(_lowerCAmelCase		)

				pt_model.load_state_dict(_lowerCAmelCase		)

				# re-transform missing_keys to list
				A			:	Tuple										=       list(_lowerCAmelCase		)

				if len(_lowerCAmelCase		) > 0:
								logger.warning(
								    """Some weights of the Flax model were not used when initializing the PyTorch model"""
								    f''' {pt_model.__class__.__name__}: {unexpected_keys}\n- This IS expected if you are initializing'''
								    f''' {pt_model.__class__.__name__} from a Flax model trained on another task or with another architecture'''
								    """ (e.g. initializing a BertForSequenceClassification model from a FlaxBertForPreTraining model).\n- This"""
								    f''' IS NOT expected if you are initializing {pt_model.__class__.__name__} from a Flax model that you expect'''
								    """ to be exactly identical (e.g. initializing a BertForSequenceClassification model from a"""
								    """ FlaxBertForSequenceClassification model)."""		)
				else:
								logger.warning(f'''All Flax model weights were used when initializing {pt_model.__class__.__name__}.\n'''		)
				if len(_lowerCAmelCase		) > 0:
								logger.warning(
								    f'''Some weights of {pt_model.__class__.__name__} were not initialized from the Flax model and are newly'''
								    f''' initialized: {missing_keys}\nYou should probably TRAIN this model on a down-stream task to be able to'''
								    """ use it for predictions and inference."""		)
				else:
								logger.warning(
								    f'''All the weights of {pt_model.__class__.__name__} were initialized from the Flax model.\n'''
								    """If your task is similar to the task the model of the checkpoint was trained on, """
								    f'''you can already use {pt_model.__class__.__name__} for predictions without further training.'''		)

				return pt_model







from __future__ import annotations




def      __UpperCamelCase     (  _lowerCAmelCase		)	->  list[int]:



    """simple docstring"""






    A			:	Tuple										=       2
    A			:	List[Any]										=       []
    while i * i <= n:
        if n % i:
            i += 1
        else:
            n //= i
            factors.append(_lowerCAmelCase		)
    if n > 1:
        factors.append(_lowerCAmelCase		)
    return factors


if __name__ == "__main__":
     import doctest

     doctest.testmod()


