o
    Xiu                     @  s   d dl mZ d dlZd dlZd dlZd dlmZmZmZm	Z	m
Z
 d dlmZ d dlZd dlmZ d dlmZmZmZmZ e
dZedZ	d(d)ddZ		d*d+ddZd,ddZd-d d!Zd.d&d'ZdS )/    )annotationsN)AnyCallableOptionalSequenceTypeVar)	ParamSpec)ir)	ast_utils	converter	irbuildervalues_R_Pfast.FunctionDefopsetvalues.Opsetglobal_namesdict[str, Any]sourcestrdefault_opsetOptional[values.Opset]returnirbuilder.IRFunctionc                 C  s   t j||||d}|| S )zACheck that a function falls into the ONNXScript subset of Python.)r   r   r   r   )r   	Convertertranslate_function_def)r   r   r   r   r   convert r   M/home/ubuntu/.local/lib/python3.10/site-packages/onnxscript/_internal/main.pyscript_check   s   
r!   kwargsr   =Callable[[Callable[_P, _R]], onnxscript.OnnxFunction[_P, _R]]c                   s:   pt ddtt jstdd fdd	}|S )a8  Main decorator. Declares a function as an onnx function.

    Args:
        opset: Opset the function belongs to (see :ref:`l-api-opsets`).
        default_opset: Opset to use for operators not in the function's opset.
        kwargs: Additional keyword arguments.

    Returns:
        an instance of :class:`onnxscript.values.OnnxFunction`

    Example:
    ::

        @script()
        def log2(x):
            one = op.Constant(value=make_tensor('one', TensorProto.FLOAT, [1], [1]))
            return op.Div(op.Log(x), op.CastLike(op.Log(cst), x))

    Or:

    ::

        from onnxscript.onnx_opset import opset16

        @script(opset16)
        def log2(x):
            one = op.Constant(value=make_tensor('one', TensorProto.FLOAT, [1], [1]))
            return op.Div(op.Log(x), op.CastLike(op.Log(cst), x))
    this   zLScript parameter must be an opset. Did you use @script instead of @script()?r   Callable[_P, _R]r   onnxscript.OnnxFunction[_P, _R]c                   sn   t | s	tdt| \}}t | }t | }|j }|	|j
 t||| d}t| ||S )Nz=The ONNXScript decorator should be applied to functions only.)r   )inspect
isfunction	TypeErrorr
   get_src_and_ast	getmodulegetclosurevars__dict__copyupdate	nonlocalsr!   
onnxscriptOnnxFunction)r   srcf_astmoduleclosureenvresultr   r"   r   r   r    	transformQ   s   



zscript.<locals>.transformN)r   r&   r   r'   )r   Opset
isinstancer*   )r   r   r"   r;   r   r:   r    script)   s   "r>   (Callable[[Callable], values.OnnxClosure]c                    s:   t d t d} | jd }|jjd fdd	}|S )aQ  A parametric decorator used to annotate nested-functions that are used
    as graph-attributes.

    Returns:
        A decorator that returns its input function, but attaches a graph_proto
        attribute representing the input function. The translation is not
        done at this time, but previously when the outer-level function
        was translated to an OnnxFunction. The decorator just looks up
        and retrieves the GraphProto representation previously generated.

    Example:
    ::

        @script()
        def cumulative_sum(X: INT64['N']):

            # Translation of cumulative_sum by @script will also translate Sum
            # into a GraphProto, which will be stored in the OnnxFunction generated
            # for cumulative_sum. At run-time (in eager-mode), the @graph decorator
            # retrieves the pre-computed GraphProto and attaches it to the Sum function.
            @graph()
            def Sum(sum_in, next):
                sum_out = sum_in + next
                scan_out = op.Identity(sum_out)
                return sum_out, scan_out
            zero = op.Constant(value_int=0)
            # The call to higher-order operator Scan below uses the above function
            # Sum as a graph-attribute.
            all_sum, result = op.Scan (zero, X, body=Sum, num_scan_inputs=1)
            return result

    r%      selfr   r   r   values.OnnxClosurec                   s   t | j  | S N)r   OnnxClosure__name__r   function_framenested_functionsr   r    r;      s   zgraph.<locals>.transformN)r   r   r   rB   )sys	_getframef_localsfunction_irrI   )wrapper_frameonnx_functionr;   r   rG   r    graphe   s   
*

rP   boolc                 C  s   t | tjS )zAReturn True if f is a function converted by onnxscript decorator.)r=   r2   r3   rF   r   r   r    is_converted_fun   s   rR   	functionsSequence[values.OnnxFunction]filenameNonec                 C  s>   t jt jg g g ddiddd | D ddd}t || d S )	N    )inputsoutputsnodesopset_importsc                 S  s   g | ]
}t j| qS r   )r	   serdedeserialize_functionto_function_proto).0r   r   r   r    
<listcomp>   s    z#export_onnx_lib.<locals>.<listcomp>
   p2o)rS   
ir_versionproducer_name)r	   ModelGraphsave)rS   rU   modelr   r   r    export_onnx_lib   s   rj   rC   )r   r   r   r   r   r   r   r   r   r   r   r   )NN)r   r   r   r   r"   r   r   r#   )r   r?   )r   r   r   rQ   )rS   rT   rU   r   r   rV   )
__future__r   astr(   rJ   typingr   r   r   r   r   typing_extensionsr   r2   r	   onnxscript._internalr
   r   r   r   r   r   r!   r>   rP   rR   rj   r   r   r   r    <module>   s&   
<
5