'''simple docstring'''





import logging
from pathlib import Path

import numpy as np
import pytorch_lightning as pl
import torch
from pytorch_lightning.callbacks import EarlyStopping, ModelCheckpoint
from pytorch_lightning.utilities import rank_zero_only
from utils_rag import save_json





def       lowerCAmelCase_							(   snake_case_			:					Optional[int]     )       -> Optional[int]:


     '''simple docstring'''




     UpperCAmelCase_			       =  filter(lambda snake_case_     : p.requires_grad   ,       model.parameters()     )
     UpperCAmelCase_			       =  sum([np.prod(p.size()     ) for p in model_parameters]     )
     return params


SCREAMING_SNAKE_CASE_:	Tuple    =logging.getLogger(__name__)





def       lowerCAmelCase_							(   snake_case_			:					str   ,       snake_case_			:					List[Any]     )       -> Union[str, Any]:


     '''simple docstring'''




     if metric == "rouge2":
          UpperCAmelCase_			       =  "{val_avg_rouge2:.4f}-{step_count}"
     elif metric == "bleu":
          UpperCAmelCase_			       =  "{val_avg_bleu:.4f}-{step_count}"
     elif metric == "em":
          UpperCAmelCase_			       =  "{val_avg_em:.4f}-{step_count}"
     else:
          raise NotImplementedError(
              f"""seq2seq callbacks only support rouge2 and bleu, got {metric}, You can make your own by adding to this"""
              " function."     )

     UpperCAmelCase_			       =  ModelCheckpoint(
         dirpath=snake_case_   ,       filename=snake_case_   ,       monitor=f"""val_{metric}"""   ,       mode="max"   ,       save_top_k=3   ,       every_n_epochs=1   ,       )
     return checkpoint_callback





def       lowerCAmelCase_							(   snake_case_			:					Union[str, Any]   ,       snake_case_			:					Optional[int]     )       -> Any:


     '''simple docstring'''




     return EarlyStopping(
         monitor=f"""val_{metric}"""   ,       mode="min" if "loss" in metric else "max"   ,       patience=snake_case_   ,       verbose=snake_case_   ,       )






class 			__A (					pl.Callback      ):



    def    _lowercase		(self       :       Optional[Any]  ,     __a       :       Optional[int]  ,     __a       :       Any					):
         UpperCAmelCase_			       =  {f"""lr_group_{i}""": param["lr"] for i, param in enumerate(pl_module.trainer.optimizers[0].param_groups					)}
         pl_module.logger.log_metrics(__a					)



    @rank_zero_only
    def    _lowercase		(self       :       str  ,     __a       :       pl.Trainer  ,     __a       :       pl.LightningModule  ,     __a       :       str  ,     __a       :       Optional[Any]=True					):
         logger.info(f"""***** {type_path} results at step {trainer.global_step:05d} *****"""					)
         UpperCAmelCase_			       =  trainer.callback_metrics
         trainer.logger.log_metrics({k: v for k, v in metrics.items() if k not in ["log", "progress_bar", "preds"]}					)
         # Log results
         UpperCAmelCase_			       =  Path(pl_module.hparams.output_dir					)
         if type_path == "test":
              UpperCAmelCase_			       =  od / "test_results.txt"
              UpperCAmelCase_			       =  od / "test_generations.txt"
         else:
              # this never gets hit. I prefer not to save intermediate generations, and results are in metrics.json
              # If people want this it will be easy enough to add back.
              UpperCAmelCase_			       =  od / f"""{type_path}_results/{trainer.global_step:05d}.txt"""
              UpperCAmelCase_			       =  od / f"""{type_path}_generations/{trainer.global_step:05d}.txt"""
              results_file.parent.mkdir(exist_ok=__a					)
              generations_file.parent.mkdir(exist_ok=__a					)
         with open(__a  ,     "a+"					) as writer:
              for key in sorted(__a					):
                   if key in ["log", "progress_bar", "preds"]:
                        continue
                   UpperCAmelCase_			       =  metrics[key]
                   if isinstance(__a  ,     torch.Tensor					):
                        UpperCAmelCase_			       =  val.item()
                   UpperCAmelCase_			       =  f"""{key}: {val:.6f}\n"""
                   writer.write(__a					)

         if not save_generations:
              return

         if "preds" in metrics:
              UpperCAmelCase_			       =  "\n".join(metrics["preds"]					)
              generations_file.open("w+"					).write(__a					)



    @rank_zero_only
    def    _lowercase		(self       :       int  ,     __a       :       Optional[int]  ,     __a       :       List[Any]					):
         try:
              UpperCAmelCase_			       =  pl_module.model.model.num_parameters()
         except AttributeError:
              UpperCAmelCase_			       =  pl_module.model.num_parameters()

         UpperCAmelCase_			       =  count_trainable_parameters(__a					)
         # mp stands for million parameters
         trainer.logger.log_metrics({"n_params": npars, "mp": npars / 1E6, "grad_mp": n_trainable_pars / 1E6}					)



    @rank_zero_only
    def    _lowercase		(self       :       Optional[Any]  ,     __a       :       pl.Trainer  ,     __a       :       pl.LightningModule					):
         save_json(pl_module.metrics  ,     pl_module.metrics_save_path					)
         return self._write_logs(__a  ,     __a  ,     "test"					)






    @rank_zero_only
    def    _lowercase		(self       :       List[Any]  ,     __a       :       pl.Trainer  ,     __a       :       int					):
         save_json(pl_module.metrics  ,     pl_module.metrics_save_path					)
         # Uncommenting this will save val generations
         # return self._write_logs(trainer, pl_module, "valid")









import random
import unittest

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

from diffusers import (
    AutoencoderKL,
    DDIMScheduler,
    UNetaDConditionModel,
    VideoToVideoSDPipeline,
)
from diffusers.utils import floats_tensor, is_xformers_available, skip_mps
from diffusers.utils.testing_utils import enable_full_determinism, slow, torch_device

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


enable_full_determinism()



@skip_mps
class        lowerCAmelCase__					(  _lowerCamelCase ,				unittest.TestCase       ):
				A_   :     int								=     VideoToVideoSDPipeline
				A_   :     Optional[Any]								=     TEXT_GUIDED_IMAGE_VARIATION_PARAMS.union({'video'}       ) - {'image', 'width', 'height'}
				A_   :     List[str]								=     TEXT_GUIDED_IMAGE_VARIATION_BATCH_PARAMS.union({'video'}       ) - {'image'}
				A_   :     Tuple								=     PipelineTesterMixin.required_optional_params - {'latents'}
				A_   :     Dict								=     False

				# No `output_type`.
				A_   :     str								=     frozenset(
				    [
				        'num_inference_steps',
				        'generator',
				        'latents',
				        'return_dict',
				        'callback',
				        'callback_steps',
				    ]       )


				def __UpperCamelCase						(							self      :  Optional[int]       )		->     List[Any]:
											torch.manual_seed(0       )
											A      						=    UNetaDConditionModel(
											    block_out_channels=(32, 64, 64, 64)						, layers_per_block=2						, sample_size=32						, in_channels=4						, out_channels=4						, down_block_types=('CrossAttnDownBlock3D', 'CrossAttnDownBlock3D', 'CrossAttnDownBlock3D', 'DownBlock3D')						, up_block_types=('UpBlock3D', 'CrossAttnUpBlock3D', 'CrossAttnUpBlock3D', 'CrossAttnUpBlock3D')						, cross_attention_dim=32						, attention_head_dim=4						, )
											A      						=    DDIMScheduler(
											    beta_start=0.0_0_0_8_5						, beta_end=0.0_1_2						, beta_schedule='scaled_linear'						, clip_sample=__UpperCamelCase						, set_alpha_to_one=__UpperCamelCase						, )
											torch.manual_seed(0       )
											A      						=    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						, sample_size=128						, )
											torch.manual_seed(0       )
											A      						=    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=1_000						, hidden_act='gelu'						, projection_dim=512						, )
											A      						=    CLIPTextModel(__UpperCamelCase       )
											A      						=    CLIPTokenizer.from_pretrained('hf-internal-testing/tiny-random-clip'       )

											A      						=    {
											    'unet': unet,
											    'scheduler': scheduler,
											    'vae': vae,
											    'text_encoder': text_encoder,
											    'tokenizer': tokenizer,
											}
											return components


				def __UpperCamelCase						(							self      :  Optional[Any]						, __UpperCamelCase      :  Any						, __UpperCamelCase      :  str=0       )		->     Optional[int]:
											# 3 frames
											A      						=    floats_tensor((1, 3, 3, 32, 32)						, rng=random.Random(__UpperCamelCase       )       ).to(__UpperCamelCase       )

											if str(__UpperCamelCase       ).startswith('mps'       ):
																		A      						=    torch.manual_seed(__UpperCamelCase       )
											else:
																		A      						=    torch.Generator(device=__UpperCamelCase       ).manual_seed(__UpperCamelCase       )
											A      						=    {
											    'prompt': 'A painting of a squirrel eating a burger',
											    'video': video,
											    'generator': generator,
											    'num_inference_steps': 2,
											    'guidance_scale': 6.0,
											    'output_type': 'pt',
											}
											return inputs


				def __UpperCamelCase						(							self      :  Optional[int]       )		->     str:
											A      						=    'cpu'  # ensure determinism for the device-dependent torch.Generator
											A      						=    self.get_dummy_components()
											A      						=    VideoToVideoSDPipeline(**__UpperCamelCase       )
											A      						=    sd_pipe.to(__UpperCamelCase       )
											sd_pipe.set_progress_bar_config(disable=__UpperCamelCase       )

											A      						=    self.get_dummy_inputs(__UpperCamelCase       )
											A      						=    'np'
											A      						=    sd_pipe(**__UpperCamelCase       ).frames
											A      						=    frames[0][-3:, -3:, -1]

											assert frames[0].shape == (32, 32, 3)
											A      						=    np.array([106, 117, 113, 174, 137, 112, 148, 151, 131]       )

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


				@unittest.skipIf(
				    torch_device != 'cuda' or not is_xformers_available()						, reason='XFormers attention is only available with CUDA and `xformers` installed'						, )
				def __UpperCamelCase						(							self      :  int       )		->     Tuple:
											self._test_xformers_attention_forwardGenerator_pass(test_mean_pixel_difference=__UpperCamelCase						, expected_max_diff=5e-3       )


				@unittest.skip(reason='Batching needs to be properly figured out first for this pipeline.'       )
				def __UpperCamelCase						(							self      :  Optional[int]       )		->     Any:
											pass


				@unittest.skip(reason='Batching needs to be properly figured out first for this pipeline.'       )
				def __UpperCamelCase						(							self      :  str       )		->     Any:
											pass


				@unittest.skip(reason='`num_images_per_prompt` argument is not supported for this pipeline.'       )
				def __UpperCamelCase						(							self      :  Union[str, Any]       )		->     Optional[Any]:
											pass


				def __UpperCamelCase						(							self      :  Any       )		->     Any:
											return super().test_progress_bar()





@slow
@skip_mps
class        lowerCAmelCase__					(  unittest.TestCase       ):


				def __UpperCamelCase						(							self      :  Optional[Any]       )		->     Dict:
											A      						=    VideoToVideoSDPipeline.from_pretrained('cerspense/zeroscope_v2_XL'						, torch_dtype=torch.floataa       )
											pipe.enable_model_cpu_offload()

											# 10 frames
											A      						=    torch.Generator(device='cpu'       ).manual_seed(0       )
											A      						=    torch.randn((1, 10, 3, 1_024, 576)						, generator=__UpperCamelCase       )
											A      						=    video.to('cuda'       )

											A      						=    'Spiderman is surfing'

											A      						=    pipe(__UpperCamelCase						, video=__UpperCamelCase						, generator=__UpperCamelCase						, num_inference_steps=3						, output_type='pt'       ).frames

											A      						=    np.array([-1.0_4_5_8_9_8_4, -1.1_2_7_9_2_9_7, -0.9_6_6_3_0_8_6, -0.9_1_5_0_3_9_0_6, -0.7_5_0_9_7_6_5_6]       )
											assert np.abs(video_frames.cpu().numpy()[0, 0, 0, 0, -5:] - expected_array       ).sum() < 1e-2