



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        a						(      _UpperCAmelCase							:					int						):







		'''simple docstring'''





		__UpperCAmelCase    :     Union[str, Any]													=	filter(lambda _UpperCAmelCase						: p.requires_grad ,   model.parameters()						)
		__UpperCAmelCase    :     int													=	sum([np.prod(p.size()						) for p in model_parameters]						)
		return params


__A   			=logging.getLogger(__name__)

def        a						(      _UpperCAmelCase							:					Optional[int] ,   _UpperCAmelCase							:					List[Any]						):







		'''simple docstring'''





		if metric == "rouge2":
				__UpperCAmelCase    :     Any													=	'''{val_avg_rouge2:.4f}-{step_count}'''
		elif metric == "bleu":
				__UpperCAmelCase    :     Optional[int]													=	'''{val_avg_bleu:.4f}-{step_count}'''
		elif metric == "em":
				__UpperCAmelCase    :     List[str]													=	'''{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    :     List[Any]													=	ModelCheckpoint(
		    dirpath=_UpperCAmelCase ,   filename=_UpperCAmelCase ,   monitor=f'val_{metric}' ,   mode='''max''' ,   save_top_k=3 ,   every_n_epochs=1 ,   )
		return checkpoint_callback

def        a						(      _UpperCAmelCase							:					Tuple ,   _UpperCAmelCase							:					Any						):







		'''simple docstring'''





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

class 		UpperCAmelCase__			(			pl.Callback   ):




			'''simple docstring'''






			def  snake_case__     (   self							: Tuple       ,       a_							: Optional[int]       ,       a_							: Tuple ):
					'''simple docstring'''





					__UpperCAmelCase    :     str													=	{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  snake_case__     (   self							: str       ,       a_							: pl.Trainer       ,       a_							: pl.LightningModule       ,       a_							: str       ,       a_							: Optional[int]=True ):
					'''simple docstring'''





					logger.info(F'***** {type_path} results at step {trainer.global_step:05d} *****' )
					__UpperCAmelCase    :     Optional[Any]													=	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    :     Tuple													=	Path(pl_module.hparams.output_dir )
					if type_path == "test":
							__UpperCAmelCase    :     int													=	od / '''test_results.txt'''
							__UpperCAmelCase    :     Tuple													=	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    :     Dict													=	od / F'{type_path}_results/{trainer.global_step:05d}.txt'
							__UpperCAmelCase    :     Any													=	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    :     str													=	metrics[key]
									if isinstance(a_       ,       torch.Tensor ):
											__UpperCAmelCase    :     List[str]													=	val.item()
									__UpperCAmelCase    :     int													=	F'{key}: {val:.6f}\n'
									writer.write(a_ )

					if not save_generations:
							return

					if "preds" in metrics:
							__UpperCAmelCase    :     List[str]													=	'''\n'''.join(metrics['''preds'''] )
							generations_file.open('''w+''' ).write(a_ )




			@rank_zero_only
			def  snake_case__     (   self							: Tuple       ,       a_							: Any       ,       a_							: int ):
					'''simple docstring'''





					try:
							__UpperCAmelCase    :     List[str]													=	pl_module.model.model.num_parameters()
					except AttributeError:
							__UpperCAmelCase    :     Any													=	pl_module.model.num_parameters()

					__UpperCAmelCase    :     int													=	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  snake_case__     (   self							: Union[str, Any]       ,       a_							: pl.Trainer       ,       a_							: pl.LightningModule ):
					'''simple docstring'''





					save_json(pl_module.metrics       ,       pl_module.metrics_save_path )
					return self._write_logs(a_       ,       a_       ,       '''test''' )




			@rank_zero_only
			def  snake_case__     (   self							: Optional[int]       ,       a_							: pl.Trainer       ,       a_							: List[str] ):
					'''simple docstring'''





					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 qiskit

def        a						(      _UpperCAmelCase							:					int ,   _UpperCAmelCase							:					int						):







		'''simple docstring'''





		__UpperCAmelCase    :     List[str]													=	qiskit.Aer.get_backend('''aer_simulator'''						)

		__UpperCAmelCase    :     Optional[Any]													=	qiskit.QuantumCircuit(4 ,   2						)
		# encode inputs in qubits 0 and 1
		if bita == 1:
				qc_ha.x(0						)
		if bita == 1:
				qc_ha.x(1						)
		qc_ha.barrier()

		# use cnots to write XOR of the inputs on qubit2
		qc_ha.cx(0 ,   2						)
		qc_ha.cx(1 ,   2						)

		# use ccx / toffoli gate to write AND of the inputs on qubit3
		qc_ha.ccx(0 ,   1 ,   3						)
		qc_ha.barrier()

		# extract outputs
		qc_ha.measure(2 ,   0						)  # extract XOR value
		qc_ha.measure(3 ,   1						)  # extract AND value

		# Execute the circuit on the qasm simulator
		__UpperCAmelCase    :     str													=	qiskit.execute(_UpperCAmelCase ,   _UpperCAmelCase ,   shots=10_00						)

		# Return the histogram data of the results of the experiment
		return job.result().get_counts(_UpperCAmelCase						)


if __name__ == "__main__":
				__A   			=half_adder(1, 1)
				print(f'''Half Adder Output Qubit Counts: {counts}''')





