

import collections
import types

import numpy as np

from ..utils import (
    add_end_docstrings,
    is_tensorflow_probability_available,
    is_tf_available,
    is_torch_available,
    requires_backends,
)
from .base import PIPELINE_INIT_ARGS, ArgumentHandler, Dataset, Pipeline, PipelineException


if is_torch_available():
  import torch

  from ..models.auto.modeling_auto import (
      MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING,
      MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING,
  )

if is_tf_available() and is_tensorflow_probability_available():
  import tensorflow as tf
  import tensorflow_probability as tfp

  from ..models.auto.modeling_tf_auto import (
      TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING,
      TF_MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING,
  )






class 							A_				(	snake_case__      ):


     def __call__(							self    :	Optional[int]    ,						UpperCAmelCase    :	str=None    ,						UpperCAmelCase    :	Optional[Any]=None    ,						**UpperCAmelCase    :	List[Any]      )							->			List[Any]:
      # Returns tqa_pipeline_inputs of shape:
      # [
      #   {"table": pd.DataFrame, "query": List[str]},
      #   ...,
      #   {"table": pd.DataFrame, "query" : List[str]}
      # ]
      requires_backends(self    ,						'pandas'      )
      import pandas as pd

      if table is None:
       raise ValueError('Keyword argument `table` cannot be None.'      )
      elif query is None:
       if isinstance(UpperCAmelCase    ,						UpperCAmelCase      ) and table.get('query'      ) is not None and table.get('table'      ) is not None:
        __lowerCAmelCase:     Tuple     			=   [table]
       elif isinstance(UpperCAmelCase    ,						UpperCAmelCase      ) and len(UpperCAmelCase      ) > 0:
        if not all(isinstance(UpperCAmelCase    ,						UpperCAmelCase      ) for d in table      ):
         raise ValueError(
             F'''Keyword argument `table` should be a list of dict, but is {(type(UpperCAmelCase      ) for d in table)}'''      )

        if table[0].get('query'      ) is not None and table[0].get('table'      ) is not None:
         __lowerCAmelCase:     str     			=   table
        else:
         raise ValueError(
             'If keyword argument `table` is a list of dictionaries, each dictionary should have a `table`'
             F''' and `query` key, but only dictionary has keys {table[0].keys()} `table` and `query` keys.'''      )
       elif Dataset is not None and isinstance(UpperCAmelCase    ,						UpperCAmelCase      ) or isinstance(UpperCAmelCase    ,						types.GeneratorType      ):
        return table
       else:
        raise ValueError(
            'Invalid input. Keyword argument `table` should be either of type `dict` or `list`, but '
            F'''is {type(UpperCAmelCase      )})'''      )
      else:
       __lowerCAmelCase:     List[Any]     			=   [{'table': table, 'query': query}]

      for tqa_pipeline_input in tqa_pipeline_inputs:
       if not isinstance(tqa_pipeline_input['table']    ,						pd.DataFrame      ):
        if tqa_pipeline_input["table"] is None:
         raise ValueError('Table cannot be None.'      )

        __lowerCAmelCase:     Dict     			=   pd.DataFrame(tqa_pipeline_input['table']      )

      return tqa_pipeline_inputs







@add_end_docstrings(snake_case__      )
class 							A_				(	snake_case__      ):
     _lowercase    :  str          =			'table,query'


     def __init__(							self    :	List[Any]    ,						UpperCAmelCase    :	Optional[Any]=TableQuestionAnsweringArgumentHandler()    ,						*UpperCAmelCase    :	Optional[int]    ,						**UpperCAmelCase    :	List[str]      )							->			Dict:
      super().__init__(*UpperCAmelCase    ,						**UpperCAmelCase      )
      __lowerCAmelCase:     Tuple     			=   args_parser

      self.check_model_type(
          dict(
              TF_MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING.items()
              + TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING.items()      )
          if self.framework == 'tf'
          else dict(
              MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING.items() + MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING.items()      )      )

      __lowerCAmelCase:     Union[str, Any]     			=   bool(getattr(self.model.config    ,						'aggregation_labels'    ,						UpperCAmelCase      )      ) and bool(
          getattr(self.model.config    ,						'num_aggregation_labels'    ,						UpperCAmelCase      )      )
      __lowerCAmelCase:     Optional[int]     			=   'tapas' if hasattr(self.model.config    ,						'aggregation_labels'      ) else None


     def 						UpperCAmelCase						(							self    :	Union[str, Any]    ,						**UpperCAmelCase    :	Optional[int]      )							->			int:
      return self.model(**UpperCAmelCase      )


     def 						UpperCAmelCase						(							self    :	Optional[int]    ,						**UpperCAmelCase    :	List[str]      )							->			Optional[int]:
      if self.framework == "pt":
       __lowerCAmelCase:     Tuple     			=   []
       __lowerCAmelCase:     Union[str, Any]     			=   []
       __lowerCAmelCase:     Dict     			=   None
       __lowerCAmelCase:     Union[str, Any]     			=   inputs['input_ids'].shape[0]

       __lowerCAmelCase:     Union[str, Any]     			=   inputs['input_ids'].to(self.device      )
       __lowerCAmelCase:     Union[str, Any]     			=   inputs['attention_mask'].to(self.device      )
       __lowerCAmelCase:     Dict     			=   inputs['token_type_ids'].to(self.device      )
       __lowerCAmelCase:     Tuple     			=   None

       for index in range(UpperCAmelCase      ):
        # If sequences have already been processed, the token type IDs will be created according to the previous
        # answer.
        if prev_answers is not None:
         __lowerCAmelCase:     List[str]     			=   token_type_ids_example[:, 3]  # shape (seq_len,)
         __lowerCAmelCase:     List[Any]     			=   np.zeros_like(prev_labels_example.cpu().numpy()      )  # shape (seq_len,)

         __lowerCAmelCase:     Tuple     			=   token_type_ids[index]  # shape (seq_len, 7)
         for i in range(model_labels.shape[0]      ):
          __lowerCAmelCase:     str     			=   token_type_ids_example[:, 0].tolist()[i]
          __lowerCAmelCase:     List[str]     			=   token_type_ids_example[:, 1].tolist()[i] - 1
          __lowerCAmelCase:     List[str]     			=   token_type_ids_example[:, 2].tolist()[i] - 1

          if row_id >= 0 and col_id >= 0 and segment_id == 1:
           __lowerCAmelCase:     Union[str, Any]     			=   int(prev_answers[(col_id, row_id)]      )

         __lowerCAmelCase:     Optional[Any]     			=   torch.from_numpy(UpperCAmelCase      ).type(torch.long      ).to(self.device      )

        __lowerCAmelCase:     Dict     			=   input_ids[index]
        __lowerCAmelCase:     Optional[Any]     			=   attention_mask[index]  # shape (seq_len,)
        __lowerCAmelCase:     Any     			=   token_type_ids[index]  # shape (seq_len, 7)
        __lowerCAmelCase:     Dict     			=   self.model(
            input_ids=input_ids_example.unsqueeze(0      )    ,						attention_mask=attention_mask_example.unsqueeze(0      )    ,						token_type_ids=token_type_ids_example.unsqueeze(0      )    ,						)
        __lowerCAmelCase:     Union[str, Any]     			=   outputs.logits

        if self.aggregate:
         all_aggregations.append(outputs.logits_aggregation      )

        all_logits.append(UpperCAmelCase      )

        __lowerCAmelCase:     Union[str, Any]     			=   torch.distributions.Bernoulli(logits=UpperCAmelCase      )
        __lowerCAmelCase:     Union[str, Any]     			=   dist_per_token.probs * attention_mask_example.type(torch.floataa      ).to(
            dist_per_token.probs.device      )

        __lowerCAmelCase:     Optional[Any]     			=   collections.defaultdict(UpperCAmelCase      )
        for i, p in enumerate(probabilities.squeeze().tolist()      ):
         __lowerCAmelCase:     str     			=   token_type_ids_example[:, 0].tolist()[i]
         __lowerCAmelCase:     Any     			=   token_type_ids_example[:, 1].tolist()[i] - 1
         __lowerCAmelCase:     Dict     			=   token_type_ids_example[:, 2].tolist()[i] - 1
         if col >= 0 and row >= 0 and segment_id == 1:
          coords_to_probs[(col, row)].append(UpperCAmelCase      )

        __lowerCAmelCase:     List[str]     			=   {key: np.array(coords_to_probs[key]      ).mean() > 0.5 for key in coords_to_probs}

       __lowerCAmelCase:     int     			=   torch.cat(tuple(UpperCAmelCase      )    ,						0      )

       return (logits_batch,) if not self.aggregate else (logits_batch, torch.cat(tuple(UpperCAmelCase      )    ,						0      ))
      else:
       __lowerCAmelCase:     Any     			=   []
       __lowerCAmelCase:     Optional[int]     			=   []
       __lowerCAmelCase:     Dict     			=   None
       __lowerCAmelCase:     List[str]     			=   inputs['input_ids'].shape[0]

       __lowerCAmelCase:     Tuple     			=   inputs['input_ids']
       __lowerCAmelCase:     str     			=   inputs['attention_mask']
       __lowerCAmelCase:     Optional[int]     			=   inputs['token_type_ids'].numpy()
       __lowerCAmelCase:     int     			=   None

       for index in range(UpperCAmelCase      ):
        # If sequences have already been processed, the token type IDs will be created according to the previous
        # answer.
        if prev_answers is not None:
         __lowerCAmelCase:     List[str]     			=   token_type_ids_example[:, 3]  # shape (seq_len,)
         __lowerCAmelCase:     Tuple     			=   np.zeros_like(UpperCAmelCase    ,						dtype=np.intaa      )  # shape (seq_len,)

         __lowerCAmelCase:     List[Any]     			=   token_type_ids[index]  # shape (seq_len, 7)
         for i in range(model_labels.shape[0]      ):
          __lowerCAmelCase:     List[Any]     			=   token_type_ids_example[:, 0].tolist()[i]
          __lowerCAmelCase:     List[Any]     			=   token_type_ids_example[:, 1].tolist()[i] - 1
          __lowerCAmelCase:     Union[str, Any]     			=   token_type_ids_example[:, 2].tolist()[i] - 1

          if row_id >= 0 and col_id >= 0 and segment_id == 1:
           __lowerCAmelCase:     str     			=   int(prev_answers[(col_id, row_id)]      )

         __lowerCAmelCase:     Union[str, Any]     			=   model_labels

        __lowerCAmelCase:     Union[str, Any]     			=   input_ids[index]
        __lowerCAmelCase:     Union[str, Any]     			=   attention_mask[index]  # shape (seq_len,)
        __lowerCAmelCase:     Tuple     			=   token_type_ids[index]  # shape (seq_len, 7)
        __lowerCAmelCase:     str     			=   self.model(
            input_ids=np.expand_dims(UpperCAmelCase    ,						axis=0      )    ,						attention_mask=np.expand_dims(UpperCAmelCase    ,						axis=0      )    ,						token_type_ids=np.expand_dims(UpperCAmelCase    ,						axis=0      )    ,						)
        __lowerCAmelCase:     Union[str, Any]     			=   outputs.logits

        if self.aggregate:
         all_aggregations.append(outputs.logits_aggregation      )

        all_logits.append(UpperCAmelCase      )

        __lowerCAmelCase:     Union[str, Any]     			=   tfp.distributions.Bernoulli(logits=UpperCAmelCase      )
        __lowerCAmelCase:     List[str]     			=   dist_per_token.probs_parameter() * tf.cast(UpperCAmelCase    ,						tf.floataa      )

        __lowerCAmelCase:     Union[str, Any]     			=   collections.defaultdict(UpperCAmelCase      )
        __lowerCAmelCase:     Union[str, Any]     			=   token_type_ids_example
        for i, p in enumerate(tf.squeeze(UpperCAmelCase      ).numpy().tolist()      ):
         __lowerCAmelCase:     Any     			=   token_type_ids_example[:, 0].tolist()[i]
         __lowerCAmelCase:     Union[str, Any]     			=   token_type_ids_example[:, 1].tolist()[i] - 1
         __lowerCAmelCase:     Optional[int]     			=   token_type_ids_example[:, 2].tolist()[i] - 1
         if col >= 0 and row >= 0 and segment_id == 1:
          coords_to_probs[(col, row)].append(UpperCAmelCase      )

        __lowerCAmelCase:     List[str]     			=   {key: np.array(coords_to_probs[key]      ).mean() > 0.5 for key in coords_to_probs}

       __lowerCAmelCase:     Optional[int]     			=   tf.concat(tuple(UpperCAmelCase      )    ,						0      )

       return (logits_batch,) if not self.aggregate else (logits_batch, tf.concat(tuple(UpperCAmelCase      )    ,						0      ))


     def __call__(							self    :	Optional[int]    ,						*UpperCAmelCase    :	str    ,						**UpperCAmelCase    :	Optional[Any]      )							->			Union[str, Any]:
      __lowerCAmelCase:     List[str]     			=   self._args_parser(*UpperCAmelCase    ,						**UpperCAmelCase      )

      __lowerCAmelCase:     List[str]     			=   super().__call__(UpperCAmelCase    ,						**UpperCAmelCase      )
      if len(UpperCAmelCase      ) == 1:
       return results[0]
      return results


     def 						UpperCAmelCase						(							self    :	Any    ,						UpperCAmelCase    :	Dict=None    ,						UpperCAmelCase    :	Dict=None    ,						UpperCAmelCase    :	Optional[int]=None    ,						**UpperCAmelCase    :	List[Any]      )							->			Optional[Any]:
      __lowerCAmelCase:     Union[str, Any]     			=   {}
      if padding is not None:
       __lowerCAmelCase:     Union[str, Any]     			=   padding
      if truncation is not None:
       __lowerCAmelCase:     Union[str, Any]     			=   truncation

      __lowerCAmelCase:     Tuple     			=   {}
      if sequential is not None:
       __lowerCAmelCase:     Dict     			=   sequential
      return preprocess_params, forward_params, {}


     def 						UpperCAmelCase						(							self    :	List[Any]    ,						UpperCAmelCase    :	Any    ,						UpperCAmelCase    :	Dict=None    ,						UpperCAmelCase    :	Union[str, Any]=True    ,						UpperCAmelCase    :	Optional[Any]=None      )							->			Optional[int]:
      if truncation is None:
       if self.type == "tapas":
        __lowerCAmelCase:     Any     			=   'drop_rows_to_fit'
       else:
        __lowerCAmelCase:     List[Any]     			=   'do_not_truncate'

      __lowerCAmelCase			,							__lowerCAmelCase:     Dict     			=   pipeline_input['table'], pipeline_input['query']
      if table.empty:
       raise ValueError('table is empty'      )
      if query is None or query == "":
       raise ValueError('query is empty'      )
      __lowerCAmelCase:     Optional[Any]     			=   self.tokenizer(UpperCAmelCase    ,						UpperCAmelCase    ,						return_tensors=self.framework    ,						truncation=UpperCAmelCase    ,						padding=UpperCAmelCase      )
      __lowerCAmelCase:     Optional[int]     			=   table
      return inputs


     def 						UpperCAmelCase						(							self    :	Optional[Any]    ,						UpperCAmelCase    :	str    ,						UpperCAmelCase    :	Any=False      )							->			List[str]:
      __lowerCAmelCase:     Optional[Any]     			=   model_inputs.pop('table'      )

      if self.type == "tapas":
       if sequential:
        __lowerCAmelCase:     Dict     			=   self.sequential_inference(**UpperCAmelCase      )
       else:
        __lowerCAmelCase:     List[str]     			=   self.batch_inference(**UpperCAmelCase      )
      else:
       __lowerCAmelCase:     Union[str, Any]     			=   self.model.generate(**UpperCAmelCase      )
      __lowerCAmelCase:     int     			=   {'model_inputs': model_inputs, 'table': table, 'outputs': outputs}
      return model_outputs


     def 						UpperCAmelCase						(							self    :	Any    ,						UpperCAmelCase    :	List[str]      )							->			Dict:
      __lowerCAmelCase:     Optional[Any]     			=   model_outputs['model_inputs']
      __lowerCAmelCase:     Union[str, Any]     			=   model_outputs['table']
      __lowerCAmelCase:     int     			=   model_outputs['outputs']
      if self.type == "tapas":
       if self.aggregate:
        __lowerCAmelCase			,							__lowerCAmelCase:     Optional[Any]     			=   outputs[:2]
        __lowerCAmelCase:     Any     			=   self.tokenizer.convert_logits_to_predictions(UpperCAmelCase    ,						UpperCAmelCase    ,						UpperCAmelCase      )
        __lowerCAmelCase			,							__lowerCAmelCase:     List[str]     			=   predictions
        __lowerCAmelCase:     int     			=   {i: self.model.config.aggregation_labels[pred] for i, pred in enumerate(UpperCAmelCase      )}

        __lowerCAmelCase:     Any     			=   self.model.config.no_aggregation_label_index
        __lowerCAmelCase:     Optional[Any]     			=   {
            i: aggregators[i] + ' > ' for i, pred in enumerate(UpperCAmelCase      ) if pred != no_agg_label_index
        }
       else:
        __lowerCAmelCase:     Any     			=   outputs[0]
        __lowerCAmelCase:     Dict     			=   self.tokenizer.convert_logits_to_predictions(UpperCAmelCase    ,						UpperCAmelCase      )
        __lowerCAmelCase:     Optional[int]     			=   predictions[0]
        __lowerCAmelCase:     str     			=   {}
        __lowerCAmelCase:     Any     			=   {}
       __lowerCAmelCase:     str     			=   []
       for index, coordinates in enumerate(UpperCAmelCase      ):
        __lowerCAmelCase:     List[Any]     			=   [table.iat[coordinate] for coordinate in coordinates]
        __lowerCAmelCase:     Optional[Any]     			=   aggregators.get(UpperCAmelCase    ,						''      )
        __lowerCAmelCase:     Optional[Any]     			=   aggregators_prefix.get(UpperCAmelCase    ,						''      )
        __lowerCAmelCase:     List[str]     			=   {
            'answer': aggregator_prefix + ', '.join(UpperCAmelCase      ),
            'coordinates': coordinates,
            'cells': [table.iat[coordinate] for coordinate in coordinates],
        }
        if aggregator:
         __lowerCAmelCase:     str     			=   aggregator

        answers.append(UpperCAmelCase      )
       if len(UpperCAmelCase      ) == 0:
        raise PipelineException('Empty answer'      )
      else:
       __lowerCAmelCase:     Optional[Any]     			=   [{'answer': answer} for answer in self.tokenizer.batch_decode(UpperCAmelCase    ,						skip_special_tokens=UpperCAmelCase      )]

      return answers if len(UpperCAmelCase      ) > 1 else answers[0]








# Copyright 2023 The HuggingFace Team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from typing import TYPE_CHECKING

from ...utils import (
    OptionalDependencyNotAvailable,
    _LazyModule,
    is_torch_available,
    is_vision_available,
)


_a	 =     {
    '''configuration_tvlt''': ['''TVLT_PRETRAINED_CONFIG_ARCHIVE_MAP''', '''TvltConfig'''],
    '''feature_extraction_tvlt''': ['''TvltFeatureExtractor'''],
    '''processing_tvlt''': ['''TvltProcessor'''],
}

try:
  if not is_torch_available():
    raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
  pass
else:
  _a	 =     [
      '''TVLT_PRETRAINED_MODEL_ARCHIVE_LIST''',
      '''TvltModel''',
      '''TvltForPreTraining''',
      '''TvltForAudioVisualClassification''',
      '''TvltPreTrainedModel''',
  ]

try:
  if not is_vision_available():
    raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
  pass
else:
  _a	 =     ['''TvltImageProcessor''']


if TYPE_CHECKING:
  from .configuration_tvlt import TVLT_PRETRAINED_CONFIG_ARCHIVE_MAP, TvltConfig
  from .processing_tvlt import TvltProcessor
  from .feature_extraction_tvlt import TvltFeatureExtractor

  try:
    if not is_torch_available():
      raise OptionalDependencyNotAvailable()
  except OptionalDependencyNotAvailable:
    pass
  else:
    from .modeling_tvlt import (
        TVLT_PRETRAINED_MODEL_ARCHIVE_LIST,
        TvltForAudioVisualClassification,
        TvltForPreTraining,
        TvltModel,
        TvltPreTrainedModel,
    )

  try:
    if not is_vision_available():
      raise OptionalDependencyNotAvailable()
  except OptionalDependencyNotAvailable:
    pass
  else:
    from .image_processing_tvlt import TvltImageProcessor


else:
  import sys

  _a	 =     _LazyModule(__name__, globals()['''__file__'''], _import_structure, module_spec=__spec__)





