import tempfile
import unittest

import numpy as np
import torch

from diffusers import DiffusionPipeline
from diffusers.models.attention_processor import Attention, AttnAddedKVProcessor




class        _UpperCamelCase				(						unittest.TestCase			):


   """simple docstring"""






   def 	_SCREAMING_SNAKE_CASE      (       self				,       lowerCAmelCase__ = False						)					-> Any:

       '''simple docstring'''


       __lowercase			      =							10

       if only_cross_attention:
           __lowercase			      =							12
       else:
           # when only cross attention is not set, the cross attention dim must be the same as the query dim
           __lowercase			      =							query_dim

       return {
           "query_dim": query_dim,
           "cross_attention_dim": cross_attention_dim,
           "heads": 2,
           "dim_head": 4,
           "added_kv_proj_dim": 6,
           "norm_num_groups": 1,
           "only_cross_attention": only_cross_attention,
           "processor": AttnAddedKVProcessor(),
       }





   def 	_SCREAMING_SNAKE_CASE      (       self				,       lowerCAmelCase__				,       lowerCAmelCase__						)					-> Optional[Any]:

       '''simple docstring'''


       __lowercase			      =							2

       __lowercase			      =							torch.rand(lowerCAmelCase__				,       lowerCAmelCase__				,       3				,       2						)
       __lowercase			      =							torch.rand(lowerCAmelCase__				,       4				,       lowerCAmelCase__						)
       __lowercase			      =							None

       return {
           "hidden_states": hidden_states,
           "encoder_hidden_states": encoder_hidden_states,
           "attention_mask": attention_mask,
       }





   def 	_SCREAMING_SNAKE_CASE      (       self						)					-> List[Any]:

       '''simple docstring'''


       torch.manual_seed(0						)

       __lowercase			      =							self.get_constructor_arguments(only_cross_attention=lowerCAmelCase__						)
       __lowercase			      =							Attention(**lowerCAmelCase__						)

       self.assertTrue(attn.to_k is not None						)
       self.assertTrue(attn.to_v is not None						)

       __lowercase			      =							self.get_forward_arguments(
           query_dim=constructor_args['''query_dim''']				,       added_kv_proj_dim=constructor_args['''added_kv_proj_dim''']						)

       __lowercase			      =							attn(**lowerCAmelCase__						)

       # only self attention

       torch.manual_seed(0						)

       __lowercase			      =							self.get_constructor_arguments(only_cross_attention=lowerCAmelCase__						)
       __lowercase			      =							Attention(**lowerCAmelCase__						)

       self.assertTrue(attn.to_k is None						)
       self.assertTrue(attn.to_v is None						)

       __lowercase			      =							self.get_forward_arguments(
           query_dim=constructor_args['''query_dim''']				,       added_kv_proj_dim=constructor_args['''added_kv_proj_dim''']						)

       __lowercase			      =							attn(**lowerCAmelCase__						)

       self.assertTrue((only_cross_attn_out != self_and_cross_attn_out).all()						)




class        _UpperCamelCase				(						unittest.TestCase			):


   """simple docstring"""






   def 	_SCREAMING_SNAKE_CASE      (       self						)					-> Optional[Any]:

       '''simple docstring'''


       __lowercase			      =							DiffusionPipeline.from_pretrained('''hf-internal-testing/tiny-stable-diffusion-pipe'''				,       safety_checker=lowerCAmelCase__						)

       __lowercase			      =							pipe(
           '''foo'''				,       num_inference_steps=2				,       generator=torch.Generator('''cpu'''						).manual_seed(0						)				,       output_type='''np'''				,       ).images

       # the initial conversion succeeds
       __lowercase			      =							DiffusionPipeline.from_pretrained(
           '''hf-internal-testing/tiny-stable-diffusion-pipe'''				,       device_map='''sequential'''				,       safety_checker=lowerCAmelCase__						)

       __lowercase			      =							pipe(
           '''foo'''				,       num_inference_steps=2				,       generator=torch.Generator('''cpu'''						).manual_seed(0						)				,       output_type='''np'''				,       ).images

       with tempfile.TemporaryDirectory() as tmpdir:
           # save the converted model
           pipe.save_pretrained(lowerCAmelCase__						)

           # can also load the converted weights
           __lowercase			      =							DiffusionPipeline.from_pretrained(lowerCAmelCase__				,       device_map='''sequential'''				,       safety_checker=lowerCAmelCase__						)

       __lowercase			      =							pipe(
           '''foo'''				,       num_inference_steps=2				,       generator=torch.Generator('''cpu'''						).manual_seed(0						)				,       output_type='''np'''				,       ).images

       self.assertTrue(np.allclose(lowerCAmelCase__				,       lowerCAmelCase__				,       atol=1E-5						)						)
       self.assertTrue(np.allclose(lowerCAmelCase__				,       lowerCAmelCase__				,       atol=1E-5						)						)
import timeit




class        _UpperCamelCase				:


			"""simple docstring"""






			def __init__(       self				,       lowerCAmelCase__						)					-> List[str]:

							'''simple docstring'''


							if isinstance(lowerCAmelCase__				,       lowerCAmelCase__						):  # Initializes a matrix identical to the one provided.
											__lowercase			      =							arg
											__lowercase			      =							len(lowerCAmelCase__						)
							else:  # Initializes a square matrix of the given size and set values to zero.
											__lowercase			      =							arg
											__lowercase			      =							[[0 for _ in range(self.n						)] for _ in range(self.n						)]





			def __mul__(       self				,       lowerCAmelCase__						)					-> str:

							'''simple docstring'''


							__lowercase			      =							Matrix(self.n						)
							for i in range(self.n						):
											for j in range(self.n						):
															for k in range(self.n						):
																			matrix.t[i][j] += self.t[i][k] * b.t[k][j]
							return matrix





def     UpperCAmelCase						(   lowercase							,      lowercase							):







				"""simple docstring"""



				__lowercase			      =							Matrix([[1, 0], [0, 1]]							)
				while b > 0:
								if b & 1:
												matrix *= a
								a *= a
								b >>= 1
				return matrix





def     UpperCAmelCase						(   lowercase							,      lowercase							,      lowercase							):







				"""simple docstring"""



				if n == 1:
								return fa
				elif n == 2:
								return fa
				__lowercase			      =							Matrix([[1, 1], [1, 0]]							)
				__lowercase			      =							modular_exponentiation(lowercase							,      n - 2							)
				return fa * matrix.t[0][0] + fa * matrix.t[0][1]





def     UpperCAmelCase						(   lowercase							,      lowercase							,      lowercase							):







				"""simple docstring"""



				if n == 1:
								return fa
				elif n == 2:
								return fa

				__lowercase			      =							fa
				__lowercase			      =							fa
				n -= 2

				while n > 0:
								__lowercase      ,					__lowercase			      =							fn_a + fn_a, fn_a
								n -= 1

				return fn_a





def     UpperCAmelCase						(   ):







				"""simple docstring"""



				__lowercase			      =							'''
from random import randint
from __main__ import fibonacci_with_matrix_exponentiation
'''
				__lowercase			      =							'''fibonacci_with_matrix_exponentiation(randint(1,70000), 1, 1)'''
				__lowercase			      =							timeit.timeit(setup=lowercase							,      stmt=lowercase							,      number=100							)
				print('''With matrix exponentiation the average execution time is '''							,      exec_time / 100							)
				return exec_time





def     UpperCAmelCase						(   ):







				"""simple docstring"""



				__lowercase			      =							'''
from random import randint
from __main__ import simple_fibonacci
'''
				__lowercase			      =							'''simple_fibonacci(randint(1,70000), 1, 1)'''
				__lowercase			      =							timeit.timeit(setup=lowercase							,      stmt=lowercase							,      number=100							)
				print(
				    '''Without matrix exponentiation the average execution time is '''							,      exec_time / 100							)
				return exec_time





def     UpperCAmelCase						(   ):







				"""simple docstring"""



				matrix_exponentiation_time()
				simple_fibonacci_time()


if __name__ == "__main__":
		main()