"""simple docstring"""



import argparse
import os
import shutil
from pathlib import Path

import onnx
import torch
from packaging import version
from torch.onnx import export

from diffusers import OnnxRuntimeModel, OnnxStableDiffusionPipeline, StableDiffusionPipeline


__lowercase		:		List[str]														=							version.parse(version.parse(torch.__version__).base_version) < version.parse("1.11")





def    SCREAMING_SNAKE_CASE       (     snake_case,      snake_case,      snake_case,      snake_case,      snake_case,      snake_case,      snake_case,      snake_case=False,      ):
     output_path.parent.mkdir(parents=snake_case,      exist_ok=snake_case)
     # PyTorch deprecated the `enable_onnx_checker` and `use_external_data_format` arguments in v1.11,
     # so we check the torch version for backwards compatibility
     if is_torch_less_than_1_11:
          export(
              snake_case,      snake_case,      f=output_path.as_posix(),      input_names=snake_case,      output_names=snake_case,      dynamic_axes=snake_case,      do_constant_folding=snake_case,      use_external_data_format=snake_case,      enable_onnx_checker=snake_case,      opset_version=snake_case,      )
     else:
          export(
              snake_case,      snake_case,      f=output_path.as_posix(),      input_names=snake_case,      output_names=snake_case,      dynamic_axes=snake_case,      do_constant_folding=snake_case,      opset_version=snake_case,      )





@torch.no_grad()
def    SCREAMING_SNAKE_CASE       (     snake_case,      snake_case,      snake_case,      snake_case = False):
     __snake_case				=							torch.floataa if fpaa else torch.floataa
     if fpaa and torch.cuda.is_available():
          __snake_case				=							'''cuda'''
     elif fpaa and not torch.cuda.is_available():
          raise ValueError('''`float16` model export is only supported on GPUs with CUDA''')
     else:
          __snake_case				=							'''cpu'''
     __snake_case				=							StableDiffusionPipeline.from_pretrained(snake_case,      torch_dtype=snake_case).to(snake_case)
     __snake_case				=							Path(snake_case)

     # TEXT ENCODER
     __snake_case				=							pipeline.text_encoder.config.max_position_embeddings
     __snake_case				=							pipeline.text_encoder.config.hidden_size
     __snake_case				=							pipeline.tokenizer(
         '''A sample prompt''',      padding='''max_length''',      max_length=pipeline.tokenizer.model_max_length,      truncation=snake_case,      return_tensors='''pt''',      )
     onnx_export(
         pipeline.text_encoder,      model_args=(text_input.input_ids.to(device=snake_case,      dtype=torch.intaa)),      output_path=output_path / '''text_encoder''' / '''model.onnx''',      ordered_input_names=['''input_ids'''],      output_names=['''last_hidden_state''', '''pooler_output'''],      dynamic_axes={
             '''input_ids''': {0: '''batch''', 1: '''sequence'''},
         },      opset=snake_case,      )
     del pipeline.text_encoder

     # UNET
     __snake_case				=							pipeline.unet.config.in_channels
     __snake_case				=							pipeline.unet.config.sample_size
     __snake_case				=							output_path / '''unet''' / '''model.onnx'''
     onnx_export(
         pipeline.unet,      model_args=(
             torch.randn(2,      snake_case,      snake_case,      snake_case).to(device=snake_case,      dtype=snake_case),
             torch.randn(2).to(device=snake_case,      dtype=snake_case),
             torch.randn(2,      snake_case,      snake_case).to(device=snake_case,      dtype=snake_case),
             False,
         ),      output_path=snake_case,      ordered_input_names=['''sample''', '''timestep''', '''encoder_hidden_states''', '''return_dict'''],      output_names=['''out_sample'''],      dynamic_axes={
             '''sample''': {0: '''batch''', 1: '''channels''', 2: '''height''', 3: '''width'''},
             '''timestep''': {0: '''batch'''},
             '''encoder_hidden_states''': {0: '''batch''', 1: '''sequence'''},
         },      opset=snake_case,      use_external_data_format=snake_case,      )
     __snake_case				=							str(unet_path.absolute().as_posix())
     __snake_case				=							os.path.dirname(snake_case)
     __snake_case				=							onnx.load(snake_case)
     # clean up existing tensor files
     shutil.rmtree(snake_case)
     os.mkdir(snake_case)
     # collate external tensor files into one
     onnx.save_model(
         snake_case,      snake_case,      save_as_external_data=snake_case,      all_tensors_to_one_file=snake_case,      location='''weights.pb''',      convert_attribute=snake_case,      )
     del pipeline.unet

     # VAE ENCODER
     __snake_case				=							pipeline.vae
     __snake_case				=							vae_encoder.config.in_channels
     __snake_case				=							vae_encoder.config.sample_size
     # need to get the raw tensor output (sample) from the encoder
     __snake_case				=							lambda snake_case,      snake_case: vae_encoder.encode(snake_case,      snake_case)[0].sample()
     onnx_export(
         snake_case,      model_args=(
             torch.randn(1,      snake_case,      snake_case,      snake_case).to(device=snake_case,      dtype=snake_case),
             False,
         ),      output_path=output_path / '''vae_encoder''' / '''model.onnx''',      ordered_input_names=['''sample''', '''return_dict'''],      output_names=['''latent_sample'''],      dynamic_axes={
             '''sample''': {0: '''batch''', 1: '''channels''', 2: '''height''', 3: '''width'''},
         },      opset=snake_case,      )

     # VAE DECODER
     __snake_case				=							pipeline.vae
     __snake_case				=							vae_decoder.config.latent_channels
     __snake_case				=							vae_decoder.config.out_channels
     # forward only through the decoder part
     __snake_case				=							vae_encoder.decode
     onnx_export(
         snake_case,      model_args=(
             torch.randn(1,      snake_case,      snake_case,      snake_case).to(device=snake_case,      dtype=snake_case),
             False,
         ),      output_path=output_path / '''vae_decoder''' / '''model.onnx''',      ordered_input_names=['''latent_sample''', '''return_dict'''],      output_names=['''sample'''],      dynamic_axes={
             '''latent_sample''': {0: '''batch''', 1: '''channels''', 2: '''height''', 3: '''width'''},
         },      opset=snake_case,      )
     del pipeline.vae

     # SAFETY CHECKER
     if pipeline.safety_checker is not None:
          __snake_case				=							pipeline.safety_checker
          __snake_case				=							safety_checker.config.vision_config.num_channels
          __snake_case				=							safety_checker.config.vision_config.image_size
          __snake_case				=							safety_checker.forward_onnx
          onnx_export(
              pipeline.safety_checker,      model_args=(
                  torch.randn(
                      1,      snake_case,      snake_case,      snake_case,      ).to(device=snake_case,      dtype=snake_case),
                  torch.randn(1,      snake_case,      snake_case,      snake_case).to(device=snake_case,      dtype=snake_case),
              ),      output_path=output_path / '''safety_checker''' / '''model.onnx''',      ordered_input_names=['''clip_input''', '''images'''],      output_names=['''out_images''', '''has_nsfw_concepts'''],      dynamic_axes={
                  '''clip_input''': {0: '''batch''', 1: '''channels''', 2: '''height''', 3: '''width'''},
                  '''images''': {0: '''batch''', 1: '''height''', 2: '''width''', 3: '''channels'''},
              },      opset=snake_case,      )
          del pipeline.safety_checker
          __snake_case				=							OnnxRuntimeModel.from_pretrained(output_path / '''safety_checker''')
          __snake_case				=							pipeline.feature_extractor
     else:
          __snake_case				=							None
          __snake_case				=							None

     __snake_case				=							OnnxStableDiffusionPipeline(
         vae_encoder=OnnxRuntimeModel.from_pretrained(output_path / '''vae_encoder'''),      vae_decoder=OnnxRuntimeModel.from_pretrained(output_path / '''vae_decoder'''),      text_encoder=OnnxRuntimeModel.from_pretrained(output_path / '''text_encoder'''),      tokenizer=pipeline.tokenizer,      unet=OnnxRuntimeModel.from_pretrained(output_path / '''unet'''),      scheduler=pipeline.scheduler,      safety_checker=snake_case,      feature_extractor=snake_case,      requires_safety_checker=safety_checker is not None,      )

     onnx_pipeline.save_pretrained(snake_case)
     print('''ONNX pipeline saved to''',      snake_case)

     del pipeline
     del onnx_pipeline
     __snake_case				=							OnnxStableDiffusionPipeline.from_pretrained(snake_case,      provider='''CPUExecutionProvider''')
     print('''ONNX pipeline is loadable''')


if __name__ == "__main__":
       __lowercase		:		str														=							argparse.ArgumentParser()

       parser.add_argument(
           "--model_path",
           type=str,
           required=True,
           help="Path to the `diffusers` checkpoint to convert (either a local directory or on the Hub).",
       )

       parser.add_argument("--output_path", type=str, required=True, help="Path to the output model.")

       parser.add_argument(
           "--opset",
           default=14,
           type=int,
           help="The version of the ONNX operator set to use.",
       )
       parser.add_argument("--fp16", action="store_true", default=False, help="Export the models in `float16` mode")

       __lowercase		:		Dict														=							parser.parse_args()

       convert_models(args.model_path, args.output_path, args.opset, args.fpaa)
"""simple docstring"""



def    SCREAMING_SNAKE_CASE       (     snake_case):
     return 1 if digit in (0, 1) else (digit * factorial(digit - 1))





def    SCREAMING_SNAKE_CASE       (     snake_case):
     __snake_case				=							0
     __snake_case				=							number
     while duplicate > 0:
          __snake_case		,	__snake_case				=							divmod(snake_case,      10)
          fact_sum += factorial(snake_case)
     return fact_sum == number


if __name__ == "__main__":
       print("Program to check whether a number is a Krisnamurthy Number or not.")
       __lowercase		:		Optional[int]														=							int(input("Enter number: ").strip())
       print(
           F"""{number} is {'' if krishnamurthy(number) else 'not '}a Krishnamurthy Number."""
       )