



import argparse
import os

import align
import numpy as np
import requests
import tensorflow as tf
import torch
from PIL import Image
from tokenizer import Tokenizer

from transformers import (
    AlignConfig,
    AlignModel,
    AlignProcessor,
    BertConfig,
    BertTokenizer,
    EfficientNetConfig,
    EfficientNetImageProcessor,
)
from transformers.utils import logging


logging.set_verbosity_info()
UpperCAmelCase__			:   Any      			=    logging.get_logger(__name__)


def 	_A	(   _UpperCamelCase			):
				_UpperCAmelCase						:  Any     					=	tf.image.resize(__A      ,					(346, 346)			)
				_UpperCAmelCase						:  Optional[int]     					=	tf.image.crop_to_bounding_box(__A      ,					(346 - 289) // 2      ,					(346 - 289) // 2      ,					289      ,					289			)
				return image


def 	_A	(   ):
				_UpperCAmelCase						:  Any     					=	EfficientNetConfig.from_pretrained('''google/efficientnet-b7'''			)
				_UpperCAmelCase						:  List[Any]     					=	289
				_UpperCAmelCase						:  Dict     					=	640
				_UpperCAmelCase						:  Optional[int]     					=	{'''0''': '''LABEL_0''', '''1''': '''LABEL_1'''}
				_UpperCAmelCase						:  Optional[Any]     					=	{'''LABEL_0''': 0, '''LABEL_1''': 1}
				_UpperCAmelCase						:  Tuple     					=	[]

				_UpperCAmelCase						:  Optional[Any]     					=	BertConfig()
				_UpperCAmelCase						:  List[str]     					=	AlignConfig.from_text_vision_configs(
				    text_config=__A      ,					vision_config=__A      ,					projection_dim=640			)
				return config


def 	_A	(   ):
				_UpperCAmelCase						:  Dict     					=	'''http://images.cocodataset.org/val2017/000000039769.jpg'''
				_UpperCAmelCase						:  Any     					=	Image.open(requests.get(__A      ,					stream=__A			).raw			)
				return im


def 	_A	(   ):
				_UpperCAmelCase						:  List[Any]     					=	EfficientNetImageProcessor(
				    do_center_crop=__A      ,					rescale_factor=1 / 127.5      ,					rescale_offset=__A      ,					do_normalize=__A      ,					include_top=__A      ,					resample=Image.BILINEAR      ,					)
				_UpperCAmelCase						:  List[Any]     					=	BertTokenizer.from_pretrained('''bert-base-uncased'''			)
				_UpperCAmelCase						:  List[str]     					=	64
				_UpperCAmelCase						:  Optional[int]     					=	AlignProcessor(image_processor=__A      ,					tokenizer=__A			)
				return processor


def 	_A	(   _UpperCamelCase			):
				# EfficientNet image encoder
				_UpperCAmelCase						:  int     					=	[v.split('''_'''			)[0].split('''block'''			)[1] for v in original_param_names if v.startswith('''block'''			)]
				_UpperCAmelCase						:  Any     					=	list(set(__A			)			)
				_UpperCAmelCase						:  Tuple     					=	sorted(__A			)
				_UpperCAmelCase						:  int     					=	len(__A			)
				_UpperCAmelCase						:  Any     					=	{b: str(__A			) for b, i in zip(__A      ,					range(__A			)			)}

				_UpperCAmelCase						:  Dict     					=	[]
				rename_keys.append(('''stem_conv/kernel:0''', '''embeddings.convolution.weight''')			)
				rename_keys.append(('''stem_bn/gamma:0''', '''embeddings.batchnorm.weight''')			)
				rename_keys.append(('''stem_bn/beta:0''', '''embeddings.batchnorm.bias''')			)
				rename_keys.append(('''stem_bn/moving_mean:0''', '''embeddings.batchnorm.running_mean''')			)
				rename_keys.append(('''stem_bn/moving_variance:0''', '''embeddings.batchnorm.running_var''')			)

				for b in block_names:
								_UpperCAmelCase						:  Dict     					=	block_name_mapping[b]
								rename_keys.append((F'''block{b}_expand_conv/kernel:0''', F'''encoder.blocks.{hf_b}.expansion.expand_conv.weight''')			)
								rename_keys.append((F'''block{b}_expand_bn/gamma:0''', F'''encoder.blocks.{hf_b}.expansion.expand_bn.weight''')			)
								rename_keys.append((F'''block{b}_expand_bn/beta:0''', F'''encoder.blocks.{hf_b}.expansion.expand_bn.bias''')			)
								rename_keys.append(
								    (F'''block{b}_expand_bn/moving_mean:0''', F'''encoder.blocks.{hf_b}.expansion.expand_bn.running_mean''')			)
								rename_keys.append(
								    (F'''block{b}_expand_bn/moving_variance:0''', F'''encoder.blocks.{hf_b}.expansion.expand_bn.running_var''')			)
								rename_keys.append(
								    (F'''block{b}_dwconv/depthwise_kernel:0''', F'''encoder.blocks.{hf_b}.depthwise_conv.depthwise_conv.weight''')			)
								rename_keys.append((F'''block{b}_bn/gamma:0''', F'''encoder.blocks.{hf_b}.depthwise_conv.depthwise_norm.weight''')			)
								rename_keys.append((F'''block{b}_bn/beta:0''', F'''encoder.blocks.{hf_b}.depthwise_conv.depthwise_norm.bias''')			)
								rename_keys.append(
								    (F'''block{b}_bn/moving_mean:0''', F'''encoder.blocks.{hf_b}.depthwise_conv.depthwise_norm.running_mean''')			)
								rename_keys.append(
								    (F'''block{b}_bn/moving_variance:0''', F'''encoder.blocks.{hf_b}.depthwise_conv.depthwise_norm.running_var''')			)

								rename_keys.append((F'''block{b}_se_reduce/kernel:0''', F'''encoder.blocks.{hf_b}.squeeze_excite.reduce.weight''')			)
								rename_keys.append((F'''block{b}_se_reduce/bias:0''', F'''encoder.blocks.{hf_b}.squeeze_excite.reduce.bias''')			)
								rename_keys.append((F'''block{b}_se_expand/kernel:0''', F'''encoder.blocks.{hf_b}.squeeze_excite.expand.weight''')			)
								rename_keys.append((F'''block{b}_se_expand/bias:0''', F'''encoder.blocks.{hf_b}.squeeze_excite.expand.bias''')			)
								rename_keys.append(
								    (F'''block{b}_project_conv/kernel:0''', F'''encoder.blocks.{hf_b}.projection.project_conv.weight''')			)
								rename_keys.append((F'''block{b}_project_bn/gamma:0''', F'''encoder.blocks.{hf_b}.projection.project_bn.weight''')			)
								rename_keys.append((F'''block{b}_project_bn/beta:0''', F'''encoder.blocks.{hf_b}.projection.project_bn.bias''')			)
								rename_keys.append(
								    (F'''block{b}_project_bn/moving_mean:0''', F'''encoder.blocks.{hf_b}.projection.project_bn.running_mean''')			)
								rename_keys.append(
								    (F'''block{b}_project_bn/moving_variance:0''', F'''encoder.blocks.{hf_b}.projection.project_bn.running_var''')			)

				_UpperCAmelCase						:  Dict     					=	{}
				for item in rename_keys:
								if item[0] in original_param_names:
												_UpperCAmelCase						:  Dict     					=	'''vision_model.''' + item[1]

								# BERT text encoder
				_UpperCAmelCase						:  List[Any]     					=	[]
				_UpperCAmelCase						:  Tuple     					=	'''tf_bert_model/bert'''
				_UpperCAmelCase						:  Tuple     					=	'''text_model'''
				for i in range(12			):
								rename_keys.append(
								    (
								        F'''{old}/encoder/layer_._{i}/attention/self/query/kernel:0''',
								        F'''{new}.encoder.layer.{i}.attention.self.query.weight''',
								    )			)
								rename_keys.append(
								    (
								        F'''{old}/encoder/layer_._{i}/attention/self/query/bias:0''',
								        F'''{new}.encoder.layer.{i}.attention.self.query.bias''',
								    )			)
								rename_keys.append(
								    (
								        F'''{old}/encoder/layer_._{i}/attention/self/key/kernel:0''',
								        F'''{new}.encoder.layer.{i}.attention.self.key.weight''',
								    )			)
								rename_keys.append(
								    (
								        F'''{old}/encoder/layer_._{i}/attention/self/key/bias:0''',
								        F'''{new}.encoder.layer.{i}.attention.self.key.bias''',
								    )			)
								rename_keys.append(
								    (
								        F'''{old}/encoder/layer_._{i}/attention/self/value/kernel:0''',
								        F'''{new}.encoder.layer.{i}.attention.self.value.weight''',
								    )			)
								rename_keys.append(
								    (
								        F'''{old}/encoder/layer_._{i}/attention/self/value/bias:0''',
								        F'''{new}.encoder.layer.{i}.attention.self.value.bias''',
								    )			)
								rename_keys.append(
								    (
								        F'''{old}/encoder/layer_._{i}/attention/output/dense/kernel:0''',
								        F'''{new}.encoder.layer.{i}.attention.output.dense.weight''',
								    )			)
								rename_keys.append(
								    (
								        F'''{old}/encoder/layer_._{i}/attention/output/dense/bias:0''',
								        F'''{new}.encoder.layer.{i}.attention.output.dense.bias''',
								    )			)
								rename_keys.append(
								    (
								        F'''{old}/encoder/layer_._{i}/attention/output/LayerNorm/gamma:0''',
								        F'''{new}.encoder.layer.{i}.attention.output.LayerNorm.weight''',
								    )			)
								rename_keys.append(
								    (
								        F'''{old}/encoder/layer_._{i}/attention/output/LayerNorm/beta:0''',
								        F'''{new}.encoder.layer.{i}.attention.output.LayerNorm.bias''',
								    )			)
								rename_keys.append(
								    (
								        F'''{old}/encoder/layer_._{i}/intermediate/dense/kernel:0''',
								        F'''{new}.encoder.layer.{i}.intermediate.dense.weight''',
								    )			)
								rename_keys.append(
								    (
								        F'''{old}/encoder/layer_._{i}/intermediate/dense/bias:0''',
								        F'''{new}.encoder.layer.{i}.intermediate.dense.bias''',
								    )			)
								rename_keys.append(
								    (F'''{old}/encoder/layer_._{i}/output/dense/kernel:0''', F'''{new}.encoder.layer.{i}.output.dense.weight''')			)
								rename_keys.append(
								    (F'''{old}/encoder/layer_._{i}/output/dense/bias:0''', F'''{new}.encoder.layer.{i}.output.dense.bias''')			)
								rename_keys.append(
								    (F'''{old}/encoder/layer_._{i}/output/LayerNorm/gamma:0''', F'''{new}.encoder.layer.{i}.output.LayerNorm.weight''')			)
								rename_keys.append(
								    (F'''{old}/encoder/layer_._{i}/output/LayerNorm/beta:0''', F'''{new}.encoder.layer.{i}.output.LayerNorm.bias''')			)

				rename_keys.append((F'''{old}/embeddings/word_embeddings/weight:0''', F'''{new}.embeddings.word_embeddings.weight''')			)
				rename_keys.append(
				    (F'''{old}/embeddings/position_embeddings/embeddings:0''', F'''{new}.embeddings.position_embeddings.weight''')			)
				rename_keys.append(
				    (F'''{old}/embeddings/token_type_embeddings/embeddings:0''', F'''{new}.embeddings.token_type_embeddings.weight''')			)
				rename_keys.append((F'''{old}/embeddings/LayerNorm/gamma:0''', F'''{new}.embeddings.LayerNorm.weight''')			)
				rename_keys.append((F'''{old}/embeddings/LayerNorm/beta:0''', F'''{new}.embeddings.LayerNorm.bias''')			)

				rename_keys.append((F'''{old}/pooler/dense/kernel:0''', F'''{new}.pooler.dense.weight''')			)
				rename_keys.append((F'''{old}/pooler/dense/bias:0''', F'''{new}.pooler.dense.bias''')			)
				rename_keys.append(('''dense/kernel:0''', '''text_projection.weight''')			)
				rename_keys.append(('''dense/bias:0''', '''text_projection.bias''')			)
				rename_keys.append(('''dense/bias:0''', '''text_projection.bias''')			)
				rename_keys.append(('''temperature:0''', '''temperature''')			)

				for item in rename_keys:
								if item[0] in original_param_names:
												_UpperCAmelCase						:  Union[str, Any]     					=	item[1]
				return key_mapping


def 	_A	(   _UpperCamelCase      ,					_UpperCamelCase      ,					_UpperCamelCase			):
				list(hf_params.keys()			)

				for key, value in tf_params.items():
								if key not in key_mapping:
												continue

								_UpperCAmelCase						:  Tuple     					=	key_mapping[key]
								if "_conv" in key and "kernel" in key:
												_UpperCAmelCase						:  Tuple     					=	torch.from_numpy(__A			).permute(3      ,					2      ,					0      ,					1			)
								elif "embeddings" in key:
												_UpperCAmelCase						:  str     					=	torch.from_numpy(__A			)
								elif "depthwise_kernel" in key:
												_UpperCAmelCase						:  Union[str, Any]     					=	torch.from_numpy(__A			).permute(2      ,					3      ,					0      ,					1			)
								elif "kernel" in key:
												_UpperCAmelCase						:  List[Any]     					=	torch.from_numpy(np.transpose(__A			)			)
								elif "temperature" in key:
												_UpperCAmelCase						:  Dict     					=	value
								elif "bn/gamma" or "bn/beta" in key:
												_UpperCAmelCase						:  int     					=	torch.from_numpy(np.transpose(__A			)			).squeeze()
								else:
												_UpperCAmelCase						:  Optional[int]     					=	torch.from_numpy(__A			)

								# Replace HF parameters with original TF model parameters
								hf_params[hf_key].copy_(__A			)


@torch.no_grad()
def 	_A	(   _UpperCamelCase      ,					_UpperCamelCase      ,					_UpperCamelCase      ,					_UpperCamelCase			):
				_UpperCAmelCase						:  int     					=	64
				_UpperCAmelCase						:  str     					=	Tokenizer(__A			)
				_UpperCAmelCase						:  str     					=	align.Align('''efficientnet-b7'''      ,					'''bert-base'''      ,					640      ,					__A      ,					tok.get_vocab_size()			)
				original_model.compile()
				original_model.load_weights(__A			)

				_UpperCAmelCase						:  Optional[int]     					=	original_model.trainable_variables
				_UpperCAmelCase						:  Tuple     					=	original_model.non_trainable_variables
				_UpperCAmelCase						:  Union[str, Any]     					=	{param.name: param.numpy() for param in tf_params}
				for param in tf_non_train_params:
								_UpperCAmelCase						:  Union[str, Any]     					=	param.numpy()
				_UpperCAmelCase						:  str     					=	list(tf_params.keys()			)

				# Load HuggingFace model
				_UpperCAmelCase						:  int     					=	get_align_config()
				_UpperCAmelCase						:  List[Any]     					=	AlignModel(__A			).eval()
				_UpperCAmelCase						:  Dict     					=	hf_model.state_dict()

				# Create src-to-dst parameter name mapping dictionary
				print('''Converting parameters...'''			)
				_UpperCAmelCase						:  List[Any]     					=	rename_keys(__A			)
				replace_params(__A      ,					__A      ,					__A			)

				# Initialize processor
				_UpperCAmelCase						:  Dict     					=	get_processor()
				_UpperCAmelCase						:  List[str]     					=	processor(
				    images=prepare_img()      ,					text='''A picture of a cat'''      ,					padding='''max_length'''      ,					max_length=64      ,					return_tensors='''pt'''			)

				# HF model inference
				hf_model.eval()
				with torch.no_grad():
								_UpperCAmelCase						:  Optional[int]     					=	hf_model(**__A			)

				_UpperCAmelCase						:  Any     					=	outputs.image_embeds.detach().numpy()
				_UpperCAmelCase						:  str     					=	outputs.text_embeds.detach().numpy()

				# Original model inference
				_UpperCAmelCase						:  List[Any]     					=	False
				_UpperCAmelCase						:  str     					=	EfficientNetImageProcessor(
				    do_center_crop=__A      ,					do_rescale=__A      ,					do_normalize=__A      ,					include_top=__A      ,					resample=Image.BILINEAR      ,					)
				_UpperCAmelCase						:  Dict     					=	tf_image_processor(images=prepare_img()      ,					return_tensors='''tf'''      ,					data_format='''channels_last'''			)['''pixel_values''']
				_UpperCAmelCase						:  int     					=	tok(tf.constant(['''A picture of a cat''']			)			)

				_UpperCAmelCase						:  Optional[int]     					=	original_model.image_encoder(__A      ,					training=__A			)
				_UpperCAmelCase						:  Dict     					=	original_model.text_encoder(__A      ,					training=__A			)

				_UpperCAmelCase						:  List[str]     					=	tf.nn.la_normalize(__A      ,					axis=-1			)
				_UpperCAmelCase						:  Dict     					=	tf.nn.la_normalize(__A      ,					axis=-1			)

				# Check whether original and HF model outputs match  -> np.allclose
				if not np.allclose(__A      ,					__A      ,					atol=1e-3			):
								raise ValueError('''The predicted image features are not the same.'''			)
				if not np.allclose(__A      ,					__A      ,					atol=1e-3			):
								raise ValueError('''The predicted text features are not the same.'''			)
				print('''Model outputs match!'''			)

				if save_model:
								# Create folder to save model
								if not os.path.isdir(__A			):
												os.mkdir(__A			)
								# Save converted model and image processor
								hf_model.save_pretrained(__A			)
								processor.save_pretrained(__A			)

				if push_to_hub:
								# Push model and image processor to hub
								print('''Pushing converted ALIGN to the hub...'''			)
								processor.push_to_hub('''align-base'''			)
								hf_model.push_to_hub('''align-base'''			)


if __name__ == "__main__":
					UpperCAmelCase__			:   Dict      			=    argparse.ArgumentParser()
					# Required parameters
					parser.add_argument(
					    '--checkpoint_path',
					    default='./weights/model-weights',
					    type=str,
					    help='Path to the pretrained TF ALIGN checkpoint.',
					)
					parser.add_argument(
					    '--pytorch_dump_folder_path',
					    default='hf_model',
					    type=str,
					    help='Path to the output PyTorch model directory.',
					)
					parser.add_argument('--save_model', action='store_true', help='Save model to local')
					parser.add_argument('--push_to_hub', action='store_true', help='Push model and image processor to the hub')

					UpperCAmelCase__			:   List[str]      			=    parser.parse_args()
					convert_align_checkpoint(args.checkpoint_path, args.pytorch_dump_folder_path, args.save_model, args.push_to_hub)



def   _lowerCAmelCase(						):

  for a in range(300      ):
    for b in range(a + 1 ,							400      ):
      for c in range(b + 1 ,							500      ):
        if (a + b + c) == 1000 and (a**2) + (b**2) == (c**2):
          return a * b * c

  return -1
def   _lowerCAmelCase(						):

  for a in range(300      ):
    for b in range(400      ):
      UpperCAmelCase          =	1000 - a - b
      if a < b < c and (a**2) + (b**2) == (c**2):
        return a * b * c

  return -1
def   _lowerCAmelCase(						):
  import timeit

  print(
      timeit.timeit("solution()" ,							setup="from __main__ import solution" ,							number=1000      )      )
  print(
      timeit.timeit(
          "solution_fast()" ,							setup="from __main__ import solution_fast" ,							number=1000      )      )


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



