
import gc
import unittest

import torch
from transformers import CLIPTextConfig, CLIPTextModel, CLIPTextModelWithProjection, CLIPTokenizer

from diffusers import (
    AutoencoderKL,
    DDIMScheduler,
    DDPMScheduler,
    PriorTransformer,
    StableUnCLIPPipeline,
    UNetaDConditionModel,
)
from diffusers.pipelines.stable_diffusion.stable_unclip_image_normalizer import StableUnCLIPImageNormalizer
from diffusers.utils.testing_utils import enable_full_determinism, load_numpy, require_torch_gpu, slow, torch_device

from ..pipeline_params import TEXT_TO_IMAGE_BATCH_PARAMS, TEXT_TO_IMAGE_IMAGE_PARAMS, TEXT_TO_IMAGE_PARAMS
from ..test_pipelines_common import (
    PipelineKarrasSchedulerTesterMixin,
    PipelineLatentTesterMixin,
    PipelineTesterMixin,
    assert_mean_pixel_difference,
)


enable_full_determinism()


class 			lowercase_		(      A  ,      A  ,      A  ,      unittest.TestCase       ):
       __lowerCamelCase				       =						StableUnCLIPPipeline
       __lowerCamelCase				       =						TEXT_TO_IMAGE_PARAMS
       __lowerCamelCase				       =						TEXT_TO_IMAGE_BATCH_PARAMS
       __lowerCamelCase				       =						TEXT_TO_IMAGE_IMAGE_PARAMS
       __lowerCamelCase				       =						TEXT_TO_IMAGE_IMAGE_PARAMS

       # TODO(will) Expected attn_bias.stride(1) == 0 to be true, but got false
       __lowerCamelCase				       =						False


       def 	_snake_case				(    self				)						->    List[str]:
              SCREAMING_SNAKE_CASE_							:				str		=32
              SCREAMING_SNAKE_CASE_							:				Dict		=embedder_hidden_size

              # prior components

              torch.manual_seed(0				)
              SCREAMING_SNAKE_CASE_							:				Union[str, Any]		=CLIPTokenizer.from_pretrained('''hf-internal-testing/tiny-random-clip'''				)

              torch.manual_seed(0				)
              SCREAMING_SNAKE_CASE_							:				Tuple		=CLIPTextModelWithProjection(
                  CLIPTextConfig(
                      bos_token_id=0						,       eos_token_id=2						,       hidden_size=__A						,       projection_dim=__A						,       intermediate_size=37						,       layer_norm_eps=1e-0_5						,       num_attention_heads=4						,       num_hidden_layers=5						,       pad_token_id=1						,       vocab_size=1_000						,       )				)

              torch.manual_seed(0				)
              SCREAMING_SNAKE_CASE_							:				str		=PriorTransformer(
                  num_attention_heads=2						,       attention_head_dim=12						,       embedding_dim=__A						,       num_layers=1						,       )

              torch.manual_seed(0				)
              SCREAMING_SNAKE_CASE_							:				Union[str, Any]		=DDPMScheduler(
                  variance_type='''fixed_small_log'''						,       prediction_type='''sample'''						,       num_train_timesteps=1_000						,       clip_sample=__A						,       clip_sample_range=5.0						,       beta_schedule='''squaredcos_cap_v2'''						,       )

              # regular denoising components

              torch.manual_seed(0				)
              SCREAMING_SNAKE_CASE_							:				List[Any]		=StableUnCLIPImageNormalizer(embedding_dim=__A				)
              SCREAMING_SNAKE_CASE_							:				Any		=DDPMScheduler(beta_schedule='''squaredcos_cap_v2'''				)

              torch.manual_seed(0				)
              SCREAMING_SNAKE_CASE_							:				Optional[int]		=CLIPTokenizer.from_pretrained('''hf-internal-testing/tiny-random-clip'''				)

              torch.manual_seed(0				)
              SCREAMING_SNAKE_CASE_							:				Union[str, Any]		=CLIPTextModel(
                  CLIPTextConfig(
                      bos_token_id=0						,       eos_token_id=2						,       hidden_size=__A						,       projection_dim=32						,       intermediate_size=37						,       layer_norm_eps=1e-0_5						,       num_attention_heads=4						,       num_hidden_layers=5						,       pad_token_id=1						,       vocab_size=1_000						,       )				)

              torch.manual_seed(0				)
              SCREAMING_SNAKE_CASE_							:				Dict		=UNetaDConditionModel(
                  sample_size=32						,       in_channels=4						,       out_channels=4						,       down_block_types=('''CrossAttnDownBlock2D''', '''DownBlock2D''')						,       up_block_types=('''UpBlock2D''', '''CrossAttnUpBlock2D''')						,       block_out_channels=(32, 64)						,       attention_head_dim=(2, 4)						,       class_embed_type='''projection'''						,       projection_class_embeddings_input_dim=embedder_projection_dim * 2						,       cross_attention_dim=__A						,       layers_per_block=1						,       upcast_attention=__A						,       use_linear_projection=__A						,       )

              torch.manual_seed(0				)
              SCREAMING_SNAKE_CASE_							:				Tuple		=DDIMScheduler(
                  beta_schedule='''scaled_linear'''						,       beta_start=0.00_085						,       beta_end=0.012						,       prediction_type='''v_prediction'''						,       set_alpha_to_one=__A						,       steps_offset=1						,       )

              torch.manual_seed(0				)
              SCREAMING_SNAKE_CASE_							:				int		=AutoencoderKL()

              SCREAMING_SNAKE_CASE_							:				Union[str, Any]		={
                  # prior components
                  '''prior_tokenizer''': prior_tokenizer,
                  '''prior_text_encoder''': prior_text_encoder,
                  '''prior''': prior,
                  '''prior_scheduler''': prior_scheduler,
                  # image noising components
                  '''image_normalizer''': image_normalizer,
                  '''image_noising_scheduler''': image_noising_scheduler,
                  # regular denoising components
                  '''tokenizer''': tokenizer,
                  '''text_encoder''': text_encoder,
                  '''unet''': unet,
                  '''scheduler''': scheduler,
                  '''vae''': vae,
              }

              return components


       def 	_snake_case				(    self						,       __A						,       __A=0				)						->    int:
              if str(__A				).startswith('''mps'''				):
                     SCREAMING_SNAKE_CASE_							:				Dict		=torch.manual_seed(__A				)
              else:
                     SCREAMING_SNAKE_CASE_							:				int		=torch.Generator(device=__A				).manual_seed(__A				)
              SCREAMING_SNAKE_CASE_							:				List[str]		={
                  '''prompt''': '''A painting of a squirrel eating a burger''',
                  '''generator''': generator,
                  '''num_inference_steps''': 2,
                  '''prior_num_inference_steps''': 2,
                  '''output_type''': '''numpy''',
              }
              return inputs


       def 	_snake_case				(    self				)						->    List[Any]:
              SCREAMING_SNAKE_CASE_							:				str		=torch_device == '''cpu'''

              self._test_attention_slicing_forward_pass(test_max_difference=__A				)





       def 	_snake_case				(    self				)						->    Any:
              SCREAMING_SNAKE_CASE_							:				str		=torch_device in ['''cpu''', '''mps''']

              self._test_inference_batch_single_identical(test_max_difference=__A				)






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


       def 	_snake_case				(    self				)						->    Optional[int]:
              # clean up the VRAM after each test
              super().tearDown()
              gc.collect()
              torch.cuda.empty_cache()


       def 	_snake_case				(    self				)						->    str:
              SCREAMING_SNAKE_CASE_							:				int		=load_numpy(
                  '''https://huggingface.co/datasets/hf-internal-testing/diffusers-images/resolve/main/stable_unclip/stable_unclip_2_1_l_anime_turtle_fp16.npy'''				)

              SCREAMING_SNAKE_CASE_							:				List[Any]		=StableUnCLIPPipeline.from_pretrained('''fusing/stable-unclip-2-1-l'''						,       torch_dtype=torch.floataa				)
              pipe.to(__A				)
              pipe.set_progress_bar_config(disable=__A				)
              # stable unclip will oom when integration tests are run on a V100,
              # so turn on memory savings
              pipe.enable_attention_slicing()
              pipe.enable_sequential_cpu_offload()

              SCREAMING_SNAKE_CASE_							:				Dict		=torch.Generator(device='''cpu'''				).manual_seed(0				)
              SCREAMING_SNAKE_CASE_							:				Tuple		=pipe('''anime turle'''						,       generator=__A						,       output_type='''np'''				)

              SCREAMING_SNAKE_CASE_							:				Optional[int]		=output.images[0]

              assert image.shape == (768, 768, 3)

              assert_mean_pixel_difference(__A						,       __A				)





       def 	_snake_case				(    self				)						->    Tuple:
              torch.cuda.empty_cache()
              torch.cuda.reset_max_memory_allocated()
              torch.cuda.reset_peak_memory_stats()

              SCREAMING_SNAKE_CASE_							:				str		=StableUnCLIPPipeline.from_pretrained('''fusing/stable-unclip-2-1-l'''						,       torch_dtype=torch.floataa				)
              SCREAMING_SNAKE_CASE_							:				Tuple		=pipe.to(__A				)
              pipe.set_progress_bar_config(disable=__A				)
              pipe.enable_attention_slicing()
              pipe.enable_sequential_cpu_offload()

              SCREAMING_SNAKE_CASE_							:				Optional[Any]		=pipe(
                  '''anime turtle'''						,       prior_num_inference_steps=2						,       num_inference_steps=2						,       output_type='''np'''						,       )

              SCREAMING_SNAKE_CASE_							:				Dict		=torch.cuda.max_memory_allocated()
              # make sure that less than 7 GB is allocated
              assert mem_bytes < 7 * 10**9


from math import ceil, sqrt
def 							SCREAMING_SNAKE_CASE_	(					UpperCAmelCase_	:     int = 1_0_0_0_0_0_0				)			->						int:
       SCREAMING_SNAKE_CASE_							:				List[Any]		=0

       for outer_width in range(3			,							(limit // 4) + 2				):
              if outer_width**2 > limit:
                     SCREAMING_SNAKE_CASE_							:				List[str]		=max(ceil(sqrt(outer_width**2 - limit				)				)			,							1				)
              else:
                     SCREAMING_SNAKE_CASE_							:				List[str]		=1
              if (outer_width - hole_width_lower_bound) % 2:
                     hole_width_lower_bound += 1

              answer += (outer_width - hole_width_lower_bound - 2) // 2 + 1

       return answer


if __name__ == "__main__":
 print(F"{solution() = }")
