





"""simple docstring"""




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


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






def  _SCREAMING_SNAKE_CASE						(      _lowercase		:       Optional[Any]       ,			_lowercase		:       Tuple       ,			_lowercase		:       Any       ,			_lowercase		:       Union[str, Any]=False   )					->Optional[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 :						Tuple      =							os.path.abspath(_lowercase   )
		logger.info(F"""Loading PyTorch weights from {pt_path}"""   )

		a :						Any      =							torch.load(_lowercase       ,			map_location="cpu"   )
		logger.info(F"""PyTorch checkpoint contains {sum(t.numel() for t in pt_state_dict.values()   ):,} parameters."""   )

		a :						str      =							convert_pytorch_state_dict_to_flax(_lowercase       ,			_lowercase   )
	else:
		# model is sharded and pytorch_checkpoint_path already contains the list of .pt shard files
		a :						Optional[Any]      =							convert_pytorch_sharded_state_dict_to_flax(_lowercase       ,			_lowercase   )
	return flax_state_dict






def  _SCREAMING_SNAKE_CASE						(      _lowercase		:       Dict       ,			_lowercase		:       Any       ,			_lowercase		:       List[Any]       ,			_lowercase		:       Optional[Any]       ,			)					->(Tuple[str], np.ndarray):






	'''simple docstring'''






	def is_key_or_prefix_key_in_dict(_lowercase		:       Optional[int]   ) -> bool:
		return len(set(_lowercase   ) & {key, (model_prefix,) + key}   ) > 0

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

	# batch norm layer mean
	a :						Tuple      =							pt_tuple_key[:-1] + ("""mean""",)
	if pt_tuple_key[-1] == "running_mean" and not is_key_or_prefix_key_in_dict(_lowercase   ):
		return renamed_pt_tuple_key, pt_tensor

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

	# embedding
	a :						Tuple      =							pt_tuple_key[:-1] + ("""embedding""",)
	if pt_tuple_key[-1] == "weight" and is_key_or_prefix_key_in_dict(_lowercase   ):
		return renamed_pt_tuple_key, pt_tensor

	# conv layer
	a :						List[str]      =							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(_lowercase   ):
		a :						Union[str, Any]      =							pt_tensor.transpose(2       ,			3       ,			1       ,			0   )
		return renamed_pt_tuple_key, pt_tensor

	# linear layer
	a :						int      =							pt_tuple_key[:-1] + ("""kernel""",)
	if pt_tuple_key[-1] == "weight" and not is_key_or_prefix_key_in_dict(_lowercase   ):
		a :						str      =							pt_tensor.T
		return renamed_pt_tuple_key, pt_tensor

	# old PyTorch layer norm weight
	a :						Tuple      =							pt_tuple_key[:-1] + ("""weight""",)
	if pt_tuple_key[-1] == "gamma":
		return renamed_pt_tuple_key, pt_tensor

	# old PyTorch layer norm bias
	a :						List[str]      =							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 :						int      =							pt_tuple_key[-2] + """_g"""
	elif pt_tuple_key[-3::2] == ("parametrizations", "original1"):
		a :						Optional[int]      =							pt_tuple_key[-2] + """_v"""
	if name is not None:
		a :						List[str]      =							pt_tuple_key[:-3] + (name,)
		return renamed_pt_tuple_key, pt_tensor

	return pt_tuple_key, pt_tensor






def  _SCREAMING_SNAKE_CASE						(      _lowercase		:       Any       ,			_lowercase		:       Union[str, Any]   )					->Dict:






	'''simple docstring'''






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

	a :						Optional[Any]      =							flax_model.base_model_prefix

	# use params dict if the model contains batch norm layers
	if "params" in flax_model.params:
		a :						Any      =							flax_model.params["""params"""]
	else:
		a :						Optional[Any]      =							flax_model.params
	a :						Tuple      =							flatten_dict(_lowercase   )

	# 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(_lowercase   )

	a :						List[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 :						List[str]      =							(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 :						Optional[Any]      =							tuple(pt_key.split("."   )   )

		# remove base model prefix if necessary
		a :						str      =							pt_tuple_key[0] == model_prefix
		if load_model_with_head_into_base_model and has_base_model_prefix:
			a :						Optional[int]      =							pt_tuple_key[1:]

		# Correctly rename weight parameters
		a :						int      =							rename_key_and_reshape_tensor(
		    _lowercase       ,			_lowercase       ,			_lowercase       ,			_lowercase   )

		# add model prefix if necessary
		a :						str      =							(model_prefix,) + flax_key in random_flax_state_dict
		if load_base_model_into_model_with_head and require_base_model_prefix:
			a :						str      =							(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 :						Any      =							jnp.asarray(_lowercase   )
				continue
			# remove num_batches_tracked key
			if "num_batches_tracked" in flax_key[-1]:
				flax_state_dict.pop(_lowercase       ,			_lowercase   )
				continue

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

		else:
			# also add unexpected weight so that warning is thrown
			a :						Any      =							jnp.asarray(_lowercase   )

	return unflatten_dict(_lowercase   )






def  _SCREAMING_SNAKE_CASE						(      _lowercase		:       Union[str, Any]       ,			_lowercase		:       Optional[int]   )					->str:






	'''simple docstring'''






	import torch

	# Load the index
	a :						List[str]      =							{}
	for shard_file in shard_filenames:
		# load using msgpack utils
		a :						Tuple      =							torch.load(_lowercase   )
		a :						Optional[int]      =							{k: v.numpy() for k, v in pt_state_dict.items()}

		a :						Optional[Any]      =							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 :						List[Any]      =							flax_model.params["""params"""]

			a :						int      =							flatten_dict(_lowercase   )
			random_flax_state_dict.update(flatten_dict(flax_model.params["batch_stats"]   )   )
		else:
			a :						Any      =							flax_model.params
			a :						List[Any]      =							flatten_dict(_lowercase   )

		a :						int      =							(model_prefix not in flax_model_params) and (
		    model_prefix in {k.split("."   )[0] for k in pt_state_dict.keys()}
		)
		a :						str      =							(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 :						Optional[int]      =							tuple(pt_key.split("."   )   )

			# remove base model prefix if necessary
			a :						Dict      =							pt_tuple_key[0] == model_prefix
			if load_model_with_head_into_base_model and has_base_model_prefix:
				a :						Optional[int]      =							pt_tuple_key[1:]

			# Correctly rename weight parameters
			a :						Union[str, Any]      =							rename_key_and_reshape_tensor(
			    _lowercase       ,			_lowercase       ,			_lowercase       ,			_lowercase   )
			# 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 :						Optional[int]      =							(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 :						Any      =							jnp.asarray(_lowercase   )
					continue
				if "var" in flax_key[-1]:
					a :						List[str]      =							jnp.asarray(_lowercase   )
					continue
				# remove num_batches_tracked key
				if "num_batches_tracked" in flax_key[-1]:
					flax_state_dict.pop(_lowercase       ,			_lowercase   )
					continue

				# also add unexpected weight so that warning is thrown
				a :						Optional[int]      =							jnp.asarray(_lowercase   )

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






def  _SCREAMING_SNAKE_CASE						(      _lowercase		:       Optional[int]       ,			_lowercase		:       Tuple   )					->Union[str, Any]:






	'''simple docstring'''






	a :						Optional[Any]      =							os.path.abspath(_lowercase   )
	logger.info(F"""Loading Flax weights from {flax_checkpoint_path}"""   )

	# import correct flax class
	a :						Dict      =							getattr(_lowercase       ,			"Flax" + model.__class__.__name__   )

	# load flax weight dict
	with open(_lowercase       ,			"rb"   ) as state_f:
		try:
			a :						Any      =							from_bytes(_lowercase       ,			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(_lowercase       ,			_lowercase   )







def  _SCREAMING_SNAKE_CASE						(      _lowercase		:       Any       ,			_lowercase		:       Tuple   )					->Optional[Any]:






	'''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 :						List[Any]      =							flatten_dict(jax.tree_util.tree_map(lambda _lowercase   : x.dtype == jnp.bfloataa       ,			_lowercase   )   ).values()
	if any(_lowercase   ):
		# 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 :						Union[str, Any]      =							jax.tree_util.tree_map(
		    lambda _lowercase   : params.astype(np.floataa   ) if params.dtype == jnp.bfloataa else params       ,			_lowercase   )

	a :						int      =							flatten_dict(_lowercase   )
	a :						str      =							pt_model.state_dict()

	a :						Optional[int]      =							(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 :						List[str]      =							[]
	a :						Optional[int]      =							set(pt_model_dict.keys()   )

	for flax_key_tuple, flax_tensor in flax_state_dict.items():
		a :						Dict      =							flax_key_tuple[0] == pt_model.base_model_prefix
		a :						List[str]      =							""".""".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 :						int      =							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(_lowercase   ) not in pt_model_dict:
			# conv layer
			a :						Union[str, Any]      =							flax_key_tuple[:-1] + ("""weight""",)
			a :						str      =							jnp.transpose(_lowercase       ,			(3, 2, 0, 1)   )
		elif flax_key_tuple[-1] == "kernel" and ".".join(_lowercase   ) not in pt_model_dict:
			# linear layer
			a :						Optional[Any]      =							flax_key_tuple[:-1] + ("""weight""",)
			a :						Union[str, Any]      =							flax_tensor.T
		elif flax_key_tuple[-1] in ["scale", "embedding"]:
			a :						Any      =							flax_key_tuple[:-1] + ("""weight""",)

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

		if "batch_stats" in flax_state:
			a :						int      =							""".""".join(flax_key_tuple[1:]   )  # Remove the params/batch_stats header
		else:
			a :						Optional[Any]      =							""".""".join(_lowercase   )

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

		if flax_key in special_pt_names:
			a :						Optional[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 :						Dict      =							np.asarray(_lowercase   ) if not isinstance(_lowercase       ,			np.ndarray   ) else flax_tensor
				a :						Optional[int]      =							torch.from_numpy(_lowercase   )
				# remove from missing keys
				missing_keys.remove(_lowercase   )
		else:
			# weight is not expected by PyTorch model
			unexpected_keys.append(_lowercase   )

	pt_model.load_state_dict(_lowercase   )

	# re-transform missing_keys to list
	a :						Optional[Any]      =							list(_lowercase   )

	if len(_lowercase   ) > 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(_lowercase   ) > 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





"""simple docstring"""
from __future__ import annotations

from functools import lru_cache
from math import ceil

_A							=  1_00

_A							=  set(range(3, NUM_PRIMES, 2))
primes.add(2)
_A							=  42

for prime in range(3, ceil(NUM_PRIMES**0.5), 2):
    if prime not in primes:
        continue
    primes.difference_update(set(range(prime * prime, NUM_PRIMES, prime)))




@lru_cache(maxsize=1_00    )
def 					a__						(						lowerCAmelCase    )	-> set[int]:
      if number_to_partition < 0:
            return set()
      elif number_to_partition == 0:
            return {1}

      UpperCAmelCase__			:							set[int]							=    set()
      UpperCAmelCase__			:							int
      UpperCAmelCase__			:							int

      for prime in primes:
            if prime > number_to_partition:
                  continue
            for sub in partition(number_to_partition - prime    ):
                  ret.add(sub * prime    )

      return ret




def 					a__						(						lowerCAmelCase = 50_00    )	-> int | None:
      for number_to_partition in range(1			,	lowerCAmelCase    ):
            if len(partition(lowerCAmelCase    )    ) > number_unique_partitions:
                  return number_to_partition
      return None


if __name__ == "__main__":
    print(f'''{solution() = }''')

