o
    ;ήc=                     @   sX  d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZddl	m
Z
mZ ddlmZ ddlmZ G dd dejZded	ed
efddZdejdejej ded	edef
ddZdejdejdejdejeef fddZdejdejej ded	edejdedededejeef dejej fddZdd Zd d! Zed"kre  dS dS )#    N   )files_from_file_or_dirpath_match_suffix_ignore_case)get_optimization_level)create_config_from_modelsc                   @   s   e Zd ZdZdZdS )OptimizationStyler   r   N)__name__
__module____qualname__FixedRuntime r   r   S/tmp/pip-target-vg8gfxp4/lib/python/onnxruntime/tools/convert_onnx_models_to_ort.pyr      s    r   optimization_level_stroptimization_stylesuffixc                 C   s2   d | dkrd|  nd|tjkrd|S d|S )Nz{}{}{}all. z.with_runtime_opt)formatr   r   )r   r   r   r   r   r   _optimization_suffix   s   r   model_path_or_dir
output_direnable_type_reductionc                 C   sV   d |rdndt||d}|  r|p| | S | d| }|d ur)||j S |S )Nz{}{}required_operators_and_typesrequired_operatorsz.configr   )r   r   is_dirwith_suffixname)r   r   r   r   r   config_namemodel_config_pathr   r   r   _create_config_file_path!   s   


r!   optimization_leveloutput_model_pathcustom_op_librarysession_options_config_entriesc                 C   sL   t  }t||_| |_|r|t| | D ]
\}}||| q|S )N)ortSessionOptionsstroptimized_model_filepathgraph_optimization_levelregister_custom_ops_libraryitemsadd_session_config_entry)r"   r#   r$   r%   sokeyvaluer   r   r   _create_session_options8   s   
r1   create_optimized_onnx_modelallow_conversion_failurestarget_platformreturnc	                 C   s  |   r| n| j}	|p|	}t|}
dtjfdd}t| |}t|dkr+td| dg}d }|
t	j
jkr=|dkr=dg}g }|D ]}z~||	}|| jjd	d	d
 || t||d}|r|| t||d}t|
|||}|tjkr}|dd td|| t	jt||||d}t|
|||}|dd |tjkr|dd td|| t	jt||||d}|| W qA ty } ztd|| |sԂ W Y d }~qAd }~ww tdt|t| |S )N	file_pathc                 S   s0   t | dsdS t | drtd|  d dS dS )Nz.onnxF.optimized.onnxz
Ignoring ''T)r   print)r6   r   r   r   is_model_file_to_convert\   s   

z*_convert.<locals>.is_model_file_to_convertr   z!No model files were found in '{}'CPUExecutionProvideramd64NchwcTransformerT)parentsexist_okz.ortr7   (optimization.minimal_build_optimizationsapplyz$Saving optimized ONNX model {} to {})sess_options	providersdisabled_optimizerszsession.save_model_formatORTsavez9Converting optimized ONNX model {} to ORT format model {}zError converting {}: {}z$Converted {}/{} models successfully.)r   parentr   pathlibPathr   len
ValueErrorr   r&   GraphOptimizationLevelORT_ENABLE_ALLrelative_tomkdirr   r   r1   r   r   r-   r9   InferenceSessionr(   append	Exception)r   r   r   r   r$   r2   r3   r4   r%   	model_dirr"   r:   modelsrC   optimizer_filterconverted_modelsmodelrelative_model_pathort_target_pathoptimized_target_pathr.   _er   r   r   _convertK   sh   






r]   c                  C   s   t jtjtdd} | jdtjdd | jddt	j
jt	jjgdd	 t	D d
t	jj dt	j
j dt	j
j dt	jj d	d | jdddd | jdtjd dd | jdddd | jdddd | jdtd ddgdd | jd tjd!d |  S )"Na  Convert the ONNX format model/s in the provided directory to ORT format models.
        All files with a `.onnx` extension will be processed. For each one, an ORT format model will be created in the
        given output directory, if specified, or the same directory.
        A configuration file will also be created containing the list of required operators for all
        converted models. This configuration file should be used as input to the minimal build via the
        `--include_ops_by_config` parameter.
        )descriptionz--output_dirzProvide an output directory for the converted model/s and configuration file. If unspecified, the converted ORT format model/s will be in the same directory as the ONNX model/s.)typehelpz--optimization_style+c                 S   s   g | ]}|j qS r   )r   ).0r\   r   r   r   
<listcomp>   s    zparse_args.<locals>.<listcomp>zStyle of optimization to perform on the ORT format model. Multiple values may be provided. The conversion will run once for each value. The general guidance is to use models optimized with 'z(' style when using NNAPI or CoreML and 'z' style otherwise. 'zv': Run optimizations directly before saving the ORT format model. This bakes in any platform-specific optimizations. 'aP  ': Run basic optimizations directly and save certain other optimizations to be applied at runtime if possible. This is useful when using a compiling EP like NNAPI or CoreML that may run an unknown (at model conversion time) number of nodes. The saved optimizations can further optimize nodes not assigned to the compiling EP at runtime.)nargsdefaultchoicesr`   z--enable_type_reduction
store_truezAdd operator specific type information to the configuration file to potentially reduce the types supported by individual operator implementations.)actionr`   z--custom_op_libraryzNProvide path to shared library containing custom operator kernels to register.)r_   re   r`   z--save_optimized_onnx_modelz~Save the optimized version of each ONNX model. This will have the same level of optimizations applied as the ORT format model.z--allow_conversion_failuresz@Whether to proceed after encountering model conversion failures.z--target_platformarmr<   zSpecify the target platform where the exported model will be used. This parameter can be used to choose between platform-specific options, such as QDQIsInt8Allowed(arm), NCHWc (amd64) and NHWC (arm/amd64) format, different optimizer level options, etc.)r_   re   rf   r`   r   zProvide path to ONNX model or directory containing ONNX model/s to convert. All files with a .onnx extension, including those in subdirectories, will be processed.)argparseArgumentParserospathbasename__file__add_argumentrH   rI   r   r   r   r   r(   
parse_args)parserr   r   r   rq      st   
rq   c                  C   s  t  } d }| jd ur| j s| jjdd | jjdd}dd | jD }tdd}| j }| j	r8| j	 nd }| sI|
 sItd||rV|
 sVtd	|i }| jd
krbd|d< nd|d< |D ]~}td|j| t|||||| j| j| j|d	}t W}	|tjkr| r|n|j}
|	tj|
dd}| }d|d< td |t|||tj|d| j| j|d	7 }td|j| t||||| j}t||| j W d    n1 sw   Y  qhd S )NT)r>   )strictc                 S   s   g | ]}t | qS r   )r   )rb   	style_strr   r   r   rc     s    z.convert_onnx_models_to_ort.<locals>.<listcomp>1ORT_CONVERT_ONNX_MODELS_TO_ORT_OPTIMIZATION_LEVELr   z+Model path '{}' is not a file or directory.z+Unable to find custom operator library '{}'ri   1zsession.qdqisint8allowed0z=Converting models with optimization style '{}' and level '{}')	r   r   r   r   r$   r2   r3   r4   r%   z.without_runtime_opt)dirr   rA   r@   zConverting models again without runtime optimizations to generate a complete config file. These converted models are temporary and will be deleted.FzYGenerating config file from ORT format models with optimization style '{}' and level '{}') rq   r   r   rO   resolver   rl   getenvr   r$   is_fileFileNotFoundErrorr   r4   r9   r   r]   save_optimized_onnx_modelr3   
contextlib	ExitStackr   r   rG   enter_contexttempfileTemporaryDirectorycopyr   r!   r   r   )argsr   optimization_stylesr   r   r$   r%   r   rV   context_stackrS   temp_output_dir4session_options_config_entries_for_second_conversionconfig_filer   r   r   convert_onnx_models_to_ort
  s   






r   __main__) rj   r~   enumrl   rH   r   typingonnxruntimer&   
file_utilsr   r   onnx_model_utilsr   ort_format_modelr   Enumr   r(   r   rI   Optionalboolr!   rL   Dictr1   Listr]   rq   r   r   r   r   r   r   <module>   sv   



	


hW`
