'''simple docstring'''

import logging

import torch
from torch import nn
from torch.nn import CrossEntropyLoss, MSELoss

from transformers.file_utils import add_start_docstrings, add_start_docstrings_to_model_forward
from transformers.models.bert.modeling_bert import (
    BERT_INPUTS_DOCSTRING,
    BERT_START_DOCSTRING,
    BertEncoder,
    BertModel,
    BertPreTrainedModel,
)


A_     :						Optional[int]    							=logging.getLogger(__name__)


class     __UpperCAmelCase       ( __a		):





  def 						UpperCAmelCase_	(	self    ,     _lowerCamelCase    ,     _lowerCamelCase    ,     _lowerCamelCase=None    ,     _lowerCamelCase=None ):
     lowerCAmelCase_			=      self.layer[current_layer](_lowerCamelCase    ,     _lowerCamelCase    ,     head_mask[current_layer] )

     lowerCAmelCase_			=      layer_outputs[0]

     return hidden_states






@add_start_docstrings(
    'The bare Bert Model transformer with PABEE outputting raw hidden-states without any specific head on top.'						,       __a						,       )
class     __UpperCAmelCase       ( __a		):





  def __init__(	self    ,     _lowerCamelCase ):
     super().__init__(_lowerCamelCase )

     lowerCAmelCase_			=      BertEncoderWithPabee(_lowerCamelCase )

     self.init_weights()
     lowerCAmelCase_			=      0
     lowerCAmelCase_			=      0
     lowerCAmelCase_			=      0

     lowerCAmelCase_			=      0





  def 						UpperCAmelCase_	(	self    ,     _lowerCamelCase ):
     lowerCAmelCase_			=      threshold





  def 						UpperCAmelCase_	(	self    ,     _lowerCamelCase ):
     lowerCAmelCase_			=      patience





  def 						UpperCAmelCase_	(	self ):
     lowerCAmelCase_			=      0
     lowerCAmelCase_			=      0





  def 						UpperCAmelCase_	(	self ):
     lowerCAmelCase_			=      self.inference_layers_num / self.inference_instances_num
     lowerCAmelCase_			=      (
         F'''*** Patience = {self.patience} Avg. Inference Layers = {avg_inf_layers:.2f} Speed Up ='''
         F''' {1 - avg_inf_layers / self.config.num_hidden_layers:.2f} ***'''
     )
     print(_lowerCamelCase )







  @add_start_docstrings_to_model_forward(_lowerCamelCase )
  def 						UpperCAmelCase_	(	self    ,     _lowerCamelCase=None    ,     _lowerCamelCase=None    ,     _lowerCamelCase=None    ,     _lowerCamelCase=None    ,     _lowerCamelCase=None    ,     _lowerCamelCase=None    ,     _lowerCamelCase=None    ,     _lowerCamelCase=None    ,     _lowerCamelCase=None    ,     _lowerCamelCase=None    ,     _lowerCamelCase=False    ,     ):

     if input_ids is not None and inputs_embeds is not None:
        raise ValueError('''You cannot specify both input_ids and inputs_embeds at the same time''' )
     elif input_ids is not None:
        lowerCAmelCase_			=      input_ids.size()
     elif inputs_embeds is not None:
        lowerCAmelCase_			=      inputs_embeds.size()[:-1]
     else:
        raise ValueError('''You have to specify either input_ids or inputs_embeds''' )

     lowerCAmelCase_			=      input_ids.device if input_ids is not None else inputs_embeds.device

     if attention_mask is None:
        lowerCAmelCase_			=      torch.ones(_lowerCamelCase    ,     device=_lowerCamelCase )
     if token_type_ids is None:
        lowerCAmelCase_			=      torch.zeros(_lowerCamelCase    ,     dtype=torch.long    ,     device=_lowerCamelCase )

     # We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length]
     # ourselves in which case we just need to make it broadcastable to all heads.
     lowerCAmelCase_			=      self.get_extended_attention_mask(_lowerCamelCase    ,     _lowerCamelCase    ,     _lowerCamelCase )

     # If a 2D ou 3D attention mask is provided for the cross-attention
     # we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length]
     if self.config.is_decoder and encoder_hidden_states is not None:
        lowerCAmelCase_	,lowerCAmelCase_	,lowerCAmelCase_			=      encoder_hidden_states.size()
        lowerCAmelCase_			=      (encoder_batch_size, encoder_sequence_length)
        if encoder_attention_mask is None:
           lowerCAmelCase_			=      torch.ones(_lowerCamelCase    ,     device=_lowerCamelCase )
        lowerCAmelCase_			=      self.invert_attention_mask(_lowerCamelCase )
     else:
        lowerCAmelCase_			=      None

     # Prepare head mask if needed
     # 1.0 in head_mask indicate we keep the head
     # attention_probs has shape bsz x n_heads x N x N
     # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads]
     # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length]
     lowerCAmelCase_			=      self.get_head_mask(_lowerCamelCase    ,     self.config.num_hidden_layers )

     lowerCAmelCase_			=      self.embeddings(
         input_ids=_lowerCamelCase    ,     position_ids=_lowerCamelCase    ,     token_type_ids=_lowerCamelCase    ,     inputs_embeds=_lowerCamelCase )
     lowerCAmelCase_			=      embedding_output

     if self.training:
        lowerCAmelCase_			=      []
        for i in range(self.config.num_hidden_layers ):
           lowerCAmelCase_			=      self.encoder.adaptive_forward(
               _lowerCamelCase    ,     current_layer=_lowerCamelCase    ,     attention_mask=_lowerCamelCase    ,     head_mask=_lowerCamelCase )

           lowerCAmelCase_			=      self.pooler(_lowerCamelCase )
           lowerCAmelCase_			=      output_layers[i](output_dropout(_lowerCamelCase ) )
           res.append(_lowerCamelCase )
     elif self.patience == 0:  # Use all layers for inference
        lowerCAmelCase_			=      self.encoder(
            _lowerCamelCase    ,     attention_mask=_lowerCamelCase    ,     head_mask=_lowerCamelCase    ,     encoder_hidden_states=_lowerCamelCase    ,     encoder_attention_mask=_lowerCamelCase    ,     )
        lowerCAmelCase_			=      self.pooler(encoder_outputs[0] )
        lowerCAmelCase_			=      [output_layers[self.config.num_hidden_layers - 1](_lowerCamelCase )]
     else:
        lowerCAmelCase_			=      0
        lowerCAmelCase_			=      None
        lowerCAmelCase_			=      0
        for i in range(self.config.num_hidden_layers ):
           calculated_layer_num += 1
           lowerCAmelCase_			=      self.encoder.adaptive_forward(
               _lowerCamelCase    ,     current_layer=_lowerCamelCase    ,     attention_mask=_lowerCamelCase    ,     head_mask=_lowerCamelCase )

           lowerCAmelCase_			=      self.pooler(_lowerCamelCase )
           lowerCAmelCase_			=      output_layers[i](_lowerCamelCase )
           if regression:
              lowerCAmelCase_			=      logits.detach()
              if patient_result is not None:
                 lowerCAmelCase_			=      patient_result.detach()
              if (patient_result is not None) and torch.abs(patient_result - labels ) < self.regression_threshold:
                 patient_counter += 1
              else:
                 lowerCAmelCase_			=      0
           else:
              lowerCAmelCase_			=      logits.detach().argmax(dim=1 )
              if patient_result is not None:
                 lowerCAmelCase_			=      patient_result.detach().argmax(dim=1 )
              if (patient_result is not None) and torch.all(labels.eq(_lowerCamelCase ) ):
                 patient_counter += 1
              else:
                 lowerCAmelCase_			=      0

           lowerCAmelCase_			=      logits
           if patient_counter == self.patience:
              break
        lowerCAmelCase_			=      [patient_result]
        self.inference_layers_num += calculated_layer_num
        self.inference_instances_num += 1

     return res






@add_start_docstrings(
    'Bert Model transformer with PABEE and a sequence classification/regression head on top (a linear layer on top of\n    the pooled output) e.g. for GLUE tasks. '						,       __a						,       )
class     __UpperCAmelCase       ( __a		):





  def __init__(	self    ,     _lowerCamelCase ):
     super().__init__(_lowerCamelCase )
     lowerCAmelCase_			=      config.num_labels

     lowerCAmelCase_			=      BertModelWithPabee(_lowerCamelCase )
     lowerCAmelCase_			=      nn.Dropout(config.hidden_dropout_prob )
     lowerCAmelCase_			=      nn.ModuleList(
         [nn.Linear(config.hidden_size    ,     self.config.num_labels ) for _ in range(config.num_hidden_layers )] )

     self.init_weights()







  @add_start_docstrings_to_model_forward(_lowerCamelCase )
  def 						UpperCAmelCase_	(	self    ,     _lowerCamelCase=None    ,     _lowerCamelCase=None    ,     _lowerCamelCase=None    ,     _lowerCamelCase=None    ,     _lowerCamelCase=None    ,     _lowerCamelCase=None    ,     _lowerCamelCase=None    ,     ):
     lowerCAmelCase_			=      self.bert(
         input_ids=_lowerCamelCase    ,     attention_mask=_lowerCamelCase    ,     token_type_ids=_lowerCamelCase    ,     position_ids=_lowerCamelCase    ,     head_mask=_lowerCamelCase    ,     inputs_embeds=_lowerCamelCase    ,     output_dropout=self.dropout    ,     output_layers=self.classifiers    ,     regression=self.num_labels == 1    ,     )

     lowerCAmelCase_			=      (logits[-1],)

     if labels is not None:
        lowerCAmelCase_			=      None
        lowerCAmelCase_			=      0
        for ix, logits_item in enumerate(_lowerCamelCase ):
           if self.num_labels == 1:
              #  We are doing regression
              lowerCAmelCase_			=      MSELoss()
              lowerCAmelCase_			=      loss_fct(logits_item.view(-1 )    ,     labels.view(-1 ) )
           else:
              lowerCAmelCase_			=      CrossEntropyLoss()
              lowerCAmelCase_			=      loss_fct(logits_item.view(-1    ,     self.num_labels )    ,     labels.view(-1 ) )
           if total_loss is None:
              lowerCAmelCase_			=      loss
           else:
              total_loss += loss * (ix + 1)
           total_weights += ix + 1
        lowerCAmelCase_			=      (total_loss / total_weights,) + outputs

     return outputs






'''simple docstring'''

import os



def snake_case_      (					__snake_case  :							List[Any])			->					str:
   lowerCAmelCase_			=      len(grid[0])
   lowerCAmelCase_			=      len(__snake_case)

   lowerCAmelCase_			=      0
   lowerCAmelCase_			=      0
   lowerCAmelCase_			=      0

   # Check vertically, horizontally, diagonally at the same time (only works
   # for nxn grid)
   for i in range(__snake_case):
      for j in range(n_rows - 3):
         lowerCAmelCase_			=      grid[j][i] * grid[j + 1][i] * grid[j + 2][i] * grid[j + 3][i]
         lowerCAmelCase_			=      grid[i][j] * grid[i][j + 1] * grid[i][j + 2] * grid[i][j + 3]

         # Left-to-right diagonal (\) product
         if i < n_columns - 3:
            lowerCAmelCase_			=      (
                grid[i][j]
                * grid[i + 1][j + 1]
                * grid[i + 2][j + 2]
                * grid[i + 3][j + 3]
            )

         # Right-to-left diagonal(/) product
         if i > 2:
            lowerCAmelCase_			=      (
                grid[i][j]
                * grid[i - 1][j + 1]
                * grid[i - 2][j + 2]
                * grid[i - 3][j + 3]
            )

         lowerCAmelCase_			=      max(
             __snake_case	,   __snake_case	,   __snake_case	,   __snake_case)
         if max_product > largest:
            lowerCAmelCase_			=      max_product

   return largest



def snake_case_      (					)			->					List[Any]:
   lowerCAmelCase_			=      []
   with open(os.path.dirname(__snake_case) + '''/grid.txt''') as file:
      for line in file:
         grid.append(line.strip('''\n''').split(''' '''))

   lowerCAmelCase_			=      [[int(__snake_case) for i in grid[j]] for j in range(len(__snake_case))]

   return largest_product(__snake_case)


if __name__ == "__main__":
 print(solution())





