



import flax.linen as nn
import jax.numpy as jnp

from .attention_flax import FlaxTransformeraDModel
from .resnet_flax import FlaxDownsampleaD, FlaxResnetBlockaD, FlaxUpsampleaD






class 						__a (     nn.Module				):
	SCREAMING_SNAKE_CASE       =       42
	SCREAMING_SNAKE_CASE       =       42
	SCREAMING_SNAKE_CASE       =       0.0
	SCREAMING_SNAKE_CASE       =       1
	SCREAMING_SNAKE_CASE       =       1
	SCREAMING_SNAKE_CASE       =       True
	SCREAMING_SNAKE_CASE       =       False
	SCREAMING_SNAKE_CASE       =       False
	SCREAMING_SNAKE_CASE       =       False
	SCREAMING_SNAKE_CASE       =       jnp.floataa



	def 		UpperCamelCase							(						self							:    Tuple)->							Dict:
						__lowerCAmelCase	   =[]
						__lowerCAmelCase	   =[]

						for i in range(self.num_layers):
											__lowerCAmelCase	   =self.in_channels if i == 0 else self.out_channels

											__lowerCAmelCase	   =FlaxResnetBlockaD(
											    in_channels=snake_case_				,	out_channels=self.out_channels				,	dropout_prob=self.dropout				,	dtype=self.dtype				,	)
											resnets.append(snake_case_)

											__lowerCAmelCase	   =FlaxTransformeraDModel(
											    in_channels=self.out_channels				,	n_heads=self.num_attention_heads				,	d_head=self.out_channels // self.num_attention_heads				,	depth=1				,	use_linear_projection=self.use_linear_projection				,	only_cross_attention=self.only_cross_attention				,	use_memory_efficient_attention=self.use_memory_efficient_attention				,	dtype=self.dtype				,	)
											attentions.append(snake_case_)

						__lowerCAmelCase	   =resnets
						__lowerCAmelCase	   =attentions

						if self.add_downsample:
											__lowerCAmelCase	   =FlaxDownsampleaD(self.out_channels				,	dtype=self.dtype)



	def __call__(						self							:    str				,	snake_case_							:    Dict				,	snake_case_							:    List[str]				,	snake_case_							:    List[str]				,	snake_case_							:    Optional[int]=True)->							Optional[int]:
						__lowerCAmelCase	   =()

						for resnet, attn in zip(self.resnets				,	self.attentions):
											__lowerCAmelCase	   =resnet(snake_case_				,	snake_case_				,	deterministic=snake_case_)
											__lowerCAmelCase	   =attn(snake_case_				,	snake_case_				,	deterministic=snake_case_)
											output_states += (hidden_states,)

						if self.add_downsample:
											__lowerCAmelCase	   =self.downsamplers_a(snake_case_)
											output_states += (hidden_states,)

						return hidden_states, output_states






class 						__a (     nn.Module				):
	SCREAMING_SNAKE_CASE       =       42
	SCREAMING_SNAKE_CASE       =       42
	SCREAMING_SNAKE_CASE       =       0.0
	SCREAMING_SNAKE_CASE       =       1
	SCREAMING_SNAKE_CASE       =       True
	SCREAMING_SNAKE_CASE       =       jnp.floataa



	def 		UpperCamelCase							(						self							:    str)->							Tuple:
						__lowerCAmelCase	   =[]

						for i in range(self.num_layers):
											__lowerCAmelCase	   =self.in_channels if i == 0 else self.out_channels

											__lowerCAmelCase	   =FlaxResnetBlockaD(
											    in_channels=snake_case_				,	out_channels=self.out_channels				,	dropout_prob=self.dropout				,	dtype=self.dtype				,	)
											resnets.append(snake_case_)
						__lowerCAmelCase	   =resnets

						if self.add_downsample:
											__lowerCAmelCase	   =FlaxDownsampleaD(self.out_channels				,	dtype=self.dtype)



	def __call__(						self							:    Dict				,	snake_case_							:    List[str]				,	snake_case_							:    List[Any]				,	snake_case_							:    Optional[int]=True)->							Optional[Any]:
						__lowerCAmelCase	   =()

						for resnet in self.resnets:
											__lowerCAmelCase	   =resnet(snake_case_				,	snake_case_				,	deterministic=snake_case_)
											output_states += (hidden_states,)

						if self.add_downsample:
											__lowerCAmelCase	   =self.downsamplers_a(snake_case_)
											output_states += (hidden_states,)

						return hidden_states, output_states






class 						__a (     nn.Module				):
	SCREAMING_SNAKE_CASE       =       42
	SCREAMING_SNAKE_CASE       =       42
	SCREAMING_SNAKE_CASE       =       42
	SCREAMING_SNAKE_CASE       =       0.0
	SCREAMING_SNAKE_CASE       =       1
	SCREAMING_SNAKE_CASE       =       1
	SCREAMING_SNAKE_CASE       =       True
	SCREAMING_SNAKE_CASE       =       False
	SCREAMING_SNAKE_CASE       =       False
	SCREAMING_SNAKE_CASE       =       False
	SCREAMING_SNAKE_CASE       =       jnp.floataa



	def 		UpperCamelCase							(						self							:    List[str])->							List[Any]:
						__lowerCAmelCase	   =[]
						__lowerCAmelCase	   =[]

						for i in range(self.num_layers):
											__lowerCAmelCase	   =self.in_channels if (i == self.num_layers - 1) else self.out_channels
											__lowerCAmelCase	   =self.prev_output_channel if i == 0 else self.out_channels

											__lowerCAmelCase	   =FlaxResnetBlockaD(
											    in_channels=resnet_in_channels + res_skip_channels				,	out_channels=self.out_channels				,	dropout_prob=self.dropout				,	dtype=self.dtype				,	)
											resnets.append(snake_case_)

											__lowerCAmelCase	   =FlaxTransformeraDModel(
											    in_channels=self.out_channels				,	n_heads=self.num_attention_heads				,	d_head=self.out_channels // self.num_attention_heads				,	depth=1				,	use_linear_projection=self.use_linear_projection				,	only_cross_attention=self.only_cross_attention				,	use_memory_efficient_attention=self.use_memory_efficient_attention				,	dtype=self.dtype				,	)
											attentions.append(snake_case_)

						__lowerCAmelCase	   =resnets
						__lowerCAmelCase	   =attentions

						if self.add_upsample:
											__lowerCAmelCase	   =FlaxUpsampleaD(self.out_channels				,	dtype=self.dtype)



	def __call__(						self							:    Optional[int]				,	snake_case_							:    Dict				,	snake_case_							:    Dict				,	snake_case_							:    Any				,	snake_case_							:    List[str]				,	snake_case_							:    Optional[Any]=True)->							Tuple:
						for resnet, attn in zip(self.resnets				,	self.attentions):
											# pop res hidden states
											__lowerCAmelCase	   =res_hidden_states_tuple[-1]
											__lowerCAmelCase	   =res_hidden_states_tuple[:-1]
											__lowerCAmelCase	   =jnp.concatenate((hidden_states, res_hidden_states)				,	axis=-1)

											__lowerCAmelCase	   =resnet(snake_case_				,	snake_case_				,	deterministic=snake_case_)
											__lowerCAmelCase	   =attn(snake_case_				,	snake_case_				,	deterministic=snake_case_)

						if self.add_upsample:
											__lowerCAmelCase	   =self.upsamplers_a(snake_case_)

						return hidden_states






class 						__a (     nn.Module				):
	SCREAMING_SNAKE_CASE       =       42
	SCREAMING_SNAKE_CASE       =       42
	SCREAMING_SNAKE_CASE       =       42
	SCREAMING_SNAKE_CASE       =       0.0
	SCREAMING_SNAKE_CASE       =       1
	SCREAMING_SNAKE_CASE       =       True
	SCREAMING_SNAKE_CASE       =       jnp.floataa



	def 		UpperCamelCase							(						self							:    Optional[Any])->							Dict:
						__lowerCAmelCase	   =[]

						for i in range(self.num_layers):
											__lowerCAmelCase	   =self.in_channels if (i == self.num_layers - 1) else self.out_channels
											__lowerCAmelCase	   =self.prev_output_channel if i == 0 else self.out_channels

											__lowerCAmelCase	   =FlaxResnetBlockaD(
											    in_channels=resnet_in_channels + res_skip_channels				,	out_channels=self.out_channels				,	dropout_prob=self.dropout				,	dtype=self.dtype				,	)
											resnets.append(snake_case_)

						__lowerCAmelCase	   =resnets

						if self.add_upsample:
											__lowerCAmelCase	   =FlaxUpsampleaD(self.out_channels				,	dtype=self.dtype)



	def __call__(						self							:    Optional[int]				,	snake_case_							:    Dict				,	snake_case_							:    Dict				,	snake_case_							:    Optional[Any]				,	snake_case_							:    List[Any]=True)->							Optional[Any]:
						for resnet in self.resnets:
											# pop res hidden states
											__lowerCAmelCase	   =res_hidden_states_tuple[-1]
											__lowerCAmelCase	   =res_hidden_states_tuple[:-1]
											__lowerCAmelCase	   =jnp.concatenate((hidden_states, res_hidden_states)				,	axis=-1)

											__lowerCAmelCase	   =resnet(snake_case_				,	snake_case_				,	deterministic=snake_case_)

						if self.add_upsample:
											__lowerCAmelCase	   =self.upsamplers_a(snake_case_)

						return hidden_states






class 						__a (     nn.Module				):
	SCREAMING_SNAKE_CASE       =       42
	SCREAMING_SNAKE_CASE       =       0.0
	SCREAMING_SNAKE_CASE       =       1
	SCREAMING_SNAKE_CASE       =       1
	SCREAMING_SNAKE_CASE       =       False
	SCREAMING_SNAKE_CASE       =       False
	SCREAMING_SNAKE_CASE       =       jnp.floataa



	def 		UpperCamelCase							(						self							:    List[str])->							List[str]:
						# there is always at least one resnet
						__lowerCAmelCase	   =[
						    FlaxResnetBlockaD(
						        in_channels=self.in_channels				,	out_channels=self.in_channels				,	dropout_prob=self.dropout				,	dtype=self.dtype				,	)
						]

						__lowerCAmelCase	   =[]

						for _ in range(self.num_layers):
											__lowerCAmelCase	   =FlaxTransformeraDModel(
											    in_channels=self.in_channels				,	n_heads=self.num_attention_heads				,	d_head=self.in_channels // self.num_attention_heads				,	depth=1				,	use_linear_projection=self.use_linear_projection				,	use_memory_efficient_attention=self.use_memory_efficient_attention				,	dtype=self.dtype				,	)
											attentions.append(snake_case_)

											__lowerCAmelCase	   =FlaxResnetBlockaD(
											    in_channels=self.in_channels				,	out_channels=self.in_channels				,	dropout_prob=self.dropout				,	dtype=self.dtype				,	)
											resnets.append(snake_case_)

						__lowerCAmelCase	   =resnets
						__lowerCAmelCase	   =attentions



	def __call__(						self							:    Tuple				,	snake_case_							:    int				,	snake_case_							:    List[Any]				,	snake_case_							:    List[Any]				,	snake_case_							:    Dict=True)->							Dict:
						__lowerCAmelCase	   =self.resnets[0](snake_case_				,	snake_case_)
						for attn, resnet in zip(self.attentions				,	self.resnets[1:]):
											__lowerCAmelCase	   =attn(snake_case_				,	snake_case_				,	deterministic=snake_case_)
											__lowerCAmelCase	   =resnet(snake_case_				,	snake_case_				,	deterministic=snake_case_)

						return hidden_states









def 					__lowerCAmelCase		(  __lowerCamelCase	:    int	)  ->						None:
					__lowerCAmelCase	   =generate_pascal_triangle(__lowerCamelCase	)
					for row_idx in range(__lowerCamelCase	):
										# Print left spaces
										for _ in range(num_rows - row_idx - 1	):
															print(end=""" """	)
										# Print row values
										for col_idx in range(row_idx + 1	):
															if col_idx != row_idx:
																				print(triangle[row_idx][col_idx]				,   end=""" """	)
															else:
																				print(triangle[row_idx][col_idx]				,   end=""""""	)
										print()






def 					__lowerCAmelCase		(  __lowerCamelCase	:    int	)  ->						list[list[int]]:

					if not isinstance(__lowerCamelCase				,   __lowerCamelCase	):
										raise TypeError("""The input value of 'num_rows' should be 'int'"""	)

					if num_rows == 0:
										return []
					elif num_rows < 0:
										raise ValueError(
										    """The input value of 'num_rows' should be greater than or equal to 0"""	)

					__lowerCAmelCase	   =[]
					for current_row_idx in range(__lowerCamelCase	):
										__lowerCAmelCase	   =populate_current_row(__lowerCamelCase				,   __lowerCamelCase	)
										triangle.append(__lowerCamelCase	)
					return triangle






def 					__lowerCAmelCase		(  __lowerCamelCase	:    list[list[int]]				,   __lowerCamelCase	:    int	)  ->						list[int]:
					__lowerCAmelCase	   =[-1] * (current_row_idx + 1)
					# first and last elements of current row are equal to 1
					__lowerCAmelCase   ,	__lowerCAmelCase	   =1, 1
					for current_col_idx in range(1				,   __lowerCamelCase	):
										calculate_current_element(
										    __lowerCamelCase				,   __lowerCamelCase				,   __lowerCamelCase				,   __lowerCamelCase	)
					return current_row






def 					__lowerCAmelCase		(  __lowerCamelCase	:    list[list[int]]				,   __lowerCamelCase	:    list[int]				,   __lowerCamelCase	:    int				,   __lowerCamelCase	:    int				,   )  ->						None:
					__lowerCAmelCase	   =triangle[current_row_idx - 1][current_col_idx - 1]
					__lowerCAmelCase	   =triangle[current_row_idx - 1][current_col_idx]
					__lowerCAmelCase	   =above_to_left_elt + above_to_right_elt






def 					__lowerCAmelCase		(  __lowerCamelCase	:    int	)  ->						list[list[int]]:

					if not isinstance(__lowerCamelCase				,   __lowerCamelCase	):
										raise TypeError("""The input value of 'num_rows' should be 'int'"""	)

					if num_rows == 0:
										return []
					elif num_rows < 0:
										raise ValueError(
										    """The input value of 'num_rows' should be greater than or equal to 0"""	)

					__lowerCAmelCase	   =[[1]]

					for row_index in range(1				,   __lowerCamelCase	):
										__lowerCAmelCase	   =[0] + result[-1] + [0]
										__lowerCAmelCase	   =row_index + 1
										# Calculate the number of distinct elements in a row
										__lowerCAmelCase	   =sum(divmod(__lowerCamelCase				,   2	)	)
										__lowerCAmelCase	   =[
										    temp_row[i - 1] + temp_row[i] for i in range(1				,   distinct_elements + 1	)
										]
										__lowerCAmelCase	   =row_first_half[: (row_index + 1) // 2]
										row_second_half.reverse()
										__lowerCAmelCase	   =row_first_half + row_second_half
										result.append(__lowerCamelCase	)

					return result






def 					__lowerCAmelCase		(  )  ->						None:
					from collections.abc import Callable
					from timeit import timeit

					def benchmark_a_function(__lowerCamelCase	:    Callable				,   __lowerCamelCase	:    int	) -> None:
										__lowerCAmelCase	   =f"""{func.__name__}({value})"""
										__lowerCAmelCase	   =timeit(f"""__main__.{call}"""				,   setup="""import __main__"""	)
										# print(f"{call:38} = {func(value)} -- {timing:.4f} seconds")
										print(f"""{call:38} -- {timing:.4f} seconds"""	)

					for value in range(15	):  # (1, 7, 14):
										for func in (generate_pascal_triangle, generate_pascal_triangle_optimized):
															benchmark_a_function(__lowerCamelCase				,   __lowerCamelCase	)
										print()


if __name__ == "__main__":
				import doctest

				doctest.testmod()
				benchmark()




