U
    ,dD                  +   @   sd  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mZ d dlZd dlmZmZ d dlmZmZ d dlmZmZ d dlmZmZmZ d dlZeejdZdd	d
dZddddZ ej!e j!gej"e j"gg ej#e j#gej$e j$ge j%ge j&ge j'ge j(gg e j)ge j*gg g g g g ej+e j+ge j,ge j-gg g g g ej.e j.gg g g g ej/e j/gej0e j0gg g g g g g ej1e j1gej2e j2gej3e j3gej4e j4gg d*Z5dddddddgZ6dd e57 D Z5dd e57 D Z8dd e57 D Z9d+ddZ:dd Z;d d! Z<eG d"d# d#eZ=e=>  d$d% Z?d&d' Z@eG d(d) d)eZAeBd*kr`eC  dS ),    N)chaincombinations)configcpu)prangenjit)compile_isolatedFlags)TestCasetagoverride_env_configz"SVML tests need SVML to be presentZnehalemZhaswellskylake-avx512)          -prefer-256-bit)*sincospowexplogacosacoshasinasinhatan2atanatanhZcbrtZcdfnormZ
cdfnorminvceilZcosdcosherferfcZerfcinvZerfinvZexp10Zexp2expm1floorfmodhypotZinvsqrtlog10log1plog2logbZ	nearbyintZrintroundZsindsinhsqrttantanhtruncr-   r.   r'   r#   r(   r/   r   c                 C   s"   i | ]\}}t |d kr||qS )r   )len).0kv r5   9/tmp/pip-unpacked-wheel-eu7e0c37/numba/tests/test_svml.py
<dictcomp>U   s       r7   c                 C   s&   g | ]\}}d dd |D kr|qS )z<ufuncc                 S   s   g | ]}t |d d qS  r   strsplitr2   pr5   r5   r6   
<listcomp>X   s     <listcomp>.<listcomp>r5   r2   fr4   r5   r5   r6   r?   W   s
      r?   c                 C   s&   g | ]\}}d dd |D kr|qS )z	<built-inc                 S   s   g | ]}t |d d qS r8   r:   r=   r5   r5   r6   r?   Z   s     r@   r5   rA   r5   r5   r6   r?   Y   s
              c                 C   s  |dkr.d dd |D }d||| |f }	np|dkrhd||| d |f }	|	|dr`d	| nd
7 }	n6|dks||dks|td dd |D }djf t }	|dkp|dk}
|
r| d n| }|
r|d n|}|rdnd}tjrd| nd| }d|||f }|dkr|g}d|g}n>|g}g }|dkrV|
s<|dkrV|dd||d |f g7 }| dkr|dkrzdg}||g}n|dkrdg}||g}|	||fS )z
    For a given function and its usage modes,
    returns python code and assembly patterns it should and should not generate
    scalar,c                 S   s   g | ]}|d  qS )z[0]r5   r2   ar5   r5   r6   r?   e   s     z!func_patterns.<locals>.<listcomp>z%s%s[0] += math.%s(%s)
numpyz%s%s += np.%s(%s)intz.astype(np.%s)

ranger   c                 S   s   g | ]}|d  qS )z[i]r5   rF   r5   r5   r6   r?   l   s     zP{pad}for i in {mode}({res}.size):
{pad}{pad}{res}[i] += math.{func}({arg_list})
float32	complex64rB   r   r   Z_haz$_$z__svml_%s%d%s,Z__svml_r   int32z%zmmr-   ZsqrtsZvsqrtp)join
startswithAssertionErrorformatlocalsr   IS_OSX)funcargsresdtypemodevlenfastmathpadarg_listbodyZis_f32rB   r4   Z	prec_suffZscalar_funcZ	svml_funccontainsavoidsr5   r5   r6   func_patterns]   s@    





rb   c                 C   s   |  d| | d| S )z, Returns pretty name for given set of modes _r5   )rY   rZ   r[   namer5   r5   r6   usecase_name   s    re   c              	   C   s   t | |||}djf t }t|dkr*tnt}| drD|t}t }t }|D ]<}	t	|	dgd| |||\}
}}|
| ||
7 }|
| qT|d7 }i }t|t | ||| _|| ||fS )z? Combine multiple function calls under single umbrella usecase z\def {name}(n):
        x   = np.empty(n*8, dtype=np.{dtype})
        ret = np.empty_like(x)
rH   complexxretz        return ret)re   rS   rT   setnumpy_funcsother_funcsrQ   
differencecomplex_funcs_excluderb   updateexecglobals__doc__)rY   rZ   r[   r\   rd   r_   funcsr`   ra   rB   bcrG   Zldictr5   r5   r6   combo_svml_usecase   s&    



ru   c                   @   sR   e Zd ZdZdZeddgee	 Z
edd Zedd Zed	d
 ZdS )TestSVMLGenerationz; Tests all SVML-generating functions produce desired calls F|z\$[a-z_]\w+,c                 C   sN   t | |}z| \}}W n  tk
r8   t }d}Y nX |||d d S )NF)statusmsg)getattr	Exception	traceback
format_excput)clstestnameZoutqueuemethodokry   r5   r5   r6   	mp_runner   s    

zTestSVMLGeneration.mp_runnerc           	         s    drdkrd S  do&dk}tjft fdd}td }d| t | t| d	fd
d}t d| | d S )Nrf   rH   rI   r   c            	   
      s
  t d d \} }}tdt Z tdt @ ztd d d| }W n   td| j Y nX W 5 Q R X W 5 Q R X |  fdd	|D } fd
d	|D }| o| }dfdd	 	dD }d| d| d| d| j }||fS )Nr\   rd   NUMBA_CPU_NAMENUMBA_CPU_FEATURESerror_modelr\   r   zraised while compiling c                    s   g | ]}| kr|qS r5   r5   r2   patternasmr5   r6   r?      s      zITestSVMLGeneration._inject_test.<locals>.run_template.<locals>.<listcomp>c                    s   g | ]}| kr|qS r5   r5   r   r   r5   r6   r?      s      rJ   c                    s$   g | ]} j |rd |kr|qS )")
asm_filtersearch)r2   line)r   r5   r6   r?      s     zWhile expecting z	 and not z,
it contains:
z
when compiling )
ru   r   vlen2cpuvlen2cpu_featuresr   r{   rq   Zinspect_asmrP   r<   )	fnr`   ra   Z	jitted_fnmissedfoundr   Zdetailry   )r   rY   flagsrZ   sigr[   r   r6   run_template   s2    

(
z5TestSVMLGeneration._inject_test.<locals>.run_templaterd   Zrun_zNot implementedc           	         s   t d}| }|jt| j |gd}|  |jdd}|j}|d kr||d kr`| 	d n|dk r|| 	d|  d | j
|dd	d
 | }|d }|d }| j||d
 d S )Nspawn)targetrW      )timeoutzProcess timed out.r   zProcess terminated with signal .zprocess ended unexpectedly)ry   rx   ry   )mpZget_contextQueueProcesstyper   startrP   exitcodeZfailassertEqualget
assertTrue)	selfctxqr>   Zterm_or_timeoutr   outrx   ry   )r   r5   r6   test_runner   s     
z4TestSVMLGeneration._inject_test.<locals>.test_runnerZtest_)rQ   numbaZint64staticmethodre   setattrunittest
skipUnless)	r   rY   rZ   r[   r   skippedr   Zpostfixr   r5   )r   rY   r   rZ   r   r   r[   r6   _inject_test   s    
zTestSVMLGeneration._inject_testc                 C   s|   ddddddddg}dD ]6}t D ],}|D ]"}dD ]}| |||t| q4q,q$qd	D ]}t| |td
t| | qXd S )NFrH   Zusecase)r\   r   rd   TZfastmath_usecase)rM   float64rL   rO   )rD   rK   r   rH   )Ztest_int32_range4_usecaseZ	important)r   r   dictr   r   rz   )r   Z	flag_listrY   r[   r   rZ   nr5   r5   r6   autogenerate  s    zTestSVMLGeneration.autogenerateN)__name__
__module____qualname__rq   _numba_parallel_test_recompilerP   list
svml_funcsr   classmethodr   r   r   r5   r5   r5   r6   rv      s   
	
@rv   c                 C   s
   t | S N)mathr   )rg   r5   r5   r6   math_sin_scalar  s    r   c                 C   s6   t j| t jd}t| D ]}tt |||< q|S )NrY   )npemptyr   rK   r   r   )r   rh   rg   r5   r5   r6   math_sin_loop  s    r   c                       sd   e Zd ZdZdZ fddZdd Zdd Zd	d
 Zdd Z	dd Z
dd Zdd Zdd Z  ZS )TestSVMLz  Tests SVML behaves as expected Fc                    sB   t  | _d| j_t  | _d| j_td| j_tt| j	|  d S )NT)
r	   r   Znrt	fastflagsr   ZFastMathOptionsr\   superr   __init__)r   rW   	__class__r5   r6   r   ,  s    zTestSVML.__init__c                 O   sB   |rt tdd |D }t||| jd}t||| jd}||fS )Nc                 S   s   g | ]}t |qS r5   )r   Ztypeof)r2   rg   r5   r5   r6   r?   8  s     z$TestSVML.compile.<locals>.<listcomp>)r   )rR   tupler   r   r   )r   rV   rW   kwargsr   stdfastr5   r5   r6   r   6  s
    zTestSVML.compilec                 G   sz   |s
t  S g }|D ]^}t|tjr4||d qt|tjrP||  qt|tjrh|| qt	dqt |S )Nr3   z%Unsupported argument type encountered)
r   
isinstancer   ZndarrayappendcopynumbernumbersNumber
ValueError)r   rW   new_argsrg   r5   r5   r6   	copy_args?  s    
zTestSVML.copy_argsc              
   O   s   | j |f| \}}|dd }|dd }|dd}|dd}	|| j|  }
|j| j|  }|j| j|  }tjj||
f| tjj||
f| td|P td|	: | j |f| \}}|r| || |r| || W 5 Q R X W 5 Q R X d S )	Nstd_patternfast_patterncpu_namer   cpu_featuresr   r   r   )	r   popr   Zentry_pointr   ZtestingZassert_almost_equalr   check_svml_presence)r   ZpyfuncrW   r   ZjitstdZjitfastr   r   r   r   Zpy_expectedZjitstd_resultZjitfast_resultr5   r5   r6   checkN  s$    zTestSVML.checkc                 C   s   |j  }| || d S r   )ZlibraryZget_asm_strZassertIn)r   rV   r   r   r5   r5   r6   r   p  s    
zTestSVML.check_svml_presencec                 C   s2   t jr
dnd}| jtd|d | jtd|d d S )Nz$_sinz$sing      @)r   )r   )r   rU   r   r   )r   patr5   r5   r6   test_scalar_contextt  s    zTestSVML.test_scalar_contextc                 C   s   d}d}| j td||d d S )Nz__svml_sin8_ha,z__svml_sin8,
   )r   r   )r   r   )r   r   r   r5   r5   r6   	test_svmlz  s    zTestSVML.test_svmlc                 C   sP   d}t jtjd|gt jt jd}| \}}|jdkrLtd|j| f d S )Na  if 1:
            import os
            import numpy as np
            import math

            def math_sin_loop(n):
                ret = np.empty(n, dtype=np.float64)
                for x in range(n):
                    ret[x] = math.sin(np.float64(x))
                return ret

            def check_no_svml():
                try:
                    # ban the use of SVML
                    os.environ['NUMBA_DISABLE_INTEL_SVML'] = '1'

                    # delay numba imports to account for env change as
                    # numba.__init__ picks up SVML and it is too late by
                    # then to override using `numba.config`
                    import numba
                    from numba import config
                    from numba.core import cpu
                    from numba.tests.support import override_env_config
                    from numba.core.compiler import compile_isolated, Flags

                    # compile for overridden CPU, with and without fastmath
                    with override_env_config('NUMBA_CPU_NAME', 'skylake-avx512'),                          override_env_config('NUMBA_CPU_FEATURES', ''):
                        sig = (numba.int32,)
                        f = Flags()
                        f.nrt = True
                        std = compile_isolated(math_sin_loop, sig, flags=f)
                        f.fastmath = cpu.FastMathOptions(True)
                        fast = compile_isolated(math_sin_loop, sig, flags=f)
                        fns = std, fast

                        # assert no SVML call is present in the asm
                        for fn in fns:
                            asm = fn.library.get_asm_str()
                            assert '__svml_sin' not in asm
                finally:
                    # not really needed as process is separate
                    os.environ['NUMBA_DISABLE_INTEL_SVML'] = '0'
                    config.reload_config()
            check_no_svml()
            z-c)stdoutstderrr   z/process failed with code %s: stderr follows
%s
)	
subprocessPopensys
executablePIPEcommunicate
returncoderR   decode)r   codepopenr   errr5   r5   r6   test_svml_disabled  s    .
 
zTestSVML.test_svml_disabledc                 C   s<   t dhdddd }|d | d||jd k d S )	Nr   rH   r   c                 S   sL   t j| d t jd}t |}t|jD ]}||  t|| 7  < q(|S )Nr   r   )r   r   r   Z
empty_likerK   sizer   r    )r   rg   rh   ir5   r5   r6   impl  s
    
z@TestSVML.test_svml_working_in_non_isolated_context.<locals>.impl   Zintel_svmlccr   )r   r   Zinspect_llvmZ
signatures)r   r   r5   r5   r6   )test_svml_working_in_non_isolated_context  s    
z2TestSVML.test_svml_working_in_non_isolated_context)r   r   r   rq   r   r   r   r   r   r   r   r   r   r   __classcell__r5   r5   r   r6   r   %  s   
	"8r   __main__)rC   )Dr   rH   r   r   r   	importlibr   r   r|   multiprocessingr   	itertoolsr   r   r   Z
numba.corer   r   r   r   Znumba.core.compilerr   r	   Znumba.tests.supportr
   r   r   r   r   Z
USING_SVMLZ
needs_svmlr   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r'   r(   r,   r-   r.   r/   r   rm   itemsrj   rk   rb   re   ru   rv   r   r   r   r   r   mainr5   r5   r5   r6   <module>   s   











-
4e  
