code: 
  
  
  
  
  
  
  from __future__ import annotations
  
  from collections import deque
  from enum import Enum
  from math import atana, degrees
  from sys import maxsize
  
  
  
  
  
  class     __a						(					A__ ):
   _lowerCAmelCase : List[str] 				=				1
   _lowerCAmelCase : Optional[Any] 				=				2
   _lowerCAmelCase : Dict 				=				3
  
  
  
  
  
  
  
   def __repr__(	self      :     List[Any]		):
  
  
        '''simple docstring'''
  
  
  
  
  
  
        return F'{self.__class__.__name__}.{self.name}'
  
  
  
  
  
  
  
  def 	SCREAMING_SNAKE_CASE							(      __lowerCAmelCase      ,					__lowerCAmelCase      ,					__lowerCAmelCase    )				->			float:
       UpperCamelCase__    :     Any        =						point
       return degrees(atana(y - miny      ,					x - minx    )    )
  
  
  
  
  
  
  
  def 	SCREAMING_SNAKE_CASE							(      __lowerCAmelCase      ,					__lowerCAmelCase      ,					__lowerCAmelCase    )				->			Direction:
       UpperCamelCase__    :     Optional[Any]        =						starting
       UpperCamelCase__    :     Tuple        =						via
       UpperCamelCase__    :     Optional[Any]        =						target
       UpperCamelCase__    :     List[str]        =						degrees(atana(ya - ya      ,					xa - xa    )    )
       via_angle %= 360
       UpperCamelCase__    :     int        =						degrees(atana(ya - ya      ,					xa - xa    )    )
       target_angle %= 360
       # t-
       #  \ \
       #   \ v
       #    \|
       #     s
       # via_angle is always lower than target_angle, if direction is left.
       # If they are same, it means they are on a same line of convex hull.
       if target_angle > via_angle:
            return Direction.left
       elif target_angle == via_angle:
            return Direction.straight
       else:
            return Direction.right
  
  
  
  
  
  
  
  def 	SCREAMING_SNAKE_CASE							(      __lowerCAmelCase    )				->			list[tuple[int, int]]:
  
       if len(__lowerCAmelCase    ) <= 2:
            # There is no convex hull
            raise ValueError("graham_scan: argument must contain more than 3 points."    )
       if len(__lowerCAmelCase    ) == 3:
            return points
       # find the lowest and the most left point
       UpperCamelCase__    :     Any        =						0
       UpperCamelCase__    :     Optional[int]        =						maxsize, maxsize
       for i, point in enumerate(__lowerCAmelCase    ):
            UpperCamelCase__    :     List[str]        =						point[0]
            UpperCamelCase__    :     Any        =						point[1]
            if y < miny:
                 UpperCamelCase__    :     str        =						y
                 UpperCamelCase__    :     int        =						x
                 UpperCamelCase__    :     List[str]        =						i
            if y == miny and x < minx:
                 UpperCamelCase__    :     Any        =						x
                 UpperCamelCase__    :     Union[str, Any]        =						i
  
      # remove the lowest and the most left point from points for preparing for sort
       points.pop(__lowerCAmelCase    )
  
       UpperCamelCase__    :     List[Any]        =						sorted(__lowerCAmelCase      ,					key=lambda __lowerCAmelCase    : angle_comparer(__lowerCAmelCase      ,					__lowerCAmelCase      ,					__lowerCAmelCase    )    )
       # This insert actually costs complexity,
       # and you should instead add (minx, miny) into stack later.
       # I'm using insert just for easy understanding.
       sorted_points.insert(0      ,					(minx, miny)    )
  
       UpperCamelCase__    :     deque[tuple[int, int]]        =						deque()
       stack.append(sorted_points[0]    )
       stack.append(sorted_points[1]    )
       stack.append(sorted_points[2]    )
       # In any ways, the first 3 points line are towards left.
       # Because we sort them the angle from minx, miny.
       UpperCamelCase__    :     Dict        =						Direction.left
  
       for i in range(3      ,					len(__lowerCAmelCase    )    ):
            while True:
                 UpperCamelCase__    :     Dict        =						stack[-2]
                 UpperCamelCase__    :     List[str]        =						stack[-1]
                 UpperCamelCase__    :     List[str]        =						sorted_points[i]
                 UpperCamelCase__    :     Optional[int]        =						check_direction(__lowerCAmelCase      ,					__lowerCAmelCase      ,					__lowerCAmelCase    )
  
                 if next_direction == Direction.left:
                      UpperCamelCase__    :     Dict        =						Direction.left
                      break
                 if next_direction == Direction.straight:
                      if current_direction == Direction.left:
                           # We keep current_direction as left.
                           # Because if the straight line keeps as straight,
                           # we want to know if this straight line is towards left.
                           break
                      elif current_direction == Direction.right:
                           # If the straight line is towards right,
                           # every previous points on those straigh line is not convex hull.
                           stack.pop()
                 if next_direction == Direction.right:
                      stack.pop()
            stack.append(sorted_points[i]    )
       return list(__lowerCAmelCase    )
style_context: 
  
  
  
  
  
  
  import os
  from dataclasses import replace
  
  import jax
  import wandb
  from bigbird_flax import Args, DataCollator, FlaxBigBirdForNaturalQuestions, Trainer, build_tx, train_step, val_step
  from datasets import load_dataset
  from flax import jax_utils
  
  from transformers import BigBirdTokenizerFast
  
  
  if __name__ == "__main__":
   print('''#################### AVAILABLE DEVICES ####################''')
   print(jax.devices())
   print('''###########################################################''')
  
   # setup for wandb sweep
   lowerCamelCase			:							str       =Args()
   lowerCamelCase			:							str       =wandb.init(project='''bigbird-natural-questions''', config=args.__dict__)
   lowerCamelCase			:							Any       =dict(logger.config)
   del wandb_args["batch_size"]
   lowerCamelCase			:							str       =replace(args, **wandb_args)
   lowerCamelCase			:							List[str]       =args.base_dir + '''-''' + wandb.run.id
   lowerCamelCase			:							str       =replace(args, base_dir=base_dir)
   print(args)
  
   lowerCamelCase			:							List[Any]       =load_dataset('''json''', data_files=args.tr_data_path)['''train''']
   lowerCamelCase			:							str       =load_dataset('''json''', data_files=args.val_data_path)['''train''']
  
   # drop extra batch for now
   lowerCamelCase			:							List[Any]       =range(len(tr_dataset) - len(tr_dataset) % args.batch_size)
   lowerCamelCase			:							Union[str, Any]       =tr_dataset.shuffle().select(indices)
   lowerCamelCase			:							List[str]       =range(len(val_dataset) - len(val_dataset) % args.batch_size)
   lowerCamelCase			:							Dict       =val_dataset.shuffle().select(indices)
  
   if os.environ.get('''TRAIN_ON_SMALL''', '''false''') == "true":
    lowerCamelCase			:							Optional[int]       =tr_dataset.shuffle().select(range(80000))
    lowerCamelCase			:							List[Any]       =val_dataset.shuffle().select(range(8000))
  
   print(tr_dataset)
   print(val_dataset)
  
   lowerCamelCase			:							int       =FlaxBigBirdForNaturalQuestions.from_pretrained(
       args.model_id, block_size=args.block_size, num_random_blocks=args.num_random_blocks
   )
   lowerCamelCase			:							Union[str, Any]       =BigBirdTokenizerFast.from_pretrained(args.model_id)
   lowerCamelCase			:							Dict       =DataCollator(pad_id=tokenizer.pad_token_id, max_length=4096)
  
   lowerCamelCase			:							List[str]       ={
       '''lr''': args.lr,
       '''init_lr''': args.init_lr,
       '''warmup_steps''': args.warmup_steps,
       '''num_train_steps''': args.max_epochs * (len(tr_dataset) // args.batch_size),
       '''weight_decay''': args.weight_decay,
   }
   lowerCamelCase       ,    lowerCamelCase			:							Tuple       =build_tx(**tx_args)
  
   lowerCamelCase			:							Optional[Any]       =Trainer(
       args=args,
       data_collator=data_collator,
       model_save_fn=model.save_pretrained,
       train_step_fn=train_step,
       val_step_fn=val_step,
       logger=logger,
       scheduler_fn=lr,
   )
  
   lowerCamelCase			:							Tuple       =None
   lowerCamelCase			:							str       =trainer.create_state(model, tx, num_train_steps=tx_args['''num_train_steps'''], ckpt_dir=ckpt_dir)
   try:
    trainer.train(state, tr_dataset, val_dataset)
   except KeyboardInterrupt:
    print('''Oooops; TRAINING STOPPED UNFORTUNATELY''')
  
   print('''SAVING WEIGHTS IN `final-weights`''')
   lowerCamelCase			:							str       =jax_utils.unreplicate(state.params)
   model.save_pretrained(os.path.join(args.base_dir, '''final-weights'''), params=params)