



'''simple docstring'''





from copy import deepcopy
from typing import Optional, Union

import numpy as np

from ...processing_utils import ProcessorMixin
from ...tokenization_utils_base import BatchEncoding
from ...utils import TensorType, is_tf_available, is_torch_available


if is_torch_available():
  import torch

if is_tf_available():
  import tensorflow as tf






class __A     (    A		):



 '''simple docstring'''







 __lowerCamelCase       :			Union[str, Any]		=			['image_processor']
 __lowerCamelCase       :			Dict		=			'SamImageProcessor'



 def __init__(self					,  A			)       ->	List[Any]:


      """simple docstring"""



      super().__init__(A			)
      _a           =    self.image_processor
      _a           =    -10
      _a           =    self.image_processor.size['''longest_edge''']



 def __call__(self					,  A=None					,  A=None					,  A=None					,  A=None					,  A = None					,  **A					,  )       ->	BatchEncoding:


      """simple docstring"""



      _a           =    self.image_processor(
          A					,  return_tensors=A					,  **A					,  )

      # pop arguments that are not used in the foward but used nevertheless
      _a           =    encoding_image_processor['''original_sizes''']

      if hasattr(A					,  '''numpy'''			):  # Checks if Torch or TF tensor
           _a           =    original_sizes.numpy()

      _a    ,       _a    ,       _a           =    self._check_and_preprocess_points(
          input_points=A					,  input_labels=A					,  input_boxes=A					,  )

      _a           =    self._normalize_and_convert(
          A					,  A					,  input_points=A					,  input_labels=A					,  input_boxes=A					,  return_tensors=A					,  )

      return encoding_image_processor



 def    a__    (self					,  A					,  A					,  A=None					,  A=None					,  A=None					,  A="pt"					,  )       ->	Dict:


      """simple docstring"""



      if input_points is not None:
           if len(A			) != len(A			):
                _a           =    [
                    self._normalize_coordinates(self.target_size					,  A					,  original_sizes[0]			) for point in input_points
                ]
           else:
                _a           =    [
                    self._normalize_coordinates(self.target_size					,  A					,  A			)
                    for point, original_size in zip(A					,  A			)
                ]
           # check that all arrays have the same shape
           if not all(point.shape == input_points[0].shape for point in input_points			):
                if input_labels is not None:
                     _a    ,       _a           =    self._pad_points_and_labels(A					,  A			)

           _a           =    np.array(A			)

      if input_labels is not None:
           _a           =    np.array(A			)

      if input_boxes is not None:
           if len(A			) != len(A			):
                _a           =    [
                    self._normalize_coordinates(self.target_size					,  A					,  original_sizes[0]					,  is_bounding_box=A			)
                    for box in input_boxes
                ]
           else:
                _a           =    [
                    self._normalize_coordinates(self.target_size					,  A					,  A					,  is_bounding_box=A			)
                    for box, original_size in zip(A					,  A			)
                ]
           _a           =    np.array(A			)

      if input_boxes is not None:
           if return_tensors == "pt":
                _a           =    torch.from_numpy(A			)
                # boxes batch size of 1 by default
                _a           =    input_boxes.unsqueeze(1			) if len(input_boxes.shape			) != 3 else input_boxes
           elif return_tensors == "tf":
                _a           =    tf.convert_to_tensor(A			)
                # boxes batch size of 1 by default
                _a           =    tf.expand_dims(A					,  1			) if len(input_boxes.shape			) != 3 else input_boxes
           encoding_image_processor.update({'''input_boxes''': input_boxes}			)
      if input_points is not None:
           if return_tensors == "pt":
                _a           =    torch.from_numpy(A			)
                # point batch size of 1 by default
                _a           =    input_points.unsqueeze(1			) if len(input_points.shape			) != 4 else input_points
           elif return_tensors == "tf":
                _a           =    tf.convert_to_tensor(A			)
                # point batch size of 1 by default
                _a           =    tf.expand_dims(A					,  1			) if len(input_points.shape			) != 4 else input_points
           encoding_image_processor.update({'''input_points''': input_points}			)
      if input_labels is not None:
           if return_tensors == "pt":
                _a           =    torch.from_numpy(A			)
                # point batch size of 1 by default
                _a           =    input_labels.unsqueeze(1			) if len(input_labels.shape			) != 3 else input_labels
           elif return_tensors == "tf":
                _a           =    tf.convert_to_tensor(A			)
                # point batch size of 1 by default
                _a           =    tf.expand_dims(A					,  1			) if len(input_labels.shape			) != 3 else input_labels
           encoding_image_processor.update({'''input_labels''': input_labels}			)

      return encoding_image_processor



 def    a__    (self					,  A					,  A			)       ->	Dict:


      """simple docstring"""



      _a           =    max([point.shape[0] for point in input_points]			)
      _a           =    []
      for i, point in enumerate(A			):
           if point.shape[0] != expected_nb_points:
                _a           =    np.concatenate(
                    [point, np.zeros((expected_nb_points - point.shape[0], 2)			) + self.point_pad_value]					,  axis=0			)
                _a           =    np.append(input_labels[i]					,  [self.point_pad_value]			)
           processed_input_points.append(A			)
      _a           =    processed_input_points
      return input_points, input_labels



 def    a__    (self					,  A					,  A					,  A					,  A=False			)       ->	np.ndarray:


      """simple docstring"""



      _a    ,       _a           =    original_size
      _a    ,       _a           =    self.image_processor._get_preprocess_shape(A					,  longest_edge=A			)
      _a           =    deepcopy(A			).astype(A			)

      if is_bounding_box:
           _a           =    coords.reshape(-1					,  2					,  2			)

      _a           =    coords[..., 0] * (new_w / old_w)
      _a           =    coords[..., 1] * (new_h / old_h)

      if is_bounding_box:
           _a           =    coords.reshape(-1					,  4			)

      return coords



 def    a__    (self					,  A=None					,  A=None					,  A=None					,  )       ->	Dict:


      """simple docstring"""



      if input_points is not None:
           if hasattr(A					,  '''numpy'''			):  # Checks for TF or Torch tensor
                _a           =    input_points.numpy().tolist()

           if not isinstance(A					,  A			) or not isinstance(input_points[0]					,  A			):
                raise ValueError('''Input points must be a list of list of floating points.'''			)
           _a           =    [np.array(A			) for input_point in input_points]
      else:
           _a           =    None

      if input_labels is not None:
           if hasattr(A					,  '''numpy'''			):
                _a           =    input_labels.numpy().tolist()

           if not isinstance(A					,  A			) or not isinstance(input_labels[0]					,  A			):
                raise ValueError('''Input labels must be a list of list integers.'''			)
           _a           =    [np.array(A			) for label in input_labels]
      else:
           _a           =    None

      if input_boxes is not None:
           if hasattr(A					,  '''numpy'''			):
                _a           =    input_boxes.numpy().tolist()

           if (
               not isinstance(A					,  A			)
               or not isinstance(input_boxes[0]					,  A			)
               or not isinstance(input_boxes[0][0]					,  A			)
           ):
                raise ValueError('''Input boxes must be a list of list of list of floating points.'''			)
           _a           =    [np.array(A			).astype(np.floataa			) for box in input_boxes]
      else:
           _a           =    None

      return input_points, input_labels, input_boxes



 @property
 def    a__    (self			)       ->	Union[str, Any]:


      """simple docstring"""



      _a           =    self.image_processor.model_input_names
      return list(dict.fromkeys(A			)			)



 def    a__    (self					,  *A					,  **A			)       ->	List[str]:


      """simple docstring"""



      return self.image_processor.post_process_masks(*A					,  **A			)








'''simple docstring'''





import inspect
import unittest

import torch
import torch.nn as nn

from accelerate.hooks import (
    AlignDevicesHook,
    ModelHook,
    SequentialHook,
    add_hook_to_module,
    attach_align_device_hook,
    remove_hook_from_module,
    remove_hook_from_submodules,
)
from accelerate.test_utils import require_multi_gpu






class __A     (    nn.Module		):



 '''simple docstring'''







 def __init__(self			)       ->	Dict:


      """simple docstring"""



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



 def    a__    (self					,  A			)       ->	Dict:


      """simple docstring"""



      return self.lineara(self.batchnorm(self.lineara(A			)			)			)






class __A     (    A		):



 '''simple docstring'''







 def    a__    (self					,  A					,  *A					,  **A			)       ->	Optional[Any]:


      """simple docstring"""



      return (args[0] + 1,) + args[1:], kwargs






class __A     (    A		):



 '''simple docstring'''







 def    a__    (self					,  A					,  A			)       ->	int:


      """simple docstring"""



      return output + 1






class __A     (    unittest.TestCase		):



 '''simple docstring'''







 def    a__    (self			)       ->	Union[str, Any]:


      """simple docstring"""



      _a           =    ModelForTest()
      _a           =    ModelHook()

      add_hook_to_module(A					,  A			)
      self.assertEqual(test_model._hf_hook					,  A			)
      self.assertTrue(hasattr(A					,  '''_old_forward'''			)			)

      # Check adding the hook did not change the name or the signature
      self.assertEqual(test_model.forward.__name__					,  '''forward'''			)
      self.assertListEqual(list(inspect.signature(test_model.forward			).parameters			)					,  ['''x''']			)

      remove_hook_from_module(A			)
      self.assertFalse(hasattr(A					,  '''_hf_hook'''			)			)
      self.assertFalse(hasattr(A					,  '''_old_forward'''			)			)



 def    a__    (self			)       ->	Any:


      """simple docstring"""



      _a           =    ModelForTest()
      _a           =    ModelHook()

      add_hook_to_module(A					,  A			)
      add_hook_to_module(A					,  A					,  append=A			)

      self.assertEqual(isinstance(test_model._hf_hook					,  A			)					,  A			)
      self.assertEqual(len(test_model._hf_hook.hooks			)					,  2			)
      self.assertTrue(hasattr(A					,  '''_old_forward'''			)			)

      # Check adding the hook did not change the name or the signature
      self.assertEqual(test_model.forward.__name__					,  '''forward'''			)
      self.assertListEqual(list(inspect.signature(test_model.forward			).parameters			)					,  ['''x''']			)

      remove_hook_from_module(A			)
      self.assertFalse(hasattr(A					,  '''_hf_hook'''			)			)
      self.assertFalse(hasattr(A					,  '''_old_forward'''			)			)



 def    a__    (self			)       ->	Union[str, Any]:


      """simple docstring"""



      _a           =    ModelForTest()
      _a           =    torch.randn(2					,  3			)
      _a           =    test_model(x + 1			)
      _a           =    test_model(x + 2			)

      _a           =    PreForwardHook()
      add_hook_to_module(A					,  A			)
      _a           =    test_model(A			)
      self.assertTrue(torch.allclose(A					,  A					,  atol=1E-5			)			)

      # Attaching a hook to a model when it already has one replaces, does not chain
      _a           =    PreForwardHook()
      add_hook_to_module(A					,  A			)
      _a           =    test_model(A			)
      self.assertTrue(torch.allclose(A					,  A					,  atol=1E-5			)			)

      # You need to use the sequential hook to chain two or more hooks
      _a           =    SequentialHook(PreForwardHook()					,  PreForwardHook()			)
      add_hook_to_module(A					,  A			)

      _a           =    test_model(A			)
      assert torch.allclose(A					,  A					,  atol=1E-5			)



 def    a__    (self			)       ->	str:


      """simple docstring"""



      _a           =    ModelForTest()
      _a           =    torch.randn(2					,  3			)
      _a           =    test_model(A			)

      _a           =    PostForwardHook()
      add_hook_to_module(A					,  A			)
      _a           =    test_model(A			)
      self.assertTrue(torch.allclose(A					,  output + 1					,  atol=1E-5			)			)

      # Attaching a hook to a model when it already has one replaces, does not chain
      _a           =    PostForwardHook()
      add_hook_to_module(A					,  A			)
      _a           =    test_model(A			)
      self.assertTrue(torch.allclose(A					,  output + 1					,  atol=1E-5			)			)

      # You need to use the sequential hook to chain two or more hooks
      _a           =    SequentialHook(PostForwardHook()					,  PostForwardHook()			)
      add_hook_to_module(A					,  A			)

      _a           =    test_model(A			)
      assert torch.allclose(A					,  output + 2					,  atol=1E-5			)



 def    a__    (self			)       ->	List[str]:


      """simple docstring"""



      _a           =    ModelForTest()
      _a           =    torch.randn(2					,  3			)
      _a           =    test_model(A			)

      _a           =    PostForwardHook()
      add_hook_to_module(A					,  A			)
      _a           =    test_model(A			)
      self.assertTrue(torch.allclose(A					,  output + 1			)			)
      self.assertTrue(outputa.requires_grad			)

      _a           =    True
      _a           =    test_model(A			)
      self.assertFalse(outputa.requires_grad			)



 @require_multi_gpu
 def    a__    (self			)       ->	List[Any]:


      """simple docstring"""



      _a           =    ModelForTest()
      # Everything is on CPU
      self.assertEqual(model.lineara.weight.device					,  torch.device('''cpu'''			)			)
      self.assertEqual(model.batchnorm.weight.device					,  torch.device('''cpu'''			)			)
      self.assertEqual(model.lineara.weight.device					,  torch.device('''cpu'''			)			)

      # This will move each submodule on different devices
      add_hook_to_module(model.lineara					,  AlignDevicesHook(execution_device=0			)			)
      add_hook_to_module(model.batchnorm					,  AlignDevicesHook(execution_device=0			)			)
      add_hook_to_module(model.lineara					,  AlignDevicesHook(execution_device=1			)			)

      self.assertEqual(model.lineara.weight.device					,  torch.device(0			)			)
      self.assertEqual(model.batchnorm.weight.device					,  torch.device(0			)			)
      self.assertEqual(model.batchnorm.running_mean.device					,  torch.device(0			)			)
      self.assertEqual(model.lineara.weight.device					,  torch.device(1			)			)

      # We can still make a forward pass. The input does not need to be on any particular device
      _a           =    torch.randn(2					,  3			)
      _a           =    model(A			)
      self.assertEqual(output.device					,  torch.device(1			)			)

      # We can add a general hook to put back output on same device as input.
      add_hook_to_module(A					,  AlignDevicesHook(io_same_device=A			)			)
      _a           =    torch.randn(2					,  3			).to(0			)
      _a           =    model(A			)
      self.assertEqual(output.device					,  torch.device(0			)			)



 def    a__    (self			)       ->	List[str]:


      """simple docstring"""



      _a           =    ModelForTest()

      # Everything is on CPU
      self.assertEqual(model.lineara.weight.device					,  torch.device('''cpu'''			)			)
      self.assertEqual(model.batchnorm.weight.device					,  torch.device('''cpu'''			)			)
      self.assertEqual(model.lineara.weight.device					,  torch.device('''cpu'''			)			)

      # This will move each submodule on different devices
      _a           =    {'''execution_device''': 0 if torch.cuda.is_available() else '''cpu''', '''offload''': True}

      add_hook_to_module(model.lineara					,  AlignDevicesHook(**A			)			)
      add_hook_to_module(model.batchnorm					,  AlignDevicesHook(**A			)			)
      add_hook_to_module(model.lineara					,  AlignDevicesHook(**A			)			)

      # Parameters have been offloaded, so on the meta device
      self.assertEqual(model.lineara.weight.device					,  torch.device('''meta'''			)			)
      self.assertEqual(model.batchnorm.weight.device					,  torch.device('''meta'''			)			)
      self.assertEqual(model.lineara.weight.device					,  torch.device('''meta'''			)			)
      # Buffers are not included in the offload by default, so are on the execution device
      _a           =    torch.device(hook_kwargs['''execution_device''']			)
      self.assertEqual(model.batchnorm.running_mean.device					,  A			)

      _a           =    torch.randn(2					,  3			)
      _a           =    model(A			)
      self.assertEqual(output.device					,  A			)

      # Removing hooks loads back the weights in the model.
      remove_hook_from_module(model.lineara			)
      remove_hook_from_module(model.batchnorm			)
      remove_hook_from_module(model.lineara			)
      self.assertEqual(model.lineara.weight.device					,  torch.device('''cpu'''			)			)
      self.assertEqual(model.batchnorm.weight.device					,  torch.device('''cpu'''			)			)
      self.assertEqual(model.lineara.weight.device					,  torch.device('''cpu'''			)			)

      # Now test with buffers included in the offload
      _a           =    {
          '''execution_device''': 0 if torch.cuda.is_available() else '''cpu''',
          '''offload''': True,
          '''offload_buffers''': True,
      }

      add_hook_to_module(model.lineara					,  AlignDevicesHook(**A			)			)
      add_hook_to_module(model.batchnorm					,  AlignDevicesHook(**A			)			)
      add_hook_to_module(model.lineara					,  AlignDevicesHook(**A			)			)

      # Parameters have been offloaded, so on the meta device, buffers included
      self.assertEqual(model.lineara.weight.device					,  torch.device('''meta'''			)			)
      self.assertEqual(model.batchnorm.weight.device					,  torch.device('''meta'''			)			)
      self.assertEqual(model.lineara.weight.device					,  torch.device('''meta'''			)			)
      self.assertEqual(model.batchnorm.running_mean.device					,  torch.device('''meta'''			)			)

      _a           =    torch.randn(2					,  3			)
      _a           =    model(A			)
      self.assertEqual(output.device					,  A			)

      # Removing hooks loads back the weights in the model.
      remove_hook_from_module(model.lineara			)
      remove_hook_from_module(model.batchnorm			)
      remove_hook_from_module(model.lineara			)
      self.assertEqual(model.lineara.weight.device					,  torch.device('''cpu'''			)			)
      self.assertEqual(model.batchnorm.weight.device					,  torch.device('''cpu'''			)			)
      self.assertEqual(model.lineara.weight.device					,  torch.device('''cpu'''			)			)



 def    a__    (self			)       ->	Optional[int]:


      """simple docstring"""



      _a           =    ModelForTest()

      # Everything is on CPU
      self.assertEqual(model.lineara.weight.device					,  torch.device('''cpu'''			)			)
      self.assertEqual(model.batchnorm.weight.device					,  torch.device('''cpu'''			)			)
      self.assertEqual(model.lineara.weight.device					,  torch.device('''cpu'''			)			)

      # This will move each submodule on different devices
      _a           =    0 if torch.cuda.is_available() else '''cpu'''
      attach_align_device_hook(A					,  execution_device=A					,  offload=A			)

      # Parameters have been offloaded, so on the meta device
      self.assertEqual(model.lineara.weight.device					,  torch.device('''meta'''			)			)
      self.assertEqual(model.batchnorm.weight.device					,  torch.device('''meta'''			)			)
      self.assertEqual(model.lineara.weight.device					,  torch.device('''meta'''			)			)
      # Buffers are not included in the offload by default, so are on the execution device
      _a           =    torch.device(A			)
      self.assertEqual(model.batchnorm.running_mean.device					,  A			)

      _a           =    torch.randn(2					,  3			)
      _a           =    model(A			)
      self.assertEqual(output.device					,  A			)

      # Removing hooks loads back the weights in the model.
      remove_hook_from_submodules(A			)
      self.assertEqual(model.lineara.weight.device					,  torch.device('''cpu'''			)			)
      self.assertEqual(model.batchnorm.weight.device					,  torch.device('''cpu'''			)			)
      self.assertEqual(model.lineara.weight.device					,  torch.device('''cpu'''			)			)

      # Now test with buffers included in the offload
      attach_align_device_hook(A					,  execution_device=A					,  offload=A					,  offload_buffers=A			)

      # Parameters have been offloaded, so on the meta device, buffers included
      self.assertEqual(model.lineara.weight.device					,  torch.device('''meta'''			)			)
      self.assertEqual(model.batchnorm.weight.device					,  torch.device('''meta'''			)			)
      self.assertEqual(model.lineara.weight.device					,  torch.device('''meta'''			)			)
      self.assertEqual(model.batchnorm.running_mean.device					,  torch.device('''meta'''			)			)

      _a           =    torch.randn(2					,  3			)
      _a           =    model(A			)
      self.assertEqual(output.device					,  A			)

      # Removing hooks loads back the weights in the model.
      remove_hook_from_submodules(A			)
      self.assertEqual(model.lineara.weight.device					,  torch.device('''cpu'''			)			)
      self.assertEqual(model.batchnorm.weight.device					,  torch.device('''cpu'''			)			)
      self.assertEqual(model.lineara.weight.device					,  torch.device('''cpu'''			)			)



 def    a__    (self			)       ->	Any:


      """simple docstring"""



      _a           =    ModelForTest()

      # Everything is on CPU
      self.assertEqual(model.lineara.weight.device					,  torch.device('''cpu'''			)			)
      self.assertEqual(model.batchnorm.weight.device					,  torch.device('''cpu'''			)			)
      self.assertEqual(model.lineara.weight.device					,  torch.device('''cpu'''			)			)

      # This will move each submodule on different devices
      _a           =    0 if torch.cuda.is_available() else '''cpu'''
      attach_align_device_hook(
          A					,  execution_device=A					,  offload=A					,  weights_map=model.state_dict()			)

      # Parameters have been offloaded, so on the meta device
      self.assertEqual(model.lineara.weight.device					,  torch.device('''meta'''			)			)
      self.assertEqual(model.batchnorm.weight.device					,  torch.device('''meta'''			)			)
      self.assertEqual(model.lineara.weight.device					,  torch.device('''meta'''			)			)
      # Buffers are not included in the offload by default, so are on the execution device
      _a           =    torch.device(A			)
      self.assertEqual(model.batchnorm.running_mean.device					,  A			)

      _a           =    torch.randn(2					,  3			)
      _a           =    model(A			)
      self.assertEqual(output.device					,  A			)

      # Removing hooks loads back the weights in the model.
      remove_hook_from_submodules(A			)
      self.assertEqual(model.lineara.weight.device					,  torch.device('''cpu'''			)			)
      self.assertEqual(model.batchnorm.weight.device					,  torch.device('''cpu'''			)			)
      self.assertEqual(model.lineara.weight.device					,  torch.device('''cpu'''			)			)

      # Now test with buffers included in the offload
      attach_align_device_hook(
          A					,  execution_device=A					,  offload=A					,  weights_map=model.state_dict()					,  offload_buffers=A					,  )

      # Parameters have been offloaded, so on the meta device, buffers included
      self.assertEqual(model.lineara.weight.device					,  torch.device('''meta'''			)			)
      self.assertEqual(model.batchnorm.weight.device					,  torch.device('''meta'''			)			)
      self.assertEqual(model.lineara.weight.device					,  torch.device('''meta'''			)			)
      self.assertEqual(model.batchnorm.running_mean.device					,  torch.device('''meta'''			)			)

      _a           =    torch.randn(2					,  3			)
      _a           =    model(A			)
      self.assertEqual(output.device					,  A			)

      # Removing hooks loads back the weights in the model.
      remove_hook_from_submodules(A			)
      self.assertEqual(model.lineara.weight.device					,  torch.device('''cpu'''			)			)
      self.assertEqual(model.batchnorm.weight.device					,  torch.device('''cpu'''			)			)
      self.assertEqual(model.lineara.weight.device					,  torch.device('''cpu'''			)			)



