




import warnings
from collections import OrderedDict
from typing import Any, Mapping, Optional

from ... import PreTrainedTokenizer
from ...configuration_utils import PretrainedConfig
from ...onnx import OnnxConfig, OnnxConfigWithPast, OnnxSeqaSeqConfigWithPast
from ...onnx.utils import compute_effective_axis_dimension
from ...utils import TensorType, is_torch_available, logging


lowercase_	       =			logging.get_logger(__name__)

lowercase_	       =			{
    '''facebook/bart-large''': '''https://huggingface.co/facebook/bart-large/resolve/main/config.json''',
    # See all BART models at https://huggingface.co/models?filter=bart
}






class 						__a (     __a				):
	SCREAMING_SNAKE_CASE       =       '''bart'''
	SCREAMING_SNAKE_CASE       =       ['''past_key_values''']
	SCREAMING_SNAKE_CASE       =       {'''num_attention_heads''': '''encoder_attention_heads''', '''hidden_size''': '''d_model'''}



	def __init__(						self							:    List[Any]				,	snake_case_							:    Union[str, Any]=5_02_65				,	snake_case_							:    int=10_24				,	snake_case_							:    Optional[Any]=12				,	snake_case_							:    Dict=40_96				,	snake_case_							:    Dict=16				,	snake_case_							:    int=12				,	snake_case_							:    Optional[Any]=40_96				,	snake_case_							:    Optional[Any]=16				,	snake_case_							:    Tuple=0.0				,	snake_case_							:    Dict=0.0				,	snake_case_							:    Optional[Any]="gelu"				,	snake_case_							:    Dict=10_24				,	snake_case_							:    Any=0.1				,	snake_case_							:    List[Any]=0.0				,	snake_case_							:    str=0.0				,	snake_case_							:    Optional[int]=0.0_2				,	snake_case_							:    Optional[int]=0.0				,	snake_case_							:    List[str]=False				,	snake_case_							:    Tuple=True				,	snake_case_							:    List[Any]=3				,	snake_case_							:    str=1				,	snake_case_							:    Tuple=0				,	snake_case_							:    Union[str, Any]=2				,	snake_case_							:    Optional[int]=True				,	snake_case_							:    Optional[Any]=2				,	snake_case_							:    List[str]=2				,	**snake_case_							:    Tuple				,	)->							List[Any]:
						__lowerCAmelCase	   =vocab_size
						__lowerCAmelCase	   =max_position_embeddings
						__lowerCAmelCase	   =d_model
						__lowerCAmelCase	   =encoder_ffn_dim
						__lowerCAmelCase	   =encoder_layers
						__lowerCAmelCase	   =encoder_attention_heads
						__lowerCAmelCase	   =decoder_ffn_dim
						__lowerCAmelCase	   =decoder_layers
						__lowerCAmelCase	   =decoder_attention_heads
						__lowerCAmelCase	   =dropout
						__lowerCAmelCase	   =attention_dropout
						__lowerCAmelCase	   =activation_dropout
						__lowerCAmelCase	   =activation_function
						__lowerCAmelCase	   =init_std
						__lowerCAmelCase	   =encoder_layerdrop
						__lowerCAmelCase	   =decoder_layerdrop
						__lowerCAmelCase	   =classifier_dropout
						__lowerCAmelCase	   =use_cache
						__lowerCAmelCase	   =encoder_layers
						__lowerCAmelCase	   =scale_embedding  # scale factor will be sqrt(d_model) if True

						super().__init__(
						    num_labels=snake_case__				,	pad_token_id=snake_case__				,	bos_token_id=snake_case__				,	eos_token_id=snake_case__				,	is_encoder_decoder=snake_case__				,	decoder_start_token_id=snake_case__				,	forced_eos_token_id=snake_case__				,	**snake_case__				,	)

						# ensure backward compatibility for BART CNN models
						if self.forced_bos_token_id is None and kwargs.get("""force_bos_token_to_be_generated"""				,	snake_case__):
											__lowerCAmelCase	   =self.bos_token_id
											warnings.warn(
											    F"""Please make sure the config includes `forced_bos_token_id={self.bos_token_id}` in future versions. """
											    """The config can simply be saved and uploaded again to be fixed.""")






class 						__a (     __a				):



	@property
	def 		UpperCamelCase							(						self							:    List[str])->							Optional[Any]:
						if self.task in ["default", "seq2seq-lm"]:
											__lowerCAmelCase	   =OrderedDict(
											    [
											        ("""input_ids""", {0: """batch""", 1: """encoder_sequence"""}),
											        ("""attention_mask""", {0: """batch""", 1: """encoder_sequence"""}),
											    ])

											if self.use_past:
																__lowerCAmelCase	   ={0: """batch"""}
																__lowerCAmelCase	   ={0: """batch""", 1: """past_decoder_sequence + sequence"""}
											else:
																__lowerCAmelCase	   ={0: """batch""", 1: """decoder_sequence"""}
																__lowerCAmelCase	   ={0: """batch""", 1: """decoder_sequence"""}

											if self.use_past:
																self.fill_with_past_key_values_(snake_case__				,	direction="""inputs""")
						elif self.task == "causal-lm":
											# TODO: figure this case out.
											__lowerCAmelCase	   =OrderedDict(
											    [
											        ("""input_ids""", {0: """batch""", 1: """encoder_sequence"""}),
											        ("""attention_mask""", {0: """batch""", 1: """encoder_sequence"""}),
											    ])
											if self.use_past:
																__lowerCAmelCase   ,	__lowerCAmelCase	   =self.num_layers
																for i in range(snake_case__):
																					__lowerCAmelCase	   ={0: """batch""", 2: """past_sequence + sequence"""}
																					__lowerCAmelCase	   ={0: """batch""", 2: """past_sequence + sequence"""}
						else:
											__lowerCAmelCase	   =OrderedDict(
											    [
											        ("""input_ids""", {0: """batch""", 1: """encoder_sequence"""}),
											        ("""attention_mask""", {0: """batch""", 1: """encoder_sequence"""}),
											        ("""decoder_input_ids""", {0: """batch""", 1: """decoder_sequence"""}),
											        ("""decoder_attention_mask""", {0: """batch""", 1: """decoder_sequence"""}),
											    ])

						return common_inputs



	@property
	def 		UpperCamelCase							(						self							:    int)->							str:
						if self.task in ["default", "seq2seq-lm"]:
											__lowerCAmelCase	   =super().outputs
						else:
											__lowerCAmelCase	   =super(snake_case__				,	self).outputs
											if self.use_past:
																__lowerCAmelCase   ,	__lowerCAmelCase	   =self.num_layers
																for i in range(snake_case__):
																					__lowerCAmelCase	   ={0: """batch""", 2: """past_sequence + sequence"""}
																					__lowerCAmelCase	   ={0: """batch""", 2: """past_sequence + sequence"""}
						return common_outputs



	def 		UpperCamelCase							(						self							:    Optional[int]				,	snake_case_							:    PreTrainedTokenizer				,	snake_case_							:    int = -1				,	snake_case_							:    int = -1				,	snake_case_							:    bool = False				,	snake_case_							:    Optional[TensorType] = None				,	)->							Dict:
						__lowerCAmelCase	   =self._generate_dummy_inputs_for_sequence_classification_and_question_answering(
						    snake_case__				,	snake_case__				,	snake_case__				,	snake_case__				,	snake_case__)

						# Generate decoder inputs
						__lowerCAmelCase	   =seq_length if not self.use_past else 1
						__lowerCAmelCase	   =self._generate_dummy_inputs_for_sequence_classification_and_question_answering(
						    snake_case__				,	snake_case__				,	snake_case__				,	snake_case__				,	snake_case__)
						__lowerCAmelCase	   ={F"""decoder_{name}""": tensor for name, tensor in decoder_inputs.items()}
						__lowerCAmelCase	   =dict(**snake_case__				,	**snake_case__)

						if self.use_past:
											if not is_torch_available():
																raise ValueError("""Cannot generate dummy past_keys inputs without PyTorch installed.""")
											else:
																import torch
											__lowerCAmelCase   ,	__lowerCAmelCase	   =common_inputs["""input_ids"""].shape
											__lowerCAmelCase	   =common_inputs["""decoder_input_ids"""].shape[1]
											__lowerCAmelCase   ,	__lowerCAmelCase	   =self.num_attention_heads
											__lowerCAmelCase	   =(
											    batch,
											    num_encoder_attention_heads,
											    encoder_seq_length,
											    self._config.hidden_size // num_encoder_attention_heads,
											)
											__lowerCAmelCase	   =decoder_seq_length + 3
											__lowerCAmelCase	   =(
											    batch,
											    num_decoder_attention_heads,
											    decoder_past_length,
											    self._config.hidden_size // num_decoder_attention_heads,
											)

											__lowerCAmelCase	   =torch.cat(
											    [common_inputs["""decoder_attention_mask"""], torch.ones(snake_case__				,	snake_case__)]				,	dim=1)

											__lowerCAmelCase	   =[]
											# If the number of encoder and decoder layers are present in the model configuration, both are considered
											__lowerCAmelCase   ,	__lowerCAmelCase	   =self.num_layers
											__lowerCAmelCase	   =min(snake_case__				,	snake_case__)
											__lowerCAmelCase	   =max(snake_case__				,	snake_case__) - min_num_layers
											__lowerCAmelCase	   ="""encoder""" if num_encoder_layers > num_decoder_layers else """decoder"""

											for _ in range(snake_case__):
																common_inputs["past_key_values"].append(
																    (
																        torch.zeros(snake_case__),
																        torch.zeros(snake_case__),
																        torch.zeros(snake_case__),
																        torch.zeros(snake_case__),
																    ))
											# TODO: test this.
											__lowerCAmelCase	   =encoder_shape if remaining_side_name == """encoder""" else decoder_shape
											for _ in range(snake_case__				,	snake_case__):
																common_inputs["past_key_values"].append((torch.zeros(snake_case__), torch.zeros(snake_case__)))
						return common_inputs



	def 		UpperCamelCase							(						self							:    Optional[Any]				,	snake_case_							:    PreTrainedTokenizer				,	snake_case_							:    int = -1				,	snake_case_							:    int = -1				,	snake_case_							:    bool = False				,	snake_case_							:    Optional[TensorType] = None				,	)->							Union[str, Any]:
						__lowerCAmelCase	   =self._generate_dummy_inputs_for_sequence_classification_and_question_answering(
						    snake_case__				,	snake_case__				,	snake_case__				,	snake_case__				,	snake_case__)

						if self.use_past:
											if not is_torch_available():
																raise ValueError("""Cannot generate dummy past_keys inputs without PyTorch installed.""")
											else:
																import torch
											__lowerCAmelCase   ,	__lowerCAmelCase	   =common_inputs["""input_ids"""].shape
											# Not using the same length for past_key_values
											__lowerCAmelCase	   =seqlen + 2
											__lowerCAmelCase   ,	__lowerCAmelCase	   =self.num_layers
											__lowerCAmelCase   ,	__lowerCAmelCase	   =self.num_attention_heads
											__lowerCAmelCase	   =(
											    batch,
											    num_encoder_attention_heads,
											    past_key_values_length,
											    self._config.hidden_size // num_encoder_attention_heads,
											)

											__lowerCAmelCase	   =common_inputs["""attention_mask"""].dtype
											__lowerCAmelCase	   =torch.cat(
											    [common_inputs["""attention_mask"""], torch.ones(snake_case__				,	snake_case__				,	dtype=snake_case__)]				,	dim=1)
											__lowerCAmelCase	   =[
											    (torch.zeros(snake_case__), torch.zeros(snake_case__)) for _ in range(snake_case__)
											]
						return common_inputs



	def 		UpperCamelCase							(						self							:    Optional[Any]				,	snake_case_							:    PreTrainedTokenizer				,	snake_case_							:    int = -1				,	snake_case_							:    int = -1				,	snake_case_							:    bool = False				,	snake_case_							:    Optional[TensorType] = None				,	)->							str:
						# Copied from OnnxConfig.generate_dummy_inputs
						# Did not use super(OnnxConfigWithPast, self).generate_dummy_inputs for code clarity.
						# If dynamic axis (-1) we forward with a fixed dimension of 2 samples to avoid optimizations made by ONNX
						__lowerCAmelCase	   =compute_effective_axis_dimension(
						    snake_case__				,	fixed_dimension=OnnxConfig.default_fixed_batch				,	num_token_to_add=0)

						# If dynamic axis (-1) we forward with a fixed dimension of 8 tokens to avoid optimizations made by ONNX
						__lowerCAmelCase	   =tokenizer.num_special_tokens_to_add(snake_case__)
						__lowerCAmelCase	   =compute_effective_axis_dimension(
						    snake_case__				,	fixed_dimension=OnnxConfig.default_fixed_sequence				,	num_token_to_add=snake_case__)

						# Generate dummy inputs according to compute batch and sequence
						__lowerCAmelCase	   =[""" """.join([tokenizer.unk_token]) * seq_length] * batch_size
						__lowerCAmelCase	   =dict(tokenizer(snake_case__				,	return_tensors=snake_case__))
						return common_inputs



	def 		UpperCamelCase							(						self							:    Union[str, Any]				,	snake_case_							:    PreTrainedTokenizer				,	snake_case_							:    int = -1				,	snake_case_							:    int = -1				,	snake_case_							:    bool = False				,	snake_case_							:    Optional[TensorType] = None				,	)->							Union[str, Any]:
						if self.task in ["default", "seq2seq-lm"]:
											__lowerCAmelCase	   =self._generate_dummy_inputs_for_default_and_seqaseq_lm(
											    snake_case__				,	batch_size=snake_case__				,	seq_length=snake_case__				,	is_pair=snake_case__				,	framework=snake_case__)

						elif self.task == "causal-lm":
											__lowerCAmelCase	   =self._generate_dummy_inputs_for_causal_lm(
											    snake_case__				,	batch_size=snake_case__				,	seq_length=snake_case__				,	is_pair=snake_case__				,	framework=snake_case__)
						else:
											__lowerCAmelCase	   =self._generate_dummy_inputs_for_sequence_classification_and_question_answering(
											    snake_case__				,	batch_size=snake_case__				,	seq_length=snake_case__				,	is_pair=snake_case__				,	framework=snake_case__)

						return common_inputs



	def 		UpperCamelCase							(						self							:    Tuple				,	snake_case_							:    Union[str, Any]				,	snake_case_							:    List[str]				,	snake_case_							:    Union[str, Any]				,	snake_case_							:    int)->							str:
						if self.task in ["default", "seq2seq-lm"]:
											__lowerCAmelCase	   =super()._flatten_past_key_values_(snake_case__				,	snake_case__				,	snake_case__				,	snake_case__)
						else:
											__lowerCAmelCase	   =super(snake_case__				,	self)._flatten_past_key_values_(
											    snake_case__				,	snake_case__				,	snake_case__				,	snake_case__)









def 					__lowerCAmelCase		(  __lowerCamelCase	:    list				,   __lowerCamelCase	:    int				,   __lowerCamelCase	:    int = 0				,   __lowerCamelCase	:    int = 0	)  ->						int:
					__lowerCAmelCase	   =right or len(__lowerCamelCase	) - 1
					if left > right:
										return -1
					elif list_data[left] == key:
										return left
					elif list_data[right] == key:
										return right
					else:
										return search(__lowerCamelCase				,   __lowerCamelCase				,   left + 1				,   right - 1	)


if __name__ == "__main__":
				import doctest

				doctest.testmod()




