

"""simple docstring"""


import unittest

import numpy as np
import torch

from diffusers import DDIMPipeline, DDIMScheduler, UNetaDModel
from diffusers.utils.testing_utils import enable_full_determinism, require_torch_gpu, slow, torch_device

from ..pipeline_params import UNCONDITIONAL_IMAGE_GENERATION_BATCH_PARAMS, UNCONDITIONAL_IMAGE_GENERATION_PARAMS
from ..test_pipelines_common import PipelineTesterMixin


enable_full_determinism()





class lowerCamelCase__   (				SCREAMING_SNAKE_CASE     ,   unittest.TestCase    ):



    '''simple docstring'''




    _lowerCamelCase					=   DDIMPipeline
    _lowerCamelCase					=   UNCONDITIONAL_IMAGE_GENERATION_PARAMS
    _lowerCamelCase					=   PipelineTesterMixin.required_optional_params - {
        '''num_images_per_prompt''',
        '''latents''',
        '''callback''',
        '''callback_steps''',
    }
    _lowerCamelCase					=   UNCONDITIONAL_IMAGE_GENERATION_BATCH_PARAMS
    _lowerCamelCase					=   False




    def UpperCamelCase__		( self    )    ->      Union[str, Any]:
          torch.manual_seed(0    )
          A				  =		UNetaDModel(
              block_out_channels=(3_2, 6_4) ,layers_per_block=2 ,sample_size=3_2 ,in_channels=3 ,out_channels=3 ,down_block_types=("""DownBlock2D""", """AttnDownBlock2D""") ,up_block_types=("""AttnUpBlock2D""", """UpBlock2D""") ,)
          A				  =		DDIMScheduler()
          A				  =		{"""unet""": unet, """scheduler""": scheduler}
          return components




    def UpperCamelCase__		( self ,lowerCamelCase_ ,lowerCamelCase_=0    )    ->      Any:
          if str(lowerCamelCase_    ).startswith("""mps"""    ):
                A				  =		torch.manual_seed(lowerCamelCase_    )
          else:
                A				  =		torch.Generator(device=lowerCamelCase_    ).manual_seed(lowerCamelCase_    )
          A				  =		{
              """batch_size""": 1,
              """generator""": generator,
              """num_inference_steps""": 2,
              """output_type""": """numpy""",
          }
          return inputs




    def UpperCamelCase__		( self    )    ->      Dict:
          A				  =		"""cpu"""

          A				  =		self.get_dummy_components()
          A				  =		self.pipeline_class(**lowerCamelCase_    )
          pipe.to(lowerCamelCase_    )
          pipe.set_progress_bar_config(disable=lowerCamelCase_    )

          A				  =		self.get_dummy_inputs(lowerCamelCase_    )
          A				  =		pipe(**lowerCamelCase_    ).images
          A				  =		image[0, -3:, -3:, -1]

          self.assertEqual(image.shape ,(1, 3_2, 3_2, 3)    )
          A				  =		np.array(
              [1.000E00, 5.717E-01, 4.717E-01, 1.000E00, 0.000E00, 1.000E00, 3.000E-04, 0.000E00, 9.000E-04]    )
          A				  =		np.abs(image_slice.flatten() - expected_slice    ).max()
          self.assertLessEqual(lowerCamelCase_ ,1E-3    )




    def UpperCamelCase__		( self    )    ->      List[Any]:
          super().test_dict_tuple_outputs_equivalent(expected_max_difference=3E-3    )




    def UpperCamelCase__		( self    )    ->      Optional[Any]:
          super().test_save_load_local(expected_max_difference=3E-3    )




    def UpperCamelCase__		( self    )    ->      Optional[int]:
          super().test_save_load_optional_components(expected_max_difference=3E-3    )




    def UpperCamelCase__		( self    )    ->      Optional[int]:
          super().test_inference_batch_single_identical(expected_max_diff=3E-3    )





@slow
@require_torch_gpu
class lowerCamelCase__   (				unittest.TestCase    ):



    '''simple docstring'''




    def UpperCamelCase__		( self    )    ->      Optional[Any]:
          A				  =		"""google/ddpm-cifar10-32"""

          A				  =		UNetaDModel.from_pretrained(lowerCamelCase_    )
          A				  =		DDIMScheduler()

          A				  =		DDIMPipeline(unet=lowerCamelCase_ ,scheduler=lowerCamelCase_    )
          ddim.to(lowerCamelCase_    )
          ddim.set_progress_bar_config(disable=lowerCamelCase_    )

          A				  =		torch.manual_seed(0    )
          A				  =		ddim(generator=lowerCamelCase_ ,eta=0.0 ,output_type="""numpy"""    ).images

          A				  =		image[0, -3:, -3:, -1]

          assert image.shape == (1, 3_2, 3_2, 3)
          A				  =		np.array([0.17_23, 0.16_17, 0.16_00, 0.16_26, 0.14_97, 0.15_13, 0.15_05, 0.14_42, 0.14_53]    )

          assert np.abs(image_slice.flatten() - expected_slice    ).max() < 1E-2




    def UpperCamelCase__		( self    )    ->      int:
          A				  =		"""google/ddpm-ema-bedroom-256"""

          A				  =		UNetaDModel.from_pretrained(lowerCamelCase_    )
          A				  =		DDIMScheduler.from_pretrained(lowerCamelCase_    )

          A				  =		DDIMPipeline(unet=lowerCamelCase_ ,scheduler=lowerCamelCase_    )
          ddpm.to(lowerCamelCase_    )
          ddpm.set_progress_bar_config(disable=lowerCamelCase_    )

          A				  =		torch.manual_seed(0    )
          A				  =		ddpm(generator=lowerCamelCase_ ,output_type="""numpy"""    ).images

          A				  =		image[0, -3:, -3:, -1]

          assert image.shape == (1, 2_5_6, 2_5_6, 3)
          A				  =		np.array([0.00_60, 0.02_01, 0.03_44, 0.00_24, 0.00_18, 0.00_02, 0.00_22, 0.00_00, 0.00_69]    )

          assert np.abs(image_slice.flatten() - expected_slice    ).max() < 1E-2







"""simple docstring"""


import functools
import gc
import inspect

import torch

from .imports import is_npu_available, is_xpu_available



def   _A					(	*_a	:						int				):



      """simple docstring"""






      if not isinstance(_a     ,   _a				):
            A				  =		list(_a				)
      for i in range(len(_a				)				):
            A				  =		None
      gc.collect()
      if is_xpu_available():
            torch.xpu.empty_cache()
      elif is_npu_available():
            torch.npu.empty_cache()
      else:
            torch.cuda.empty_cache()
      return objects



def   _A					(	_a	:						Exception				):



      """simple docstring"""






      A				  =		[
          """CUDA out of memory.""",  # CUDA OOM
          """cuDNN error: CUDNN_STATUS_NOT_SUPPORTED.""",  # CUDNN SNAFU
          """DefaultCPUAllocator: can't allocate memory""",  # CPU OOM
      ]
      if isinstance(_a     ,   _a				) and len(exception.args				) == 1:
            return any(err in exception.args[0] for err in _statements				)
      return False





def   _A					(	_a	:						callable = None     ,   _a	:						int = 1_2_8				):



      """simple docstring"""






      if function is None:
            return functools.partial(_a     ,   starting_batch_size=_a				)

      A				  =		starting_batch_size

      def decorator(*_a	:						Union[str, Any]     ,   **_a	:						List[Any]				):
            nonlocal batch_size
            gc.collect()
            if is_xpu_available():
                  torch.xpu.empty_cache()
            elif is_npu_available():
                  torch.npu.empty_cache()
            else:
                  torch.cuda.empty_cache()
            A				  =		list(inspect.signature(_a				).parameters.keys()				)
            # Guard against user error
            if len(_a				) < (len(_a				) + 1):
                  A				  =		""", """.join([f'{arg}={value}' for arg, value in zip(params[1:]     ,   args[1:]				)]				)
                  raise TypeError(
                      f'Batch size was passed into `{function.__name__}` as the first argument when called.'
                      f'Remove this as the decorator already does so: `{function.__name__}({arg_str})`'				)
            while True:
                  if batch_size == 0:
                        raise RuntimeError("""No executable batch size found, reached zero."""				)
                  try:
                        return function(_a     ,   *_a     ,   **_a				)
                  except Exception as e:
                        if should_reduce_batch_size(_a				):
                              gc.collect()
                              if is_xpu_available():
                                    torch.xpu.empty_cache()
                              elif is_npu_available():
                                    torch.npu.empty_cache()
                              else:
                                    torch.cuda.empty_cache()
                              batch_size //= 2
                        else:
                              raise

      return decorator




