


from typing import Optional, Tuple, Union

import flax
import flax.linen as nn
import jax
import jax.numpy as jnp
from flax.core.frozen_dict import FrozenDict

from ..configuration_utils import ConfigMixin, flax_register_to_config
from ..utils import BaseOutput
from .embeddings_flax import FlaxTimestepEmbedding, FlaxTimesteps
from .modeling_flax_utils import FlaxModelMixin
from .unet_ad_blocks_flax import (
    FlaxCrossAttnDownBlockaD,
    FlaxCrossAttnUpBlockaD,
    FlaxDownBlockaD,
    FlaxUNetMidBlockaDCrossAttn,
    FlaxUpBlockaD,
)




@flax.struct.dataclass
class       lowercase_					(lowercase__   ):
				snake_case	    =42







@flax_register_to_config
class       lowercase_					(nn.Module      ,					lowercase__      ,					lowercase__   ):
				snake_case	    =32
				snake_case	    =4
				snake_case	    =4
				snake_case	    =(
				    "CrossAttnDownBlock2D",
				    "CrossAttnDownBlock2D",
				    "CrossAttnDownBlock2D",
				    "DownBlock2D",
				)
				snake_case	    =("UpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D")
				snake_case	    =False
				snake_case	    =(320, 640, 1280, 1280)
				snake_case	    =2
				snake_case	    =8
				snake_case	    =None
				snake_case	    =1280
				snake_case	    =0.0
				snake_case	    =False
				snake_case	    =jnp.floataa
				snake_case	    =True
				snake_case	    =0
				snake_case	    =False





				def 						__UpperCamelCase    (				self       ,  lowercase_)  -> FrozenDict:
											# init input tensors
											a__      =(1, self.in_channels, self.sample_size, self.sample_size)
											a__      =jnp.zeros(lowercase_       ,  dtype=jnp.floataa)
											a__      =jnp.ones((1,)       ,  dtype=jnp.intaa)
											a__      =jnp.zeros((1, 1, self.cross_attention_dim)       ,  dtype=jnp.floataa)

											a__    ,     a__      =jax.random.split(lowercase_)
											a__      ={'params': params_rng, 'dropout': dropout_rng}

											return self.init(lowercase_       ,  lowercase_       ,  lowercase_       ,  lowercase_)["params"]





				def 						__UpperCamelCase    (				self)  -> Union[str, Any]:
											a__      =self.block_out_channels
											a__      =block_out_channels[0] * 4

											if self.num_attention_heads is not None:
																		raise ValueError(
																		    'At the moment it is not possible to define the number of attention heads via `num_attention_heads` because of a naming issue as described in https://github.com/huggingface/diffusers/issues/2011#issuecomment-1547958131. Passing `num_attention_heads` will only be supported in diffusers v0.19.')

											# If `num_attention_heads` is not defined (which is the case for most models)
											# it will default to `attention_head_dim`. This looks weird upon first reading it and it is.
											# The reason for this behavior is to correct for incorrectly named variables that were introduced
											# when this library was created. The incorrect naming was only discovered much later in https://github.com/huggingface/diffusers/issues/2011#issuecomment-1547958131
											# Changing `attention_head_dim` to `num_attention_heads` for 40,000+ configurations is too backwards breaking
											# which is why we correct for the naming here.
											a__      =self.num_attention_heads or self.attention_head_dim

											# input
											a__      =nn.Conv(
											    block_out_channels[0]       ,  kernel_size=(3, 3)       ,  strides=(1, 1)       ,  padding=((1, 1), (1, 1))       ,  dtype=self.dtype       ,  )

											# time
											a__      =FlaxTimesteps(
											    block_out_channels[0]       ,  flip_sin_to_cos=self.flip_sin_to_cos       ,  freq_shift=self.config.freq_shift)
											a__      =FlaxTimestepEmbedding(lowercase_       ,  dtype=self.dtype)

											a__      =self.only_cross_attention
											if isinstance(lowercase_       ,  lowercase_):
																		a__      =(only_cross_attention,) * len(self.down_block_types)

											if isinstance(lowercase_       ,  lowercase_):
																		a__      =(num_attention_heads,) * len(self.down_block_types)

											# down
											a__      =[]
											a__      =block_out_channels[0]
											for i, down_block_type in enumerate(self.down_block_types):
																		a__      =output_channel
																		a__      =block_out_channels[i]
																		a__      =i == len(lowercase_) - 1

																		if down_block_type == "CrossAttnDownBlock2D":
																									a__      =FlaxCrossAttnDownBlockaD(
																									    in_channels=lowercase_       ,  out_channels=lowercase_       ,  dropout=self.dropout       ,  num_layers=self.layers_per_block       ,  num_attention_heads=num_attention_heads[i]       ,  add_downsample=not is_final_block       ,  use_linear_projection=self.use_linear_projection       ,  only_cross_attention=only_cross_attention[i]       ,  use_memory_efficient_attention=self.use_memory_efficient_attention       ,  dtype=self.dtype       ,  )
																		else:
																									a__      =FlaxDownBlockaD(
																									    in_channels=lowercase_       ,  out_channels=lowercase_       ,  dropout=self.dropout       ,  num_layers=self.layers_per_block       ,  add_downsample=not is_final_block       ,  dtype=self.dtype       ,  )

																		down_blocks.append(lowercase_)
											a__      =down_blocks

											# mid
											a__      =FlaxUNetMidBlockaDCrossAttn(
											    in_channels=block_out_channels[-1]       ,  dropout=self.dropout       ,  num_attention_heads=num_attention_heads[-1]       ,  use_linear_projection=self.use_linear_projection       ,  use_memory_efficient_attention=self.use_memory_efficient_attention       ,  dtype=self.dtype       ,  )

											# up
											a__      =[]
											a__      =list(reversed(lowercase_))
											a__      =list(reversed(lowercase_))
											a__      =list(reversed(lowercase_))
											a__      =reversed_block_out_channels[0]
											for i, up_block_type in enumerate(self.up_block_types):
																		a__      =output_channel
																		a__      =reversed_block_out_channels[i]
																		a__      =reversed_block_out_channels[min(i + 1       ,  len(lowercase_) - 1)]

																		a__      =i == len(lowercase_) - 1

																		if up_block_type == "CrossAttnUpBlock2D":
																									a__      =FlaxCrossAttnUpBlockaD(
																									    in_channels=lowercase_       ,  out_channels=lowercase_       ,  prev_output_channel=lowercase_       ,  num_layers=self.layers_per_block + 1       ,  num_attention_heads=reversed_num_attention_heads[i]       ,  add_upsample=not is_final_block       ,  dropout=self.dropout       ,  use_linear_projection=self.use_linear_projection       ,  only_cross_attention=only_cross_attention[i]       ,  use_memory_efficient_attention=self.use_memory_efficient_attention       ,  dtype=self.dtype       ,  )
																		else:
																									a__      =FlaxUpBlockaD(
																									    in_channels=lowercase_       ,  out_channels=lowercase_       ,  prev_output_channel=lowercase_       ,  num_layers=self.layers_per_block + 1       ,  add_upsample=not is_final_block       ,  dropout=self.dropout       ,  dtype=self.dtype       ,  )

																		up_blocks.append(lowercase_)
																		a__      =output_channel
											a__      =up_blocks

											# out
											a__      =nn.GroupNorm(num_groups=32       ,  epsilon=1e-5)
											a__      =nn.Conv(
											    self.out_channels       ,  kernel_size=(3, 3)       ,  strides=(1, 1)       ,  padding=((1, 1), (1, 1))       ,  dtype=self.dtype       ,  )





				def __call__(				self       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  lowercase_=None       ,  lowercase_=None       ,  lowercase_ = True       ,  lowercase_ = False       ,  )  -> Union[FlaxUNetaDConditionOutput, Tuple]:
											# 1. time
											if not isinstance(lowercase_       ,  jnp.ndarray):
																		a__      =jnp.array([timesteps]       ,  dtype=jnp.intaa)
											elif isinstance(lowercase_       ,  jnp.ndarray) and len(timesteps.shape) == 0:
																		a__      =timesteps.astype(dtype=jnp.floataa)
																		a__      =jnp.expand_dims(lowercase_       ,  0)

											a__      =self.time_proj(lowercase_)
											a__      =self.time_embedding(lowercase_)

											# 2. pre-process
											a__      =jnp.transpose(lowercase_       ,  (0, 2, 3, 1))
											a__      =self.conv_in(lowercase_)

											# 3. down
											a__      =(sample,)
											for down_block in self.down_blocks:
																		if isinstance(lowercase_       ,  lowercase_):
																									a__    ,     a__      =down_block(lowercase_       ,  lowercase_       ,  lowercase_       ,  deterministic=not train)
																		else:
																									a__    ,     a__      =down_block(lowercase_       ,  lowercase_       ,  deterministic=not train)
																		down_block_res_samples += res_samples

											if down_block_additional_residuals is not None:
																		a__      =()

																		for down_block_res_sample, down_block_additional_residual in zip(
																		    lowercase_       ,  lowercase_):
																									down_block_res_sample += down_block_additional_residual
																									new_down_block_res_samples += (down_block_res_sample,)

																		a__      =new_down_block_res_samples

											# 4. mid
											a__      =self.mid_block(lowercase_       ,  lowercase_       ,  lowercase_       ,  deterministic=not train)

											if mid_block_additional_residual is not None:
																		sample += mid_block_additional_residual

											# 5. up
											for up_block in self.up_blocks:
																		a__      =down_block_res_samples[-(self.layers_per_block + 1) :]
																		a__      =down_block_res_samples[: -(self.layers_per_block + 1)]
																		if isinstance(lowercase_       ,  lowercase_):
																									a__      =up_block(
																									    lowercase_       ,  temb=lowercase_       ,  encoder_hidden_states=lowercase_       ,  res_hidden_states_tuple=lowercase_       ,  deterministic=not train       ,  )
																		else:
																									a__      =up_block(lowercase_       ,  temb=lowercase_       ,  res_hidden_states_tuple=lowercase_       ,  deterministic=not train)

        # 6. post-process
											a__      =self.conv_norm_out(lowercase_)
											a__      =nn.silu(lowercase_)
											a__      =self.conv_out(lowercase_)
											a__      =jnp.transpose(lowercase_       ,  (0, 3, 1, 2))

											if not return_dict:
																		return (sample,)

											return FlaxUNetaDConditionOutput(sample=lowercase_)





import absl  # noqa: F401 # Here to have a nice missing dependency error message early on
import nltk  # noqa: F401 # Here to have a nice missing dependency error message early on
import numpy  # noqa: F401 # Here to have a nice missing dependency error message early on
import six  # noqa: F401 # Here to have a nice missing dependency error message early on
from rouge_score import rouge_scorer, scoring

import datasets


_lowerCAmelCase:						Union[str, Any]   				=       '\\n@inproceedings{lin-2004-rouge,\n    title = "{ROUGE}: A Package for Automatic Evaluation of Summaries",\n    author = "Lin, Chin-Yew",\n    booktitle = "Text Summarization Branches Out",\n    month = jul,\n    year = "2004",\n    address = "Barcelona, Spain",\n    publisher = "Association for Computational Linguistics",\n    url = "https://www.aclweb.org/anthology/W04-1013",\n    pages = "74--81",\n}\n'

_lowerCAmelCase:						Dict   				=       '\\nROUGE, or Recall-Oriented Understudy for Gisting Evaluation, is a set of metrics and a software package used for\nevaluating automatic summarization and machine translation software in natural language processing.\nThe metrics compare an automatically produced summary or translation against a reference or a set of references (human-produced) summary or translation.\n\nNote that ROUGE is case insensitive, meaning that upper case letters are treated the same way as lower case letters.\n\nThis metrics is a wrapper around Google Research reimplementation of ROUGE:\nhttps://github.com/google-research/google-research/tree/master/rouge\n'

_lowerCAmelCase:						List[Any]   				=       '\nCalculates average rouge scores for a list of hypotheses and references\nArgs:\n    predictions: list of predictions to score. Each prediction\n        should be a string with tokens separated by spaces.\n    references: list of reference for each prediction. Each\n        reference should be a string with tokens separated by spaces.\n    rouge_types: A list of rouge types to calculate.\n        Valid names:\n        `"rouge{n}"` (e.g. `"rouge1"`, `"rouge2"`) where: {n} is the n-gram based scoring,\n        `"rougeL"`: Longest common subsequence based scoring.\n        `"rougeLSum"`: rougeLsum splits text using `"\n"`.\n        See details in https://github.com/huggingface/datasets/issues/617\n    use_stemmer: Bool indicating whether Porter stemmer should be used to strip word suffixes.\n    use_aggregator: Return aggregates if this is set to True\nReturns:\n    rouge1: rouge_1 (precision, recall, f1),\n    rouge2: rouge_2 (precision, recall, f1),\n    rougeL: rouge_l (precision, recall, f1),\n    rougeLsum: rouge_lsum (precision, recall, f1)\nExamples:\n\n    >>> rouge = datasets.load_metric(\'rouge\')\n    >>> predictions = ["hello there", "general kenobi"]\n    >>> references = ["hello there", "general kenobi"]\n    >>> results = rouge.compute(predictions=predictions, references=references)\n    >>> print(list(results.keys()))\n    [\'rouge1\', \'rouge2\', \'rougeL\', \'rougeLsum\']\n    >>> print(results["rouge1"])\n    AggregateScore(low=Score(precision=1.0, recall=1.0, fmeasure=1.0), mid=Score(precision=1.0, recall=1.0, fmeasure=1.0), high=Score(precision=1.0, recall=1.0, fmeasure=1.0))\n    >>> print(results["rouge1"].mid.fmeasure)\n    1.0\n'




@datasets.utils.file_utils.add_start_docstrings(_DESCRIPTION      ,					_KWARGS_DESCRIPTION   )
class       lowercase_					(datasets.Metric   ):





				def 						__UpperCamelCase    (				self)  -> Optional[int]:
											return datasets.MetricInfo(
											    description=_DESCRIPTION       ,  citation=_CITATION       ,  inputs_description=_KWARGS_DESCRIPTION       ,  features=datasets.Features(
											        {
											            'predictions': datasets.Value('string'       ,  id='sequence'),
											            'references': datasets.Value('string'       ,  id='sequence'),
											        })       ,  codebase_urls=['https://github.com/google-research/google-research/tree/master/rouge']       ,  reference_urls=[
											        'https://en.wikipedia.org/wiki/ROUGE_(metric)',
											        'https://github.com/google-research/google-research/tree/master/rouge',
											    ]       ,  )





				def 						__UpperCamelCase    (				self       ,  lowercase_       ,  lowercase_       ,  lowercase_=None       ,  lowercase_=True       ,  lowercase_=False)  -> Any:
											if rouge_types is None:
																		a__      =['rouge1', 'rouge2', 'rougeL', 'rougeLsum']

											a__      =rouge_scorer.RougeScorer(rouge_types=lowercase_       ,  use_stemmer=lowercase_)
											if use_aggregator:
																		a__      =scoring.BootstrapAggregator()
											else:
																		a__      =[]

											for ref, pred in zip(lowercase_       ,  lowercase_):
																		a__      =scorer.score(lowercase_       ,  lowercase_)
																		if use_aggregator:
																									aggregator.add_scores(lowercase_)
																		else:
																									scores.append(lowercase_)

											if use_aggregator:
																		a__      =aggregator.aggregate()
											else:
																		a__      ={}
																		for key in scores[0]:
																									a__      =[score[key] for score in scores]

											return result

