o
    #j~                     @   s  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	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 d dlmZ d dlmZ zd dlmZ W n eyi   ee	jdZY nw ddlmZ dd	lmZ dd
lmZmZ e dZ!e!"ej# ej$ddZ%e& Z'e'(e% e!)e' ej*Z+e+,dZ-g dZ.g dZ/g dZ0dgZ1e2 rg dZ3nddgZ4dZ5dZ6dZ7dZ8ej9: ej9; ej9< ej9= ej9> ej9? gZ@edd ZAdd ZBdd ZCeDd d!d"gZEG d#d$ d$ZFeDd%g d&ZGG d'd( d(ZHd)d* ZId+d, ZJd-d. ZKd/d0 ZLdd2d3ZMd4d5 ZNd6d7 ZOd8d9 ZPd:d; ZQd<d= ZRd>d? ZSd@dA ZTdBdC ZUddDdEZVdFdG ZWdHdI ZXdJdK ZYdLdM ZZdNdO Z[ddPdQZ\dRdS Z]ddUdVZ^dWdX Z_dYdZ Z`dd[d\Zad]d^ Zbd_d` ZcddadbZddcdd ZeddedfZf	1ddgdhZgdidj Zhdkdl ZiddmdnZjdodp Zk	1ddqdrZldsdt ZmddudvZndwdx ZoddydzZpdd{d|Zqd}d~ ZrdddZsdS )    N)contextmanager)	machinery)	bdist_egg)DEVNULLwb   )core)OpProtoHolder)get_includeget_libzutils.cpp_extensionz)%(asctime)s - %(levelname)s - %(message)s)fmtwin)z/MTz/wd4819z/wd4251z/wd4244z/wd4267z/wd4275z/wd4018z/wd4190z/EHscz/wz/DGOOGLE_GLOG_DLL_DECLz/DBOOST_HAS_STATIC_ASSERTz/DNDEBUGz/DPADDLE_USE_DSO)z-fno-commonz-dynamicz-DNDEBUGz-gz-fwrapvz-O3-archx86_64)z-dynamiclibz
-undefinedZdynamic_lookupr   r   z/MACHINE:X64)z-DPADDLE_WITH_HIP-DEIGEN_USE_GPUz-DEIGEN_USE_HIPz-DPADDLE_WITH_CUDAr   )      r   )   r   i^  a  
                        *************************************
                        *  Compiler Compatibility WARNING   *
                        *************************************

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Found that your compiler ({user_compiler}) is not compatible with the compiler
built Paddle for this platform, which is {paddle_compiler} on {platform}. Please
use {paddle_compiler} to compile your custom op. Or you may compile Paddle from
source using {user_compiler}, and then also use it compile your custom op.

See https://www.paddlepaddle.org.cn/documentation/docs/zh/install/compile/fromsource.html
for help with compiling Paddle from source.

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ax  
                            **********************************
                            *    ABI Compatibility WARNING   *
                            **********************************

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Found that your compiler ({user_compiler} == {version}) may be ABI-incompatible with pre-installed Paddle!
Please use compiler that is ABI-compatible with GCC >= 5.4 (Recommended 8.2).

See https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html for ABI Compatibility
information

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
c                  c   s    t j} tt _dV  | t _dS )zE
    Context to manage how to write `__bootstrap__` code in .egg
    N)r   Z
write_stubcustom_write_stub)Zorigin_write_stub r   k/var/www/html/Deteccion_Ine/venv/lib/python3.10/site-packages/paddle/utils/cpp_extension/extension_utils.pybootstrap_context   s
   
r   c                 C   s   t |  t  S N)r   !load_op_meta_info_and_register_opr	   instanceZupdate_op_proto)Zlib_filenamer   r   r   r      s   
r   c                 C   s   t d }tj| \}}|d | } g }t  r"t	d n#t 
 \}}|j}t|}	|	D ]	}
|t|
 q3t	dt|	  t|d}||j| d|d W d   dS 1 scw   Y  dS )	zs
    Customized write_stub function to allow us to inject generated python
    api codes into egg python file.
    a  
        {custom_api}

        import os
        import sys
        import types
        import paddle
        import importlib.abc
        import importlib.util

        cur_dir = os.path.dirname(os.path.abspath(__file__))
        so_path = os.path.join(cur_dir, "{resource}")

        def __bootstrap__():
            assert os.path.exists(so_path)
            # load custom op shared library with abs path
            custom_ops = paddle.utils.cpp_extension.load_op_meta_info_and_register_op(so_path)

            if os.name == 'nt' or sys.platform.startswith('darwin'):
                # Cpp Extension only support Linux now
                mod = types.ModuleType(__name__)
            else:
                try:
                    spec = importlib.util.spec_from_file_location(__name__, so_path)
                    assert spec is not None
                    mod = importlib.util.module_from_spec(spec)
                    assert isinstance(spec.loader, importlib.abc.Loader)
                    spec.loader.exec_module(mod)
                except ImportError:
                    mod = types.ModuleType(__name__)

            for custom_op in custom_ops:
                setattr(mod, custom_op, eval(custom_op))

        __bootstrap__()

        Z_pd_z6Received len(custom_op) =  0, using cpp extension onlyz4Received len(custom_op) =  %d, using custom operatorw

)resourceZ
custom_apiN)textwrapdedentlstripospathsplitextCustomOpInfor   emptyprintlastso_pathr   append_custom_api_contentlenopenwriteformatjoin)r   ZpyfileZ_stub_templatefilenameextapi_content_Zop_infor(   Znew_custom_opsop_namefr   r   r   r      s6   &*

"r   OpInfoso_namer(   c                   @   s>   e Zd ZdZedd Zdd ZdddZd	d
 Zdd Z	dS )r$   zO
    A global Singleton map to record all compiled custom ops information.
    c                 C   s   t | ds	|  | _| jS )N	_instance)hasattrr8   )clsr   r   r   r      s   
zCustomOpInfo.instancec                 C   s"   t | jdr
J dt | _d S )Nr8   z3Please use `instance()` to get CustomOpInfo object!)r9   	__class__collectionsOrderedDictop_info_mapselfr   r   r   __init__   s   zCustomOpInfo.__init__Nc                 C   s   t ||| j|< d S r   )r6   r>   )r@   r4   r7   r(   r   r   r   add  s   zCustomOpInfo.addc                 C   s$   t | jdks	J tt| j S )z:
        Return the last inserted custom op info.
        r   )r+   r>   nextreverseditemsr?   r   r   r   r'     s   zCustomOpInfo.lastc                 C   s   | j rdS dS )NFT)r>   r?   r   r   r   r%     s   zCustomOpInfo.emptyr   )
__name__
__module____qualname____doc__classmethodr   rA   rB   r'   r%   r   r   r   r   r$      s    

r$   VersionFields)sourcesextra_compile_argsextra_link_argslibrary_dirsruntime_library_dirsinclude_dirsZdefine_macrosZundef_macrosc                   @   s(   e Zd Zdd Zdd Zedd ZdS )VersionManagerc                 C   s   || _ | || _d S r   )version_fieldhasherversion)r@   rS   r   r   r   rA   #  s   zVersionManager.__init__c                 C   sr   ddl m} t }|jD ]'}t||}|sqt|ttt	fr+||}t
|t|}qtdt||| S )Nr   )flattenzASupport types with list, tuple and dict, but received {} with {}.)Zpaddle.utilsrV   hashlibmd5_fieldsgetattr
isinstancelisttupledictcombine_hashRuntimeErrorr.   type	hexdigest)r@   rS   rV   rX   fieldelemZ	flat_elemr   r   r   rT   '  s   

zVersionManager.hasherc                 C   s
   | j  S r   )rS   _asdictr?   r   r   r   details;  s   
zVersionManager.detailsN)rF   rG   rH   rA   rT   propertyrf   r   r   r   r   rR   "  s
    rR   c                 C   s   |  t|  | S )z
    Return new hash value.
    DO NOT use `hash()` because it doesn't generate stable value between different process.
    See https://stackoverflow.com/questions/27522626/hash-function-in-python-3-3-returns-different-results-between-sessions
    )updatereprencode)rX   valuer   r   r   r_   @  s   r_   c                    s  dd }dd }d}t j| }t j| }t j||} fddtjD }t|}	t|	}
t j	| rqt j	|rq||}|
|d}|durm||
jkrotd	||
j| t |  |
j}|
j||< ||| dS dS dS t j	|s|t | |
j}|
j||< ||| dS )
z
    If already compiling source before, we should check whether cflags
    have changed and delete the built object to re-compile the source
    even though source file content keeps unchanaged.
    c                 S   sT   t |tsJ t| d}|tj|ddd W d    d S 1 s#w   Y  d S )Nr   r   T)indent	sort_keys)r[   r^   r,   r-   jsondumps)r"   version_infor5   r   r   r   	serializeQ  s   "z0clean_object_if_change_cflags.<locals>.serializec                 S   sP   t j| sJ t| d}| }t|W  d    S 1 s!w   Y  d S )Nr)r!   r"   existsr,   readrn   loads)r"   r5   contentr   r   r   deserializeV  s
   $z2clean_object_if_change_cflags.<locals>.deserializezversion.txtc                    s   g | ]}t  |d qS r   )rZ   ).0rc   	extensionr   r   
<listcomp>c      z1clean_object_if_change_cflags.<locals>.<listcomp>NzeRe-Compiling {}, because specified cflags have been changed. New signature {} has been saved into {}.)r!   r"   dirnamebasenamer/   rK   rY   _makerR   rs   getrU   log_vr.   removerf   makedirs)r(   rz   rq   rw   ZVERSION_FILEbase_dirr7   Zversion_fileargsrS   Z	versionerZold_version_infoZ
so_versionZnew_version_inforf   r   ry   r   clean_object_if_change_cflagsJ  s8   




r   c                 C   s@   t  rtddg |  t|  } | S tg d |  t|  } | S )M
    Prepare all necessary compiled flags for nvcc compiling CUDA files.
    
-Xcompiler-fPIC)z-ccbinccr   r   z--expt-relaxed-constexprz-DNVCC)r   is_compiled_with_rocmCOMMON_HIPCC_FLAGSget_rocm_arch_flagsCOMMON_NVCC_FLAGSget_cuda_arch_flagscflagsr   r   r   prepare_unix_cudaflags  s&   	
r   c                 C   s   t dg |  t|  } | S )r   -w)r   r   r   r   r   r   prepare_win_cudaflags  s   r   Fc                    sL   |dkrdnd t  fdd| D s$|rdnd} | }| | dS dS )	zG
    Append -std=c++11/14 in cflags if without specific it before.
    Zmsvcz/std:z-std=c                 3   s    | ]} |v V  qd S r   r   )rx   flagZcpp_flag_prefixr   r   	<genexpr>      z)add_std_without_repeat.<locals>.<genexpr>zc++14zc++11N)anyr)   )r   Zcompiler_typeZ	use_std14suffixZcpp_flagr   r   r   add_std_without_repeat  s   r   c                 C   s   g S )z
    For an arch, say "6.1", the added compile flag will be
    ``-gencode=arch=compute_61,code=sm_61``.
    For an added "+PTX", an additional
    ``-gencode=arch=compute_xx,code=compute_xx`` is added.
    r   r   r   r   r   r     s   r   c                 C   s   | ddg } | S )zE
    For ROCm platform, amdgpu target should be added for HIPCC.
    z-fno-gpu-rdcz-amdgpu-target=gfx906r   r   r   r   r   r     s   r   c                  C   s    ddl } tjtj| jdS )z)
    Return installed base dir path.
    r   Nbase)paddler!   r"   r/   r}   __file__)r   r   r   r   _get_base_path  s   r   c                  C   s   t rdnd} d|  S )z(
    Return pybind DSO module name.
    .pyd.soZ	libpaddle)
IS_WINDOWS)ext_namer   r   r   _get_core_name  s   r   c                  C   s*   t  } d| dd  d}tjt |S )z=
    Return real path of libcore_(no)avx.dylib on MacOS.
    libN.dylibr   r!   r"   r/   r   )raw_core_namelib_core_namer   r   r   _get_lib_core_path  s   r   c                  C   s   t  } d}tjt |S )z?
    Return real path of libcore_(no)avx.dylib on Windows.
    zlibpaddle.dllr   )r   Zdll_core_namer   r   r   _get_dll_core_path  s   r   c                 C   sP   t j| sJ tdr&d}dt  }d| d| d|  }t| dS dS )a  
    NOTE(Aurelius84): Runtime path of libpaddle.so is modified into `@loader_path/../libs`
    in setup.py.in. While loading custom op, `@loader_path` is the dirname of custom op
    instead of `paddle/base`. So we modify `@loader_path` from custom dylib into `@rpath`
    to ensure dynamic loader find it correctly.

    Moreover, we will add `-rpath site-packages/paddle/base` while linking the dylib so
    that we don't need to set `LD_LIBRARY_PATH` any more.
    darwinz@loader_path/../libs/z@rpath/zinstall_name_tool -change  N)r!   r"   rs   OS_NAME
startswithr   run_cmd)r(   Zorigin_runtime_pathZrpathcmdr   r   r   _reset_so_rpath  s   

r   c           
      C   s   d}t j| }t j||}t j|sJ d| dt|d}dd | D }W d   n1 s6w   Y  dg}t|}|D ]}|D ]}t j||}	t j|	r\|	|	 qHqD|	| |
  |S )	zV
    Get all include directories when compiling the PaddlePaddle
    source code.
    zincludes.txtzFile z does not existrr   c                 S   s   g | ]
}|  r|  qS r   )strip)rx   liner   r   r   r{     s    z4_get_include_dirs_when_compiling.<locals>.<listcomp>Nzpaddle/base/platform)r!   r"   abspathr/   isfiler,   	readlinesr\   isdirr)   sort)
compile_dirZinclude_dirs_filer"   r5   rQ   Z
extra_dirsZall_include_dirsZ	extra_dirZinclude_dirdr   r   r    _get_include_dirs_when_compiling  s.   


r   c                 C   s  t | tsJ g }| dd}|rt|}t| dg }|| |t| |t  || d< | dg }|t| || d< | dg }t |tr\dD ]
}||vr[g ||< qQt	r| dg }|t
 t }	||	  |r{|dd	g || d< nU| dg }td
r|dt   n|dt   t }	|d|	  t|dg |rt r|d n|d || d< | dg }
|
t| |
| d< |du rt|dg || d< d| d< | S )zM
    Normalize include_dirs, library_dir and other attributes in kwargs.
    Z_compile_dirNrQ   rO   rM   )ZcxxnvccrN   zcudadevrt.libzcudart_static.liblinuxz-l:z-Wl,-rpath,z-lr   z
-lamdhip64z-lcudartrP   z-DPADDLE_WITH_CUSTOM_KERNELzc++language)r[   r^   r   r   r\   extendfind_paddle_includesfind_python_includesfind_paddle_librariesr   MSVC_LINK_FLAGScreate_sym_link_if_not_existr)   r   r   r   r   add_compile_flagr   r   )kwargsuse_cudaZcompile_include_dirsr   rQ   rO   rM   compilerrN   r   rP   r   r   r   normalize_extension_kwargs  s^   





r   c                  C   s  t ds	ts	J t } tjt | }trVt }tj	|sFzt
|| W n tyE   td| |||  td| d|  Y nw tj	|sNJ | dd d S t }tj	|szt
|| tj	|snJ W n ty   td| ||w | dd	 S )
z3
    Create soft symbol link of `libpaddle.so`
    r   zFailed to create soft symbol link for {}.
 You can run prompt as administrator and execute the following command manually: `mklink {} {}`. Now it will create hard link for {} trickly.z
mklink /H r   Nz.libzgFailed to create soft symbol link for {}.
 Please execute the following command manually: `ln -s {} {}`r   )r   r   r   r   r!   r"   r/   r   r   rs   symlink	Exceptionwarningswarnr.   r   r   r`   )r   Z	core_pathZnew_dll_core_pathZnew_lib_core_pathr   r   r   r   i  sF   	r   c                  C   s   t jdpt jd} | du retrdnd}z6tt jd&}tj|dg|d}| }|	d	d
 }t j
t j
|} W d   n1 sFw   Y  W n   trbtd}t|d
kra|d
 } nd} Y | rst j
| sst rsd} | S )z0
    Use heuristic method to find cuda path
    Z	CUDA_HOMEZ	CUDA_PATHNwherewhichr   r   stderr
r   z7C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v*.*z/usr/local/cuda)r!   environr   r   r,   devnull
subprocesscheck_outputdecodesplitr"   r}   globr+   rs   r   Zis_compiled_with_cuda)	cuda_home	which_cmdr   Z	nvcc_pathZcandidate_pathsr   r   r   find_cuda_home  s>   

r   c                  C   s   t jdpt jd} | du rQtrdnd}z4tt jd$}tj|dg|d}| }|	d	}t j
t j
|} W d   n1 sDw   Y  W n   d
} Y | r_t j
| s_t r_d} | S )z0
    Use heuristic method to find rocm path
    Z	ROCM_HOMEZ	ROCM_PATHNr   r   r   Zhipccr   r   z	/opt/rocm)r!   r   r   r   r,   r   r   r   r   rstripr"   r}   rs   r   r   )	rocm_homer   r   Z
hipcc_pathr   r   r   find_rocm_home  s.   
	
r   c                  C   &   t  } | du rtdtj| dgS )z8
    Use heuristic method to find cuda include path
    NINot found CUDA runtime, please use `export CUDA_HOME=XXX` to specific it.include)r   
ValueErrorr!   r"   r/   )r   r   r   r   find_cuda_includes     r   c                  C   r   )z8
    Use heuristic method to find rocm include path
    NzJNot found ROCM runtime, please use `export ROCM_PATH= XXX` to specific it.r   r   r   r!   r"   r/   )r   r   r   r   find_rocm_includes  r   r   c                 C   s|   t  }tj|d}||g}| r%t rt }|| nt }|| t	
dr<t }|dur<tj|r<|| |S )z3
    Return Paddle necessary include dir path.
    Zthird_partyr   N)r
   r!   r"   r/   r   r   r   r   r   r   r   find_clang_cpp_includers   r)   )r   Zpaddle_include_dirZthird_party_dirrQ   Zrocm_include_dirZcuda_include_dirstd_v1_includesr   r   r   r     s   


r   c                  C   s6   t jdtrdndd} | durt| tsJ | gS g S )z8
    Return necessary include dir path of Python.h.
    r   ntposix_prefix)schemeN)	sysconfigget_pathr   r[   str)Zpython_include_pathr   r   r   r     s   r   clangc                 C   s   d }z8t | dg}| }|d}|D ]"}d|v r7|dd  }|r7tj|r7tjtj	|d}qW |S  t
yI   td Y |S w )Nz	--version
ZInstalledDir:zinclude/c++/v1zWFailed to search `include/c++/v1/` include dirs. Don't worry because it's not required.)r   r   r   r   r   r!   r"   rs   r/   r}   r   r   r   )r   r   Zcompiler_versioninfosinfoZv1_pathr   r   r   r   '  s*   
r   c                  C   sD   t  } | du rtdtrtj| ddg}|S tj| dg}|S )z;
    Use heuristic method to find cuda static lib path
    Nr   r   x64Zlib64)r   r   r   r!   r"   r/   )r   cuda_lib_dirr   r   r   find_cuda_libraries<  s   r   c                  C   s*   t  } | du rtdtj| dg}|S )z<
    Use heuristic method to find rocm dynamic lib path
    NzINot found ROCM runtime, please use `export ROCM_PATH=XXX` to specific it.r   r   )r   rocm_lib_dirr   r   r   find_rocm_librariesM  s   r   c                 C   sF   t  g}| rt rt }|| nt }|| |t  |S )z3
    Return Paddle necessary library dir path.
    )r   r   r   r   r   r   r)   r   )r   Zpaddle_lib_dirsr   r   r   r   r   r   [  s   
r   c                 C   sB   t |tsJ t | tr|  D ]}|| qd S | | d S r   )r[   r\   r^   valuesr   )rM   flagsr   r   r   r   r   p  s   
r   c                 C   s.   dh}t j| }t|dksJ |d |v S )Nz.cu   r   )r!   r"   r#   r+   )r"   Zcuda_suffixrE   r   r   r   is_cuda_filey  s   r  c                 C   sh   t jd}|du r'd}t jt jd|}trt j|}td	||  t j
|s2t | |S )a  
    Return paddle extension root directory to put shared library. It could be specified by
    ``export PADDLE_EXTENSION_DIR=XXX`` . If not set, ``~/.cache/paddle_extension`` will be used
    by default.

    Returns:
        The root directory of compiling customized operators.

    Examples:

    .. code-block:: python

        >>> from paddle.utils.cpp_extension import get_build_directory

        >>> build_dir = get_build_directory()
        >>> print(build_dir)

    ZPADDLE_EXTENSION_DIRNZpaddle_extensionsz~/.cachez<$PADDLE_EXTENSION_DIR is not set, using path: {} by default.)r!   r   r   r"   r/   
expanduserr   normpathr   r.   rs   r   )verboseZroot_extensions_directorydir_namer   r   r   get_build_directory  s&   
r  c                 C   sf   | t  jvrtd|  dt  | }dd |jD }dd |jD }dd |jD }|||fS )zg
    Parse input names and outpus detail information from registered custom op
    from OpInfoMap.
    zPlease load zc shared library file firstly by `paddle.utils.cpp_extension.load_op_meta_info_and_register_op(...)`c                 S      g | ]}|j qS r   namerx   xr   r   r   r{         z!parse_op_info.<locals>.<listcomp>c                 S   s   g | ]
}|j tvr|j qS r   )r	  DEFAULT_OP_ATTR_NAMESr
  r   r   r   r{     s    c                 S   r  r   r  r
  r   r   r   r{     r  )r	   r   Zop_proto_mapr   Zget_op_protoZinputsattrsZoutputs)r4   Zop_protoin_names
attr_names	out_namesr   r   r   parse_op_info  s   

r  c           
      C   s*  t rd}n
tdrd}nd}tj|| | }tj|s&td| dtd| | t	|}tj
dks=tjdrDt| |||S z%tj| |}|d	usRJ tj|}t|jtjjsbJ |j| W n ty}   td
 t| ||| Y S w t| |||}|D ]}	t||	t||	 q|S )zF
    Load shared library and import it as callable python module.
    r   r   r   r   zExtension path:  does not exist.zloading shared library from: r   Nzusing custom operator only)r   r   r   r!   r"   r/   rs   FileNotFoundErrorr   r   r	  sysplatform_generate_python_module	importlibutilspec_from_file_locationmodule_from_specr[   loaderabcLoaderexec_moduleImportErrorsetattrrZ   )
module_namebuild_directoryr  Zdynamic_suffixZext_pathop_namesspecmoduleZ	op_moduler4   r   r   r   _import_module_from_library  s@   
r'  c                    s   dd t t j}tj|| d | d  td  | t	 fdd dd	 |D }t
 d
}|d| W d   n1 sIw   Y  t | |}|S )zS
    Automatically generate python file to allow import or load into as module
    c                 S   s   t j| rt |  d S d S r   )r!   r"   rs   r   )filepathr   r   r   remove_if_exit  s   z/_generate_python_module.<locals>.remove_if_exitr3   z.pyzgenerate api file: c                      s    S r   r   r   Zapi_filer)  r   r   <lambda>  s    z)_generate_python_module.<locals>.<lambda>c                 S   s   g | ]}t |qS r   )r*   )rx   r4   r   r   r   r{     s    z+_generate_python_module.<locals>.<listcomp>r   r   N)r   	threadingcurrentThreadidentr!   r"   r/   r   atexitregisterr,   r-   _load_module_from_file)r"  r$  r#  r  	thread_idr2   r5   Zcustom_moduler   r*  r   r    s   r  c                 C   s>  d}d| d}d| d| d| d| d| d| d	| d
| d| d| d|  d}	t |D ]M\}
}d}|
|v r?||
 }|dkrd|| v rd|| v r|| dd  }|d| d| d| d| d| d| d| d| d| d7 }tr|	d| d| d| d| d| d7 }	q0|	d| d| d| d| d | 
7 }	q0|dkrd|| v r|| dd  }|d| d!| d| d"| d#	7 }tr|	d| d$| d| d7 }	q0|	d| d$| d | 7 }	q0|dkrAd|| v rA|| dd  }|d| d| d| d%| d| d| d&7 }tr-|	d| d| d| d| d'	7 }	q0|	d| d| d| d| d | 
7 }	q0|dkrhtsh||  }|d| d(| d&7 }|	d| d$| d | 7 }	q0|d| d(| d&7 }|	d| d$| d'7 }	q0|d| d)7 }|	d| d*|  d+| d| d,| d)7 }	||	fS )-Nz        z	res = []
zstart_idx = 0z	ins = {}
z
ins_map = r   z
outs = {}
zouts_list = z#for key, value in ins_map.items():
z    # handle optional inputs
z    if value is not None:
z        ins[key] = value
zhelper = LayerHelper("z", **locals())
r   z@VECTORz	@OPTIONAL@r   zif z is not None:
z/    res.append(outs[start_idx: start_idx + len(z)])
z    start_idx += len(z)
zelse:
z    res.append(None)
z    start_idx += 1z
    outs['zA'] = [helper.create_variable(dtype='float32') for _ in range(len(z))]z'] = z+res.append(outs[start_idx: start_idx + len(zstart_idx += len()zouts['z     res.append(outs[start_idx])
zstart_idx += 1z,'] = helper.create_variable(dtype='float32')zres.append(outs[start_idx])
z%return res[0] if len(res)==1 else reszhelper.append_op(type="z#", inputs=ins, outputs=outs, attrs=zVres = [outs[out_name] if out_name in outs.keys() else None for out_name in outs_list]
)	enumerater   lowerr   )r4   r  r  ins_map	attrs_map	outs_listinplace_reverse_idxrl   dynamic_contentstatic_contentZout_idxZout_nameZin_idxZlower_in_namesr   r   r   _gen_output_content  sd  












r=  c                 C   sT   t | \}}}}}}}}t| ||||||\}	}
td }|j| ||	|
d}|S )Na(  
        import paddle.base.core as core
        from paddle.framework import in_dynamic_mode
        from paddle.base.layer_helper import LayerHelper

        def {op_name}({params_list}):
            # The output variable's dtype use default value 'float32',
            # and the actual dtype of output variable will be inferred in runtime.
            if in_dynamic_mode():
                outs = core.eager._run_custom_op("{op_name}", {params_list})
                {dynamic_content}
            else:
                {static_content}
            )r4   params_listr;  r<  )_get_api_inputs_strr=  r   r   r    r.   )r4   r>  r7  r8  r9  r  r  r  r:  r;  r<  ZAPI_TEMPLATEr2   r   r   r   r*   y  s>   
	r*   c                 C   sj   t j| std|  dtd|  | d| }t|| }tj	|j
|}tj|}|| |S )z'
    Load module from python file.
    zFile : r  zimport module from file: Z_paddle_cpp_extension_)r!   r"   rs   r  r   r   SourceFileLoaderr  r  spec_from_loaderr	  r  r  )Zapi_file_pathr"  r  r   r  r%  r&  r   r   r   r1    s   
r1  c           
      C   s   t | \}}}|| }ddd |D }dddd |D  }dddd |D  }dddd |D  }tj| }	||||||||	fS )	z;
    Returns string of api parameters and inputs dict.
    ,c                 S   s   g | ]}| d d  qS )r3  r   )r   r6  )rx   pr   r   r   r{     s    z'_get_api_inputs_str.<locals>.<listcomp>z{%s}c                 S   &   g | ]}d  ||dd  qS z	'{}' : {}r3  r   r.   r   r6  )rx   Zin_namer   r   r   r{         c                 S   rD  rE  rF  )rx   	attr_namer   r   r   r{     rG  z[%s]c                 S   s   g | ]}d | d qS )'r   rx   r	  r   r   r   r{     r|   )r  r/   r   eagerZ _get_custom_operator_inplace_map)
r4   r  r  r  Zparam_namesr>  r7  r8  r9  r:  r   r   r   r?    s0   r?  c
                 C   s   t d }
d}tdd |D rd}td| |	 |
j| |r#dndt|t|t|t|t|t||d		}td
| |	 t|d}|| W d   dS 1 sXw   Y  dS )zL
    Automatically generate setup.py and write it into build directory.
    a  
    import os
    from paddle.utils.cpp_extension import CppExtension, CUDAExtension, BuildExtension, setup
    from paddle.utils.cpp_extension import get_build_directory


    setup(
        name='{name}',
        ext_modules=[
            {prefix}Extension(
                sources={sources},
                include_dirs={include_dirs},
                library_dirs={library_dirs},
                extra_compile_args={{'cxx':{extra_cxx_cflags}, 'nvcc':{extra_cuda_cflags}}},
                extra_link_args={extra_link_args})],
        cmdclass={{"build_ext" : BuildExtension.with_options(
            output_dir=r'{build_dir}',
            no_python_abi_suffix=True)
        }})Fc                 s   s    | ]}t |V  qd S r   )r  )rx   sourcer   r   r   r     r   z$_write_setup_file.<locals>.<genexpr>Tzwith_cuda: CUDAZCpp)	r	  prefixrL   rQ   rO   extra_cxx_cflagsextra_cuda_cflagsrN   	build_dirzwrite setup.py into r   N)	r   r   r    r   r   r.   list2strr,   r-   )r	  rL   	file_pathrQ  rQ   rO   rO  rP  Z	link_argsr  templateZ	with_cudarv   r5   r   r   r   _write_setup_file  s0   
"rU  c                 C   s4   | du rdS t | ttfsJ dd | D } t| S )zP
    Convert list[str] into string. For example: ['x', 'y'] -> "['x', 'y']"
    Nz[]c                 S   s   g | ]}| qS r   r   )rx   argr   r   r   r{   )  r  zlist2str.<locals>.<listcomp>)r[   r\   r]   ri   )r   r   r   r   rR  "  s
   rR  c           	      C   s   t j| sJ t j| }t j| }tj}zt|dg}|	 }t
d| d|  | W n tyI   t \}}}td| d| w trYd| d| d| d	}nd
| d| d| d	}td t|| dS )z,
    Build shared library in subprocess
    z-VzUsing Python interpreter: z, version: z)Failed to check Python interpreter with `z`, errors: zcd /d z && r   z buildzcd z9Compiling user custom op, it will cost a few seconds.....N)r!   r"   rs   r}   r~   r  
executabler   r   r   r   r   r   exc_infor`   r   r&   r   )	rS  r  Zext_dirZ
setup_fileinterpreter
py_versionr3   errorZcompile_cmdr   r   r   _jit_compile-  s,   r\  c              	   C   s^   dd }t  }| D ]!}t|d}| }|||O }W d   n1 s%w   Y  q	t|S )z9
    Parse registerring custom op name from sources.
    c                 S   s4   t d}t dd| } || }dd |D }|S )NzPD_BUILD_OP\(([^,\)]+)\)z\s|\t|\n c                 S   s   h | ]	}t d d|qS )Z_gradr]  )resubrJ  r   r   r   	<setcomp>W  s    z4parse_op_name_from.<locals>.regex.<locals>.<setcomp>)r^  compiler_  findall)rv   patternr4   r   r   r   regexS  s
   

z!parse_op_name_from.<locals>.regexrr   N)setr,   rt   r\   )rL   rd  r$  rL  r5   rv   r   r   r   parse_op_name_fromN  s   rf  c                 C   sl   t d|  | z|rtj| dtjdW S tj| dtdW S  ty5   t \}}}tdt	 d| w )z*
    Execute command with subprocess.
    zexecute command: T)shellr   )rg  stdoutzFailed to run command: z
, errors: )
r   r   
check_callSTDOUTr   r   r  rX  r`   ra  )commandr  r3   r[  r   r   r   r   d  s   r   c           
   	      s  t jddv r
dS ts<tjd| gtjd}t j|	 
  t fddt D s<ttj| t d td	 d
S d}tdrEdS zOtdrat}t| ddg}|	 }|
 d}n2trt}tj| tjd}z|	d}W n ty   |	d}Y nw td|
 }|dur| }W n ty   t \}}	}td|  d|	  Y d
S w t|dksJ ttt ||krdS tt!j| d"|d d
S )zi
    Check whether GCC version on user local machine is compatible with Paddle in
    site-packages.
    ZPADDLE_SKIP_CHECK_ABI)Truetrue1Tr   r   c                 3   s    | ]}| v V  qd S r   r   rJ  Zcompiler_pathr   r   r     s
    
z*check_abi_compatibility.<locals>.<genexpr>r   )user_compilerZpaddle_compilerr  F)r   r   r   r   r   z-dumpfullversionz-dumpversion.zUTF-8gbkz(\d+)\.(\d+)\.(\d+)Nz%Failed to check compiler version for z: r   )rp  rU   )#r!   r   r   r   r   r   rj  r"   realpathr   r   r   #_expected_compiler_current_platformr   r   WRONG_COMPILER_WARNINGr.   r   r   GCC_MINI_VERSIONr   MSVC_MINI_VERSIONUnicodeDecodeErrorr^  searchgroupsr   r  rX  r+   r]   mapintABI_INCOMPATIBILITY_WARNINGr/   )
r   r  Zcmd_outrU   Zmini_required_versionrp   Zcompiler_infomatchr3   r[  r   ro  r   check_abi_compatibilityx  sv   


	
r  c                  C   s:   t drddg} | S t drg d} | S trdg} | S )z?
    Returns supported compiler string on current platform
    r   r   zclang++r   )gcczg++zgnu-c++zgnu-cccl)r   r   r   )Zexpect_compilersr   r   r   rt    s   

rt  Tc                 C   s   |r	t |  dS dS )z*
    Print log information on stdout.
    N)loggerr   )r   r  r   r   r   r     s   r   )F)r   )T)tr/  r<   r   rW   importlib.abcr  importlib.utilrn   loggingr!   r^  r   r  r   r   r,  r   
contextlibr   r   Zsetuptools.commandr   r   r   r,   r   r   r   Zbase.frameworkr	   r
   r   	getLoggerr  setLevelINFO	Formatter	formatterStreamHandlerchsetFormatter
addHandlerr  r   r   r   ZMSVC_COMPILE_FLAGSZCLANG_COMPILE_FLAGSZCLANG_LINK_FLAGSr   r   r   r   rv  rw  ru  r}  Zop_proto_and_checker_makerZkOpRoleAttrNameZkOpRoleVarAttrNameZkOpNameScopeAttrNameZkOpCreationCallstackAttrNameZkOpDeviceAttrNameZkOpWithQuantAttrNamer  r   r   r   
namedtupler6   r$   rK   rR   r_   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r'  r  r=  r*   r1  r?  rU  rR  r\  rf  r   r  rt  r   r   r   r   r   <module>   s   







J"
5
				
T/*!


	
+
/
 l
04
;
!

G