import unittest

import torch
from torch import nn

from accelerate.test_utils import require_cuda
from accelerate.utils.memory import find_executable_batch_size, release_memory




def       __lowerCAmelCase      (						)    ->  Union[str, Any]:
  raise RuntimeError("CUDA out of memory."					)


class 			UpperCAmelCase__    (		nn.Module					):



  """simple docstring"""






  def __init__(				self:			Optional[int]   ) -> Union[str, Any]:




    '''simple docstring'''




    super().__init__()
    __UpperCAmelCase						    =       nn.Linear(3				,				4   )
    __UpperCAmelCase						    =       nn.BatchNormad(4   )
    __UpperCAmelCase						    =       nn.Linear(4				,				5   )






  def 	_UpperCAmelCase				(				self:			Union[str, Any]				,				__lowerCAmelCase:			Optional[Any]   ) -> Any:




    '''simple docstring'''




    return self.lineara(self.batchnorm(self.lineara(__lowerCAmelCase   )   )   )






class 			UpperCAmelCase__    (		unittest.TestCase					):



  """simple docstring"""






  def 	_UpperCAmelCase				(				self:			List[str]   ) -> int:




    '''simple docstring'''




    __UpperCAmelCase						    =       []

    @find_executable_batch_size(starting_batch_size=128   )
    def mock_training_loop_function(__lowerCAmelCase:			Optional[int]   ):
      nonlocal batch_sizes
      batch_sizes.append(__lowerCAmelCase   )
      if batch_size != 8:
        raise_fake_out_of_memory()

    mock_training_loop_function()
    self.assertListEqual(__lowerCAmelCase				,				[128, 64, 32, 16, 8]   )






  def 	_UpperCAmelCase				(				self:			List[str]   ) -> Any:




    '''simple docstring'''




    __UpperCAmelCase						    =       []

    @find_executable_batch_size(starting_batch_size=128   )
    def mock_training_loop_function(__lowerCAmelCase:			Any				,				__lowerCAmelCase:			Union[str, Any]   ):
      nonlocal batch_sizes
      batch_sizes.append(__lowerCAmelCase   )
      if batch_size != 8:
        raise_fake_out_of_memory()
      return batch_size, arga

    __UpperCAmelCase    ,		__UpperCAmelCase						    =       mock_training_loop_function("hello"   )
    self.assertListEqual(__lowerCAmelCase				,				[128, 64, 32, 16, 8]   )
    self.assertListEqual([bs, arga]				,				[8, "hello"]   )






  def 	_UpperCAmelCase				(				self:			Optional[int]   ) -> Dict:




    '''simple docstring'''




    @find_executable_batch_size(starting_batch_size=0   )
    def mock_training_loop_function(__lowerCAmelCase:			Any   ):
      pass

    with self.assertRaises(__lowerCAmelCase   ) as cm:
      mock_training_loop_function()
      self.assertIn("No executable batch size found, reached zero."				,				cm.exception.args[0]   )






  def 	_UpperCAmelCase				(				self:			Union[str, Any]   ) -> Optional[int]:




    '''simple docstring'''




    @find_executable_batch_size(starting_batch_size=16   )
    def mock_training_loop_function(__lowerCAmelCase:			Dict   ):
      if batch_size > 0:
        raise_fake_out_of_memory()
      pass

    with self.assertRaises(__lowerCAmelCase   ) as cm:
      mock_training_loop_function()
      self.assertIn("No executable batch size found, reached zero."				,				cm.exception.args[0]   )






  def 	_UpperCAmelCase				(				self:			str   ) -> str:




    '''simple docstring'''




    @find_executable_batch_size(starting_batch_size=128   )
    def mock_training_loop_function(__lowerCAmelCase:			Dict				,				__lowerCAmelCase:			Dict				,				__lowerCAmelCase:			int   ):
      if batch_size != 8:
        raise raise_fake_out_of_memory()

    with self.assertRaises(__lowerCAmelCase   ) as cm:
      mock_training_loop_function(128				,				"hello"				,				"world"   )
      self.assertIn("Batch size was passed into `f`"				,				cm.exception.args[0]   )
      self.assertIn("`f(arg1='hello', arg2='world')"				,				cm.exception.args[0]   )






  def 	_UpperCAmelCase				(				self:			Optional[int]   ) -> List[Any]:




    '''simple docstring'''




    @find_executable_batch_size(starting_batch_size=16   )
    def mock_training_loop_function(__lowerCAmelCase:			Optional[Any]   ):
      raise ValueError("Oops, we had an error!"   )

    with self.assertRaises(__lowerCAmelCase   ) as cm:
      mock_training_loop_function()
      self.assertIn("Oops, we had an error!"				,				cm.exception.args[0]   )






  @require_cuda
  def 	_UpperCAmelCase				(				self:			Optional[int]   ) -> str:




    '''simple docstring'''




    __UpperCAmelCase						    =       torch.cuda.memory_allocated()
    __UpperCAmelCase						    =       ModelForTest()
    model.cuda()
    self.assertGreater(torch.cuda.memory_allocated()				,				__lowerCAmelCase   )
    __UpperCAmelCase						    =       release_memory(__lowerCAmelCase   )
    self.assertEqual(torch.cuda.memory_allocated()				,				__lowerCAmelCase   )




def       __lowerCAmelCase      (						A_   : str					)    ->  Any:
  if not head:
    return True
  # split the list to two parts
  __UpperCAmelCase    ,		__UpperCAmelCase						    =       head.next, head
  while fast and fast.next:
    __UpperCAmelCase						    =       fast.next.next
    __UpperCAmelCase						    =       slow.next
  __UpperCAmelCase						    =       slow.next
  __UpperCAmelCase						    =       None  # Don't forget here! But forget still works!
  # reverse the second part
  __UpperCAmelCase						    =       None
  while second:
    __UpperCAmelCase						    =       second.next
    __UpperCAmelCase						    =       node
    __UpperCAmelCase						    =       second
    __UpperCAmelCase						    =       nxt
  # compare two parts
  # second part has the same or one less node
  while node:
    if node.val != head.val:
      return False
    __UpperCAmelCase						    =       node.next
    __UpperCAmelCase						    =       head.next
  return True




def       __lowerCAmelCase      (						A_   : Optional[Any]					)    ->  Optional[Any]:
  if not head or not head.next:
    return True

  # 1. Get the midpoint (slow)
  __UpperCAmelCase						    =       __UpperCAmelCase						    =       __UpperCAmelCase						    =       head
  while fast and fast.next:
    __UpperCAmelCase    ,		__UpperCAmelCase						    =       fast.next.next, slow.next

  # 2. Push the second half into the stack
  __UpperCAmelCase						    =       [slow.val]
  while slow.next:
    __UpperCAmelCase						    =       slow.next
    stack.append(slow.val					)

  # 3. Comparison
  while stack:
    if stack.pop() != cur.val:
      return False
    __UpperCAmelCase						    =       cur.next

  return True





def       __lowerCAmelCase      (						A_   : int					)    ->  Optional[int]:
  if not head or not head.next:
    return True
  __UpperCAmelCase						    =       {}
  __UpperCAmelCase						    =       0
  while head:
    if head.val in d:
      d[head.val].append(A_					)
    else:
      __UpperCAmelCase						    =       [pos]
    __UpperCAmelCase						    =       head.next
    pos += 1
  __UpperCAmelCase						    =       pos - 1
  __UpperCAmelCase						    =       0
  for v in d.values():
    if len(A_					) % 2 != 0:
      middle += 1
    else:
      __UpperCAmelCase						    =       0
      for i in range(0						,	len(A_					)					):
        if v[i] + v[len(A_					) - 1 - step] != checksum:
          return False
        step += 1
    if middle > 1:
      return False
  return True



