

import gc
import random
import unittest

import numpy as np
import torch
from transformers import CLIPTextConfig, CLIPTextModel, CLIPTokenizer

from diffusers import AutoencoderKL, CycleDiffusionPipeline, DDIMScheduler, UNetaDConditionModel
from diffusers.utils import floats_tensor, load_image, load_numpy, slow, torch_device
from diffusers.utils.testing_utils import enable_full_determinism, require_torch_gpu, skip_mps

from ..pipeline_params import (
    IMAGE_TO_IMAGE_IMAGE_PARAMS,
    TEXT_GUIDED_IMAGE_VARIATION_BATCH_PARAMS,
    TEXT_GUIDED_IMAGE_VARIATION_PARAMS,
)
from ..test_pipelines_common import PipelineLatentTesterMixin, PipelineTesterMixin


enable_full_determinism()






class        A_		(       SCREAMING_SNAKE_CASE			,							SCREAMING_SNAKE_CASE			,							unittest.TestCase				):
							_UpperCAmelCase    :  Union[str, Any]						      =      CycleDiffusionPipeline
							_UpperCAmelCase    :  Tuple						      =      TEXT_GUIDED_IMAGE_VARIATION_PARAMS - {
							    '''negative_prompt''',
							    '''height''',
							    '''width''',
							    '''negative_prompt_embeds''',
							}
							_UpperCAmelCase    :  int						      =      PipelineTesterMixin.required_optional_params - {'''latents'''}
							_UpperCAmelCase    :  Dict						      =      TEXT_GUIDED_IMAGE_VARIATION_BATCH_PARAMS.union({'''source_prompt'''}				)
							_UpperCAmelCase    :  Union[str, Any]						      =      IMAGE_TO_IMAGE_IMAGE_PARAMS
							_UpperCAmelCase    :  List[str]						      =      IMAGE_TO_IMAGE_IMAGE_PARAMS
							def     lowerCAmelCase     (		self		:			Optional[int]):
								torch.manual_seed(0)
								__lowerCamelCase				:				Tuple					       = UNetaDConditionModel(
								    block_out_channels=(3_2, 6_4)   ,layers_per_block=2   ,sample_size=3_2   ,in_channels=4   ,out_channels=4   ,down_block_types=('DownBlock2D', 'CrossAttnDownBlock2D')   ,up_block_types=('CrossAttnUpBlock2D', 'UpBlock2D')   ,cross_attention_dim=3_2   ,)
								__lowerCamelCase				:				Optional[int]					       = DDIMScheduler(
								    beta_start=0.00085   ,beta_end=0.012   ,beta_schedule='scaled_linear'   ,num_train_timesteps=1_0_0_0   ,clip_sample=SCREAMING_SNAKE_CASE__   ,set_alpha_to_one=SCREAMING_SNAKE_CASE__   ,)
								torch.manual_seed(0)
								__lowerCamelCase				:				str					       = AutoencoderKL(
								    block_out_channels=[3_2, 6_4]   ,in_channels=3   ,out_channels=3   ,down_block_types=['DownEncoderBlock2D', 'DownEncoderBlock2D']   ,up_block_types=['UpDecoderBlock2D', 'UpDecoderBlock2D']   ,latent_channels=4   ,)
								torch.manual_seed(0)
								__lowerCamelCase				:				List[Any]					       = CLIPTextConfig(
								    bos_token_id=0   ,eos_token_id=2   ,hidden_size=3_2   ,intermediate_size=3_7   ,layer_norm_eps=1E-05   ,num_attention_heads=4   ,num_hidden_layers=5   ,pad_token_id=1   ,vocab_size=1_0_0_0   ,)
								__lowerCamelCase				:				int					       = CLIPTextModel(SCREAMING_SNAKE_CASE__)
								__lowerCamelCase				:				List[Any]					       = CLIPTokenizer.from_pretrained('hf-internal-testing/tiny-random-clip')

								__lowerCamelCase				:				Tuple					       = {
								    'unet': unet,
								    'scheduler': scheduler,
								    'vae': vae,
								    'text_encoder': text_encoder,
								    'tokenizer': tokenizer,
								    'safety_checker': None,
								    'feature_extractor': None,
								}
								return components
							def     lowerCAmelCase     (		self		:			List[Any]   ,SCREAMING_SNAKE_CASE__		:			List[Any]   ,SCREAMING_SNAKE_CASE__		:			List[str]=0):
								__lowerCamelCase				:				str					       = floats_tensor((1, 3, 3_2, 3_2)   ,rng=random.Random(SCREAMING_SNAKE_CASE__)).to(SCREAMING_SNAKE_CASE__)
								__lowerCamelCase				:				Optional[int]					       = image / 2 + 0.5
								if str(SCREAMING_SNAKE_CASE__).startswith('mps'):
									__lowerCamelCase				:				List[str]					       = torch.manual_seed(SCREAMING_SNAKE_CASE__)
								else:
									__lowerCamelCase				:				Tuple					       = torch.Generator(device=SCREAMING_SNAKE_CASE__).manual_seed(SCREAMING_SNAKE_CASE__)
								__lowerCamelCase				:				Tuple					       = {
								    'prompt': 'An astronaut riding an elephant',
								    'source_prompt': 'An astronaut riding a horse',
								    'image': image,
								    'generator': generator,
								    'num_inference_steps': 2,
								    'eta': 0.1,
								    'strength': 0.8,
								    'guidance_scale': 3,
								    'source_guidance_scale': 1,
								    'output_type': 'numpy',
								}
								return inputs
							def     lowerCAmelCase     (		self		:			Optional[Any]):
								__lowerCamelCase				:				int					       = 'cpu'  # ensure determinism for the device-dependent torch.Generator

								__lowerCamelCase				:				Dict					       = self.get_dummy_components()
								__lowerCamelCase				:				Dict					       = CycleDiffusionPipeline(**SCREAMING_SNAKE_CASE__)
								__lowerCamelCase				:				List[str]					       = pipe.to(SCREAMING_SNAKE_CASE__)
								pipe.set_progress_bar_config(disable=SCREAMING_SNAKE_CASE__)

								__lowerCamelCase				:				int					       = self.get_dummy_inputs(SCREAMING_SNAKE_CASE__)
								__lowerCamelCase				:				Any					       = pipe(**SCREAMING_SNAKE_CASE__)
								__lowerCamelCase				:				str					       = output.images

								__lowerCamelCase				:				Tuple					       = images[0, -3:, -3:, -1]

								assert images.shape == (1, 3_2, 3_2, 3)
								__lowerCamelCase				:				Optional[int]					       = np.array([0.4459, 0.4943, 0.4544, 0.6643, 0.5474, 0.4327, 0.5701, 0.5959, 0.5179])

								assert np.abs(image_slice.flatten() - expected_slice).max() < 1E-2
							@unittest.skipIf(torch_device != 'cuda'   ,'This test requires a GPU')
							def     lowerCAmelCase     (		self		:			str):
								__lowerCamelCase				:				Any					       = self.get_dummy_components()
								for name, module in components.items():
									if hasattr(SCREAMING_SNAKE_CASE__   ,'half'):
										__lowerCamelCase				:				Any					       = module.half()
								__lowerCamelCase				:				Union[str, Any]					       = CycleDiffusionPipeline(**SCREAMING_SNAKE_CASE__)
								__lowerCamelCase				:				int					       = pipe.to(SCREAMING_SNAKE_CASE__)
								pipe.set_progress_bar_config(disable=SCREAMING_SNAKE_CASE__)

								__lowerCamelCase				:				Union[str, Any]					       = self.get_dummy_inputs(SCREAMING_SNAKE_CASE__)
								__lowerCamelCase				:				Tuple					       = pipe(**SCREAMING_SNAKE_CASE__)
								__lowerCamelCase				:				int					       = output.images

								__lowerCamelCase				:				Any					       = images[0, -3:, -3:, -1]

								assert images.shape == (1, 3_2, 3_2, 3)
								__lowerCamelCase				:				Optional[int]					       = np.array([0.3506, 0.4543, 0.446, 0.4575, 0.5195, 0.4155, 0.5273, 0.518, 0.4116])

								assert np.abs(image_slice.flatten() - expected_slice).max() < 1E-2
							@skip_mps
							def     lowerCAmelCase     (		self		:			Dict):
								return super().test_save_load_local()
							@unittest.skip('non-deterministic pipeline')
							def     lowerCAmelCase     (		self		:			Optional[Any]):
								return super().test_inference_batch_single_identical()
							@skip_mps
							def     lowerCAmelCase     (		self		:			Any):
								return super().test_dict_tuple_outputs_equivalent()
							@skip_mps
							def     lowerCAmelCase     (		self		:			Optional[Any]):
								return super().test_save_load_optional_components()


							@skip_mps
							def     lowerCAmelCase     (		self		:			Tuple):
								return super().test_attention_slicing_forward_pass()






@slow
@require_torch_gpu
class        A_		(       unittest.TestCase				):
							def     lowerCAmelCase     (		self		:			List[Any]):
								# clean up the VRAM after each test
								super().tearDown()
								gc.collect()
								torch.cuda.empty_cache()
							def     lowerCAmelCase     (		self		:			Union[str, Any]):
								__lowerCamelCase				:				Tuple					       = load_image(
								    'https://huggingface.co/datasets/hf-internal-testing/diffusers-images/resolve/main'
								    '/cycle-diffusion/black_colored_car.png')
								__lowerCamelCase				:				Tuple					       = load_numpy(
								    'https://huggingface.co/datasets/hf-internal-testing/diffusers-images/resolve/main/cycle-diffusion/blue_colored_car_fp16.npy')
								__lowerCamelCase				:				Optional[int]					       = init_image.resize((5_1_2, 5_1_2))

								__lowerCamelCase				:				Optional[int]					       = 'CompVis/stable-diffusion-v1-4'
								__lowerCamelCase				:				Tuple					       = DDIMScheduler.from_pretrained(SCREAMING_SNAKE_CASE__   ,subfolder='scheduler')
								__lowerCamelCase				:				Optional[int]					       = CycleDiffusionPipeline.from_pretrained(
								    SCREAMING_SNAKE_CASE__   ,scheduler=SCREAMING_SNAKE_CASE__   ,safety_checker=SCREAMING_SNAKE_CASE__   ,torch_dtype=torch.floataa   ,revision='fp16')

								pipe.to(SCREAMING_SNAKE_CASE__)
								pipe.set_progress_bar_config(disable=SCREAMING_SNAKE_CASE__)
								pipe.enable_attention_slicing()

								__lowerCamelCase				:				Union[str, Any]					       = 'A black colored car'
								__lowerCamelCase				:				Optional[int]					       = 'A blue colored car'

								__lowerCamelCase				:				List[Any]					       = torch.manual_seed(0)
								__lowerCamelCase				:				Union[str, Any]					       = pipe(
								    prompt=SCREAMING_SNAKE_CASE__   ,source_prompt=SCREAMING_SNAKE_CASE__   ,image=SCREAMING_SNAKE_CASE__   ,num_inference_steps=1_0_0   ,eta=0.1   ,strength=0.85   ,guidance_scale=3   ,source_guidance_scale=1   ,generator=SCREAMING_SNAKE_CASE__   ,output_type='np'   ,)
								__lowerCamelCase				:				List[Any]					       = output.images

								# the values aren't exactly equal, but the images look the same visually
								assert np.abs(image - expected_image).max() < 5E-1


							def     lowerCAmelCase     (		self		:			Union[str, Any]):
								__lowerCamelCase				:				int					       = load_image(
								    'https://huggingface.co/datasets/hf-internal-testing/diffusers-images/resolve/main'
								    '/cycle-diffusion/black_colored_car.png')
								__lowerCamelCase				:				List[str]					       = load_numpy(
								    'https://huggingface.co/datasets/hf-internal-testing/diffusers-images/resolve/main/cycle-diffusion/blue_colored_car.npy')
								__lowerCamelCase				:				List[str]					       = init_image.resize((5_1_2, 5_1_2))

								__lowerCamelCase				:				int					       = 'CompVis/stable-diffusion-v1-4'
								__lowerCamelCase				:				int					       = DDIMScheduler.from_pretrained(SCREAMING_SNAKE_CASE__   ,subfolder='scheduler')
								__lowerCamelCase				:				Optional[Any]					       = CycleDiffusionPipeline.from_pretrained(SCREAMING_SNAKE_CASE__   ,scheduler=SCREAMING_SNAKE_CASE__   ,safety_checker=SCREAMING_SNAKE_CASE__)

								pipe.to(SCREAMING_SNAKE_CASE__)
								pipe.set_progress_bar_config(disable=SCREAMING_SNAKE_CASE__)
								pipe.enable_attention_slicing()

								__lowerCamelCase				:				str					       = 'A black colored car'
								__lowerCamelCase				:				List[str]					       = 'A blue colored car'

								__lowerCamelCase				:				int					       = torch.manual_seed(0)
								__lowerCamelCase				:				Tuple					       = pipe(
								    prompt=SCREAMING_SNAKE_CASE__   ,source_prompt=SCREAMING_SNAKE_CASE__   ,image=SCREAMING_SNAKE_CASE__   ,num_inference_steps=1_0_0   ,eta=0.1   ,strength=0.85   ,guidance_scale=3   ,source_guidance_scale=1   ,generator=SCREAMING_SNAKE_CASE__   ,output_type='np'   ,)
								__lowerCamelCase				:				List[Any]					       = output.images

								assert np.abs(image - expected_image).max() < 2E-2











import os
import sys
import tempfile

import torch

from .state import AcceleratorState
from .utils import PrecisionType, PrepareForLaunch, is_mps_available, patch_environment


def        SCREAMING_SNAKE_CASE      (       _UpperCAmelCase						,	_UpperCAmelCase=()						,	_UpperCAmelCase=None						,	_UpperCAmelCase="no"						,	_UpperCAmelCase="29500" )			->     Tuple:
    lowerCamelCase__    :      Dict					 =		False
    lowerCamelCase__    :      Dict					 =		False
    if any(key.startswith('KAGGLE' ) for key in os.environ.keys() ):
        lowerCamelCase__    :      Optional[Any]					 =		True
    elif "IPython" in sys.modules:
        lowerCamelCase__    :      Optional[Any]					 =		'google.colab' in str(sys.modules['IPython'].get_ipython() )

    try:
        lowerCamelCase__    :      List[str]					 =		PrecisionType(mixed_precision.lower() )
    except ValueError:
        raise ValueError(
            F"""Unknown mixed_precision mode: {args.mixed_precision.lower()}. Choose between {PrecisionType.list()}.""" )

    if (in_colab or in_kaggle) and (os.environ.get('TPU_NAME'						,	_UpperCAmelCase ) is not None):
        # TPU launch
        import torch_xla.distributed.xla_multiprocessing as xmp

        if len(AcceleratorState._shared_state ) > 0:
            raise ValueError(
                'To train on TPU in Colab or Kaggle Kernel, the `Accelerator` should only be initialized inside '
                'your training function. Restart your notebook and make sure no cells initializes an '
                '`Accelerator`.' )
        if num_processes is None:
            lowerCamelCase__    :      Optional[Any]					 =		8

        lowerCamelCase__    :      List[str]					 =		PrepareForLaunch(_UpperCAmelCase						,	distributed_type='TPU' )
        print(F"""Launching a training on {num_processes} TPU cores.""" )
        xmp.spawn(_UpperCAmelCase						,	args=_UpperCAmelCase						,	nprocs=_UpperCAmelCase						,	start_method='fork' )
    elif in_colab:
        # No need for a distributed launch otherwise as it's either CPU or one GPU.
        if torch.cuda.is_available():
            print('Launching training on one GPU.' )
        else:
            print('Launching training on one CPU.' )
        function(*_UpperCAmelCase )
    else:
        if num_processes is None:
            raise ValueError(
                'You have to specify the number of GPUs you would like to use, add `num_processes=...` to your call.' )

        if num_processes > 1:
            # Multi-GPU launch
            from torch.multiprocessing import start_processes
            from torch.multiprocessing.spawn import ProcessRaisedException

            if len(AcceleratorState._shared_state ) > 0:
                raise ValueError(
                    'To launch a multi-GPU training from your notebook, the `Accelerator` should only be initialized '
                    'inside your training function. Restart your notebook and make sure no cells initializes an '
                    '`Accelerator`.' )

            if torch.cuda.is_initialized():
                raise ValueError(
                    'To launch a multi-GPU training from your notebook, you need to avoid running any instruction '
                    'using `torch.cuda` in any cell. Restart your notebook and make sure no cells use any CUDA '
                    'function.' )

            # torch.distributed will expect a few environment variable to be here. We set the ones common to each
            # process here (the other ones will be set be the launcher).
            with patch_environment(
                world_size=_UpperCAmelCase						,	master_addr='127.0.01'						,	master_port=_UpperCAmelCase						,	mixed_precision=_UpperCAmelCase ):
                lowerCamelCase__    :      Optional[int]					 =		PrepareForLaunch(_UpperCAmelCase						,	distributed_type='MULTI_GPU' )
                print(F"""Launching training on {num_processes} GPUs.""" )
                try:
                    start_processes(_UpperCAmelCase						,	args=_UpperCAmelCase						,	nprocs=_UpperCAmelCase						,	start_method='fork' )
                except ProcessRaisedException as e:
                    if "Cannot re-initialize CUDA in forked subprocess" in e.args[0]:
                        raise RuntimeError(
                            'CUDA has been initialized before the `notebook_launcher` could create a forked subprocess. '
                            'This likely stems from an outside import causing issues once the `notebook_launcher()` is called. '
                            'Please review your imports and test them when running the `notebook_launcher()` to identify '
                            'which one is problematic.' ) from e

        else:
            # No need for a distributed launch otherwise as it's either CPU, GPU or MPS.
            if is_mps_available():
                lowerCamelCase__    :      int					 =		'1'
                print('Launching training on MPS.' )
            elif torch.cuda.is_available():
                print('Launching training on one GPU.' )
            else:
                print('Launching training on CPU.' )
            function(*_UpperCAmelCase )


def        SCREAMING_SNAKE_CASE      (       _UpperCAmelCase						,	_UpperCAmelCase=()						,	_UpperCAmelCase=2 )			->     Optional[Any]:
    from torch.multiprocessing import start_processes

    with tempfile.NamedTemporaryFile() as tmp_file:
        # torch.distributed will expect a few environment variable to be here. We set the ones common to each
        # process here (the other ones will be set be the launcher).
        with patch_environment(
            world_size=_UpperCAmelCase						,	master_addr='127.0.01'						,	master_port='29500'						,	accelerate_mixed_precision='no'						,	accelerate_debug_rdv_file=tmp_file.name						,	accelerate_use_cpu='yes'						,	):
            lowerCamelCase__    :      Optional[Any]					 =		PrepareForLaunch(_UpperCAmelCase						,	debug=_UpperCAmelCase )
            start_processes(_UpperCAmelCase						,	args=_UpperCAmelCase						,	nprocs=_UpperCAmelCase						,	start_method='fork' )





