
'''simple docstring'''





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 			lowerCAmelCase__ (							UpperCamelCase							):



  '''simple docstring'''






  def __call__(self	:			Optional[Any]						,			lowerCAmelCase_	:			List[Any]=None						,			lowerCAmelCase_	:			Any=None						,			**lowerCAmelCase_	:			List[Any]     ) ->							Union[str, 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(lowerCAmelCase_						,			lowerCAmelCase_     ) and table.get("query"     ) is not None and table.get("table"     ) is not None:
                    snake_case_    							=				[table]
              elif isinstance(lowerCAmelCase_						,			lowerCAmelCase_     ) and len(lowerCAmelCase_     ) > 0:
                    if not all(isinstance(lowerCAmelCase_						,			lowerCAmelCase_     ) for d in table     ):
                          raise ValueError(
                              f'''Keyword argument `table` should be a list of dict, but is {(type(lowerCAmelCase_     ) for d in table)}'''     )

                    if table[0].get("query"     ) is not None and table[0].get("table"     ) is not None:
                          snake_case_    							=				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(lowerCAmelCase_						,			lowerCAmelCase_     ) or isinstance(lowerCAmelCase_						,			types.GeneratorType     ):
                    return table
              else:
                    raise ValueError(
                        "Invalid input. Keyword argument `table` should be either of type `dict` or `list`, but "
                        f'''is {type(lowerCAmelCase_     )})'''     )
        else:
              snake_case_    							=				[{"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."     )

                    snake_case_    							=				pd.DataFrame(tqa_pipeline_input["table"]     )

        return tqa_pipeline_inputs



@add_end_docstrings(UpperCamelCase							)
class 			lowerCAmelCase__ (							UpperCamelCase							):



  '''simple docstring'''






  _UpperCamelCase							=			'table,query'

  def __init__(self	:			Union[str, Any]						,			lowerCAmelCase_	:			Any=TableQuestionAnsweringArgumentHandler()						,			*lowerCAmelCase_	:			Tuple						,			**lowerCAmelCase_	:			str     ) ->							Optional[Any]:
        super().__init__(*lowerCAmelCase_						,			**lowerCAmelCase_     )
        snake_case_    							=				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()     )     )

        snake_case_    							=				bool(getattr(self.model.config						,			"aggregation_labels"						,			lowerCAmelCase_     )     ) and bool(
            getattr(self.model.config						,			"num_aggregation_labels"						,			lowerCAmelCase_     )     )
        snake_case_    							=				"tapas" if hasattr(self.model.config						,			"aggregation_labels"     ) else None

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

  def 		_lowerCamelCase						(self	:			List[str]						,			**lowerCAmelCase_	:			str     ) ->							Dict:
        if self.framework == "pt":
              snake_case_    							=				[]
              snake_case_    							=				[]
              snake_case_    							=				None
              snake_case_    							=				inputs["input_ids"].shape[0]

              snake_case_    							=				inputs["input_ids"].to(self.device     )
              snake_case_    							=				inputs["attention_mask"].to(self.device     )
              snake_case_    							=				inputs["token_type_ids"].to(self.device     )
              snake_case_    							=				None

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

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

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

                          snake_case_    							=				torch.from_numpy(lowerCAmelCase_     ).type(torch.long     ).to(self.device     )

                    snake_case_    							=				input_ids[index]
                    snake_case_    							=				attention_mask[index]  # shape (seq_len,)
                    snake_case_    							=				token_type_ids[index]  # shape (seq_len, 7)
                    snake_case_    							=				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     )						,			)
                    snake_case_    							=				outputs.logits

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

                    all_logits.append(lowerCAmelCase_     )

                    snake_case_    							=				torch.distributions.Bernoulli(logits=lowerCAmelCase_     )
                    snake_case_    							=				dist_per_token.probs * attention_mask_example.type(torch.floataa     ).to(
                        dist_per_token.probs.device     )

                    snake_case_    							=				collections.defaultdict(lowerCAmelCase_     )
                    for i, p in enumerate(probabilities.squeeze().tolist()     ):
                          snake_case_    							=				token_type_ids_example[:, 0].tolist()[i]
                          snake_case_    							=				token_type_ids_example[:, 1].tolist()[i] - 1
                          snake_case_    							=				token_type_ids_example[:, 2].tolist()[i] - 1
                          if col >= 0 and row >= 0 and segment_id == 1:
                                coords_to_probs[(col, row)].append(lowerCAmelCase_     )

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

              snake_case_    							=				torch.cat(tuple(lowerCAmelCase_     )						,			0     )

              return (logits_batch,) if not self.aggregate else (logits_batch, torch.cat(tuple(lowerCAmelCase_     )						,			0     ))
        else:
              snake_case_    							=				[]
              snake_case_    							=				[]
              snake_case_    							=				None
              snake_case_    							=				inputs["input_ids"].shape[0]

              snake_case_    							=				inputs["input_ids"]
              snake_case_    							=				inputs["attention_mask"]
              snake_case_    							=				inputs["token_type_ids"].numpy()
              snake_case_    							=				None

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

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

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

                          snake_case_    							=				model_labels

                    snake_case_    							=				input_ids[index]
                    snake_case_    							=				attention_mask[index]  # shape (seq_len,)
                    snake_case_    							=				token_type_ids[index]  # shape (seq_len, 7)
                    snake_case_    							=				self.model(
                        input_ids=np.expand_dims(lowerCAmelCase_						,			axis=0     )						,			attention_mask=np.expand_dims(lowerCAmelCase_						,			axis=0     )						,			token_type_ids=np.expand_dims(lowerCAmelCase_						,			axis=0     )						,			)
                    snake_case_    							=				outputs.logits

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

                    all_logits.append(lowerCAmelCase_     )

                    snake_case_    							=				tfp.distributions.Bernoulli(logits=lowerCAmelCase_     )
                    snake_case_    							=				dist_per_token.probs_parameter() * tf.cast(lowerCAmelCase_						,			tf.floataa     )

                    snake_case_    							=				collections.defaultdict(lowerCAmelCase_     )
                    snake_case_    							=				token_type_ids_example
                    for i, p in enumerate(tf.squeeze(lowerCAmelCase_     ).numpy().tolist()     ):
                          snake_case_    							=				token_type_ids_example[:, 0].tolist()[i]
                          snake_case_    							=				token_type_ids_example[:, 1].tolist()[i] - 1
                          snake_case_    							=				token_type_ids_example[:, 2].tolist()[i] - 1
                          if col >= 0 and row >= 0 and segment_id == 1:
                                coords_to_probs[(col, row)].append(lowerCAmelCase_     )

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

              snake_case_    							=				tf.concat(tuple(lowerCAmelCase_     )						,			0     )

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

  def __call__(self	:			Dict						,			*lowerCAmelCase_	:			Dict						,			**lowerCAmelCase_	:			Union[str, Any]     ) ->							str:
        snake_case_    							=				self._args_parser(*lowerCAmelCase_						,			**lowerCAmelCase_     )

        snake_case_    							=				super().__call__(lowerCAmelCase_						,			**lowerCAmelCase_     )
        if len(lowerCAmelCase_     ) == 1:
              return results[0]
        return results

  def 		_lowerCamelCase						(self	:			Optional[Any]						,			lowerCAmelCase_	:			List[str]=None						,			lowerCAmelCase_	:			List[str]=None						,			lowerCAmelCase_	:			Tuple=None						,			**lowerCAmelCase_	:			Dict     ) ->							List[Any]:
        snake_case_    							=				{}
        if padding is not None:
              snake_case_    							=				padding
        if truncation is not None:
              snake_case_    							=				truncation

        snake_case_    							=				{}
        if sequential is not None:
              snake_case_    							=				sequential
        return preprocess_params, forward_params, {}

  def 		_lowerCamelCase						(self	:			Tuple						,			lowerCAmelCase_	:			str						,			lowerCAmelCase_	:			List[Any]=None						,			lowerCAmelCase_	:			Any=True						,			lowerCAmelCase_	:			List[Any]=None     ) ->							int:
        if truncation is None:
              if self.type == "tapas":
                    snake_case_    							=				"drop_rows_to_fit"
              else:
                    snake_case_    							=				"do_not_truncate"

        snake_case_							,						snake_case_    							=				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"     )
        snake_case_    							=				self.tokenizer(lowerCAmelCase_						,			lowerCAmelCase_						,			return_tensors=self.framework						,			truncation=lowerCAmelCase_						,			padding=lowerCAmelCase_     )
        snake_case_    							=				table
        return inputs

  def 		_lowerCamelCase						(self	:			Optional[Any]						,			lowerCAmelCase_	:			List[Any]						,			lowerCAmelCase_	:			List[Any]=False     ) ->							Tuple:
        snake_case_    							=				model_inputs.pop("table"     )

        if self.type == "tapas":
              if sequential:
                    snake_case_    							=				self.sequential_inference(**lowerCAmelCase_     )
              else:
                    snake_case_    							=				self.batch_inference(**lowerCAmelCase_     )
        else:
              snake_case_    							=				self.model.generate(**lowerCAmelCase_     )
        snake_case_    							=				{"model_inputs": model_inputs, "table": table, "outputs": outputs}
        return model_outputs


  def 		_lowerCamelCase						(self	:			Tuple						,			lowerCAmelCase_	:			List[Any]     ) ->							Any:
        snake_case_    							=				model_outputs["model_inputs"]
        snake_case_    							=				model_outputs["table"]
        snake_case_    							=				model_outputs["outputs"]
        if self.type == "tapas":
              if self.aggregate:
                    snake_case_							,						snake_case_    							=				outputs[:2]
                    snake_case_    							=				self.tokenizer.convert_logits_to_predictions(lowerCAmelCase_						,			lowerCAmelCase_						,			lowerCAmelCase_     )
                    snake_case_							,						snake_case_    							=				predictions
                    snake_case_    							=				{i: self.model.config.aggregation_labels[pred] for i, pred in enumerate(lowerCAmelCase_     )}

                    snake_case_    							=				self.model.config.no_aggregation_label_index
                    snake_case_    							=				{
                        i: aggregators[i] + " > " for i, pred in enumerate(lowerCAmelCase_     ) if pred != no_agg_label_index
                    }
              else:
                    snake_case_    							=				outputs[0]
                    snake_case_    							=				self.tokenizer.convert_logits_to_predictions(lowerCAmelCase_						,			lowerCAmelCase_     )
                    snake_case_    							=				predictions[0]
                    snake_case_    							=				{}
                    snake_case_    							=				{}
              snake_case_    							=				[]
              for index, coordinates in enumerate(lowerCAmelCase_     ):
                    snake_case_    							=				[table.iat[coordinate] for coordinate in coordinates]
                    snake_case_    							=				aggregators.get(lowerCAmelCase_						,			""     )
                    snake_case_    							=				aggregators_prefix.get(lowerCAmelCase_						,			""     )
                    snake_case_    							=				{
                        "answer": aggregator_prefix + ", ".join(lowerCAmelCase_     ),
                        "coordinates": coordinates,
                        "cells": [table.iat[coordinate] for coordinate in coordinates],
                    }
                    if aggregator:
                          snake_case_    							=				aggregator

                    answers.append(lowerCAmelCase_     )
              if len(lowerCAmelCase_     ) == 0:
                    raise PipelineException("Empty answer"     )
        else:
              snake_case_    							=				[{"answer": answer} for answer in self.tokenizer.batch_decode(lowerCAmelCase_						,			skip_special_tokens=lowerCAmelCase_     )]

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



'''simple docstring'''





import sys
from typing import Tuple

import numpy as np
import torch
from PIL import Image
from torch import nn

from transformers.image_utils import PILImageResampling
from utils import img_tensorize



class 			lowerCAmelCase__ :



  '''simple docstring'''






  def __init__(self	:			Optional[Any]						,			lowerCAmelCase_	:			List[str]						,			lowerCAmelCase_	:			Optional[int]=sys.maxsize     ) ->							Tuple:
        snake_case_    							=				"bilinear"
        snake_case_    							=				max_size
        snake_case_    							=				short_edge_length


  def __call__(self	:			int						,			lowerCAmelCase_	:			Tuple     ) ->							int:
        snake_case_    							=				[]
        for img in imgs:
              snake_case_							,						snake_case_    							=				img.shape[:2]
              # later: provide list and randomly choose index for resize
              snake_case_    							=				np.random.randint(self.short_edge_length[0]						,			self.short_edge_length[1] + 1     )
              if size == 0:
                    return img
              snake_case_    							=				size * 1.0 / min(lowerCAmelCase_						,			lowerCAmelCase_     )
              if h < w:
                    snake_case_							,						snake_case_    							=				size, scale * w
              else:
                    snake_case_							,						snake_case_    							=				scale * h, size
              if max(lowerCAmelCase_						,			lowerCAmelCase_     ) > self.max_size:
                    snake_case_    							=				self.max_size * 1.0 / max(lowerCAmelCase_						,			lowerCAmelCase_     )
                    snake_case_    							=				newh * scale
                    snake_case_    							=				neww * scale
              snake_case_    							=				int(neww + 0.5     )
              snake_case_    							=				int(newh + 0.5     )

              if img.dtype == np.uinta:
                    snake_case_    							=				Image.fromarray(lowerCAmelCase_     )
                    snake_case_    							=				pil_image.resize((neww, newh)						,			PILImageResampling.BILINEAR     )
                    snake_case_    							=				np.asarray(lowerCAmelCase_     )
              else:
                    snake_case_    							=				img.permute(2						,			0						,			1     ).unsqueeze(0     )  # 3, 0, 1)  # hw(c) -> nchw
                    snake_case_    							=				nn.functional.interpolate(
                        lowerCAmelCase_						,			(newh, neww)						,			mode=self.interp_method						,			align_corners=lowerCAmelCase_     ).squeeze(0     )
              img_augs.append(lowerCAmelCase_     )

        return img_augs



class 			lowerCAmelCase__ :



  '''simple docstring'''






  def __init__(self	:			Tuple						,			lowerCAmelCase_	:			Optional[Any]     ) ->							int:
        snake_case_    							=				ResizeShortestEdge([cfg.INPUT.MIN_SIZE_TEST, cfg.INPUT.MIN_SIZE_TEST]						,			cfg.INPUT.MAX_SIZE_TEST     )
        snake_case_    							=				cfg.INPUT.FORMAT
        snake_case_    							=				cfg.SIZE_DIVISIBILITY
        snake_case_    							=				cfg.PAD_VALUE
        snake_case_    							=				cfg.INPUT.MAX_SIZE_TEST
        snake_case_    							=				cfg.MODEL.DEVICE
        snake_case_    							=				torch.tensor(cfg.MODEL.PIXEL_STD     ).to(self.device     ).view(len(cfg.MODEL.PIXEL_STD     )						,			1						,			1     )
        snake_case_    							=				torch.tensor(cfg.MODEL.PIXEL_MEAN     ).to(self.device     ).view(len(cfg.MODEL.PIXEL_STD     )						,			1						,			1     )
        snake_case_    							=				lambda lowerCAmelCase_     : (x - self.pixel_mean) / self.pixel_std

  def 		_lowerCamelCase						(self	:			Union[str, Any]						,			lowerCAmelCase_	:			Tuple     ) ->							Any:
        snake_case_    							=				tuple(max(lowerCAmelCase_     ) for s in zip(*[img.shape for img in images]     )     )
        snake_case_    							=				[im.shape[-2:] for im in images]
        snake_case_    							=				[
            nn.functional.pad(
                lowerCAmelCase_						,			[0, max_size[-1] - size[1], 0, max_size[-2] - size[0]]						,			value=self.pad_value						,			)
            for size, im in zip(lowerCAmelCase_						,			lowerCAmelCase_     )
        ]

        return torch.stack(lowerCAmelCase_     ), torch.tensor(lowerCAmelCase_     )


  def __call__(self	:			Tuple						,			lowerCAmelCase_	:			Optional[int]						,			lowerCAmelCase_	:			Optional[Any]=False     ) ->							int:
        with torch.no_grad():
              if not isinstance(lowerCAmelCase_						,			lowerCAmelCase_     ):
                    snake_case_    							=				[images]
              if single_image:
                    assert len(lowerCAmelCase_     ) == 1
              for i in range(len(lowerCAmelCase_     )     ):
                    if isinstance(images[i]						,			torch.Tensor     ):
                          images.insert(lowerCAmelCase_						,			images.pop(lowerCAmelCase_     ).to(self.device     ).float()     )
                    elif not isinstance(images[i]						,			torch.Tensor     ):
                          images.insert(
                              lowerCAmelCase_						,			torch.as_tensor(img_tensorize(images.pop(lowerCAmelCase_     )						,			input_format=self.input_format     )     )
                              .to(self.device     )
                              .float()						,			)
            # resize smallest edge
              snake_case_    							=				torch.tensor([im.shape[:2] for im in images]     )
              snake_case_    							=				self.aug(lowerCAmelCase_     )
              # transpose images and convert to torch tensors
              # images = [torch.as_tensor(i.astype("float32")).permute(2, 0, 1).to(self.device) for i in images]
              # now normalize before pad to avoid useless arithmetic
              snake_case_    							=				[self.normalizer(lowerCAmelCase_     ) for x in images]
              # now pad them to do the following operations
              snake_case_							,						snake_case_    							=				self.pad(lowerCAmelCase_     )
              # Normalize

              if self.size_divisibility > 0:
                    raise NotImplementedError()
              # pad
              snake_case_    							=				torch.true_divide(lowerCAmelCase_						,			lowerCAmelCase_     )
              if single_image:
                    return images[0], sizes[0], scales_yx[0]
              else:
                    return images, sizes, scales_yx

def 	snake_case_							(				_a  :				Tuple			,       _a  :				List[Any]      ):
      boxes[:, 0::2] *= scale_yx[:, 1]
      boxes[:, 1::2] *= scale_yx[:, 0]
      return boxes




def 	snake_case_							(				_a  :				Optional[int]			,       _a  :				Tuple[int, int]      ):
      assert torch.isfinite(_a      ).all(), "Box tensor contains infinite or NaN!"
      snake_case_							,						snake_case_    							=				box_size
      tensor[:, 0].clamp_(min=0			,       max=_a      )
      tensor[:, 1].clamp_(min=0			,       max=_a      )
      tensor[:, 2].clamp_(min=0			,       max=_a      )
      tensor[:, 3].clamp_(min=0			,       max=_a      )

