




'''simple docstring'''

from typing import Optional, Tuple, Union

import flax
import flax.linen as nn
import jax
import jax.numpy as jnp
from flax.core.frozen_dict import FrozenDict

from ..configuration_utils import ConfigMixin, flax_register_to_config
from ..utils import BaseOutput
from .embeddings_flax import FlaxTimestepEmbedding, FlaxTimesteps
from .modeling_flax_utils import FlaxModelMixin
from .unet_ad_blocks_flax import (
    FlaxCrossAttnDownBlockaD,
    FlaxCrossAttnUpBlockaD,
    FlaxDownBlockaD,
    FlaxUNetMidBlockaDCrossAttn,
    FlaxUpBlockaD,
)






@flax.struct.dataclass
class 						a				(   _lowerCamelCase     ):
				snake_case_      =		42







@flax_register_to_config
class 						a				(   nn.Module   ,     _lowerCamelCase   ,     _lowerCamelCase     ):
				snake_case_      =		32
				snake_case_      =		4
				snake_case_      =		4
				snake_case_      =		(
				    "CrossAttnDownBlock2D",
				    "CrossAttnDownBlock2D",
				    "CrossAttnDownBlock2D",
				    "DownBlock2D",
				)
				snake_case_      =		("UpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D")
				snake_case_      =		False
				snake_case_      =		(320, 640, 1_280, 1_280)
				snake_case_      =		2
				snake_case_      =		8
				snake_case_      =		None
				snake_case_      =		1_280
				snake_case_      =		0.0
				snake_case_      =		False
				snake_case_      =		jnp.floataa
				snake_case_      =		True
				snake_case_      =		0
				snake_case_      =		False


				def   A_ (		self    :					Optional[int]       ,				lowercase_    :					jax.random.KeyArray					):
									# init input tensors
									snake_case_									=				(1, self.in_channels, self.sample_size, self.sample_size)
									snake_case_									=				jnp.zeros(lowercase_       ,				dtype=jnp.floataa					)
									snake_case_									=				jnp.ones((1,)       ,				dtype=jnp.intaa					)
									snake_case_									=				jnp.zeros((1, 1, self.cross_attention_dim)       ,				dtype=jnp.floataa					)

									snake_case_			,snake_case_									=				jax.random.split(lowercase_					)
									snake_case_									=				{'''params''': params_rng, '''dropout''': dropout_rng}

									return self.init(lowercase_       ,				lowercase_       ,				lowercase_       ,				lowercase_					)["params"]


				def   A_ (		self    :					List[str]					):
									snake_case_									=				self.block_out_channels
									snake_case_									=				block_out_channels[0] * 4

									if self.num_attention_heads is not None:
														raise ValueError(
														    '''At the moment it is not possible to define the number of attention heads via `num_attention_heads` because of a naming issue as described in https://github.com/huggingface/diffusers/issues/2011#issuecomment-1547958131. Passing `num_attention_heads` will only be supported in diffusers v0.19.'''					)

									# If `num_attention_heads` is not defined (which is the case for most models)
									# it will default to `attention_head_dim`. This looks weird upon first reading it and it is.
									# The reason for this behavior is to correct for incorrectly named variables that were introduced
									# when this library was created. The incorrect naming was only discovered much later in https://github.com/huggingface/diffusers/issues/2011#issuecomment-1547958131
									# Changing `attention_head_dim` to `num_attention_heads` for 40,000+ configurations is too backwards breaking
									# which is why we correct for the naming here.
									snake_case_									=				self.num_attention_heads or self.attention_head_dim

									# input
									snake_case_									=				nn.Conv(
									    block_out_channels[0]       ,				kernel_size=(3, 3)       ,				strides=(1, 1)       ,				padding=((1, 1), (1, 1))       ,				dtype=self.dtype       ,				)

									# time
									snake_case_									=				FlaxTimesteps(
									    block_out_channels[0]       ,				flip_sin_to_cos=self.flip_sin_to_cos       ,				freq_shift=self.config.freq_shift					)
									snake_case_									=				FlaxTimestepEmbedding(lowercase_       ,				dtype=self.dtype					)

									snake_case_									=				self.only_cross_attention
									if isinstance(lowercase_       ,				lowercase_					):
														snake_case_									=				(only_cross_attention,) * len(self.down_block_types					)

									if isinstance(lowercase_       ,				lowercase_					):
														snake_case_									=				(num_attention_heads,) * len(self.down_block_types					)

									# down
									snake_case_									=				[]
									snake_case_									=				block_out_channels[0]
									for i, down_block_type in enumerate(self.down_block_types					):
														snake_case_									=				output_channel
														snake_case_									=				block_out_channels[i]
														snake_case_									=				i == len(lowercase_					) - 1

														if down_block_type == "CrossAttnDownBlock2D":
																			snake_case_									=				FlaxCrossAttnDownBlockaD(
																			    in_channels=lowercase_       ,				out_channels=lowercase_       ,				dropout=self.dropout       ,				num_layers=self.layers_per_block       ,				num_attention_heads=num_attention_heads[i]       ,				add_downsample=not is_final_block       ,				use_linear_projection=self.use_linear_projection       ,				only_cross_attention=only_cross_attention[i]       ,				use_memory_efficient_attention=self.use_memory_efficient_attention       ,				dtype=self.dtype       ,				)
														else:
																			snake_case_									=				FlaxDownBlockaD(
																			    in_channels=lowercase_       ,				out_channels=lowercase_       ,				dropout=self.dropout       ,				num_layers=self.layers_per_block       ,				add_downsample=not is_final_block       ,				dtype=self.dtype       ,				)

														down_blocks.append(lowercase_					)
									snake_case_									=				down_blocks

									# mid
									snake_case_									=				FlaxUNetMidBlockaDCrossAttn(
									    in_channels=block_out_channels[-1]       ,				dropout=self.dropout       ,				num_attention_heads=num_attention_heads[-1]       ,				use_linear_projection=self.use_linear_projection       ,				use_memory_efficient_attention=self.use_memory_efficient_attention       ,				dtype=self.dtype       ,				)

									# up
									snake_case_									=				[]
									snake_case_									=				list(reversed(lowercase_					)					)
									snake_case_									=				list(reversed(lowercase_					)					)
									snake_case_									=				list(reversed(lowercase_					)					)
									snake_case_									=				reversed_block_out_channels[0]
									for i, up_block_type in enumerate(self.up_block_types					):
														snake_case_									=				output_channel
														snake_case_									=				reversed_block_out_channels[i]
														snake_case_									=				reversed_block_out_channels[min(i + 1       ,				len(lowercase_					) - 1					)]

														snake_case_									=				i == len(lowercase_					) - 1

														if up_block_type == "CrossAttnUpBlock2D":
																			snake_case_									=				FlaxCrossAttnUpBlockaD(
																			    in_channels=lowercase_       ,				out_channels=lowercase_       ,				prev_output_channel=lowercase_       ,				num_layers=self.layers_per_block + 1       ,				num_attention_heads=reversed_num_attention_heads[i]       ,				add_upsample=not is_final_block       ,				dropout=self.dropout       ,				use_linear_projection=self.use_linear_projection       ,				only_cross_attention=only_cross_attention[i]       ,				use_memory_efficient_attention=self.use_memory_efficient_attention       ,				dtype=self.dtype       ,				)
														else:
																			snake_case_									=				FlaxUpBlockaD(
																			    in_channels=lowercase_       ,				out_channels=lowercase_       ,				prev_output_channel=lowercase_       ,				num_layers=self.layers_per_block + 1       ,				add_upsample=not is_final_block       ,				dropout=self.dropout       ,				dtype=self.dtype       ,				)

														up_blocks.append(lowercase_					)
														snake_case_									=				output_channel
									snake_case_									=				up_blocks

									# out
									snake_case_									=				nn.GroupNorm(num_groups=32       ,				epsilon=1e-5					)
									snake_case_									=				nn.Conv(
									    self.out_channels       ,				kernel_size=(3, 3)       ,				strides=(1, 1)       ,				padding=((1, 1), (1, 1))       ,				dtype=self.dtype       ,				)


				def __call__(		self    :					Union[str, Any]       ,				lowercase_    :					Union[str, Any]       ,				lowercase_    :					int       ,				lowercase_    :					Any       ,				lowercase_    :					int=None       ,				lowercase_    :					Any=None       ,				lowercase_    :					bool = True       ,				lowercase_    :					bool = False       ,				):
									# 1. time
									if not isinstance(lowercase_       ,				jnp.ndarray					):
														snake_case_									=				jnp.array([timesteps]       ,				dtype=jnp.intaa					)
									elif isinstance(lowercase_       ,				jnp.ndarray					) and len(timesteps.shape					) == 0:
														snake_case_									=				timesteps.astype(dtype=jnp.floataa					)
														snake_case_									=				jnp.expand_dims(lowercase_       ,				0					)

									snake_case_									=				self.time_proj(lowercase_					)
									snake_case_									=				self.time_embedding(lowercase_					)

									# 2. pre-process
									snake_case_									=				jnp.transpose(lowercase_       ,				(0, 2, 3, 1)					)
									snake_case_									=				self.conv_in(lowercase_					)

									# 3. down
									snake_case_									=				(sample,)
									for down_block in self.down_blocks:
														if isinstance(lowercase_       ,				lowercase_					):
																			snake_case_			,snake_case_									=				down_block(lowercase_       ,				lowercase_       ,				lowercase_       ,				deterministic=not train					)
														else:
																			snake_case_			,snake_case_									=				down_block(lowercase_       ,				lowercase_       ,				deterministic=not train					)
														down_block_res_samples += res_samples

									if down_block_additional_residuals is not None:
														snake_case_									=				()

														for down_block_res_sample, down_block_additional_residual in zip(
														    lowercase_       ,				lowercase_					):
																			down_block_res_sample += down_block_additional_residual
																			new_down_block_res_samples += (down_block_res_sample,)

														snake_case_									=				new_down_block_res_samples

									# 4. mid
									snake_case_									=				self.mid_block(lowercase_       ,				lowercase_       ,				lowercase_       ,				deterministic=not train					)

									if mid_block_additional_residual is not None:
														sample += mid_block_additional_residual

									# 5. up
									for up_block in self.up_blocks:
														snake_case_									=				down_block_res_samples[-(self.layers_per_block + 1) :]
														snake_case_									=				down_block_res_samples[: -(self.layers_per_block + 1)]
														if isinstance(lowercase_       ,				lowercase_					):
																			snake_case_									=				up_block(
																			    lowercase_       ,				temb=lowercase_       ,				encoder_hidden_states=lowercase_       ,				res_hidden_states_tuple=lowercase_       ,				deterministic=not train       ,				)
														else:
																			snake_case_									=				up_block(lowercase_       ,				temb=lowercase_       ,				res_hidden_states_tuple=lowercase_       ,				deterministic=not train					)

        # 6. post-process
									snake_case_									=				self.conv_norm_out(lowercase_					)
									snake_case_									=				nn.silu(lowercase_					)
									snake_case_									=				self.conv_out(lowercase_					)
									snake_case_									=				jnp.transpose(lowercase_       ,				(0, 3, 1, 2)					)

									if not return_dict:
														return (sample,)

									return FlaxUNetaDConditionOutput(sample=lowercase_					)







'''simple docstring'''

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				(   _lowerCamelCase   ,     _lowerCamelCase   ,     unittest.TestCase     ):
				snake_case_      =		CycleDiffusionPipeline
				snake_case_      =		TEXT_GUIDED_IMAGE_VARIATION_PARAMS - {
				    "negative_prompt",
				    "height",
				    "width",
				    "negative_prompt_embeds",
				}
				snake_case_      =		PipelineTesterMixin.required_optional_params - {"latents"}
				snake_case_      =		TEXT_GUIDED_IMAGE_VARIATION_BATCH_PARAMS.union({"source_prompt"}     )
				snake_case_      =		IMAGE_TO_IMAGE_IMAGE_PARAMS
				snake_case_      =		IMAGE_TO_IMAGE_IMAGE_PARAMS


				def   A_ (		self    :					Tuple					):
									torch.manual_seed(0					)
									snake_case_									=				UNetaDConditionModel(
									    block_out_channels=(32, 64)       ,				layers_per_block=2       ,				sample_size=32       ,				in_channels=4       ,				out_channels=4       ,				down_block_types=('''DownBlock2D''', '''CrossAttnDownBlock2D''')       ,				up_block_types=('''CrossAttnUpBlock2D''', '''UpBlock2D''')       ,				cross_attention_dim=32       ,				)
									snake_case_									=				DDIMScheduler(
									    beta_start=0.0_0085       ,				beta_end=0.012       ,				beta_schedule='''scaled_linear'''       ,				num_train_timesteps=1000       ,				clip_sample=lowercase_       ,				set_alpha_to_one=lowercase_       ,				)
									torch.manual_seed(0					)
									snake_case_									=				AutoencoderKL(
									    block_out_channels=[32, 64]       ,				in_channels=3       ,				out_channels=3       ,				down_block_types=['''DownEncoderBlock2D''', '''DownEncoderBlock2D''']       ,				up_block_types=['''UpDecoderBlock2D''', '''UpDecoderBlock2D''']       ,				latent_channels=4       ,				)
									torch.manual_seed(0					)
									snake_case_									=				CLIPTextConfig(
									    bos_token_id=0       ,				eos_token_id=2       ,				hidden_size=32       ,				intermediate_size=37       ,				layer_norm_eps=1e-05       ,				num_attention_heads=4       ,				num_hidden_layers=5       ,				pad_token_id=1       ,				vocab_size=1000       ,				)
									snake_case_									=				CLIPTextModel(lowercase_					)
									snake_case_									=				CLIPTokenizer.from_pretrained('''hf-internal-testing/tiny-random-clip'''					)

									snake_case_									=				{
									    '''unet''': unet,
									    '''scheduler''': scheduler,
									    '''vae''': vae,
									    '''text_encoder''': text_encoder,
									    '''tokenizer''': tokenizer,
									    '''safety_checker''': None,
									    '''feature_extractor''': None,
									}
									return components


				def   A_ (		self    :					Any       ,				lowercase_    :					int       ,				lowercase_    :					Optional[Any]=0					):
									snake_case_									=				floats_tensor((1, 3, 32, 32)       ,				rng=random.Random(lowercase_					)					).to(lowercase_					)
									snake_case_									=				image / 2 + 0.5
									if str(lowercase_					).startswith('''mps'''					):
														snake_case_									=				torch.manual_seed(lowercase_					)
									else:
														snake_case_									=				torch.Generator(device=lowercase_					).manual_seed(lowercase_					)
									snake_case_									=				{
									    '''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   A_ (		self    :					Union[str, Any]					):
									snake_case_									=				'''cpu'''  # ensure determinism for the device-dependent torch.Generator

									snake_case_									=				self.get_dummy_components()
									snake_case_									=				CycleDiffusionPipeline(**lowercase_					)
									snake_case_									=				pipe.to(lowercase_					)
									pipe.set_progress_bar_config(disable=lowercase_					)

									snake_case_									=				self.get_dummy_inputs(lowercase_					)
									snake_case_									=				pipe(**lowercase_					)
									snake_case_									=				output.images

									snake_case_									=				images[0, -3:, -3:, -1]

									assert images.shape == (1, 32, 32, 3)
									snake_case_									=				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   A_ (		self    :					Union[str, Any]					):
									snake_case_									=				self.get_dummy_components()
									for name, module in components.items():
														if hasattr(lowercase_       ,				'''half'''					):
																			snake_case_									=				module.half()
									snake_case_									=				CycleDiffusionPipeline(**lowercase_					)
									snake_case_									=				pipe.to(lowercase_					)
									pipe.set_progress_bar_config(disable=lowercase_					)

									snake_case_									=				self.get_dummy_inputs(lowercase_					)
									snake_case_									=				pipe(**lowercase_					)
									snake_case_									=				output.images

									snake_case_									=				images[0, -3:, -3:, -1]

									assert images.shape == (1, 32, 32, 3)
									snake_case_									=				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   A_ (		self    :					Optional[int]					):
									return super().test_save_load_local()


				@unittest.skip('''non-deterministic pipeline'''					)
				def   A_ (		self    :					List[Any]					):
									return super().test_inference_batch_single_identical()


				@skip_mps
				def   A_ (		self    :					Union[str, Any]					):
									return super().test_dict_tuple_outputs_equivalent()


				@skip_mps
				def   A_ (		self    :					Union[str, Any]					):
									return super().test_save_load_optional_components()


				@skip_mps
				def   A_ (		self    :					Union[str, Any]					):
									return super().test_attention_slicing_forward_pass()







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


				def   A_ (		self    :					List[Any]					):
									# clean up the VRAM after each test
									super().tearDown()
									gc.collect()
									torch.cuda.empty_cache()


				def   A_ (		self    :					Union[str, Any]					):
									snake_case_									=				load_image(
									    '''https://huggingface.co/datasets/hf-internal-testing/diffusers-images/resolve/main'''
									    '''/cycle-diffusion/black_colored_car.png'''					)
									snake_case_									=				load_numpy(
									    '''https://huggingface.co/datasets/hf-internal-testing/diffusers-images/resolve/main/cycle-diffusion/blue_colored_car_fp16.npy'''					)
									snake_case_									=				init_image.resize((512, 512)					)

									snake_case_									=				'''CompVis/stable-diffusion-v1-4'''
									snake_case_									=				DDIMScheduler.from_pretrained(lowercase_       ,				subfolder='''scheduler'''					)
									snake_case_									=				CycleDiffusionPipeline.from_pretrained(
									    lowercase_       ,				scheduler=lowercase_       ,				safety_checker=lowercase_       ,				torch_dtype=torch.floataa       ,				revision='''fp16'''					)

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

									snake_case_									=				'''A black colored car'''
									snake_case_									=				'''A blue colored car'''

									snake_case_									=				torch.manual_seed(0					)
									snake_case_									=				pipe(
									    prompt=lowercase_       ,				source_prompt=lowercase_       ,				image=lowercase_       ,				num_inference_steps=100       ,				eta=0.1       ,				strength=0.85       ,				guidance_scale=3       ,				source_guidance_scale=1       ,				generator=lowercase_       ,				output_type='''np'''       ,				)
									snake_case_									=				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   A_ (		self    :					List[str]					):
									snake_case_									=				load_image(
									    '''https://huggingface.co/datasets/hf-internal-testing/diffusers-images/resolve/main'''
									    '''/cycle-diffusion/black_colored_car.png'''					)
									snake_case_									=				load_numpy(
									    '''https://huggingface.co/datasets/hf-internal-testing/diffusers-images/resolve/main/cycle-diffusion/blue_colored_car.npy'''					)
									snake_case_									=				init_image.resize((512, 512)					)

									snake_case_									=				'''CompVis/stable-diffusion-v1-4'''
									snake_case_									=				DDIMScheduler.from_pretrained(lowercase_       ,				subfolder='''scheduler'''					)
									snake_case_									=				CycleDiffusionPipeline.from_pretrained(lowercase_       ,				scheduler=lowercase_       ,				safety_checker=lowercase_					)

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

									snake_case_									=				'''A black colored car'''
									snake_case_									=				'''A blue colored car'''

									snake_case_									=				torch.manual_seed(0					)
									snake_case_									=				pipe(
									    prompt=lowercase_       ,				source_prompt=lowercase_       ,				image=lowercase_       ,				num_inference_steps=100       ,				eta=0.1       ,				strength=0.85       ,				guidance_scale=3       ,				source_guidance_scale=1       ,				generator=lowercase_       ,				output_type='''np'''       ,				)
									snake_case_									=				output.images

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

