


'''simple docstring'''




import logging
import os

import quant_trainer
import torch
from torch.utils.data import DataLoader

from transformers import Trainer, is_torch_tpu_available
from transformers.trainer_utils import PredictionOutput


__snake_case    						=logging.getLogger(__name__)

if is_torch_tpu_available(check_device=False):
       import torch_xla.core.xla_model as xm
       import torch_xla.debug.metrics as met

class 		UpperCAmelCase_      (  __lowercase		):





     def __init__( self       :      List[Any]    ,      *UpperCAmelCase__       :      int    ,      UpperCAmelCase__       :      Optional[int]=None    ,      UpperCAmelCase__       :      Dict=None    ,      UpperCAmelCase__       :      str=None    ,      **UpperCAmelCase__       :      Tuple    )				->  Tuple:
        super().__init__(*UpperCAmelCase__    ,      **UpperCAmelCase__    )
        lowerCAmelCase     =			eval_examples
        lowerCAmelCase     =			post_process_function
        lowerCAmelCase     =			quant_trainer_args
        lowerCAmelCase     =			1_2_8  # default number of calibration samples





     def 							__UpperCAmelCase      ( self       :      Union[str, Any]    ,      UpperCAmelCase__       :      List[str]=None    )				->  Union[str, Any]:
        if calib_dataset is None and self.calib_dataset is None:
           raise ValueError('Trainer: calibration requires an calib_dataset.'    )
        lowerCAmelCase     =			calib_dataset if calib_dataset is not None else self.calib_dataset

        lowerCAmelCase     =			self._remove_unused_columns(UpperCAmelCase__    ,      description='Calibration'    )

        return DataLoader(
            UpperCAmelCase__    ,      batch_size=self.args.eval_batch_size    ,      collate_fn=self.data_collator    ,      drop_last=self.args.dataloader_drop_last    ,      num_workers=self.args.dataloader_num_workers    ,      pin_memory=self.args.dataloader_pin_memory    ,      shuffle=UpperCAmelCase__    ,      )





     def 							__UpperCAmelCase      ( self       :      Tuple    ,      UpperCAmelCase__       :      int=None    )				->  Tuple:
        lowerCAmelCase     =			self.train_dataset if calib_dataset is None else calib_dataset
        lowerCAmelCase     =			self.get_calib_dataloader(UpperCAmelCase__    )

        lowerCAmelCase     =			self.model
        quant_trainer.configure_model(UpperCAmelCase__    ,      self.quant_trainer_args    ,      calib=UpperCAmelCase__    )
        model.eval()
        quant_trainer.enable_calibration(UpperCAmelCase__    )

        logger.info('***** Running calibration *****'    )
        logger.info(F'''  Num examples = {self.calib_num}'''    )
        logger.info(F'''  Batch size = {calib_dataloader.batch_size}'''    )

        for step, inputs in enumerate(UpperCAmelCase__    ):
           # Prediction step
           lowerCAmelCase     ,  lowerCAmelCase     ,  lowerCAmelCase     =			self.prediction_step(UpperCAmelCase__    ,      UpperCAmelCase__    ,      prediction_loss_only=UpperCAmelCase__    )
           if (step + 1) * calib_dataloader.batch_size >= self.calib_num:
              break

        quant_trainer.finish_calibration(UpperCAmelCase__    ,      self.quant_trainer_args    )
        lowerCAmelCase     =			model





     def 							__UpperCAmelCase      ( self       :      Any    ,      UpperCAmelCase__       :      Any=None    ,      UpperCAmelCase__       :      List[Any]=None    ,      UpperCAmelCase__       :      Any=None    ,      UpperCAmelCase__       :      str = "eval"    )				->  int:
        lowerCAmelCase     =			self.eval_dataset if eval_dataset is None else eval_dataset
        lowerCAmelCase     =			self.get_eval_dataloader(UpperCAmelCase__    )
        lowerCAmelCase     =			self.eval_examples if eval_examples is None else eval_examples

        # Temporarily disable metric computation, we will do it in the loop here.
        lowerCAmelCase     =			self.compute_metrics
        lowerCAmelCase     =			None
        lowerCAmelCase     =			self.prediction_loop if self.args.use_legacy_prediction_loop else self.evaluation_loop
        try:
           lowerCAmelCase     =			eval_loop(
               UpperCAmelCase__    ,      description='Evaluation'    ,      prediction_loss_only=True if compute_metrics is None else None    ,      ignore_keys=UpperCAmelCase__    ,      )
        finally:
           lowerCAmelCase     =			compute_metrics

        if self.post_process_function is not None and self.compute_metrics is not None:
           lowerCAmelCase     =			self.post_process_function(UpperCAmelCase__    ,      UpperCAmelCase__    ,      output.predictions    )
           lowerCAmelCase     =			self.compute_metrics(UpperCAmelCase__    )

           # Prefix all keys with metric_key_prefix + '_'
           for key in list(metrics.keys()    ):
              if not key.startswith(F'''{metric_key_prefix}_'''    ):
                 lowerCAmelCase     =			metrics.pop(UpperCAmelCase__    )

           self.log(UpperCAmelCase__    )
        else:
           lowerCAmelCase     =			{}

        if self.args.tpu_metrics_debug or self.args.debug:
           # tpu-comment: Logging debug metrics for PyTorch/XLA (compile, execute times, ops, etc.)
           xm.master_print(met.metrics_report()    )

        lowerCAmelCase     =			self.callback_handler.on_evaluate(self.args    ,      self.state    ,      self.control    ,      UpperCAmelCase__    )
        return metrics





     def 							__UpperCAmelCase      ( self       :      str    ,      UpperCAmelCase__       :      Dict    ,      UpperCAmelCase__       :      Union[str, Any]    ,      UpperCAmelCase__       :      List[Any]=None    ,      UpperCAmelCase__       :      str = "test"    )				->  int:
        lowerCAmelCase     =			self.get_test_dataloader(UpperCAmelCase__    )

        # Temporarily disable metric computation, we will do it in the loop here.
        lowerCAmelCase     =			self.compute_metrics
        lowerCAmelCase     =			None
        lowerCAmelCase     =			self.prediction_loop if self.args.use_legacy_prediction_loop else self.evaluation_loop
        try:
           lowerCAmelCase     =			eval_loop(
               UpperCAmelCase__    ,      description='Prediction'    ,      prediction_loss_only=True if compute_metrics is None else None    ,      ignore_keys=UpperCAmelCase__    ,      )
        finally:
           lowerCAmelCase     =			compute_metrics

        if self.post_process_function is None or self.compute_metrics is None:
           return output

        lowerCAmelCase     =			self.post_process_function(UpperCAmelCase__    ,      UpperCAmelCase__    ,      output.predictions    ,      'predict'    )
        lowerCAmelCase     =			self.compute_metrics(UpperCAmelCase__    )

        # Prefix all keys with metric_key_prefix + '_'
        for key in list(metrics.keys()    ):
           if not key.startswith(F'''{metric_key_prefix}_'''    ):
              lowerCAmelCase     =			metrics.pop(UpperCAmelCase__    )

        return PredictionOutput(predictions=predictions.predictions    ,      label_ids=predictions.label_ids    ,      metrics=UpperCAmelCase__    )





     def 							__UpperCAmelCase      ( self       :      Union[str, Any]    ,      UpperCAmelCase__       :      Optional[Any]="./"    )				->  Union[str, Any]:
        lowerCAmelCase     =			self.eval_dataset
        lowerCAmelCase     =			self.get_eval_dataloader(UpperCAmelCase__    )

        lowerCAmelCase     =			next(iter(UpperCAmelCase__    )    )

        # saving device - to make it consistent
        lowerCAmelCase     =			torch.device('cuda' if torch.cuda.is_available() else 'cpu'    )

        # convert to tuple
        lowerCAmelCase     =			tuple(v.to(UpperCAmelCase__    ) for k, v in batch.items()    )

        logger.info('Converting model to be onnx compatible'    )
        from pytorch_quantization.nn import TensorQuantizer

        lowerCAmelCase     =			True

        lowerCAmelCase     =			self.model.to(UpperCAmelCase__    )

        model.eval()
        model.float()

        lowerCAmelCase     =			model.module if hasattr(UpperCAmelCase__    ,      'module'    ) else model
        quant_trainer.configure_model(UpperCAmelCase__    ,      self.quant_trainer_args    )

        lowerCAmelCase     =			os.path.join(UpperCAmelCase__    ,      'model.onnx'    )
        logger.info(F'''exporting model to {output_model_file}'''    )

        lowerCAmelCase     =			{0: 'batch_size', 1: 'seq_len'}

        torch.onnx.export(
            UpperCAmelCase__    ,      UpperCAmelCase__    ,      UpperCAmelCase__    ,      export_params=UpperCAmelCase__    ,      opset_version=1_3    ,      do_constant_folding=UpperCAmelCase__    ,      input_names=['input_ids', 'attention_mask', 'token_type_ids']    ,      output_names=['output_start_logits', 'output_end_logits']    ,      dynamic_axes={
                'input_ids': axes,
                'attention_mask': axes,
                'token_type_ids': axes,
                'output_start_logits': axes,
                'output_end_logits': axes,
            }    ,      verbose=UpperCAmelCase__    ,      )
        logger.info('onnx export finished'    )









'''simple docstring'''




from __future__ import annotations

from statistics import mean





def 	a_					( lowerCamelCase	:     list[int]	, lowerCamelCase	:     list[int]	, lowerCamelCase	:     int				):
   lowerCAmelCase     =			[0] * no_of_processes
   lowerCAmelCase     =			[0] * no_of_processes

   # Initialize remaining_time to waiting_time.

   for i in range(lowerCamelCase				):
      lowerCAmelCase     =			burst_time[i]
   lowerCAmelCase     =			[]

   lowerCAmelCase     =			0
   lowerCAmelCase     =			0

   # When processes are not completed,
   # A process whose arrival time has passed \
   # and has remaining execution time is put into the ready_process.
   # The shortest process in the ready_process, target_process is executed.

   while completed != no_of_processes:
      lowerCAmelCase     =			[]
      lowerCAmelCase     =			-1

      for i in range(lowerCamelCase				):
         if (arrival_time[i] <= total_time) and (remaining_time[i] > 0):
            ready_process.append(lowerCamelCase				)

      if len(lowerCamelCase				) > 0:
         lowerCAmelCase     =			ready_process[0]
         for i in ready_process:
            if remaining_time[i] < remaining_time[target_process]:
               lowerCAmelCase     =			i
         total_time += burst_time[target_process]
         completed += 1
         lowerCAmelCase     =			0
         lowerCAmelCase     =			(
             total_time - arrival_time[target_process] - burst_time[target_process]
         )
      else:
         total_time += 1

   return waiting_time





def 	a_					( lowerCamelCase	:     list[int]	, lowerCamelCase	:     int	, lowerCamelCase	:     list[int]				):
   lowerCAmelCase     =			[0] * no_of_processes
   for i in range(lowerCamelCase				):
      lowerCAmelCase     =			burst_time[i] + waiting_time[i]
   return turn_around_time


if __name__ == "__main__":
       print("""[TEST CASE 01]""")

       __snake_case    						=4
       __snake_case    						=[2, 5, 3, 7]
       __snake_case    						=[0, 0, 0, 0]
       __snake_case    						=calculate_waitingtime(arrival_time, burst_time, no_of_processes)
       __snake_case    						=calculate_turnaroundtime(
           burst_time, no_of_processes, waiting_time
       )

       # Printing the Result
       print("""PID\tBurst Time\tArrival Time\tWaiting Time\tTurnaround Time""")
       for i, process_id in enumerate(list(range(1, 5))):
              print(
                  F'''{process_id}\t{burst_time[i]}\t\t\t{arrival_time[i]}\t\t\t\t'''
                  F'''{waiting_time[i]}\t\t\t\t{turn_around_time[i]}'''
              )
       print(F'''\nAverage waiting time = {mean(waiting_time):.5f}''')
       print(F'''Average turnaround time = {mean(turn_around_time):.5f}''')





