o
    bi                      @   s   d dl Z d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlm	Z	 d dlm
Z
 d d	lmZ d d
lmZ 			dddZdd Zdd ZdS )    N)backend)treeconvert_spec_to_tensor)get_input_signature)make_tf_tensor_spec)DEFAULT_ENDPOINT_NAME)ExportArchive)patch_tf2onnx)io_utilsc                 K   s  |}|du rd}|du rt | }|r| jstddd t|D }t dv rKddlm} tt	|}t
| |fi |}	t  |jj|	|||d	 nt d
krddl}
tdd |}t|}tdd |D rntdt| drw|   t ^ tjddd tjddd tjddd tjddd tjddd z|
jj| ||||dd}t|dr|  || W n   |du rd}|
jj| |||||d Y W d   n1 sw   Y  ntd|rtd| d dS dS )a  Export the model as a ONNX artifact for inference.

    This method lets you export a model to a lightweight ONNX artifact
    that contains the model's forward pass only (its `call()` method)
    and can be served via e.g. ONNX Runtime.

    The original code of the model (including any custom layers you may
    have used) is *no longer* necessary to reload the artifact -- it is
    entirely standalone.

    Args:
        filepath: `str` or `pathlib.Path` object. The path to save the artifact.
        verbose: `bool`. Whether to print a message during export. Defaults to
            `None`, which uses the default value set by different backends and
            formats.
        input_signature: Optional. Specifies the shape and dtype of the model
            inputs. Can be a structure of `keras.InputSpec`, `tf.TensorSpec`,
            `backend.KerasTensor`, or backend tensor. If not provided, it will
            be automatically computed. Defaults to `None`.
        opset_version: Optional. An integer value that specifies the ONNX opset
            version. If not provided, the default version for the backend will
            be used. Defaults to `None`.
        **kwargs: Additional keyword arguments.

    **Note:** This feature is currently supported only with TensorFlow, JAX and
    Torch backends.

    **Note:** The dtype policy must be "float32" for the model. You can further
    optimize the ONNX artifact using the ONNX toolkit. Learn more here:
    [https://onnxruntime.ai/docs/performance/](https://onnxruntime.ai/docs/performance/).

    **Note:** The dynamic shape feature is not yet supported with Torch
    backend. As a result, you must fully define the shapes of the inputs using
    `input_signature`. If `input_signature` is not provided, all instances of
    `None` (such as the batch size) will be replaced with `1`.

    Example:

    ```python
    # Export the model as a ONNX artifact
    model.export("path/to/location", format="onnx")

    # Load the artifact in a different process/environment
    ort_session = onnxruntime.InferenceSession("path/to/location")
    ort_inputs = {
        k.name: v for k, v in zip(ort_session.get_inputs(), input_data)
    }
    predictions = ort_session.run(None, ort_inputs)
    ```
    NTzSThe model provided has never called. It must be called at least once before export.c                 S   s&   g | ]\}}t |d dpd| qS )nameNinput_)getattr).0ispec r   I/home/ubuntu/.local/lib/python3.10/site-packages/keras/src/export/onnx.py
<listcomp>S   s    zexport_onnx.<locals>.<listcomp>)
tensorflowjaxr   )tf2onnx)opsetoutput_pathtorchc                 S   s   t | ddS )N   )replace_none_numberr   )xr   r   r   <lambda>m   s    zexport_onnx.<locals>.<lambda>c                 s   s    | ]}t |tV  qd S )N)
isinstancedict)r   r   r   r   r   	<genexpr>r   s    zexport_onnx.<locals>.<genexpr>zUCurrently, `export_onnx` in the torch backend doesn't support dictionaries as inputs.evalignorez4.*\n.*\n*.*\n*.*export will treat it as a constant.*)messagez+.*not properly registered as a submodule,.*z3.*which is what 'get_attr' Nodes typically target.*z2.*underlying reference in the owning GraphModule.*z(.*suppressed about get_attr references.*)verboseopset_versioninput_namesdynamooptimizeF)r%   r&   r'   zI`export_onnx` is only compatible with TensorFlow, JAX and Torch backends.zSaved artifact at 'z'.)r   _called
ValueError	enumerater   keras.src.utils.module_utilsr   r   map_structurer   get_concrete_fnr
   convertfrom_functionr   tupleanyhasattrr"   warningscatch_warningsfilterwarningsonnxexportr)   saveNotImplementedErrorr   	print_msg)modelfilepathr%   input_signaturer&   kwargsactual_verboser'   r   decorated_fnr   sample_inputsonnx_programr   r   r   export_onnx   s   :



2rE   c                 C   sv   |   } d| vrd| d< d| vrddd| d< | d dur!td| d d dur-td| d d	 dur9td
| S )N	is_staticTjax2tf_kwargsF)
enable_xlanative_serializationzB`is_static` must be `True` in `kwargs` when using the jax backend.rH   zU`enable_xla` must be `False` in `kwargs['jax2tf_kwargs']` when using the jax backend.rI   z_`native_serialization` must be `False` in `kwargs['jax2tf_kwargs']` when using the jax backend.)copyr+   )r@   r   r   r   _check_jax_kwargs   s(   
rK   c                 K   sN   t   dkr
t|}t }|jt| |fi | t   dkr"|  |tS )z0Get the `tf.function` associated with the model.r   r   )r   rK   r	   track_and_add_endpointr   _filter_and_track_resources_get_concrete_fn)r=   r?   r@   export_archiver   r   r   r/      s   
r/   )NNN)r5   	keras.srcr   r   keras.src.export.export_utilsr   r   r   keras.src.export.saved_modelr   r	   keras.src.export.tf2onnx_libr
   keras.src.utilsr   rE   rK   r/   r   r   r   r   <module>   s"    
 (