


import os
import tempfile
import unittest

import numpy as np

from diffusers.utils import is_flax_available
from diffusers.utils.testing_utils import require_flax, slow


if is_flax_available():
			import jax
			import jax.numpy as jnp
			from flax.jax_utils import replicate
			from flax.training.common_utils import shard

			from diffusers import FlaxDDIMScheduler, FlaxDiffusionPipeline, FlaxStableDiffusionPipeline


@require_flax
class 	_a							(      unittest.TestCase      ):

							def 				lowerCamelCase_			(							self:     Optional[Any]							)      ->       Optional[int]:





									"""simple docstring"""







									with tempfile.TemporaryDirectory() as tmpdirname:
											# pipeline has Flax weights
											lowercase__						=				FlaxDiffusionPipeline.from_pretrained(
											    '''hf-internal-testing/tiny-stable-diffusion-pipe'''   ,						safety_checker=UpperCamelCase_   ,						cache_dir=UpperCamelCase_							)

											lowercase__						=				[t[-1] for t in os.walk(os.path.join(UpperCamelCase_   ,						os.listdir(UpperCamelCase_							)[0]   ,						'''snapshots'''							)							)]
											lowercase__						=				[item for sublist in all_root_files for item in sublist]

											# None of the downloaded files should be a PyTorch file even if we have some here:
											# https://huggingface.co/hf-internal-testing/tiny-stable-diffusion-pipe/blob/main/unet/diffusion_pytorch_model.bin
											assert not any(f.endswith('''.bin'''							) for f in files							)


@slow
@require_flax
class 	_a							(      unittest.TestCase      ):

							def 				lowerCamelCase_			(							self:     List[str]							)      ->       int:





									"""simple docstring"""







									lowercase__					,		lowercase__						=				FlaxStableDiffusionPipeline.from_pretrained(
									    '''hf-internal-testing/tiny-stable-diffusion-pipe'''   ,						safety_checker=UpperCamelCase_							)

									lowercase__						=				(
									    '''A cinematic film still of Morgan Freeman starring as Jimi Hendrix, portrait, 40mm lens, shallow depth of'''
									    ''' field, close up, split lighting, cinematic'''
									)

									lowercase__						=				jax.random.PRNGKey(0							)
									lowercase__						=				4

									lowercase__						=				jax.device_count()
									lowercase__						=				num_samples * [prompt]
									lowercase__						=				pipeline.prepare_inputs(UpperCamelCase_							)

									# shard inputs and rng
									lowercase__						=				replicate(UpperCamelCase_							)
									lowercase__						=				jax.random.split(UpperCamelCase_   ,						UpperCamelCase_							)
									lowercase__						=				shard(UpperCamelCase_							)

									lowercase__						=				pipeline(UpperCamelCase_   ,						UpperCamelCase_   ,						UpperCamelCase_   ,						UpperCamelCase_   ,						jit=UpperCamelCase_							).images

									assert images.shape == (num_samples, 1, 64, 64, 3)
									if jax.device_count() == 8:
											assert np.abs(np.abs(images[0, 0, :2, :2, -2:]   ,						dtype=np.floataa							).sum() - 4.1514745							) < 1E-3
											assert np.abs(np.abs(UpperCamelCase_   ,						dtype=np.floataa							).sum() - 49947.875							) < 5E-1

									lowercase__						=				pipeline.numpy_to_pil(np.asarray(images.reshape((num_samples,) + images.shape[-3:]							)							)							)
									assert len(UpperCamelCase_							) == num_samples

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





									"""simple docstring"""







									lowercase__					,		lowercase__						=				FlaxStableDiffusionPipeline.from_pretrained(
									    '''CompVis/stable-diffusion-v1-4'''   ,						revision='''flax'''   ,						safety_checker=UpperCamelCase_							)

									lowercase__						=				(
									    '''A cinematic film still of Morgan Freeman starring as Jimi Hendrix, portrait, 40mm lens, shallow depth of'''
									    ''' field, close up, split lighting, cinematic'''
									)

									lowercase__						=				jax.random.PRNGKey(0							)
									lowercase__						=				50

									lowercase__						=				jax.device_count()
									lowercase__						=				num_samples * [prompt]
									lowercase__						=				pipeline.prepare_inputs(UpperCamelCase_							)

									# shard inputs and rng
									lowercase__						=				replicate(UpperCamelCase_							)
									lowercase__						=				jax.random.split(UpperCamelCase_   ,						UpperCamelCase_							)
									lowercase__						=				shard(UpperCamelCase_							)

									lowercase__						=				pipeline(UpperCamelCase_   ,						UpperCamelCase_   ,						UpperCamelCase_   ,						UpperCamelCase_   ,						jit=UpperCamelCase_							).images

									assert images.shape == (num_samples, 1, 512, 512, 3)
									if jax.device_count() == 8:
											assert np.abs((np.abs(images[0, 0, :2, :2, -2:]   ,						dtype=np.floataa							).sum() - 0.05652401)							) < 1E-3
											assert np.abs((np.abs(UpperCamelCase_   ,						dtype=np.floataa							).sum() - 2383808.2)							) < 5E-1

							def 				lowerCamelCase_			(							self:     Tuple							)      ->       Dict:





									"""simple docstring"""







									lowercase__					,		lowercase__						=				FlaxStableDiffusionPipeline.from_pretrained(
									    '''CompVis/stable-diffusion-v1-4'''   ,						revision='''bf16'''   ,						dtype=jnp.bfloataa   ,						safety_checker=UpperCamelCase_							)

									lowercase__						=				(
									    '''A cinematic film still of Morgan Freeman starring as Jimi Hendrix, portrait, 40mm lens, shallow depth of'''
									    ''' field, close up, split lighting, cinematic'''
									)

									lowercase__						=				jax.random.PRNGKey(0							)
									lowercase__						=				50

									lowercase__						=				jax.device_count()
									lowercase__						=				num_samples * [prompt]
									lowercase__						=				pipeline.prepare_inputs(UpperCamelCase_							)

									# shard inputs and rng
									lowercase__						=				replicate(UpperCamelCase_							)
									lowercase__						=				jax.random.split(UpperCamelCase_   ,						UpperCamelCase_							)
									lowercase__						=				shard(UpperCamelCase_							)

									lowercase__						=				pipeline(UpperCamelCase_   ,						UpperCamelCase_   ,						UpperCamelCase_   ,						UpperCamelCase_   ,						jit=UpperCamelCase_							).images

									assert images.shape == (num_samples, 1, 512, 512, 3)
									if jax.device_count() == 8:
											assert np.abs((np.abs(images[0, 0, :2, :2, -2:]   ,						dtype=np.floataa							).sum() - 0.04003906)							) < 1E-3
											assert np.abs((np.abs(UpperCamelCase_   ,						dtype=np.floataa							).sum() - 2373516.75)							) < 5E-1

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





									"""simple docstring"""







									lowercase__					,		lowercase__						=				FlaxStableDiffusionPipeline.from_pretrained(
									    '''CompVis/stable-diffusion-v1-4'''   ,						revision='''bf16'''   ,						dtype=jnp.bfloataa							)

									lowercase__						=				(
									    '''A cinematic film still of Morgan Freeman starring as Jimi Hendrix, portrait, 40mm lens, shallow depth of'''
									    ''' field, close up, split lighting, cinematic'''
									)

									lowercase__						=				jax.random.PRNGKey(0							)
									lowercase__						=				50

									lowercase__						=				jax.device_count()
									lowercase__						=				num_samples * [prompt]
									lowercase__						=				pipeline.prepare_inputs(UpperCamelCase_							)

									# shard inputs and rng
									lowercase__						=				replicate(UpperCamelCase_							)
									lowercase__						=				jax.random.split(UpperCamelCase_   ,						UpperCamelCase_							)
									lowercase__						=				shard(UpperCamelCase_							)

									lowercase__						=				pipeline(UpperCamelCase_   ,						UpperCamelCase_   ,						UpperCamelCase_   ,						UpperCamelCase_   ,						jit=UpperCamelCase_							).images

									assert images.shape == (num_samples, 1, 512, 512, 3)
									if jax.device_count() == 8:
											assert np.abs((np.abs(images[0, 0, :2, :2, -2:]   ,						dtype=np.floataa							).sum() - 0.04003906)							) < 1E-3
											assert np.abs((np.abs(UpperCamelCase_   ,						dtype=np.floataa							).sum() - 2373516.75)							) < 5E-1

							def 				lowerCamelCase_			(							self:     Tuple							)      ->       Any:





									"""simple docstring"""







									lowercase__						=				FlaxDDIMScheduler(
									    beta_start=0.00085   ,						beta_end=0.012   ,						beta_schedule='''scaled_linear'''   ,						set_alpha_to_one=UpperCamelCase_   ,						steps_offset=1   ,						)

									lowercase__					,		lowercase__						=				FlaxStableDiffusionPipeline.from_pretrained(
									    '''CompVis/stable-diffusion-v1-4'''   ,						revision='''bf16'''   ,						dtype=jnp.bfloataa   ,						scheduler=UpperCamelCase_   ,						safety_checker=UpperCamelCase_   ,						)
									lowercase__						=				scheduler.create_state()

									lowercase__						=				scheduler_state

									lowercase__						=				(
									    '''A cinematic film still of Morgan Freeman starring as Jimi Hendrix, portrait, 40mm lens, shallow depth of'''
									    ''' field, close up, split lighting, cinematic'''
									)

									lowercase__						=				jax.random.PRNGKey(0							)
									lowercase__						=				50

									lowercase__						=				jax.device_count()
									lowercase__						=				num_samples * [prompt]
									lowercase__						=				pipeline.prepare_inputs(UpperCamelCase_							)

									# shard inputs and rng
									lowercase__						=				replicate(UpperCamelCase_							)
									lowercase__						=				jax.random.split(UpperCamelCase_   ,						UpperCamelCase_							)
									lowercase__						=				shard(UpperCamelCase_							)

									lowercase__						=				pipeline(UpperCamelCase_   ,						UpperCamelCase_   ,						UpperCamelCase_   ,						UpperCamelCase_   ,						jit=UpperCamelCase_							).images

									assert images.shape == (num_samples, 1, 512, 512, 3)
									if jax.device_count() == 8:
											assert np.abs((np.abs(images[0, 0, :2, :2, -2:]   ,						dtype=np.floataa							).sum() - 0.045043945)							) < 1E-3
											assert np.abs((np.abs(UpperCamelCase_   ,						dtype=np.floataa							).sum() - 2347693.5)							) < 5E-1


							def 				lowerCamelCase_			(							self:     Optional[int]							)      ->       Optional[Any]:





									"""simple docstring"""







									lowercase__						=				(
									    '''A cinematic film still of Morgan Freeman starring as Jimi Hendrix, portrait, 40mm lens, shallow depth of'''
									    ''' field, close up, split lighting, cinematic'''
									)

									lowercase__						=				jax.device_count()
									lowercase__						=				num_samples * [prompt]
									lowercase__						=				jax.random.split(jax.random.PRNGKey(0							)   ,						UpperCamelCase_							)

									lowercase__					,		lowercase__						=				FlaxStableDiffusionPipeline.from_pretrained(
									    '''CompVis/stable-diffusion-v1-4'''   ,						revision='''bf16'''   ,						dtype=jnp.bfloataa   ,						safety_checker=UpperCamelCase_   ,						)

									lowercase__						=				replicate(UpperCamelCase_							)
									lowercase__						=				pipeline.prepare_inputs(UpperCamelCase_							)
									lowercase__						=				shard(UpperCamelCase_							)
									lowercase__						=				pipeline(UpperCamelCase_   ,						UpperCamelCase_   ,						UpperCamelCase_   ,						jit=UpperCamelCase_							).images
									assert images.shape == (num_samples, 1, 512, 512, 3)
									lowercase__						=				images[2, 0, 256, 10:17, 1]

									# With memory efficient attention
									lowercase__					,		lowercase__						=				FlaxStableDiffusionPipeline.from_pretrained(
									    '''CompVis/stable-diffusion-v1-4'''   ,						revision='''bf16'''   ,						dtype=jnp.bfloataa   ,						safety_checker=UpperCamelCase_   ,						use_memory_efficient_attention=UpperCamelCase_   ,						)

									lowercase__						=				replicate(UpperCamelCase_							)
									lowercase__						=				pipeline.prepare_inputs(UpperCamelCase_							)
									lowercase__						=				shard(UpperCamelCase_							)
									lowercase__						=				pipeline(UpperCamelCase_   ,						UpperCamelCase_   ,						UpperCamelCase_   ,						jit=UpperCamelCase_							).images
									assert images_eff.shape == (num_samples, 1, 512, 512, 3)
									lowercase__						=				images[2, 0, 256, 10:17, 1]

									# I checked the results visually and they are very similar. However, I saw that the max diff is `1` and the `sum`
									# over the 8 images is exactly `256`, which is very suspicious. Testing a random slice for now.
									assert abs(slice_eff - slice							).max() < 1E-2





# DISCLAIMER: This file is strongly influenced by https://github.com/ermongroup/ddim

from dataclasses import dataclass
from typing import Optional, Tuple, Union

import flax
import jax
import jax.numpy as jnp

from ..configuration_utils import ConfigMixin, register_to_config
from .scheduling_utils_flax import (
    CommonSchedulerState,
    FlaxKarrasDiffusionSchedulers,
    FlaxSchedulerMixin,
    FlaxSchedulerOutput,
    add_noise_common,
    get_velocity_common,
)


@flax.struct.dataclass
class 	_a							:
							_lowercase     :      CommonSchedulerState

							# setable values
							_lowercase     :      jnp.ndarray
							_lowercase     :      jnp.ndarray
							_lowercase     :      Optional[int]  				=			None

							@classmethod
							def 				lowerCamelCase_			(							cls:     Dict   ,						UpperCamelCase_:     CommonSchedulerState   ,						UpperCamelCase_:     jnp.ndarray   ,						UpperCamelCase_:     jnp.ndarray							)      ->       List[str]:





									"""simple docstring"""







									return cls(common=UpperCamelCase_   ,						init_noise_sigma=UpperCamelCase_   ,						timesteps=UpperCamelCase_							)


@dataclass
class 	_a							(      UpperCamelCase__      ):
							_lowercase     :      DDPMSchedulerState


class 	_a							(      UpperCamelCase__					,     UpperCamelCase__      ):
							_lowercase     :      Tuple  				=			[e.name for e in FlaxKarrasDiffusionSchedulers]

							_lowercase     :      jnp.dtype

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





									"""simple docstring"""







									return True

							@register_to_config
							def __init__(							self:     Any   ,						UpperCamelCase_:     int = 1_000   ,						UpperCamelCase_:     float = 0.0001   ,						UpperCamelCase_:     float = 0.02   ,						UpperCamelCase_:     str = "linear"   ,						UpperCamelCase_:     Optional[jnp.ndarray] = None   ,						UpperCamelCase_:     str = "fixed_small"   ,						UpperCamelCase_:     bool = True   ,						UpperCamelCase_:     str = "epsilon"   ,						UpperCamelCase_:     jnp.dtype = jnp.floataa   ,						)      ->       int:





									"""simple docstring"""







									lowercase__						=				dtype

							def 				lowerCamelCase_			(							self:     Optional[int]   ,						UpperCamelCase_:     Optional[CommonSchedulerState] = None							)      ->       DDPMSchedulerState:





									"""simple docstring"""







									if common is None:
											lowercase__						=				CommonSchedulerState.create(self							)

									# standard deviation of the initial noise distribution
									lowercase__						=				jnp.array(1.0   ,						dtype=self.dtype							)

									lowercase__						=				jnp.arange(0   ,						self.config.num_train_timesteps							).round()[::-1]

									return DDPMSchedulerState.create(
									    common=UpperCamelCase_   ,						init_noise_sigma=UpperCamelCase_   ,						timesteps=UpperCamelCase_   ,						)

							def 				lowerCamelCase_			(							self:     Dict   ,						UpperCamelCase_:     DDPMSchedulerState   ,						UpperCamelCase_:     jnp.ndarray   ,						UpperCamelCase_:     Optional[int] = None							)      ->       jnp.ndarray:





									"""simple docstring"""







									return sample

							def 				lowerCamelCase_			(							self:     Dict   ,						UpperCamelCase_:     DDPMSchedulerState   ,						UpperCamelCase_:     int   ,						UpperCamelCase_:     Tuple = ()							)      ->       DDPMSchedulerState:





									"""simple docstring"""







									lowercase__						=				self.config.num_train_timesteps // num_inference_steps
									# creates integer timesteps by multiplying by ratio
									# rounding to avoid issues when num_inference_step is power of 3
									lowercase__						=				(jnp.arange(0   ,						UpperCamelCase_							) * step_ratio).round()[::-1]

									return state.replace(
									    num_inference_steps=UpperCamelCase_   ,						timesteps=UpperCamelCase_   ,						)

							def 				lowerCamelCase_			(							self:     Union[str, Any]   ,						UpperCamelCase_:     DDPMSchedulerState   ,						UpperCamelCase_:     Optional[Any]   ,						UpperCamelCase_:     Optional[int]=None   ,						UpperCamelCase_:     str=None							)      ->       List[Any]:





									"""simple docstring"""







									lowercase__						=				state.common.alphas_cumprod[t]
									lowercase__						=				jnp.where(t > 0   ,						state.common.alphas_cumprod[t - 1]   ,						jnp.array(1.0   ,						dtype=self.dtype							)							)

									# For t > 0, compute predicted variance βt (see formula (6) and (7) from https://arxiv.org/pdf/2006.11239.pdf)
									# and sample from it to get previous sample
									# x_{t-1} ~ N(pred_prev_sample, variance) == add variance to pred_sample
									lowercase__						=				(1 - alpha_prod_t_prev) / (1 - alpha_prod_t) * state.common.betas[t]

									if variance_type is None:
											lowercase__						=				self.config.variance_type

									# hacks - were probably added for training stability
									if variance_type == "fixed_small":
											lowercase__						=				jnp.clip(UpperCamelCase_   ,						a_min=1E-2_0							)
									# for rl-diffuser https://arxiv.org/abs/2205.09991
									elif variance_type == "fixed_small_log":
											lowercase__						=				jnp.log(jnp.clip(UpperCamelCase_   ,						a_min=1E-2_0							)							)
									elif variance_type == "fixed_large":
											lowercase__						=				state.common.betas[t]
									elif variance_type == "fixed_large_log":
											# Glide max_log
											lowercase__						=				jnp.log(state.common.betas[t]							)
									elif variance_type == "learned":
											return predicted_variance
									elif variance_type == "learned_range":
											lowercase__						=				variance
											lowercase__						=				state.common.betas[t]
											lowercase__						=				(predicted_variance + 1) / 2
											lowercase__						=				frac * max_log + (1 - frac) * min_log

									return variance

							def 				lowerCamelCase_			(							self:     Any   ,						UpperCamelCase_:     DDPMSchedulerState   ,						UpperCamelCase_:     jnp.ndarray   ,						UpperCamelCase_:     int   ,						UpperCamelCase_:     jnp.ndarray   ,						UpperCamelCase_:     Optional[jax.random.KeyArray] = None   ,						UpperCamelCase_:     bool = True   ,						)      ->       Union[FlaxDDPMSchedulerOutput, Tuple]:





									"""simple docstring"""







									lowercase__						=				timestep

									if key is None:
											lowercase__						=				jax.random.PRNGKey(0							)

									if model_output.shape[1] == sample.shape[1] * 2 and self.config.variance_type in ["learned", "learned_range"]:
											lowercase__					,		lowercase__						=				jnp.split(UpperCamelCase_   ,						sample.shape[1]   ,						axis=1							)
									else:
											lowercase__						=				None

									# 1. compute alphas, betas
									lowercase__						=				state.common.alphas_cumprod[t]
									lowercase__						=				jnp.where(t > 0   ,						state.common.alphas_cumprod[t - 1]   ,						jnp.array(1.0   ,						dtype=self.dtype							)							)
									lowercase__						=				1 - alpha_prod_t
									lowercase__						=				1 - alpha_prod_t_prev

									# 2. compute predicted original sample from predicted noise also called
									# "predicted x_0" of formula (15) from https://arxiv.org/pdf/2006.11239.pdf
									if self.config.prediction_type == "epsilon":
											lowercase__						=				(sample - beta_prod_t ** 0.5 * model_output) / alpha_prod_t ** 0.5
									elif self.config.prediction_type == "sample":
											lowercase__						=				model_output
									elif self.config.prediction_type == "v_prediction":
											lowercase__						=				(alpha_prod_t**0.5) * sample - (beta_prod_t**0.5) * model_output
									else:
											raise ValueError(
											    f'prediction_type given as {self.config.prediction_type} must be one of `epsilon`, `sample` '
											    ''' for the FlaxDDPMScheduler.'''							)

									# 3. Clip "predicted x_0"
									if self.config.clip_sample:
											lowercase__						=				jnp.clip(UpperCamelCase_   ,						-1   ,						1							)

									# 4. Compute coefficients for pred_original_sample x_0 and current sample x_t
									# See formula (7) from https://arxiv.org/pdf/2006.11239.pdf
									lowercase__						=				(alpha_prod_t_prev ** 0.5 * state.common.betas[t]) / beta_prod_t
									lowercase__						=				state.common.alphas[t] ** 0.5 * beta_prod_t_prev / beta_prod_t

									# 5. Compute predicted previous sample µ_t
									# See formula (7) from https://arxiv.org/pdf/2006.11239.pdf
									lowercase__						=				pred_original_sample_coeff * pred_original_sample + current_sample_coeff * sample

									# 6. Add noise
									def random_variance():
											lowercase__						=				jax.random.split(UpperCamelCase_   ,						num=1							)
											lowercase__						=				jax.random.normal(UpperCamelCase_   ,						shape=model_output.shape   ,						dtype=self.dtype							)
											return (self._get_variance(UpperCamelCase_   ,						UpperCamelCase_   ,						predicted_variance=UpperCamelCase_							) ** 0.5) * noise

									lowercase__						=				jnp.where(t > 0   ,						random_variance()   ,						jnp.zeros(model_output.shape   ,						dtype=self.dtype							)							)

									lowercase__						=				pred_prev_sample + variance

									if not return_dict:
											return (pred_prev_sample, state)

									return FlaxDDPMSchedulerOutput(prev_sample=UpperCamelCase_   ,						state=UpperCamelCase_							)

							def 				lowerCamelCase_			(							self:     int   ,						UpperCamelCase_:     DDPMSchedulerState   ,						UpperCamelCase_:     jnp.ndarray   ,						UpperCamelCase_:     jnp.ndarray   ,						UpperCamelCase_:     jnp.ndarray   ,						)      ->       jnp.ndarray:





									"""simple docstring"""







									return add_noise_common(state.common   ,						UpperCamelCase_   ,						UpperCamelCase_   ,						UpperCamelCase_							)

							def 				lowerCamelCase_			(							self:     List[str]   ,						UpperCamelCase_:     DDPMSchedulerState   ,						UpperCamelCase_:     jnp.ndarray   ,						UpperCamelCase_:     jnp.ndarray   ,						UpperCamelCase_:     jnp.ndarray   ,						)      ->       jnp.ndarray:





									"""simple docstring"""







									return get_velocity_common(state.common   ,						UpperCamelCase_   ,						UpperCamelCase_   ,						UpperCamelCase_							)


							def __len__(							self:     str							)      ->       List[Any]:





									"""simple docstring"""







									return self.config.num_train_timesteps


