§ y<ˆjï‡ ã ó — d Z ddlZddlZddlZddlZddlZddlZddlZ G d„ d¦ « Z G d„ d¦ « Z i Z G d„ d¦ « Z G d „ d ¦ « Z G d„ d¦ « Z G d „ d¦ « Z G d„ dee eee e¦ « Zd„ ZdS )a Provides the `CCompilerOpt` class, used for handling the CPU/hardware optimization, starting from parsing the command arguments, to managing the relation between the CPU baseline and dispatch-able features, also generating the required C headers and ending with compiling the sources with proper compiler's flags. `CCompilerOpt` doesn't provide runtime detection for the CPU features, instead only focuses on the compiler side, but it creates abstract C headers that can be used later for the final runtime dispatching process.é Nc óô — e Zd ZdZdZdZdZdZej ej ej e ¦ « ¦ « d¦ « Zi ZdZdZ e eddd ¬ ¦ « eddd¬ ¦ « eddd ¬ ¦ « ed dd¬ ¦ « eddd¬ ¦ « eddd¬ ¦ « ¬¦ « Z eddddddd¬¦ « Z edzi d eddd¬¦ « “d eddd ¬!¦ « “d" ed#dd$¬!¦ « “d% ed&d"d'¬!¦ « “d( ed)d%d*¬!¦ « “d+ ed,d(d-¬!¦ « “d. ed/d+¬0¦ « “d1 ed2d.d3d¬4¦ « “d5 ed6d1d7¬!¦ « “d8 ed9d1d7¬!¦ « “d: ed;d1¬0¦ « “d< ed=d:¬0¦ « “d> ed?d:¬0¦ « “d@ edAdBddC¬D¦ « “dE edFd@¬0¦ « “dG edHdEdIdGd¬J¦ « “dK edLdGdMdKd¬J¦ « “dN edOdEdPdNddQ¬R¦ « “dS edTdNdUdS¬V¦ « “dW edXdNdYdWd¬J¦ « “dZ ed[d\d]dZd¬J¦ « “d^ ed_dZd`d^d¬J¦ « “da eddbdc¬d¦ « “de eddad¬f¦ « “dg ed#ded¬f¦ « “dh ed&dgddi¬D¦ « “dj eddk¬l¦ « “dm eddjd¬f¦ « “dn ed#dmd¬f¦ « “do eddp¬l¦ « “dq eddo¬0¦ « “dr ed#dq¬0¦ « “ds ed&dtd¬f¦ « “du ed)ds¬0¦ « “dv ed,ds¬0¦ « “dw ed/du¬0¦ « “ŽZdx„ Zdy„ ZdS ){Ú_ConfigaÉ An abstract class holds all configurable attributes of `CCompilerOpt`, these class attributes can be used to change the default behavior of `CCompilerOpt` in order to fit other requirements. Attributes ---------- conf_nocache : bool Set True to disable memory and file cache. Default is False. conf_noopt : bool Set True to forces the optimization to be disabled, in this case `CCompilerOpt` tends to generate all expected headers in order to 'not' break the build. Default is False. conf_cache_factors : list Add extra factors to the primary caching factors. The caching factors are utilized to determine if there are changes had happened that requires to discard the cache and re-updating it. The primary factors are the arguments of `CCompilerOpt` and `CCompiler`'s properties(type, flags, etc). Default is list of two items, containing the time of last modification of `ccompiler_opt` and value of attribute "conf_noopt" conf_tmp_path : str, The path of temporary directory. Default is auto-created temporary directory via ``tempfile.mkdtemp()``. conf_check_path : str The path of testing files. Each added CPU feature must have a **C** source file contains at least one intrinsic or instruction that related to this feature, so it can be tested against the compiler. Default is ``./distutils/checks``. conf_target_groups : dict Extra tokens that can be reached from dispatch-able sources through the special mark ``@targets``. Default is an empty dictionary. **Notes**: - case-insensitive for tokens and group names - sign '#' must stick in the begin of group name and only within ``@targets`` **Example**: .. code-block:: console $ "@targets #avx_group other_tokens" > group_inside.c >>> CCompilerOpt.conf_target_groups["avx_group"] = \ "$werror $maxopt avx2 avx512f avx512_skx" >>> cco = CCompilerOpt(cc_instance) >>> cco.try_dispatch(["group_inside.c"]) conf_c_prefix : str The prefix of public C definitions. Default is ``"NPY_"``. conf_c_prefix_ : str The prefix of internal C definitions. Default is ``"NPY__"``. conf_cc_flags : dict Nested dictionaries defining several compiler flags that linked to some major functions, the main key represent the compiler name and sub-keys represent flags names. Default is already covers all supported **C** compilers. Sub-keys explained as follows: "native": str or None used by argument option `native`, to detect the current machine support via the compiler. "werror": str or None utilized to treat warning as errors during testing CPU features against the compiler and also for target's policy `$werror` via dispatch-able sources. "maxopt": str or None utilized for target's policy '$maxopt' and the value should contains the maximum acceptable optimization by the compiler. e.g. in gcc `'-O3'` **Notes**: * case-sensitive for compiler names and flags * use space to separate multiple flags * any flag will tested against the compiler and it will skipped if it's not applicable. conf_min_features : dict A dictionary defines the used CPU features for argument option `'min'`, the key represent the CPU architecture name e.g. `'x86'`. Default values provide the best effort on wide range of users platforms. **Note**: case-sensitive for architecture names. conf_features : dict Nested dictionaries used for identifying the CPU features. the primary key is represented as a feature name or group name that gathers several features. Default values covers all supported features but without the major options like "flags", these undefined options handle it by method `conf_features_partial()`. Default value is covers almost all CPU features for *X86*, *IBM/Power64* and *ARM 7/8*. Sub-keys explained as follows: "implies" : str or list, optional, List of CPU feature names to be implied by it, the feature name must be defined within `conf_features`. Default is None. "flags": str or list, optional List of compiler flags. Default is None. "detect": str or list, optional List of CPU feature names that required to be detected in runtime. By default, its the feature name or features in "group" if its specified. "implies_detect": bool, optional If True, all "detect" of implied features will be combined. Default is True. see `feature_detect()`. "group": str or list, optional Same as "implies" but doesn't require the feature name to be defined within `conf_features`. "interest": int, required a key for sorting CPU features "headers": str or list, optional intrinsics C header file "disable": str, optional force disable feature, the string value should contains the reason of disabling. "autovec": bool or None, optional True or False to declare that CPU feature can be auto-vectorized by the compiler. By default(None), treated as True if the feature contains at least one applicable flag. see `feature_can_autovec()` "extra_checks": str or list, optional Extra test case names for the CPU feature that need to be tested against the compiler. Each test case must have a C file named ``extra_xxxx.c``, where ``xxxx`` is the case name in lower case, under 'conf_check_path'. It should contain at least one intrinsic or function related to the test case. If the compiler able to successfully compile the C file then `CCompilerOpt` will add a C ``#define`` for it into the main dispatch header, e.g. ``#define {conf_c_prefix}_XXXX`` where ``XXXX`` is the case name in upper case. **NOTES**: * space can be used as separator with options that supports "str or list" * case-sensitive for all values and feature name must be in upper-case. * if flags aren't applicable, its will skipped rather than disable the CPU feature * the CPU feature will disabled if the compiler fail to compile the test file FNÚchecksÚNPY_ÚNPY__z -march=nativez-O3z-Werror)ÚnativeÚoptÚwerrorz-Werror=switch -Werrorz-xHostz/QxHostz/O3z/Werrorz/O2z/WXz-mcpu=a64fx)ÚgccÚclangÚiccÚiccwÚmsvcÚfcczSSE SSE2z SSE SSE2 SSE3Ú zVSX VSX2zNEON NEON_FP16 NEON_VFPV4 ASIMD)Úx86Úx64Úppc64Úppc64leÚs390xÚarmhfÚaarch64ÚSSEé zxmmintrin.hÚSSE2)ÚinterestÚheadersÚimpliesé zemmintrin.h)r r r ÚSSE3é zpmmintrin.hÚSSSE3é ztmmintrin.hÚSSE41é zsmmintrin.hÚPOPCNTé zpopcntintrin.hÚSSE42é )r r ÚAVXé zimmintrin.h)r r r Úimplies_detectÚXOPé zx86intrin.hÚFMA4é ÚF16Cé ÚFMA3é ÚAVX2é ÚAVX512Fé z FMA3 AVX2ÚAVX512F_REDUCE)r r r, Úextra_checksÚAVX512CDé Ú AVX512_KNLé( zAVX512ER AVX512PF)r r ÚgroupÚdetectr, Ú AVX512_KNMé) z)AVX5124FMAPS AVX5124VNNIW AVX512VPOPCNTDQÚ AVX512_SKXé* zAVX512VL AVX512BW AVX512DQzAVX512BW_MASK AVX512DQ_MASK)r r r? r@ r, r: Ú AVX512_CLXé+ Ú AVX512VNNI)r r r? r@ Ú AVX512_CNLé, zAVX512IFMA AVX512VBMIÚ AVX512_ICLé- zAVX512_CLX AVX512_CNLz(AVX512VBMI2 AVX512BITALG AVX512VPOPCNTDQÚ AVX512_SPRé. Ú AVX512FP16ÚVSXz altivec.hÚVSX_ASM)r r r: ÚVSX2)r r r, ÚVSX3ÚVSX4ÚVSX4_MMAÚVXzvecintrin.h)r r ÚVXEÚVXE2ÚNEONz arm_neon.hÚ NEON_FP16Ú NEON_VFPV4ÚASIMDzNEON_FP16 NEON_VFPV4ÚASIMDHPÚASIMDDPÚASIMDFHMc óp — | j ri S | j p| j }| j p | j p| j }|�rƒ|�r€t dwi dt d¬¦ « “dt d¬¦ « “dt d¬¦ « “dt d ¬¦ « “d t d¬¦ « “dt d ¬¦ « “dt d¬¦ « “dt d¬¦ « “dt d¬¦ « “dt d¬¦ « “dt d¬¦ « “dt d¬¦ « “dt d¬¦ « “dt d¬¦ « “dt d¬¦ « “d t d!¬¦ « “d"t d#¬¦ « “d$t d%¬¦ « “d&t d'¬¦ « “d(t d)¬¦ « “d*t d+¬¦ « “d,t d-¬¦ « “ŽS |�rp| j �rht dwi dt d¬¦ « “dt d¬¦ « “dt d¬¦ « “dt d ¬¦ « “d t d¬¦ « “di “dt d¬¦ « “dt d¬¦ « “di “dt d.¬/¦ « “dt d.¬/¦ « “dt d0d1¬2¦ « “dt dd1¬2¦ « “dt d3d4¬2¦ « “dt d5d4¬2¦ « “d t d6¬¦ « “d"t d7¬¦ « “d$t d8¬¦ « “d&t d9¬¦ « “d(t d:¬¦ « “d*t d;¬¦ « “d,t d<¬/¦ « “ŽS |�rp| j �rht dwi dt d=¬¦ « “dt d>¬¦ « “dt d?¬¦ « “dt d@¬¦ « “d t dA¬¦ « “di “dt dB¬¦ « “dt dC¬¦ « “di “dt d.¬/¦ « “dt d.¬/¦ « “dt d0dD¬2¦ « “dt ddD¬2¦ « “dt d3dE¬2¦ « “dt d5dE¬2¦ « “d t dF¬¦ « “d"t dG¬¦ « “d$t dH¬¦ « “d&t dI¬¦ « “d(t dJ¬¦ « “d*t dK¬¦ « “d,t d<¬/¦ « “ŽS |�r.| j �r&t dwi d| j rt d=¬¦ « ni “d| j rt d>¬¦ « ni “di “di “d i “dt dL¬M¦ « “di “dt dC¬¦ « “di “dt dN¬M¦ « “dt dN¬M¦ « “dt d0dO¬2¦ « “dt dPdO¬2¦ « “dt dQdR¬2¦ « “dt dSdR¬2¦ « “d t dT¬/¦ « “d"t dT¬/¦ « “d$t dR¬¦ « “d&i