



"""simple docstring"""
import logging
import math
from functools import partial
from typing import Any, Callable, Dict, Iterable, List, Optional, Sequence, Tuple, Union

import torch

from .tensor_utils import tensor_tree_map, tree_map


def 			_SCREAMING_SNAKE_CASE						(__lowerCAmelCase							) ->						List[Tuple[int, ...]]:







  '''simple docstring'''


  lowercase_								= []
  if isinstance(__lowerCAmelCase ,  __lowerCAmelCase							):
    for v in tree.values():
      shapes.extend(_fetch_dims(__lowerCAmelCase							)							)
  elif isinstance(__lowerCAmelCase ,  (list, tuple)							):
    for t in tree:
      shapes.extend(_fetch_dims(__lowerCAmelCase							)							)
  elif isinstance(__lowerCAmelCase ,  torch.Tensor							):
    shapes.append(tree.shape							)
  else:
    raise ValueError("""Not supported"""							)

  return shapes


@torch.jit.ignore
def 			_SCREAMING_SNAKE_CASE						(__lowerCAmelCase ,  __lowerCAmelCase							) ->						Tuple[int, ...]:







  '''simple docstring'''


  lowercase_								= []
  for d in reversed(__lowerCAmelCase							):
    idx.append(flat_idx % d							)
    lowercase_								= flat_idx // d

  return tuple(reversed(__lowerCAmelCase							)							)


@torch.jit.ignore
def 			_SCREAMING_SNAKE_CASE						(__lowerCAmelCase ,  __lowerCAmelCase ,  __lowerCAmelCase ,  __lowerCAmelCase = None ,  __lowerCAmelCase = None ,  ) ->						List[Tuple[slice, ...]]:







  '''simple docstring'''


  def reduce_edge_list(__lowerCAmelCase							) -> None:
    lowercase_								= True
    for i in range(len(__lowerCAmelCase							)							):
      lowercase_								= -1 * (i + 1)
      l[reversed_idx] &= tally
      lowercase_								= l[reversed_idx]

  if start_edges is None:
    lowercase_								= [s == 0 for s in start]
    reduce_edge_list(__lowerCAmelCase							)
  if end_edges is None:
    lowercase_								= [e == (d - 1) for e, d in zip(__lowerCAmelCase ,  __lowerCAmelCase							)]
    reduce_edge_list(__lowerCAmelCase							)

  # Base cases. Either start/end are empty and we're done, or the final,
  # one-dimensional tensor can be simply sliced
  if len(__lowerCAmelCase							) == 0:
    return [()]
  elif len(__lowerCAmelCase							) == 1:
    return [(slice(start[0] ,  end[0] + 1							),)]

  lowercase_								= []
  lowercase_								= []

  # Dimensions common to start and end can be selected directly
  for s, e in zip(__lowerCAmelCase ,  __lowerCAmelCase							):
    if s == e:
      path_list.append(slice(__lowerCAmelCase ,  s + 1							)							)
    else:
      break

  lowercase_								= tuple(__lowerCAmelCase							)
  lowercase_								= len(__lowerCAmelCase							)

  # start == end, and we're done
  if divergence_idx == len(__lowerCAmelCase							):
    return [path]

  def upper() -> Tuple[Tuple[slice, ...], ...]:
    assert start_edges is not None
    assert end_edges is not None

    lowercase_								= start[divergence_idx]
    return tuple(
        path + (slice(__lowerCAmelCase ,  sdi + 1							),) + s
        for s in _get_minimal_slice_set(
            start[divergence_idx + 1 :] ,  [d - 1 for d in dims[divergence_idx + 1 :]] ,  dims[divergence_idx + 1 :] ,  start_edges=start_edges[divergence_idx + 1 :] ,  end_edges=[True for _ in end_edges[divergence_idx + 1 :]] ,  )							)

  def lower() -> Tuple[Tuple[slice, ...], ...]:
    assert start_edges is not None
    assert end_edges is not None

    lowercase_								= end[divergence_idx]
    return tuple(
        path + (slice(__lowerCAmelCase ,  edi + 1							),) + s
        for s in _get_minimal_slice_set(
            [0 for _ in start[divergence_idx + 1 :]] ,  end[divergence_idx + 1 :] ,  dims[divergence_idx + 1 :] ,  start_edges=[True for _ in start_edges[divergence_idx + 1 :]] ,  end_edges=end_edges[divergence_idx + 1 :] ,  )							)

  # If both start and end are at the edges of the subtree rooted at
  # divergence_idx, we can just select the whole subtree at once
  if start_edges[divergence_idx] and end_edges[divergence_idx]:
    slices.append(path + (slice(start[divergence_idx] ,  end[divergence_idx] + 1							),)							)
  # If just start is at the edge, we can grab almost all of the subtree,
  # treating only the ragged bottom edge as an edge case
  elif start_edges[divergence_idx]:
    slices.append(path + (slice(start[divergence_idx] ,  end[divergence_idx]							),)							)
    slices.extend(lower()							)
  # Analogous to the previous case, but the top is ragged this time
  elif end_edges[divergence_idx]:
    slices.extend(upper()							)
    slices.append(path + (slice(start[divergence_idx] + 1 ,  end[divergence_idx] + 1							),)							)
  # If both sides of the range are ragged, we need to handle both sides
  # separately. If there's contiguous meat in between them, we can index it
  # in one big chunk
  else:
    slices.extend(upper()							)
    lowercase_								= end[divergence_idx] - start[divergence_idx]
    if middle_ground > 1:
      slices.append(path + (slice(start[divergence_idx] + 1 ,  end[divergence_idx]							),)							)
    slices.extend(lower()							)

  return slices


@torch.jit.ignore
def 			_SCREAMING_SNAKE_CASE						(__lowerCAmelCase ,  __lowerCAmelCase ,  __lowerCAmelCase ,  __lowerCAmelCase							) ->						torch.Tensor:







  '''simple docstring'''


  lowercase_								= t.shape[:no_batch_dims]
  lowercase_								= list(_flat_idx_to_idx(__lowerCAmelCase ,  __lowerCAmelCase							)							)
  # _get_minimal_slice_set is inclusive
  lowercase_								= list(_flat_idx_to_idx(flat_end - 1 ,  __lowerCAmelCase							)							)

  # Get an ordered list of slices to perform
  lowercase_								= _get_minimal_slice_set(
      __lowerCAmelCase ,  __lowerCAmelCase ,  __lowerCAmelCase ,  )

  lowercase_								= [t[s] for s in slices]

  return torch.cat([s.view((-1,) + t.shape[no_batch_dims:]							) for s in sliced_tensors]							)


def 			_SCREAMING_SNAKE_CASE						(__lowerCAmelCase ,  __lowerCAmelCase ,  __lowerCAmelCase ,  __lowerCAmelCase ,  __lowerCAmelCase = False ,  __lowerCAmelCase = None ,  __lowerCAmelCase = False ,  ) ->						Any:







  '''simple docstring'''


  if not (len(__lowerCAmelCase							) > 0):
    raise ValueError("""Must provide at least one input"""							)

  lowercase_								= [shape[:no_batch_dims] for shape in _fetch_dims(__lowerCAmelCase							)]
  lowercase_								= tuple([max(__lowerCAmelCase							) for s in zip(*__lowerCAmelCase							)]							)

  def _prep_inputs(__lowerCAmelCase							) -> torch.Tensor:
    if not low_mem:
      if not sum(t.shape[:no_batch_dims]							) == no_batch_dims:
        lowercase_								= t.expand(orig_batch_dims + t.shape[no_batch_dims:]							)
      lowercase_								= t.reshape(-1 ,  *t.shape[no_batch_dims:]							)
    else:
      lowercase_								= t.expand(orig_batch_dims + t.shape[no_batch_dims:]							)
    return t

  lowercase_								= tensor_tree_map(_prep_inputs ,  __lowerCAmelCase							)
  lowercase_								= None
  if _out is not None:
    lowercase_								= tensor_tree_map(lambda __lowerCAmelCase							: t.view([-1] + list(t.shape[no_batch_dims:]							)							) ,  _out							)

  lowercase_								= 1
  for d in orig_batch_dims:
    flat_batch_dim *= d

  lowercase_								= flat_batch_dim // chunk_size + (flat_batch_dim % chunk_size != 0)

  def _select_chunk(__lowerCAmelCase							) -> torch.Tensor:
    return t[i : i + chunk_size] if t.shape[0] != 1 else t

  lowercase_								= 0
  lowercase_								= prepped_outputs
  for _ in range(__lowerCAmelCase							):
    # Chunk the input
    if not low_mem:
      lowercase_								= _select_chunk
    else:
      lowercase_								= partial(
          _chunk_slice ,  flat_start=__lowerCAmelCase ,  flat_end=min(__lowerCAmelCase ,  i + chunk_size							) ,  no_batch_dims=len(__lowerCAmelCase							) ,  )

    lowercase_								= tensor_tree_map(__lowerCAmelCase ,  __lowerCAmelCase							)

    # Run the layer on the chunk
    lowercase_								= layer(**__lowerCAmelCase							)

    # Allocate space for the output
    if out is None:
      lowercase_								= tensor_tree_map(lambda __lowerCAmelCase							: t.new_zeros((flat_batch_dim,) + t.shape[1:]							) ,  __lowerCAmelCase							)

    # Put the chunk in its pre-allocated space
    if isinstance(__lowerCAmelCase ,  __lowerCAmelCase							):

      def assign(__lowerCAmelCase ,  __lowerCAmelCase							) -> None:
        for k, v in da.items():
          if isinstance(__lowerCAmelCase ,  __lowerCAmelCase							):
            assign(__lowerCAmelCase ,  da[k]							)
          else:
            if _add_into_out:
              v[i : i + chunk_size] += da[k]
            else:
              lowercase_								= da[k]

      assign(__lowerCAmelCase ,  __lowerCAmelCase							)
    elif isinstance(__lowerCAmelCase ,  __lowerCAmelCase							):
      for xa, xa in zip(__lowerCAmelCase ,  __lowerCAmelCase							):
        if _add_into_out:
          xa[i : i + chunk_size] += xa
        else:
          lowercase_								= xa
    elif isinstance(__lowerCAmelCase ,  torch.Tensor							):
      if _add_into_out:
        out[i : i + chunk_size] += output_chunk
      else:
        lowercase_								= output_chunk
    else:
      raise ValueError("""Not supported"""							)

    i += chunk_size

  lowercase_								= tensor_tree_map(lambda __lowerCAmelCase							: t.view(orig_batch_dims + t.shape[1:]							) ,  __lowerCAmelCase							)

  return out


class    SCREAMING_SNAKE_CASE__ :

    def __init__(				self			:				Tuple ,  lowerCAmelCase_			:				int = 5_1_2 ,  ):







      """simple docstring"""







      lowercase_								= max_chunk_size
      lowercase_								= None
      lowercase_								= None

    def 					_UpperCAmelCase	(				self			:				Optional[Any] ,  lowerCAmelCase_			:				Callable ,  lowerCAmelCase_			:				tuple ,  lowerCAmelCase_			:				int):







      """simple docstring"""







      logging.info("""Tuning chunk size...""")

      if min_chunk_size >= self.max_chunk_size:
        return min_chunk_size

      lowercase_								= [2**l for l in range(int(math.log(self.max_chunk_size ,  2)) + 1)]
      lowercase_								= [c for c in candidates if c > min_chunk_size]
      lowercase_								= [min_chunk_size] + candidates
      candidates[-1] += 4

      def test_chunk_size(lowerCAmelCase_			:				int) -> bool:
        try:
          with torch.no_grad():
            fn(*lowerCAmelCase_ ,  chunk_size=lowerCAmelCase_)
          return True
        except RuntimeError:
          return False

      lowercase_								= 0
      lowercase_								= len(lowerCAmelCase_) - 1
      while i > min_viable_chunk_size_index:
        lowercase_								= test_chunk_size(candidates[i])
        if not viable:
          lowercase_								= (min_viable_chunk_size_index + i) // 2
        else:
          lowercase_								= i
          lowercase_								= (i + len(lowerCAmelCase_) - 1) // 2

      return candidates[min_viable_chunk_size_index]

    def 					_UpperCAmelCase	(				self			:				Union[str, Any] ,  lowerCAmelCase_			:				Iterable ,  lowerCAmelCase_			:				Iterable):







      """simple docstring"""







      lowercase_								= True
      for aa, aa in zip(lowerCAmelCase_ ,  lowerCAmelCase_):
        assert type(lowerCAmelCase_) == type(lowerCAmelCase_)
        if isinstance(lowerCAmelCase_ ,  (list, tuple)):
          consistent &= self._compare_arg_caches(lowerCAmelCase_ ,  lowerCAmelCase_)
        elif isinstance(lowerCAmelCase_ ,  lowerCAmelCase_):
          lowercase_								= [v for _, v in sorted(aa.items() ,  key=lambda lowerCAmelCase_: x[0])]
          lowercase_								= [v for _, v in sorted(aa.items() ,  key=lambda lowerCAmelCase_: x[0])]
          consistent &= self._compare_arg_caches(lowerCAmelCase_ ,  lowerCAmelCase_)
        else:
          consistent &= aa == aa

      return consistent




    def 					_UpperCAmelCase	(				self			:				int ,  lowerCAmelCase_			:				Callable ,  lowerCAmelCase_			:				tuple ,  lowerCAmelCase_			:				int ,  ):







      """simple docstring"""







      lowercase_								= True
      lowercase_								= tree_map(lambda lowerCAmelCase_: a.shape if isinstance(lowerCAmelCase_ ,  torch.Tensor) else a ,  lowerCAmelCase_ ,  lowerCAmelCase_)
      if self.cached_arg_data is not None:
        # If args have changed shape/value, we need to re-tune
        assert len(self.cached_arg_data) == len(lowerCAmelCase_)
        lowercase_								= self._compare_arg_caches(self.cached_arg_data ,  lowerCAmelCase_)
      else:
        # Otherwise, we can reuse the precomputed value
        lowercase_								= False

      if not consistent:
        lowercase_								= self._determine_favorable_chunk_size(
            lowerCAmelCase_ ,  lowerCAmelCase_ ,  lowerCAmelCase_ ,  )
        lowercase_								= arg_data

      assert self.cached_chunk_size is not None

      return self.cached_chunk_size






"""simple docstring"""
import unittest

from transformers import MODEL_FOR_ZERO_SHOT_OBJECT_DETECTION_MAPPING, is_vision_available, pipeline
from transformers.testing_utils import (
    is_pipeline_test,
    nested_simplify,
    require_tf,
    require_torch,
    require_vision,
    slow,
)

from .test_pipelines_common import ANY


if is_vision_available():
       from PIL import Image
else:


       class    SCREAMING_SNAKE_CASE__ :

           @staticmethod
           def 					_UpperCAmelCase	(				*lowerCAmelCase_			:				Tuple ,  **lowerCAmelCase_			:				Tuple):







             """simple docstring"""







             pass


@is_pipeline_test
@require_vision
@require_torch
class    SCREAMING_SNAKE_CASE__ (							unittest.TestCase   ):
    lowercase__      =   MODEL_FOR_ZERO_SHOT_OBJECT_DETECTION_MAPPING

    def 					_UpperCAmelCase	(				self			:				Optional[Any] ,  lowerCAmelCase_			:				int ,  lowerCAmelCase_			:				int ,  lowerCAmelCase_			:				List[Any]):







      """simple docstring"""







      lowercase_								= pipeline(
          """zero-shot-object-detection""" ,  model="""hf-internal-testing/tiny-random-owlvit-object-detection""")

      lowercase_								= [
          {
              """image""": """./tests/fixtures/tests_samples/COCO/000000039769.png""",
              """candidate_labels""": ["""cat""", """remote""", """couch"""],
          }
      ]
      return object_detector, examples

    def 					_UpperCAmelCase	(				self			:				Optional[Any] ,  lowerCAmelCase_			:				int ,  lowerCAmelCase_			:				Optional[Any]):







      """simple docstring"""







      lowercase_								= object_detector(examples[0] ,  threshold=0.0)

      lowercase_								= len(lowerCAmelCase_)
      self.assertGreater(lowerCAmelCase_ ,  0)
      self.assertEqual(
          lowerCAmelCase_ ,  [
              {
                  """score""": ANY(lowerCAmelCase_),
                  """label""": ANY(lowerCAmelCase_),
                  """box""": {"""xmin""": ANY(lowerCAmelCase_), """ymin""": ANY(lowerCAmelCase_), """xmax""": ANY(lowerCAmelCase_), """ymax""": ANY(lowerCAmelCase_)},
              }
              for i in range(lowerCAmelCase_)
          ] ,  )

    @require_tf
    @unittest.skip("""Zero Shot Object Detection not implemented in TF""")
    def 					_UpperCAmelCase	(				self			:				Any):







      """simple docstring"""







      pass

    @require_torch
    def 					_UpperCAmelCase	(				self			:				List[Any]):







      """simple docstring"""







      lowercase_								= pipeline(
          """zero-shot-object-detection""" ,  model="""hf-internal-testing/tiny-random-owlvit-object-detection""")

      lowercase_								= object_detector(
          """./tests/fixtures/tests_samples/COCO/000000039769.png""" ,  candidate_labels=["""cat""", """remote""", """couch"""] ,  threshold=0.64 ,  )

      self.assertEqual(
          nested_simplify(lowerCAmelCase_ ,  decimals=4) ,  [
              {"""score""": 0.7_235, """label""": """cat""", """box""": {"""xmin""": 2_0_4, """ymin""": 1_6_7, """xmax""": 2_3_2, """ymax""": 1_9_0}},
              {"""score""": 0.7_218, """label""": """remote""", """box""": {"""xmin""": 2_0_4, """ymin""": 1_6_7, """xmax""": 2_3_2, """ymax""": 1_9_0}},
              {"""score""": 0.7_184, """label""": """couch""", """box""": {"""xmin""": 2_0_4, """ymin""": 1_6_7, """xmax""": 2_3_2, """ymax""": 1_9_0}},
              {"""score""": 0.6_748, """label""": """remote""", """box""": {"""xmin""": 5_7_1, """ymin""": 8_3, """xmax""": 5_9_8, """ymax""": 1_0_3}},
              {"""score""": 0.6_656, """label""": """cat""", """box""": {"""xmin""": 5_7_1, """ymin""": 8_3, """xmax""": 5_9_8, """ymax""": 1_0_3}},
              {"""score""": 0.6_614, """label""": """couch""", """box""": {"""xmin""": 5_7_1, """ymin""": 8_3, """xmax""": 5_9_8, """ymax""": 1_0_3}},
              {"""score""": 0.6_456, """label""": """remote""", """box""": {"""xmin""": 4_9_4, """ymin""": 1_0_5, """xmax""": 5_2_1, """ymax""": 1_2_7}},
              {"""score""": 0.642, """label""": """remote""", """box""": {"""xmin""": 6_7, """ymin""": 2_7_4, """xmax""": 9_3, """ymax""": 2_9_7}},
              {"""score""": 0.6_419, """label""": """cat""", """box""": {"""xmin""": 4_9_4, """ymin""": 1_0_5, """xmax""": 5_2_1, """ymax""": 1_2_7}},
          ] ,  )

      lowercase_								= object_detector(
          [
              {
                  """image""": """./tests/fixtures/tests_samples/COCO/000000039769.png""",
                  """candidate_labels""": ["""cat""", """remote""", """couch"""],
              }
          ] ,  threshold=0.64 ,  )

      self.assertEqual(
          nested_simplify(lowerCAmelCase_ ,  decimals=4) ,  [
              [
                  {"""score""": 0.7_235, """label""": """cat""", """box""": {"""xmin""": 2_0_4, """ymin""": 1_6_7, """xmax""": 2_3_2, """ymax""": 1_9_0}},
                  {"""score""": 0.7_218, """label""": """remote""", """box""": {"""xmin""": 2_0_4, """ymin""": 1_6_7, """xmax""": 2_3_2, """ymax""": 1_9_0}},
                  {"""score""": 0.7_184, """label""": """couch""", """box""": {"""xmin""": 2_0_4, """ymin""": 1_6_7, """xmax""": 2_3_2, """ymax""": 1_9_0}},
                  {"""score""": 0.6_748, """label""": """remote""", """box""": {"""xmin""": 5_7_1, """ymin""": 8_3, """xmax""": 5_9_8, """ymax""": 1_0_3}},
                  {"""score""": 0.6_656, """label""": """cat""", """box""": {"""xmin""": 5_7_1, """ymin""": 8_3, """xmax""": 5_9_8, """ymax""": 1_0_3}},
                  {"""score""": 0.6_614, """label""": """couch""", """box""": {"""xmin""": 5_7_1, """ymin""": 8_3, """xmax""": 5_9_8, """ymax""": 1_0_3}},
                  {"""score""": 0.6_456, """label""": """remote""", """box""": {"""xmin""": 4_9_4, """ymin""": 1_0_5, """xmax""": 5_2_1, """ymax""": 1_2_7}},
                  {"""score""": 0.642, """label""": """remote""", """box""": {"""xmin""": 6_7, """ymin""": 2_7_4, """xmax""": 9_3, """ymax""": 2_9_7}},
                  {"""score""": 0.6_419, """label""": """cat""", """box""": {"""xmin""": 4_9_4, """ymin""": 1_0_5, """xmax""": 5_2_1, """ymax""": 1_2_7}},
              ]
          ] ,  )

    @require_torch
    @slow
    def 					_UpperCAmelCase	(				self			:				Dict):







      """simple docstring"""







      lowercase_								= pipeline("""zero-shot-object-detection""")

      lowercase_								= object_detector(
          """http://images.cocodataset.org/val2017/000000039769.jpg""" ,  candidate_labels=["""cat""", """remote""", """couch"""] ,  )
      self.assertEqual(
          nested_simplify(lowerCAmelCase_ ,  decimals=4) ,  [
              {"""score""": 0.2_868, """label""": """cat""", """box""": {"""xmin""": 3_2_4, """ymin""": 2_0, """xmax""": 6_4_0, """ymax""": 3_7_3}},
              {"""score""": 0.277, """label""": """remote""", """box""": {"""xmin""": 4_0, """ymin""": 7_2, """xmax""": 1_7_7, """ymax""": 1_1_5}},
              {"""score""": 0.2_537, """label""": """cat""", """box""": {"""xmin""": 1, """ymin""": 5_5, """xmax""": 3_1_5, """ymax""": 4_7_2}},
              {"""score""": 0.1_474, """label""": """remote""", """box""": {"""xmin""": 3_3_5, """ymin""": 7_4, """xmax""": 3_7_1, """ymax""": 1_8_7}},
              {"""score""": 0.1_208, """label""": """couch""", """box""": {"""xmin""": 4, """ymin""": 0, """xmax""": 6_4_2, """ymax""": 4_7_6}},
          ] ,  )

      lowercase_								= object_detector(
          [
              {
                  """image""": """http://images.cocodataset.org/val2017/000000039769.jpg""",
                  """candidate_labels""": ["""cat""", """remote""", """couch"""],
              },
              {
                  """image""": """http://images.cocodataset.org/val2017/000000039769.jpg""",
                  """candidate_labels""": ["""cat""", """remote""", """couch"""],
              },
          ] ,  )
      self.assertEqual(
          nested_simplify(lowerCAmelCase_ ,  decimals=4) ,  [
              [
                  {"""score""": 0.2_868, """label""": """cat""", """box""": {"""xmin""": 3_2_4, """ymin""": 2_0, """xmax""": 6_4_0, """ymax""": 3_7_3}},
                  {"""score""": 0.277, """label""": """remote""", """box""": {"""xmin""": 4_0, """ymin""": 7_2, """xmax""": 1_7_7, """ymax""": 1_1_5}},
                  {"""score""": 0.2_537, """label""": """cat""", """box""": {"""xmin""": 1, """ymin""": 5_5, """xmax""": 3_1_5, """ymax""": 4_7_2}},
                  {"""score""": 0.1_474, """label""": """remote""", """box""": {"""xmin""": 3_3_5, """ymin""": 7_4, """xmax""": 3_7_1, """ymax""": 1_8_7}},
                  {"""score""": 0.1_208, """label""": """couch""", """box""": {"""xmin""": 4, """ymin""": 0, """xmax""": 6_4_2, """ymax""": 4_7_6}},
              ],
              [
                  {"""score""": 0.2_868, """label""": """cat""", """box""": {"""xmin""": 3_2_4, """ymin""": 2_0, """xmax""": 6_4_0, """ymax""": 3_7_3}},
                  {"""score""": 0.277, """label""": """remote""", """box""": {"""xmin""": 4_0, """ymin""": 7_2, """xmax""": 1_7_7, """ymax""": 1_1_5}},
                  {"""score""": 0.2_537, """label""": """cat""", """box""": {"""xmin""": 1, """ymin""": 5_5, """xmax""": 3_1_5, """ymax""": 4_7_2}},
                  {"""score""": 0.1_474, """label""": """remote""", """box""": {"""xmin""": 3_3_5, """ymin""": 7_4, """xmax""": 3_7_1, """ymax""": 1_8_7}},
                  {"""score""": 0.1_208, """label""": """couch""", """box""": {"""xmin""": 4, """ymin""": 0, """xmax""": 6_4_2, """ymax""": 4_7_6}},
              ],
          ] ,  )

    @require_tf
    @unittest.skip("""Zero Shot Object Detection not implemented in TF""")
    def 					_UpperCAmelCase	(				self			:				List[Any]):







      """simple docstring"""







      pass

    @require_torch
    @slow
    def 					_UpperCAmelCase	(				self			:				List[str]):







      """simple docstring"""







      lowercase_								= 0.2
      lowercase_								= pipeline("""zero-shot-object-detection""")

      lowercase_								= object_detector(
          """http://images.cocodataset.org/val2017/000000039769.jpg""" ,  candidate_labels=["""cat""", """remote""", """couch"""] ,  threshold=lowerCAmelCase_ ,  )
      self.assertEqual(
          nested_simplify(lowerCAmelCase_ ,  decimals=4) ,  [
              {"""score""": 0.2_868, """label""": """cat""", """box""": {"""xmin""": 3_2_4, """ymin""": 2_0, """xmax""": 6_4_0, """ymax""": 3_7_3}},
              {"""score""": 0.277, """label""": """remote""", """box""": {"""xmin""": 4_0, """ymin""": 7_2, """xmax""": 1_7_7, """ymax""": 1_1_5}},
              {"""score""": 0.2_537, """label""": """cat""", """box""": {"""xmin""": 1, """ymin""": 5_5, """xmax""": 3_1_5, """ymax""": 4_7_2}},
          ] ,  )




    @require_torch
    @slow
    def 					_UpperCAmelCase	(				self			:				Any):







      """simple docstring"""







      lowercase_								= 2
      lowercase_								= pipeline("""zero-shot-object-detection""")

      lowercase_								= object_detector(
          """http://images.cocodataset.org/val2017/000000039769.jpg""" ,  candidate_labels=["""cat""", """remote""", """couch"""] ,  top_k=lowerCAmelCase_ ,  )
      self.assertEqual(
          nested_simplify(lowerCAmelCase_ ,  decimals=4) ,  [
              {"""score""": 0.2_868, """label""": """cat""", """box""": {"""xmin""": 3_2_4, """ymin""": 2_0, """xmax""": 6_4_0, """ymax""": 3_7_3}},
              {"""score""": 0.277, """label""": """remote""", """box""": {"""xmin""": 4_0, """ymin""": 7_2, """xmax""": 1_7_7, """ymax""": 1_1_5}},
          ] ,  )

