

import math
import os
import unittest

from transformers import MegatronBertConfig, is_torch_available
from transformers.models.auto import get_values
from transformers.testing_utils import require_sentencepiece, require_tokenizers, require_torch, slow, torch_device

from ...test_configuration_common import ConfigTester
from ...test_modeling_common import ModelTesterMixin, ids_tensor, random_attention_mask
from ...test_pipeline_mixin import PipelineTesterMixin


if is_torch_available():
						import torch

						from transformers import (
						    MODEL_FOR_PRETRAINING_MAPPING,
						    MegatronBertForCausalLM,
						    MegatronBertForMaskedLM,
						    MegatronBertForMultipleChoice,
						    MegatronBertForNextSentencePrediction,
						    MegatronBertForPreTraining,
						    MegatronBertForQuestionAnswering,
						    MegatronBertForSequenceClassification,
						    MegatronBertForTokenClassification,
						    MegatronBertModel,
						)



class   __lowercase				:




			"""simple docstring"""







			def __init__( self  :     Optional[Any]   ,						lowerCAmelCase__  :     Union[str, Any]   ,						lowerCAmelCase__  :     Optional[Any]=13   ,						lowerCAmelCase__  :     Optional[int]=7   ,						lowerCAmelCase__  :     Optional[int]=True   ,						lowerCAmelCase__  :     Optional[Any]=True   ,						lowerCAmelCase__  :     Optional[Any]=True   ,						lowerCAmelCase__  :     Optional[int]=True   ,						lowerCAmelCase__  :     Union[str, Any]=99   ,						lowerCAmelCase__  :     Union[str, Any]=64   ,						lowerCAmelCase__  :     Dict=32   ,						lowerCAmelCase__  :     int=5   ,						lowerCAmelCase__  :     Optional[int]=4   ,						lowerCAmelCase__  :     Optional[int]=37   ,						lowerCAmelCase__  :     List[str]="gelu"   ,						lowerCAmelCase__  :     str=0.1   ,						lowerCAmelCase__  :     Union[str, Any]=0.1   ,						lowerCAmelCase__  :     List[str]=512   ,						lowerCAmelCase__  :     str=16   ,						lowerCAmelCase__  :     List[Any]=2   ,						lowerCAmelCase__  :     List[str]=0.02   ,						lowerCAmelCase__  :     Optional[int]=3   ,						lowerCAmelCase__  :     Any=4   ,						lowerCAmelCase__  :     Tuple=None   ,						):
									SCREAMING_SNAKE_CASE_: Union[str, Any]  		=       parent
									SCREAMING_SNAKE_CASE_: Union[str, Any]  		=       batch_size
									SCREAMING_SNAKE_CASE_: List[str]  		=       seq_length
									SCREAMING_SNAKE_CASE_: List[str]  		=       is_training
									SCREAMING_SNAKE_CASE_: int  		=       use_input_mask
									SCREAMING_SNAKE_CASE_: List[Any]  		=       use_token_type_ids
									SCREAMING_SNAKE_CASE_: Optional[int]  		=       use_labels
									SCREAMING_SNAKE_CASE_: List[str]  		=       vocab_size
									SCREAMING_SNAKE_CASE_: int  		=       hidden_size
									SCREAMING_SNAKE_CASE_: Optional[int]  		=       embedding_size
									SCREAMING_SNAKE_CASE_: Union[str, Any]  		=       num_hidden_layers
									SCREAMING_SNAKE_CASE_: int  		=       num_attention_heads
									SCREAMING_SNAKE_CASE_: Tuple  		=       intermediate_size
									SCREAMING_SNAKE_CASE_: List[Any]  		=       hidden_act
									SCREAMING_SNAKE_CASE_: Dict  		=       hidden_dropout_prob
									SCREAMING_SNAKE_CASE_: Optional[int]  		=       attention_probs_dropout_prob
									SCREAMING_SNAKE_CASE_: Any  		=       max_position_embeddings
									SCREAMING_SNAKE_CASE_: int  		=       type_vocab_size
									SCREAMING_SNAKE_CASE_: List[Any]  		=       type_sequence_label_size
									SCREAMING_SNAKE_CASE_: Any  		=       initializer_range
									SCREAMING_SNAKE_CASE_: Dict  		=       num_labels
									SCREAMING_SNAKE_CASE_: Optional[Any]  		=       num_choices
									SCREAMING_SNAKE_CASE_: List[str]  		=       scope



			def        _SCREAMING_SNAKE_CASE			( self  :     Optional[int]):
									SCREAMING_SNAKE_CASE_: str  		=       ids_tensor([self.batch_size, self.seq_length]   ,						self.vocab_size)

									SCREAMING_SNAKE_CASE_: Tuple  		=       None
									if self.use_input_mask:
															SCREAMING_SNAKE_CASE_: Any  		=       random_attention_mask([self.batch_size, self.seq_length])

									SCREAMING_SNAKE_CASE_: Optional[int]  		=       None
									if self.use_token_type_ids:
															SCREAMING_SNAKE_CASE_: int  		=       ids_tensor([self.batch_size, self.seq_length]   ,						self.type_vocab_size)

									SCREAMING_SNAKE_CASE_: int  		=       None
									SCREAMING_SNAKE_CASE_: List[str]  		=       None
									SCREAMING_SNAKE_CASE_: Union[str, Any]  		=       None
									if self.use_labels:
															SCREAMING_SNAKE_CASE_: List[str]  		=       ids_tensor([self.batch_size]   ,						self.type_sequence_label_size)
															SCREAMING_SNAKE_CASE_: Any  		=       ids_tensor([self.batch_size, self.seq_length]   ,						self.num_labels)
															SCREAMING_SNAKE_CASE_: Optional[Any]  		=       ids_tensor([self.batch_size]   ,						self.num_choices)

									SCREAMING_SNAKE_CASE_: Any  		=       self.get_config()

									return config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels



			def        _SCREAMING_SNAKE_CASE			( self  :     int):
									return MegatronBertConfig(
									    vocab_size=self.vocab_size   ,						hidden_size=self.hidden_size   ,						num_hidden_layers=self.num_hidden_layers   ,						num_attention_heads=self.num_attention_heads   ,						intermediate_size=self.intermediate_size   ,						embedding_size=self.embedding_size   ,						hidden_act=self.hidden_act   ,						hidden_dropout_prob=self.hidden_dropout_prob   ,						attention_probs_dropout_prob=self.attention_probs_dropout_prob   ,						max_position_embeddings=self.max_position_embeddings   ,						type_vocab_size=self.type_vocab_size   ,						is_decoder=lowerCAmelCase__   ,						initializer_range=self.initializer_range   ,						)



			def        _SCREAMING_SNAKE_CASE			( self  :     int   ,						lowerCAmelCase__  :     int   ,						lowerCAmelCase__  :     Any   ,						lowerCAmelCase__  :     Optional[Any]   ,						lowerCAmelCase__  :     Any   ,						lowerCAmelCase__  :     int   ,						lowerCAmelCase__  :     Optional[int]   ,						lowerCAmelCase__  :     Optional[Any]):
									SCREAMING_SNAKE_CASE_: Tuple  		=       MegatronBertModel(config=lowerCAmelCase__)
									model.to(lowerCAmelCase__)
									model.eval()
									SCREAMING_SNAKE_CASE_: int  		=       model(lowerCAmelCase__   ,						attention_mask=lowerCAmelCase__   ,						token_type_ids=lowerCAmelCase__)
									SCREAMING_SNAKE_CASE_: Optional[int]  		=       model(lowerCAmelCase__   ,						token_type_ids=lowerCAmelCase__)
									SCREAMING_SNAKE_CASE_: Optional[int]  		=       model(lowerCAmelCase__)

									self.parent.assertEqual(result.last_hidden_state.shape   ,						(self.batch_size, self.seq_length, self.hidden_size))
									self.parent.assertEqual(result.pooler_output.shape   ,						(self.batch_size, self.hidden_size))



			def        _SCREAMING_SNAKE_CASE			( self  :     str   ,						lowerCAmelCase__  :     Optional[Any]   ,						lowerCAmelCase__  :     List[str]   ,						lowerCAmelCase__  :     List[Any]   ,						lowerCAmelCase__  :     List[str]   ,						lowerCAmelCase__  :     Optional[int]   ,						lowerCAmelCase__  :     str   ,						lowerCAmelCase__  :     Optional[Any]):
									SCREAMING_SNAKE_CASE_: str  		=       MegatronBertForMaskedLM(config=lowerCAmelCase__)
									model.to(lowerCAmelCase__)
									model.eval()
									SCREAMING_SNAKE_CASE_: str  		=       model(lowerCAmelCase__   ,						attention_mask=lowerCAmelCase__   ,						token_type_ids=lowerCAmelCase__   ,						labels=lowerCAmelCase__)
									self.parent.assertEqual(result.logits.shape   ,						(self.batch_size, self.seq_length, self.vocab_size))



			def        _SCREAMING_SNAKE_CASE			( self  :     List[Any]   ,						lowerCAmelCase__  :     List[str]   ,						lowerCAmelCase__  :     Dict   ,						lowerCAmelCase__  :     Optional[int]   ,						lowerCAmelCase__  :     Union[str, Any]   ,						lowerCAmelCase__  :     Optional[Any]   ,						lowerCAmelCase__  :     str   ,						lowerCAmelCase__  :     Tuple):
									SCREAMING_SNAKE_CASE_: Optional[int]  		=       MegatronBertForCausalLM(config=lowerCAmelCase__)
									model.to(lowerCAmelCase__)
									model.eval()
									SCREAMING_SNAKE_CASE_: Tuple  		=       model(lowerCAmelCase__   ,						attention_mask=lowerCAmelCase__   ,						token_type_ids=lowerCAmelCase__   ,						labels=lowerCAmelCase__)
									self.parent.assertEqual(result.logits.shape   ,						(self.batch_size, self.seq_length, self.vocab_size))



			def        _SCREAMING_SNAKE_CASE			( self  :     List[Any]   ,						lowerCAmelCase__  :     Dict   ,						lowerCAmelCase__  :     List[str]   ,						lowerCAmelCase__  :     Dict   ,						lowerCAmelCase__  :     Optional[Any]   ,						lowerCAmelCase__  :     int   ,						lowerCAmelCase__  :     Tuple   ,						lowerCAmelCase__  :     List[str]):
									SCREAMING_SNAKE_CASE_: Union[str, Any]  		=       MegatronBertForNextSentencePrediction(config=lowerCAmelCase__)
									model.to(lowerCAmelCase__)
									model.eval()
									SCREAMING_SNAKE_CASE_: Optional[Any]  		=       model(
									    lowerCAmelCase__   ,						attention_mask=lowerCAmelCase__   ,						token_type_ids=lowerCAmelCase__   ,						labels=lowerCAmelCase__   ,						)
									self.parent.assertEqual(result.logits.shape   ,						(self.batch_size, 2))



			def        _SCREAMING_SNAKE_CASE			( self  :     List[str]   ,						lowerCAmelCase__  :     Optional[int]   ,						lowerCAmelCase__  :     List[Any]   ,						lowerCAmelCase__  :     Union[str, Any]   ,						lowerCAmelCase__  :     List[str]   ,						lowerCAmelCase__  :     str   ,						lowerCAmelCase__  :     str   ,						lowerCAmelCase__  :     Tuple):
									SCREAMING_SNAKE_CASE_: Dict  		=       MegatronBertForPreTraining(config=lowerCAmelCase__)
									model.to(lowerCAmelCase__)
									model.eval()
									SCREAMING_SNAKE_CASE_: List[str]  		=       model(
									    lowerCAmelCase__   ,						attention_mask=lowerCAmelCase__   ,						token_type_ids=lowerCAmelCase__   ,						labels=lowerCAmelCase__   ,						next_sentence_label=lowerCAmelCase__   ,						)
									self.parent.assertEqual(result.prediction_logits.shape   ,						(self.batch_size, self.seq_length, self.vocab_size))
									self.parent.assertEqual(result.seq_relationship_logits.shape   ,						(self.batch_size, 2))



			def        _SCREAMING_SNAKE_CASE			( self  :     Any   ,						lowerCAmelCase__  :     Union[str, Any]   ,						lowerCAmelCase__  :     int   ,						lowerCAmelCase__  :     Dict   ,						lowerCAmelCase__  :     Any   ,						lowerCAmelCase__  :     Tuple   ,						lowerCAmelCase__  :     int   ,						lowerCAmelCase__  :     Tuple):
									SCREAMING_SNAKE_CASE_: str  		=       MegatronBertForQuestionAnswering(config=lowerCAmelCase__)
									model.to(lowerCAmelCase__)
									model.eval()
									SCREAMING_SNAKE_CASE_: Any  		=       model(
									    lowerCAmelCase__   ,						attention_mask=lowerCAmelCase__   ,						token_type_ids=lowerCAmelCase__   ,						start_positions=lowerCAmelCase__   ,						end_positions=lowerCAmelCase__   ,						)
									self.parent.assertEqual(result.start_logits.shape   ,						(self.batch_size, self.seq_length))
									self.parent.assertEqual(result.end_logits.shape   ,						(self.batch_size, self.seq_length))



			def        _SCREAMING_SNAKE_CASE			( self  :     Optional[Any]   ,						lowerCAmelCase__  :     Optional[int]   ,						lowerCAmelCase__  :     Union[str, Any]   ,						lowerCAmelCase__  :     Dict   ,						lowerCAmelCase__  :     Tuple   ,						lowerCAmelCase__  :     Optional[int]   ,						lowerCAmelCase__  :     Union[str, Any]   ,						lowerCAmelCase__  :     Tuple):
									SCREAMING_SNAKE_CASE_: int  		=       self.num_labels
									SCREAMING_SNAKE_CASE_: Optional[int]  		=       MegatronBertForSequenceClassification(lowerCAmelCase__)
									model.to(lowerCAmelCase__)
									model.eval()
									SCREAMING_SNAKE_CASE_: str  		=       model(lowerCAmelCase__   ,						attention_mask=lowerCAmelCase__   ,						token_type_ids=lowerCAmelCase__   ,						labels=lowerCAmelCase__)
									self.parent.assertEqual(result.logits.shape   ,						(self.batch_size, self.num_labels))



			def        _SCREAMING_SNAKE_CASE			( self  :     List[Any]   ,						lowerCAmelCase__  :     List[Any]   ,						lowerCAmelCase__  :     Any   ,						lowerCAmelCase__  :     Dict   ,						lowerCAmelCase__  :     Tuple   ,						lowerCAmelCase__  :     Any   ,						lowerCAmelCase__  :     Tuple   ,						lowerCAmelCase__  :     Optional[int]):
									SCREAMING_SNAKE_CASE_: int  		=       self.num_labels
									SCREAMING_SNAKE_CASE_: Optional[int]  		=       MegatronBertForTokenClassification(config=lowerCAmelCase__)
									model.to(lowerCAmelCase__)
									model.eval()
									SCREAMING_SNAKE_CASE_: int  		=       model(lowerCAmelCase__   ,						attention_mask=lowerCAmelCase__   ,						token_type_ids=lowerCAmelCase__   ,						labels=lowerCAmelCase__)
									self.parent.assertEqual(result.logits.shape   ,						(self.batch_size, self.seq_length, self.num_labels))



			def        _SCREAMING_SNAKE_CASE			( self  :     int   ,						lowerCAmelCase__  :     int   ,						lowerCAmelCase__  :     Optional[int]   ,						lowerCAmelCase__  :     List[Any]   ,						lowerCAmelCase__  :     List[str]   ,						lowerCAmelCase__  :     Tuple   ,						lowerCAmelCase__  :     str   ,						lowerCAmelCase__  :     List[str]):
									SCREAMING_SNAKE_CASE_: str  		=       self.num_choices
									SCREAMING_SNAKE_CASE_: Union[str, Any]  		=       MegatronBertForMultipleChoice(config=lowerCAmelCase__)
									model.to(lowerCAmelCase__)
									model.eval()
									SCREAMING_SNAKE_CASE_: Optional[Any]  		=       input_ids.unsqueeze(1).expand(-1   ,						self.num_choices   ,						-1).contiguous()
									SCREAMING_SNAKE_CASE_: List[str]  		=       token_type_ids.unsqueeze(1).expand(-1   ,						self.num_choices   ,						-1).contiguous()
									SCREAMING_SNAKE_CASE_: List[str]  		=       input_mask.unsqueeze(1).expand(-1   ,						self.num_choices   ,						-1).contiguous()
									SCREAMING_SNAKE_CASE_: List[Any]  		=       model(
									    lowerCAmelCase__   ,						attention_mask=lowerCAmelCase__   ,						token_type_ids=lowerCAmelCase__   ,						labels=lowerCAmelCase__   ,						)
									self.parent.assertEqual(result.logits.shape   ,						(self.batch_size, self.num_choices))




			def        _SCREAMING_SNAKE_CASE			( self  :     List[Any]):
									SCREAMING_SNAKE_CASE_: List[Any]  		=       self.prepare_config_and_inputs()
									(
									    (
									    SCREAMING_SNAKE_CASE_
									)		,    (
									    SCREAMING_SNAKE_CASE_
									)		,    (
									    SCREAMING_SNAKE_CASE_
									)		,    (
									    SCREAMING_SNAKE_CASE_
									)		,    (
									    SCREAMING_SNAKE_CASE_
									)		,    (
									    SCREAMING_SNAKE_CASE_
									)		,    (
									    SCREAMING_SNAKE_CASE_
									)		,    
									): int  		=       config_and_inputs
									SCREAMING_SNAKE_CASE_: Optional[int]  		=       {"input_ids": input_ids, "token_type_ids": token_type_ids, "attention_mask": input_mask}
									return config, inputs_dict







@require_torch
class   __lowercase				( UpperCAmelCase_		,       UpperCAmelCase_		,       unittest.TestCase	):




			"""simple docstring"""







			_UpperCAmelCase   :							Any										=     (
			    (
			        MegatronBertModel,
			        MegatronBertForMaskedLM,
			        MegatronBertForCausalLM,
			        MegatronBertForMultipleChoice,
			        MegatronBertForNextSentencePrediction,
			        MegatronBertForPreTraining,
			        MegatronBertForQuestionAnswering,
			        MegatronBertForSequenceClassification,
			        MegatronBertForTokenClassification,
			    )
			    if is_torch_available()
			    else ()
			)
			_UpperCAmelCase   :							Optional[int]										=     (
			    {
			        '''feature-extraction''': MegatronBertModel,
			        '''fill-mask''': MegatronBertForMaskedLM,
			        '''question-answering''': MegatronBertForQuestionAnswering,
			        '''text-classification''': MegatronBertForSequenceClassification,
			        '''text-generation''': MegatronBertForCausalLM,
			        '''token-classification''': MegatronBertForTokenClassification,
			        '''zero-shot''': MegatronBertForSequenceClassification,
			    }
			    if is_torch_available()
			    else {}
			)
			_UpperCAmelCase   :							List[Any]										=     True
			# test_resize_embeddings = False
			_UpperCAmelCase   :							str										=     False



			def        _SCREAMING_SNAKE_CASE			( self  :     Any   ,						lowerCAmelCase__  :     Union[str, Any]   ,						lowerCAmelCase__  :     Union[str, Any]   ,						lowerCAmelCase__  :     Optional[int]=False):
									SCREAMING_SNAKE_CASE_: Optional[Any]  		=       super()._prepare_for_class(lowerCAmelCase__   ,						lowerCAmelCase__   ,						return_labels=lowerCAmelCase__)

									if return_labels:
															if model_class in get_values(lowerCAmelCase__):
																					SCREAMING_SNAKE_CASE_: int  		=       torch.zeros(
																					    (self.model_tester.batch_size, self.model_tester.seq_length)   ,						dtype=torch.long   ,						device=lowerCAmelCase__)
																					SCREAMING_SNAKE_CASE_: Any  		=       torch.zeros(
																					    self.model_tester.batch_size   ,						dtype=torch.long   ,						device=lowerCAmelCase__)
									return inputs_dict



			def        _SCREAMING_SNAKE_CASE			( self  :     Optional[Any]):
									SCREAMING_SNAKE_CASE_: Tuple  		=       MegatronBertModelTester(self)
									SCREAMING_SNAKE_CASE_: Optional[Any]  		=       ConfigTester(self   ,						config_class=lowerCAmelCase__   ,						hidden_size=37)



			def        _SCREAMING_SNAKE_CASE			( self  :     Dict):
									self.config_tester.run_common_tests()



			def        _SCREAMING_SNAKE_CASE			( self  :     int):
									SCREAMING_SNAKE_CASE_: List[str]  		=       self.model_tester.prepare_config_and_inputs()
									self.model_tester.create_and_check_megatron_bert_model(*lowerCAmelCase__)



			def        _SCREAMING_SNAKE_CASE			( self  :     Any):
									SCREAMING_SNAKE_CASE_: int  		=       self.model_tester.prepare_config_and_inputs()
									self.model_tester.create_and_check_megatron_bert_for_masked_lm(*lowerCAmelCase__)



			def        _SCREAMING_SNAKE_CASE			( self  :     int):
									SCREAMING_SNAKE_CASE_: Optional[int]  		=       self.model_tester.prepare_config_and_inputs()
									self.model_tester.create_and_check_megatron_bert_for_multiple_choice(*lowerCAmelCase__)



			def        _SCREAMING_SNAKE_CASE			( self  :     List[Any]):
									SCREAMING_SNAKE_CASE_: Optional[int]  		=       self.model_tester.prepare_config_and_inputs()
									self.model_tester.create_and_check_megatron_bert_for_next_sequence_prediction(*lowerCAmelCase__)



			def        _SCREAMING_SNAKE_CASE			( self  :     List[str]):
									SCREAMING_SNAKE_CASE_: Union[str, Any]  		=       self.model_tester.prepare_config_and_inputs()
									self.model_tester.create_and_check_megatron_bert_for_pretraining(*lowerCAmelCase__)



			def        _SCREAMING_SNAKE_CASE			( self  :     Optional[Any]):
									SCREAMING_SNAKE_CASE_: Any  		=       self.model_tester.prepare_config_and_inputs()
									self.model_tester.create_and_check_megatron_bert_for_question_answering(*lowerCAmelCase__)



			def        _SCREAMING_SNAKE_CASE			( self  :     List[Any]):
									SCREAMING_SNAKE_CASE_: Any  		=       self.model_tester.prepare_config_and_inputs()
									self.model_tester.create_and_check_megatron_bert_for_sequence_classification(*lowerCAmelCase__)




			def        _SCREAMING_SNAKE_CASE			( self  :     Any):
									SCREAMING_SNAKE_CASE_: List[str]  		=       self.model_tester.prepare_config_and_inputs()
									self.model_tester.create_and_check_megatron_bert_for_token_classification(*lowerCAmelCase__)







def 			A_      (    _UpperCAmelCase    ):
						return torch.tensor(
						    _UpperCAmelCase				,	dtype=torch.long				,	device=_UpperCAmelCase				,	)


lowerCAmelCase							:  List[Any]   	=						1E-4



@require_torch
@require_sentencepiece
@require_tokenizers
class   __lowercase				( unittest.TestCase	):




			"""simple docstring"""







			@slow
			@unittest.skip("Model is not available.")
			def        _SCREAMING_SNAKE_CASE			( self  :     Any):
									SCREAMING_SNAKE_CASE_: List[str]  		=       "nvidia/megatron-bert-uncased-345m"
									if "MYDIR" in os.environ:
															SCREAMING_SNAKE_CASE_: int  		=       os.path.join(os.environ["MYDIR"]   ,						lowerCAmelCase__)
									SCREAMING_SNAKE_CASE_: int  		=       MegatronBertModel.from_pretrained(lowerCAmelCase__)
									model.to(lowerCAmelCase__)
									model.half()
									SCREAMING_SNAKE_CASE_: Any  		=       _long_tensor([[101, 7110, 1005, 1056, 2023, 1_1333, 1_7413, 1029, 102]])
									with torch.no_grad():
															SCREAMING_SNAKE_CASE_: Dict  		=       model(lowerCAmelCase__)[0]
									SCREAMING_SNAKE_CASE_: int  		=       torch.Size((1, 9, 1024))
									self.assertEqual(output.shape   ,						lowerCAmelCase__)

									SCREAMING_SNAKE_CASE_: List[str]  		=       [-0.6040, -0.2517, -0.1025, 0.3420, -0.6758, -0.0017, -0.1089, -0.1990, 0.5728]
									for ii in range(3):
															for jj in range(3):
																					SCREAMING_SNAKE_CASE_: Optional[int]  		=       output[0, ii, jj]
																					SCREAMING_SNAKE_CASE_: Any  		=       expected[3 * ii + jj]
																					SCREAMING_SNAKE_CASE_: List[str]  		=       "ii={} jj={} a={} b={}".format(lowerCAmelCase__   ,						lowerCAmelCase__   ,						lowerCAmelCase__   ,						lowerCAmelCase__)
																					self.assertTrue(math.isclose(lowerCAmelCase__   ,						lowerCAmelCase__   ,						rel_tol=lowerCAmelCase__   ,						abs_tol=lowerCAmelCase__)   ,						msg=lowerCAmelCase__)









import math
import sys







def 			A_      (    _UpperCAmelCase    ):
						if number != int(_UpperCAmelCase    ):
												raise ValueError("the value of input must be a natural number"    )
						if number < 0:
												raise ValueError("the value of input must not be a negative number"    )
						if number == 0:
												return 1
						SCREAMING_SNAKE_CASE_: List[str]  		=       [-1] * (number + 1)
						SCREAMING_SNAKE_CASE_: str  		=       0
						for i in range(1				,	number + 1    ):
												SCREAMING_SNAKE_CASE_: str  		=       sys.maxsize
												SCREAMING_SNAKE_CASE_: List[Any]  		=       int(math.sqrt(_UpperCAmelCase    )    )
												for j in range(1				,	root + 1    ):
																		SCREAMING_SNAKE_CASE_: List[str]  		=       1 + answers[i - (j**2)]
																		SCREAMING_SNAKE_CASE_: Optional[Any]  		=       min(_UpperCAmelCase				,	_UpperCAmelCase    )
												SCREAMING_SNAKE_CASE_: Dict  		=       answer
						return answers[number]


if __name__ == "__main__":
						import doctest

						doctest.testmod()






