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

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


lowerCamelCase__	    =				logging.get_logger(__name__)

lowerCamelCase__	    =				{
    'facebook/blenderbot-3B': 'https://huggingface.co/facebook/blenderbot-3B/resolve/main/config.json',
    # See all Blenderbot models at https://huggingface.co/models?filter=blenderbot
}




class 					UpperCamelCase	(     snake_case__      ):
					__UpperCamelCase						=   """blenderbot"""
					__UpperCamelCase						=   ["""past_key_values"""]
					__UpperCamelCase						=   {"""num_attention_heads""": """encoder_attention_heads""", """hidden_size""": """d_model"""}




					def __init__( self :					Optional[Any]      ,_lowerCAmelCase :					str=8_008      ,_lowerCAmelCase :					Union[str, Any]=128      ,_lowerCAmelCase :					Union[str, Any]=2      ,_lowerCAmelCase :					Optional[Any]=10_240      ,_lowerCAmelCase :					List[str]=32      ,_lowerCAmelCase :					Optional[int]=24      ,_lowerCAmelCase :					Optional[int]=10_240      ,_lowerCAmelCase :					List[str]=32      ,_lowerCAmelCase :					Any=0.0      ,_lowerCAmelCase :					Union[str, Any]=0.0      ,_lowerCAmelCase :					Optional[int]=True      ,_lowerCAmelCase :					List[str]=True      ,_lowerCAmelCase :					Optional[int]="gelu"      ,_lowerCAmelCase :					Union[str, Any]=2_560      ,_lowerCAmelCase :					Union[str, Any]=0.1      ,_lowerCAmelCase :					Tuple=0.0      ,_lowerCAmelCase :					int=0.0      ,_lowerCAmelCase :					Optional[int]=0.0_2      ,_lowerCAmelCase :					Optional[int]=1      ,_lowerCAmelCase :					str=False      ,_lowerCAmelCase :					str=0      ,_lowerCAmelCase :					str=1      ,_lowerCAmelCase :					List[Any]=2      ,_lowerCAmelCase :					str=3      ,_lowerCAmelCase :					Dict=2      ,**_lowerCAmelCase :					Any      ,):


							"""simple docstring"""




							__snake_case		       =     vocab_size
							__snake_case		       =     max_position_embeddings
							__snake_case		       =     d_model
							__snake_case		       =     encoder_ffn_dim
							__snake_case		       =     encoder_layers
							__snake_case		       =     encoder_attention_heads
							__snake_case		       =     decoder_ffn_dim
							__snake_case		       =     decoder_layers
							__snake_case		       =     decoder_attention_heads
							__snake_case		       =     dropout
							__snake_case		       =     attention_dropout
							__snake_case		       =     activation_dropout
							__snake_case		       =     activation_function
							__snake_case		       =     init_std
							__snake_case		       =     encoder_layerdrop
							__snake_case		       =     decoder_layerdrop
							__snake_case		       =     use_cache
							__snake_case		       =     encoder_layers
							__snake_case		       =     scale_embedding  # scale factor will be sqrt(d_model) if True

							super().__init__(
							    pad_token_id=_lowerCAmelCase      ,bos_token_id=_lowerCAmelCase      ,eos_token_id=_lowerCAmelCase      ,is_encoder_decoder=_lowerCAmelCase      ,decoder_start_token_id=_lowerCAmelCase      ,encoder_no_repeat_ngram_size=_lowerCAmelCase      ,forced_eos_token_id=_lowerCAmelCase      ,**_lowerCAmelCase      ,)




class 					UpperCamelCase	(     snake_case__      ):




					@property
					def 							UpperCamelCase_						( self :					str						):


							"""simple docstring"""




							if self.task in ["default", "seq2seq-lm"]:
									__snake_case		       =     OrderedDict(
									    [
									        ("input_ids", {0: "batch", 1: "encoder_sequence"}),
									        ("attention_mask", {0: "batch", 1: "encoder_sequence"}),
									    ]						)
									if self.use_past:
											__snake_case		       =     {0: "batch"}
											__snake_case		       =     {0: "batch", 1: "past_decoder_sequence + sequence"}
									else:
											__snake_case		       =     {0: "batch", 1: "decoder_sequence"}
											__snake_case		       =     {0: "batch", 1: "decoder_sequence"}
									if self.use_past:
											self.fill_with_past_key_values_(_lowerCAmelCase      ,direction="inputs"						)
							elif self.task == "causal-lm":
									__snake_case		       =     OrderedDict(
									    [
									        ("input_ids", {0: "batch", 1: "encoder_sequence"}),
									        ("attention_mask", {0: "batch", 1: "encoder_sequence"}),
									    ]						)
									if self.use_past:
											__snake_case       ,       __snake_case		       =     self.num_layers
											for i in range(_lowerCAmelCase						):
													__snake_case		       =     {0: "batch", 2: "past_sequence + sequence"}
													__snake_case		       =     {0: "batch", 2: "past_sequence + sequence"}
							else:
									__snake_case		       =     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
					# Copied from transformers.models.bart.configuration_bart.BartOnnxConfig.outputs
					def 							UpperCamelCase_						( self :					int						):


							"""simple docstring"""




							if self.task in ["default", "seq2seq-lm"]:
									__snake_case		       =     super().outputs
							else:
									__snake_case		       =     super(_lowerCAmelCase      ,self						).outputs
									if self.use_past:
											__snake_case       ,       __snake_case		       =     self.num_layers
											for i in range(_lowerCAmelCase						):
													__snake_case		       =     {0: "batch", 2: "past_sequence + sequence"}
													__snake_case		       =     {0: "batch", 2: "past_sequence + sequence"}
							return common_outputs




					def 							UpperCamelCase_						( self :					Optional[int]      ,_lowerCAmelCase :					PreTrainedTokenizer      ,_lowerCAmelCase :					int = -1      ,_lowerCAmelCase :					int = -1      ,_lowerCAmelCase :					bool = False      ,_lowerCAmelCase :					Optional[TensorType] = None      ,):


							"""simple docstring"""




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

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

									for _ in range(_lowerCAmelCase						):
											common_inputs["past_key_values"].append(
											    (
											        torch.zeros(_lowerCAmelCase						),
											        torch.zeros(_lowerCAmelCase						),
											        torch.zeros(_lowerCAmelCase						),
											        torch.zeros(_lowerCAmelCase						),
											    )						)
							return common_inputs




					def 							UpperCamelCase_						( self :					Dict      ,_lowerCAmelCase :					PreTrainedTokenizer      ,_lowerCAmelCase :					int = -1      ,_lowerCAmelCase :					int = -1      ,_lowerCAmelCase :					bool = False      ,_lowerCAmelCase :					Optional[TensorType] = None      ,):


							"""simple docstring"""




							__snake_case		       =     self._generate_dummy_inputs_for_sequence_classification_and_question_answering(
							    _lowerCAmelCase      ,_lowerCAmelCase      ,_lowerCAmelCase      ,_lowerCAmelCase      ,_lowerCAmelCase						)

							if self.use_past:
									if not is_torch_available():
											raise ValueError("Cannot generate dummy past_keys inputs without PyTorch installed."						)
									else:
											import torch
									__snake_case       ,       __snake_case		       =     common_inputs["input_ids"].shape
									__snake_case		       =     seqlen
									__snake_case       ,       __snake_case		       =     self.num_layers
									__snake_case       ,       __snake_case		       =     self.num_attention_heads
									__snake_case		       =     (
									    batch,
									    num_encoder_attention_heads,
									    past_key_values_length,
									    self._config.hidden_size // num_encoder_attention_heads,
									)
									__snake_case		       =     common_inputs["attention_mask"].dtype
									__snake_case		       =     torch.cat(
									    [common_inputs["attention_mask"], torch.ones(_lowerCAmelCase      ,_lowerCAmelCase      ,dtype=_lowerCAmelCase						)]      ,dim=1						)
									__snake_case		       =     [
									    (torch.zeros(_lowerCAmelCase						), torch.zeros(_lowerCAmelCase						)) for _ in range(_lowerCAmelCase						)
									]
							return common_inputs




					def 							UpperCamelCase_						( self :					int      ,_lowerCAmelCase :					PreTrainedTokenizer      ,_lowerCAmelCase :					int = -1      ,_lowerCAmelCase :					int = -1      ,_lowerCAmelCase :					bool = False      ,_lowerCAmelCase :					Optional[TensorType] = None      ,):


							"""simple docstring"""




							__snake_case		       =     compute_effective_axis_dimension(
							    _lowerCAmelCase      ,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
							__snake_case		       =     tokenizer.num_special_tokens_to_add(_lowerCAmelCase						)
							__snake_case		       =     compute_effective_axis_dimension(
							    _lowerCAmelCase      ,fixed_dimension=OnnxConfig.default_fixed_sequence      ,num_token_to_add=_lowerCAmelCase						)

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




					def 							UpperCamelCase_						( self :					int      ,_lowerCAmelCase :					PreTrainedTokenizer      ,_lowerCAmelCase :					int = -1      ,_lowerCAmelCase :					int = -1      ,_lowerCAmelCase :					bool = False      ,_lowerCAmelCase :					Optional[TensorType] = None      ,):


							"""simple docstring"""




							if self.task in ["default", "seq2seq-lm"]:
									__snake_case		       =     self._generate_dummy_inputs_for_default_and_seqaseq_lm(
									    _lowerCAmelCase      ,batch_size=_lowerCAmelCase      ,seq_length=_lowerCAmelCase      ,is_pair=_lowerCAmelCase      ,framework=_lowerCAmelCase						)

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

							return common_inputs




					def 							UpperCamelCase_						( self :					List[str]      ,_lowerCAmelCase :					Dict      ,_lowerCAmelCase :					List[Any]      ,_lowerCAmelCase :					Any      ,_lowerCAmelCase :					Any						):


							"""simple docstring"""




							if self.task in ["default", "seq2seq-lm"]:
									__snake_case		       =     super()._flatten_past_key_values_(_lowerCAmelCase      ,_lowerCAmelCase      ,_lowerCAmelCase      ,_lowerCAmelCase						)
							else:
									__snake_case		       =     super(_lowerCAmelCase      ,self						)._flatten_past_key_values_(
									    _lowerCAmelCase      ,_lowerCAmelCase      ,_lowerCAmelCase      ,_lowerCAmelCase						)







					def 							UpperCamelCase_						( self :					Optional[Any]      ,_lowerCAmelCase :					Mapping[str, Mapping[int, str]]      ,_lowerCAmelCase :					str						):


							"""simple docstring"""




							if direction not in ["inputs", "outputs"]:
									raise ValueError(F"""direction must either be \"inputs\" or \"outputs\", but {direction} was given"""						)

							__snake_case		       =     "past_key_values" if direction == "inputs" else "present"
							__snake_case       ,       __snake_case		       =     self.num_layers

							__snake_case		       =     "past_encoder_sequence"
							__snake_case		       =     "past_decoder_sequence" if direction == "inputs" else "past_decoder_sequence + sequence"

							for i in range(_lowerCAmelCase						):
									__snake_case		       =     {0: "batch", 2: decoder_sequence}
									__snake_case		       =     {0: "batch", 2: decoder_sequence}
									__snake_case		       =     {0: "batch", 2: encoder_sequence}
									__snake_case		       =     {0: "batch", 2: encoder_sequence}






from __future__ import annotations

from collections.abc import Iterable
from dataclasses import dataclass
from typing import Any




class 					UpperCamelCase	:
					__UpperCamelCase						=   ("""_front""", """_back""", """_len""")




					@dataclass
					class 					UpperCamelCase	:
										__UpperCamelCase						=   None
										__UpperCamelCase						=   None
										__UpperCamelCase						=   None




					class 					UpperCamelCase	:
										__UpperCamelCase						=   ("""_cur""",)




										def __init__( self :					Dict      ,_lowerCAmelCase :					Deque._Node | None						):


												"""simple docstring"""




												__snake_case		       =     cur




										def __iter__( self :					Dict						):


												"""simple docstring"""




												return self







										def 							UpperCamelCase_						( self :					Optional[Any]						):


												"""simple docstring"""




												if self._cur is None:
														# finished iterating
														raise StopIteration
												__snake_case		       =     self._cur.val
												__snake_case		       =     self._cur.next_node

												return val




					def __init__( self :					Optional[int]      ,_lowerCAmelCase :					Iterable[Any] | None = None						):


							"""simple docstring"""




							__snake_case		       =     None
							__snake_case		       =     None
							__snake_case		       =     0

							if iterable is not None:
									# append every value to the deque
									for val in iterable:
											self.append(_lowerCAmelCase						)




					def 							UpperCamelCase_						( self :					int      ,_lowerCAmelCase :					Any						):


							"""simple docstring"""




							__snake_case		       =     self._Node(_lowerCAmelCase      ,_lowerCAmelCase      ,_lowerCAmelCase						)
							if self.is_empty():
									# front = back
									__snake_case		       =     __snake_case		       =     node
									__snake_case		       =     1
							else:
									# connect nodes
									__snake_case		       =     node
									__snake_case		       =     self._back
									__snake_case		       =     node  # assign new back to the new node

									self._len += 1

									# make sure there were no errors
									assert not self.is_empty(), "Error on appending value."




					def 							UpperCamelCase_						( self :					Any      ,_lowerCAmelCase :					Any						):


							"""simple docstring"""




							__snake_case		       =     self._Node(_lowerCAmelCase      ,_lowerCAmelCase      ,_lowerCAmelCase						)
							if self.is_empty():
									# front = back
									__snake_case		       =     __snake_case		       =     node
									__snake_case		       =     1
							else:
									# connect nodes
									__snake_case		       =     self._front
									__snake_case		       =     node
									__snake_case		       =     node  # assign new front to the new node

									self._len += 1

									# make sure there were no errors
									assert not self.is_empty(), "Error on appending value."




					def 							UpperCamelCase_						( self :					int      ,_lowerCAmelCase :					Iterable[Any]						):


							"""simple docstring"""




							for val in iterable:
									self.append(_lowerCAmelCase						)




					def 							UpperCamelCase_						( self :					Optional[int]      ,_lowerCAmelCase :					Iterable[Any]						):


							"""simple docstring"""




							for val in iterable:
									self.appendleft(_lowerCAmelCase						)




					def 							UpperCamelCase_						( self :					List[Any]						):


							"""simple docstring"""




							assert not self.is_empty(), "Deque is empty."

							__snake_case		       =     self._back
							__snake_case		       =     self._back.prev_node  # set new back
							# drop the last node - python will deallocate memory automatically
							__snake_case		       =     None

							self._len -= 1

							return topop.val




					def 							UpperCamelCase_						( self :					List[str]						):


							"""simple docstring"""




							assert not self.is_empty(), "Deque is empty."

							__snake_case		       =     self._front
							__snake_case		       =     self._front.next_node  # set new front and drop the first node
							__snake_case		       =     None

							self._len -= 1

							return topop.val




					def 							UpperCamelCase_						( self :					int						):


							"""simple docstring"""




							return self._front is None




					def __len__( self :					Tuple						):


							"""simple docstring"""




							return self._len




					def __eq__( self :					Union[str, Any]      ,_lowerCAmelCase :					object						):


							"""simple docstring"""




							if not isinstance(_lowerCAmelCase      ,_lowerCAmelCase						):
									return NotImplemented

							__snake_case		       =     self._front
							__snake_case		       =     other._front

							# if the length of the dequeues are not the same, they are not equal
							if len(self						) != len(_lowerCAmelCase						):
									return False

							while me is not None and oth is not None:
									# compare every value
									if me.val != oth.val:
											return False
									__snake_case		       =     me.next_node
									__snake_case		       =     oth.next_node

							return True




					def __iter__( self :					Tuple						):


							"""simple docstring"""




							return Deque._Iterator(self._front						)







					def __repr__( self :					List[Any]						):


							"""simple docstring"""




							__snake_case		       =     []
							__snake_case		       =     self._front
							while aux is not None:
									# append the values in a list to display
									values_list.append(aux.val						)
									__snake_case		       =     aux.next_node

							return F"""[{", ".join(repr(_lowerCAmelCase						) for val in values_list						)}]"""


if __name__ == "__main__":
		import doctest

		doctest.testmod()





