U
    9%e                    @   s  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	m
Z
mZmZmZmZmZmZmZmZmZmZmZmZmZ d dlmZ d dlmZmZ d dlZd dlmZ d dl Z dZ!d Z"e j#gZ$i Z%dd	d
dgZ&ddgZ'dddddgZ(dddddddgZ)ddddddd d!gZ*e'e( e) e* d"d#g Z+ed$d% Z,d&d' Z-ed(d) Z.G d*d+ d+e/Z0G d,d- d-e0Z1G d.d/ d/e1Z2G d0d1 d1e/Z3G d2d3 d3e/Z4e5ej6j78 ej9g Z:ej;j78 Z<ej=j78 Z>d4d5 ej?D Z@dS )6    N)typesirconfigcgutilserrors)mk_unique_varfind_topo_orderdprint_func_irget_global_func_typguardrequireget_definitionfind_callnamefind_build_sequence
find_constis_namedtuple_classbuild_definitionsfind_potential_aliasesget_canonical_aliasGuardException)compute_cfg_from_blocks)npydecl	signature)	intrinsicemptyZzerosZonesfullZrandZrandnZranfZrandom_samplesamplerandomZstandard_normalZ	chisquareZweibullpowerZ	geometricZexponentialZpoissonZrayleighnormaluniformbetaZbinomialfgammaZ	lognormalZlaplacerandint
triangularc                    sf   t t|tjj t t|tjj |jr0tjntj|jrBtjntj  fdd}t|||fS )a  
    Calculate index value "idx" relative to a size "size" value as
    (idx % size), where "size" is known to be positive.
    Note that we use the mod(%) operation here instead of
    (idx < 0 ? idx + size : idx) because we may have situations
    where idx > size due to the way indices are calculated
    during slice/range analysis.

    Both idx and size have to be Integer types.
    size should be from the array size vars that array_analysis
    adds and the bitwidth should match the platform maximum.
    c                    s   |   }|  } jr,||d |}n||d |}jrT||d |}n||d |}||}tj|d}	|d||	}
|d||}|d||}|	|||}|	||	|
||}|	|
||}|S )Nr      <z>=z<=)Zget_data_typesignedZsextZzextnegllvmliter   ConstantZicmp_signedselectadd)contextbuildersigargsZll_idx_unified_tyZll_unified_tyidxsizeZneg_sizezeroZidx_negativeZpos_oversizeZneg_oversizeZpos_resZneg_resmodZidx_unifiedZ
unified_ty [/var/www/html/Darija-Ai-API/env/lib/python3.8/site-packages/numba/parfors/array_analysis.pycodegenf   s"    


zwrap_index.<locals>.codegen)	r   
isinstancer   ZscalarsIntegerr)   intpZuintpr   )	typingctxr3   r4   r:   r8   r7   r9   
wrap_indexQ   s    r?   c                 C   s4   | dk r | | krdS | | S n| |kr,|S | S d S Nr   r8   )r3   r4   r8   r8   r9   wrap_index_literal   s    

rA   c                 G   s   t |dkrt|f}t |d dks,ttdd |d dd D sNtt|d d tjsltddd }t	tj
f| |fS )	z
    A function that asserts the inputs are of equivalent size,
    and throws runtime error when they are not. The input is
    a vararg that contains an error message, followed by a set
    of objects of either array, tuple or integer.
    r'   r   c                 s   s(   | ] }t |tjtjtjtjfV  qd S N)r;   r   ArrayCompatible	BaseTuple	SliceTyper<   .0ar8   r8   r9   	<genexpr>   s   zassert_equiv.<locals>.<genexpr>Nz&first argument must be a StringLiteralc           	         s   t |dkstt |d }|jd }|jd d j fdd fdd}tdt |d D ]*}||| || ||d  ||d   ql tj	d }|S )Nr'   r   c                    sN   t |tjr,| | }t |jS t |tjrDt | S | gS d S rB   )r;   r   rC   Z
make_arrayr   unpack_tupleshaperD   )rH   atyZary)r0   r/   r8   r9   unpack_shapes   s    z4assert_equiv.<locals>.codegen.<locals>.unpack_shapesc                    s   | |}||}t |t |ks(tt||D ]b\}} d||} |<\}	}
|	 W 5 Q R X |
 j tf W 5 Q R X W 5 Q R X q2d S )Nz==)lenAssertionErrorzipZicmp_unsignedZif_elseZ	call_convZreturn_user_exc)rH   rL   bZbtyZashapesZbshapesmnZm_eq_nZthenZorelser0   r/   msgrM   r8   r9   pairwise   s    


  z/assert_equiv.<locals>.codegen.<locals>.pairwise)
rN   rO   r   rJ   r2   Zliteral_valuerangeZget_constant_genericr   NoneType)	r/   r0   r1   r2   tupZtup_typerV   irr8   rT   r9   r:      s    
	(zassert_equiv.<locals>.codegen)rN   r   StarArgTuplerO   allr;   StringLiteralr   ZTypingErrorr   none)r>   valr:   r8   r8   r9   assert_equiv   s    	
"ra   c                   @   sz   e Zd ZdZd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dd Zdd Zdd Zdd ZdS )EquivSetzPEquivSet keeps track of equivalence relations between
    a set of objects.
    Nr   c                 C   s&   |r|ni | _ |r|ni | _|| _dS )zdCreate a new EquivSet object. Optional keyword arguments are for
        internal use only.
        N)
obj_to_ind
ind_to_objnext_ind)selfrc   rd   re   r8   r8   r9   __init__   s    zEquivSet.__init__c                 C   s   t  S )z)Return an empty EquivSet object.
        )rb   rf   r8   r8   r9   r      s    zEquivSet.emptyc                 C   s    t t| jt| j| jdS )Return a new copy.
        )rc   rd   next_id)rb   copydeepcopyrc   rd   re   rh   r8   r8   r9   clone   s
    

zEquivSet.clonec                 C   s   d | jS )NzEquivSet({}))formatrd   rh   r8   r8   r9   __repr__   s    zEquivSet.__repr__c                 C   s
   | j i kS )z=Return true if the set is empty, or false otherwise.
        )rc   rh   r8   r8   r9   is_empty   s    zEquivSet.is_emptyc                 C   s   | j |dS )zkReturn the internal index (greater or equal to 0) of the given
        object, or -1 if not found.
        r   )rc   get)rf   xr8   r8   r9   _get_ind   s    zEquivSet._get_indc                 C   s.   || j kr| j | }n| j}|  jd7  _|S )zyReturn the internal index (greater or equal to 0) of the given
        object, or create a new one if not found.
        r'   )rc   re   )rf   rr   rZ   r8   r8   r9   _get_or_add_ind   s
    
zEquivSet._get_or_add_indc                    s   t |dkstt fdd|D }t|}tjdkrDtd|| | jkrXg  j|< t||D ]\}}||kr| j| kr j| 	| | j
|< qb| jkrڈ j| D ]}| j
|<  j| 	| q j|= qb| j
|<  j| 	| qbdS )zXBase method that inserts a set of equivalent objects by modifying
        self.
        r'   c                 3   s   | ]}  |V  qd S rB   )rt   rG   rr   rh   r8   r9   rI     s     z#EquivSet._insert.<locals>.<genexpr>   z_insert:N)rN   rO   tupleminr   DEBUG_ARRAY_OPTprintrd   rP   appendrc   )rf   objsindsindrZ   objrr   r8   rh   r9   _insert
  s&    






zEquivSet._insertc                    sR   fddD }t |  dkr8t fdd|D S tfddD S dS )zfTry to derive if given objects are equivalent, return true
        if so, or false otherwise.
        c                    s   g | ]}  |qS r8   rs   ru   rh   r8   r9   
<listcomp>.  s     z%EquivSet.is_equiv.<locals>.<listcomp>r   c                 3   s   | ]}| kV  qd S rB   r8   rG   rZ   )r~   r8   r9   rI   1  s     z$EquivSet.is_equiv.<locals>.<genexpr>c                    s   g | ]}| d  kqS )r   r8   ru   )r|   r8   r9   r   3  s     N)maxr]   )rf   r|   r}   r8   )r~   r|   rf   r9   is_equiv*  s
    zEquivSet.is_equivc                 C   s<   |  |}|dkr8| j| }|D ]}t|tr |  S q dS )zvCheck if obj is equivalent to some int constant, and return
        the constant if found, or None otherwise.
        r   N)rs   rd   r;   int)rf   r   r~   r|   rr   r8   r8   r9   get_equiv_const5  s    



zEquivSet.get_equiv_constc                 C   s&   |  |}|dkr t| j| S t S ).Return the set of equivalent objects.
        r   )rs   setrd   )rf   r   r~   r8   r8   r9   get_equiv_setA  s    
zEquivSet.get_equiv_setc                 G   s
   |  |S )zInsert a set of equivalent objects by modifying self. This
        method can be overloaded to transform object type before insertion.
        )r   )rf   r|   r8   r8   r9   insert_equivI  s    zEquivSet.insert_equivc           	         s      } j|_|j D ]}t fdd|D }i }t||D ]2\}}||krb|| | qB|dkrB|g||< qB| D ]}t|dkr~|| q~q|S )z Return the intersection of self and the given equiv_set,
        without modifying either of them. The result will also keep
        old equivalence indices unchanged.
        c                 3   s   | ]}  |V  qd S rB   r   ru   rh   r8   r9   rI   X  s     z%EquivSet.intersect.<locals>.<genexpr>r   r'   )	r   re   rd   valuesrw   rP   r{   rN   r   )	rf   	equiv_setZnew_setr|   r}   rd   rZ   rr   vr8   rh   r9   	intersectO  s    zEquivSet.intersect)NNr   )__name__
__module____qualname____doc__rg   r   rm   ro   rp   rs   rt   r   r   r   r   r   r   r8   r8   r8   r9   rb      s   
	 rb   c                       s   e Zd ZdZd( fdd	Zdd Zdd	 Zd
d Zdd Z fddZ	 fddZ
dd Z fddZ fddZ fddZdd Zdd Zdd Zd d! Z fd"d#Zd$d% Zd&d' Z  ZS ))ShapeEquivSetad  Just like EquivSet, except that it accepts only numba IR variables
    and constants as objects, guided by their types. Arrays are considered
    equivalent as long as their shapes are equivalent. Scalars are
    equivalent only when they are equal in value. Tuples are equivalent
    when they are of the same size, and their elements are equivalent.
    Nr   c                    sH   || _ |r|ni | _|r|ni | _|r*|ni | _tt| ||| dS )zCreate a new ShapeEquivSet object, where typemap is a dictionary
        that maps variable names to their types, and it will not be modified.
        Optional keyword arguments are for internal use only.
        N)typemapdefs
ind_to_varind_to_constsuperr   rg   )rf   r   r   r   rc   rd   rj   r   	__class__r8   r9   rg   q  s
    zShapeEquivSet.__init__c                 C   s   t | ji S )z'Return an empty ShapeEquivSet.
        )r   r   rh   r8   r8   r9   r     s    zShapeEquivSet.emptyc              
   C   sB   t | jt| jt| jt| jt| j| jt| j	dS )ri   )r   r   rc   rd   rj   r   )
r   r   rk   r   r   rl   rc   rd   re   Zind_toconstrh   r8   r8   r9   rm     s    




zShapeEquivSet.clonec                 C   s   d | j| j| jS )Nz1ShapeEquivSet({}, ind_to_var={}, ind_to_const={}))rn   rd   r   r   rh   r8   r8   r9   ro     s
      zShapeEquivSet.__repr__c                    s,  t |tjst |trt |tr$|n|jjkr:fS j }t |tjtjfrt |tjrh|j	nt
|}|dkr~fS tfddt|D S nfS nft |tjrt |jtr|jS |jfS n>t |trfdd t fdd|D S t |tr|fS tjdkr(tdt| d	 d
S )zReturn a set of names for the given obj, where array and tuples
        are broken down to their individual shapes or elements. This is
        safe because both Numba array shapes and Python tuples are immutable.
        r   c                 3   s   | ]}d   |V  qdS )z{}#{}N)rn   r   namer8   r9   rI     s     z+ShapeEquivSet._get_names.<locals>.<genexpr>c                    s"     | }t|dkr|d S |S r@   )
_get_namesrN   )rr   namesrh   r8   r9   	get_names  s    
z+ShapeEquivSet._get_names.<locals>.get_namesc                 3   s   | ]} |V  qd S rB   r8   ru   )r   r8   r9   rI     s     r'   zIgnoring untracked object type z in ShapeEquivSetr8   )r;   r   Varstrr   r   r   rD   rC   ndimrN   rw   rW   Constvaluer   r   ry   rz   type)rf   r   typr   r8   )r   r   rf   r9   r     s8    




zShapeEquivSet._get_namesc                    s   t |dkstfdd|D }dd |D }t |dkr@dS dd |D }|d tfdd	|D stjdkrtd
| dS tD ],  fdd|D }tt	j
| s dS qdS )zWOverload EquivSet.is_equiv to handle Numba IR variables and
        constants.
        r'   c                    s   g | ]}  |qS r8   r   ru   rh   r8   r9   r     s     z*ShapeEquivSet.is_equiv.<locals>.<listcomp>c                 S   s   g | ]}|d kr|qS r8   r8   ru   r8   r8   r9   r     s      Fc                 S   s   g | ]}t |qS r8   rN   )rG   r   r8   r8   r9   r     s     r   c                 3   s   | ]} |kV  qd S rB   r8   ru   r   r8   r9   rI     s     z)ShapeEquivSet.is_equiv.<locals>.<genexpr>z#is_equiv: Dimension mismatch for {}c                    s   g | ]}|  qS r8   r8   rG   obj_namerZ   r8   r9   r     s     T)rN   rO   r]   r   ry   rz   rn   rW   r   r   r   )rf   r|   	obj_namesndimsr   r   rZ   r   rf   r9   r     s     
zShapeEquivSet.is_equivc                    s.   |  |}t|dkrdS tt| |d S )ztIf the given object is equivalent to a constant scalar,
        return the scalar value, or None otherwise.
        r'   Nr   )r   rN   r   r   r   rf   r   r   r   r8   r9   r     s    
zShapeEquivSet.get_equiv_constc                 C   sJ   |  |}t|dkrdS | |d }| j|g }|g krF|d S dS )ztIf the given object is equivalent to some defined variable,
        return the variable, or None otherwise.
        r'   Nr   )r   rN   rs   r   rq   )rf   r   r   r~   vsr8   r8   r9   get_equiv_var  s    
zShapeEquivSet.get_equiv_varc                    s.   |  |}t|dkrdS tt| |d S )r   r'   Nr   )r   rN   r   r   r   r   r   r8   r9   r     s    
zShapeEquivSet.get_equiv_setc           
         s   g }|D ]}|| j kr|| j |  qg }d}t }t|D ]^}|| jkr|| j| D ]$}|j|krV|| ||j qV|| jkr>|dkst| j| }q>t	t
| | | j |d  }	t|D ]}|| jkr| j|= q|| j|	< |dk	r|| j|	< dS )zCOverload EquivSet._insert to manage ind_to_var dictionary.
        Nr   )rc   r{   r   sortedr   r   r.   r   rO   r   r   r   )
rf   r|   r}   r   varlistZconstvalr   rZ   rr   Znew_indr   r8   r9   r      s0    







zShapeEquivSet._insertc                    s  t |dkstfdd|D }dd |D }t |dkr@dS tdd |D g }dd |D }|d tfd	d
|D std|g }g }|D ]z}t|ts|f}|D ]`}t|tjr|j	|kr|j	j
kr|d| n
|| t|tjr|j|kr||j qq|D ]X}|j	}	|	|kr|	jkr|	gjj< jj|	< |gjj<  jd7  _q|D ]P}
|
|krx|
jkrx|
gjj< jj|
< |
jj<  jd7  _qxd}tD ]2  fdd|D }ttj| }|p|}q|S )zOverload EquivSet.insert_equiv to handle Numba IR variables and
        constants. Input objs are either variable or constant, and at least
        one of them must be variable.
        r'   c                    s   g | ]}  |qS r8   r   ru   rh   r8   r9   r   "  s     z.ShapeEquivSet.insert_equiv.<locals>.<listcomp>c                 S   s   g | ]}|d kr|qS r   r8   ru   r8   r8   r9   r   #  s      Nc                 S   s   g | ]}t |qS r8   )listru   r8   r8   r9   r   &  s     c                 S   s   g | ]}t |qS r8   r   ru   r8   r8   r9   r   '  s     r   c                 3   s   | ]} |kV  qd S rB   r8   ru   r   r8   r9   rI   )  s    z-ShapeEquivSet.insert_equiv.<locals>.<genexpr>zDimension mismatch for {}Fc                    s   g | ]}|  qS r8   r8   r   r   r8   r9   r   O  s     )rN   rO   sumr]   rn   r;   rw   r   r   r   r   insertr{   r   r   rc   rd   re   r   r   rW   r   r   r   )rf   r|   r   r   r   r   Z	constlistr   varr   constZsome_changeZie_resr   r   r9   r     sX    


zShapeEquivSet.insert_equivc                 C   s   |  |dk	S )zEReturn true if the shape of the given variable is available.
        N	get_shaperf   r   r8   r8   r9   	has_shapeU  s    zShapeEquivSet.has_shapec                 C   s   t | j|S )ztReturn a tuple of variables that corresponds to the shape
        of the given array, or None if not found.
        )r   
_get_shaper   r8   r8   r9   r   Z  s    zShapeEquivSet.get_shapec                 C   s~   |  |}t|dk g }|D ]V}t|| jk | j| }|g krR||d  qt|| jk | j| }|| qt|S )zReturn a tuple of variables that corresponds to the shape
        of the given array, or raise GuardException if not found.
        r8   r   )get_shape_classesr   r   r{   r   rw   )rf   r   r}   rK   rZ   r   r8   r8   r9   r   `  s    


zShapeEquivSet._get_shapec                    s   t |tjr|j}| jkr& j| nd}t |tjtjtjfsDg S t |tjr^|j	dkr^g S  
|}t fdd|D }|S )zInstead of the shape tuple, return tuple of int, where
        each int is the corresponding class index of the size object.
        Unknown shapes are given class index -1. Return empty tuple
        if the input name is a scalar variable.
        Nr   c                 3   s   | ]}  |V  qd S rB   r   )rG   r   rh   r8   r9   rI     s     z2ShapeEquivSet.get_shape_classes.<locals>.<genexpr>)r;   r   r   r   r   r   rD   rE   rC   r   r   rw   )rf   r   r   r   r}   r8   rh   r9   r   r  s      
zShapeEquivSet.get_shape_classesc                    s   t t| |}i }|j D ]\}}t|dks6t|d }|| jksLt||jksZt| j| }|j| }|| jks|t||jkstg }	dd |j| D }
| j| D ]}|j	|
kr|	
| q|	||< q||_|S )z<Overload the intersect method to handle ind_to_var.
        r   c                 S   s   g | ]
}|j qS r8   r   ru   r8   r8   r9   r     s     z+ShapeEquivSet.intersect.<locals>.<listcomp>)r   r   r   rd   itemsrN   rO   rc   r   r   r{   )rf   r   newsetr   rZ   r|   r   jkr   r   rr   r   r8   r9   r     s&    



zShapeEquivSet.intersectc           	      C   s&  t |tjr|j}|| jkr| j|  d7  < t| |}|D ]}|| jkrB|| | j| }| j|= | j	| 
| | j	| g kr| j	|= || jkstdd | j| D }||krB||}| j| |= | j| g krB| j|= || j	krB| j	| D ]}| j|=  q| j	|= qBn
d| j|< dS )a  Increment the internal count of how many times a variable is being
        defined. Most variables in Numba IR are SSA, i.e., defined only once,
        but not all of them. When a variable is being re-defined, it must
        be removed from the equivalence relation and added to the redefined
        set but only if that redefinition is not known to have the same
        equivalence classes. Those variables redefined are removed from all
        the blocks' equivalence sets later.

        Arrays passed to define() use their whole name but these do not
        appear in the equivalence sets since they are stored there per
        dimension. Calling _get_names() here converts array names to
        dimensional names.

        This function would previously invalidate if there were any multiple
        definitions of a variable.  However, we realized that this behavior
        is overly restrictive.  You need only invalidate on multiple
        definitions if they are not known to be equivalent. So, the
        equivalence insertion functions now return True if some change was
        made (meaning the definition was not equivalent) and False
        otherwise. If no change was made, then define() need not be
        called. For no change to have been made, the variable must
        already be present. If the new definition of the var has the
        case where lhs and rhs are in the same equivalence class then
        again, no change will be made and define() need not be called
        or the variable invalidated.
        r'   c                 S   s   g | ]
}|j qS r8   r   ru   r8   r8   r9   r     s     z(ShapeEquivSet.define.<locals>.<listcomp>N)r;   r   r   r   r   r   r   rc   r.   rd   remover   rO   index)	rf   r   	redefinedZname_resZone_namerZ   r   r   r   r8   r8   r9   define  s6    



zShapeEquivSet.definec                 C   s*   |  D ]\}}|dkr| || qdS )zUnion with the given defs dictionary. This is meant to handle
        branch join-point, where a variable may have been defined in more
        than one branches.
        r   N)r   r   )rf   r   r   r   r   r8   r8   r9   
union_defs  s    zShapeEquivSet.union_defs)NNNNr   N)r   r   r   r   rg   r   rm   ro   r   r   r   r   r   r   r   r   r   r   r   r   r   r   __classcell__r8   r8   r   r9   r   h  s2   
      +	9<r   c                       s~   e Zd ZdZd fdd	Zdd Zdd	 Zd
d Zdd Zd fdd	Z	d fdd	Z
 fddZdd Z fddZ  ZS )SymbolicEquivSeta/  Just like ShapeEquivSet, except that it also reasons about variable
    equivalence symbolically by using their arithmetic definitions.
    The goal is to automatically derive the equivalence of array ranges
    (slicing). For instance, a[1:m] and a[0:m-1] shall be considered
    size-equivalence.
    Nr   c
           
         sT   |r|ni | _ |r|ni | _|r$|ni | _i | _i | _tt| ||||||	 dS )zCreate a new SymbolicEquivSet object, where typemap is a dictionary
        that maps variable names to their types, and it will not be modified.
        Optional keyword arguments are for internal use only.
        N)def_byref_by
ext_shapesrel_mapwrap_mapr   r   rg   )
rf   r   r   r   r   r   r   rc   rd   rj   r   r8   r9   rg     s    
     zSymbolicEquivSet.__init__c                 C   s
   t | jS )z*Return an empty SymbolicEquivSet.
        )r   r   rh   r8   r8   r9   r     s    zSymbolicEquivSet.emptyc                 C   s   d | j| j| j| j| jS )NzHSymbolicEquivSet({}, ind_to_var={}, def_by={}, ref_by={}, ext_shapes={}))rn   rd   r   r   r   r   rh   r8   r8   r9   ro      s    zSymbolicEquivSet.__repr__c                 C   sV   t | jt| jt| jt| jt| jt| jt| j	t| j
| jd	S )ri   )r   r   r   r   r   rc   rd   rj   )r   r   rk   r   r   r   r   r   rl   rc   rd   re   rh   r8   r8   r9   rm   ,  s    






zSymbolicEquivSet.clonec                 C   s   t | j|S )zjRetrieve a definition pair for the given variable,
        or return None if it is not available.
        )r   _get_or_set_relr   r8   r8   r9   get_rel;  s    zSymbolicEquivSet.get_relc                    s  t |tjr|j}tj|ddk |jkr<j| S t|dk	 dd  fdd t||}|df}t |tj	r|j
dkrt||jd	\}}|d
kr|dkrtfdd|jD }d|krdS j|g }|| t|dkr| |j|< nr|j
dkr|j|}	|j|}
|	dksN|
dkrRdS |jtjkrl|	|
}n|jtjkr |	|
}n"t |tjrt |jtr|j}t|dk	 |j|< t |tst |tr|d |ks|d dkrt |tr|\}|jkrg j|< j| | f |}|dkrj| }g }|D ].}|jkrX|fddj| D 7 }qXt|dkrt t!| |S dS )zRetrieve a definition pair for the given variable,
        and if it is not already available, try to look it up
        in the given func_ir, and remember it for future use.
        r   r'   Nc                 S   sZ   t | t}t |t}|r:|r$| | S |\}}|| | fS n| \}}|rR||| fS d S d S rB   r;   r   )rr   yZ
x_is_constZ
y_is_constr   offsetr8   r8   r9   plusN  s    

z.SymbolicEquivSet._get_or_set_rel.<locals>.plusc                    sT   t |tr| | S t | trLt |trL| d |d krL | d |d S d S d S Nr   r'   )r;   r   rw   )rr   r   )minusr   r8   r9   r   ^  s    
z/SymbolicEquivSet._get_or_set_rel.<locals>.minuscallr   r?   znumba.parfors.array_analysisc                 3   s   | ]} j |jd V  qdS )r   N)rc   rq   r   ru   rh   r8   r9   rI   u  s    z3SymbolicEquivSet._get_or_set_rel.<locals>.<genexpr>r   binopc                    s   g | ]\}}|  kr|qS r8   r8   )rG   rr   rZ   )r   r8   r9   r     s   
z4SymbolicEquivSet._get_or_set_rel.<locals>.<listcomp>)"r;   r   r   r   r   r   rq   r   r   Expropr   r   rw   r2   r   r{   rN   r   r   lhsrhsfnoperatorr.   subr   r   r   r   rs   rd   r   r   )rf   r   func_irexprr   fnamemod_namer   r   r   r   r   r~   r|   r   r   )r   r   r   rf   r9   r   A  s    


  









z SymbolicEquivSet._get_or_set_relc                    s   t |tjr|j}n|}tt| || |r| j|ddkrt |t	j
rt| j||}t |trr| ||g t |tjr| |}|| jkr|g| j|< || j|< || jkr| j| | n|g| j|< dS dS )af  Besides incrementing the definition count of the given variable
        name, it will also retrieve and simplify its definition from func_ir,
        and remember the result for later equivalence comparison. Supported
        operations are:
          1. arithmetic plus and minus with constants
          2. wrap_index (relative to some given size)
        r   r'   TN)r;   r   r   r   r   r   r   r   rq   r   Numberr   r   r   r   rt   rd   rc   r   r{   )rf   r   r   r   r   r   r   r~   r   r8   r9   r     s,    





zSymbolicEquivSet.definec                    sb  t  }t  }|D ]>}| |}|dkr2|| q||kr|| || qt|dkr`dS t|}tt| | | j| |d  }i }dd }|D ]}|| j	kr| j	| }t
|tr|\}	}
|||
 |	 |	| jkr| j|	 D ]\}}|||
|  | q|| jkr| j| D ]\}	}
|||
|	 q&q| D ]}| | qLdS )zOverload _insert method to handle ind changes between relative
        objects.  Returns True if some change is made, false otherwise.
        r   r'   Fr   c                 S   s"   || kr| | }ng }|| |< |S rB   r8   )dr   r   r8   r8   r9   
get_or_set  s
    
z,SymbolicEquivSet._insert.<locals>.get_or_setT)r   rs   r.   rN   r   r   r   r   rd   r   r;   rw   r{   r   r   )rf   r|   ZindsetZuniqsr   r~   Zoffset_dictr   r   r   r   r   rZ   r   r   r8   r9   r     s>    



zSymbolicEquivSet._insertc                 C   s$   t |tjtjfst|| j|< dS )z-remember shapes of SetItem IR nodes.
        N)r;   r   StaticSetItemSetItemrO   r   )rf   r   rK   r8   r8   r9   set_shape_setitem  s    z"SymbolicEquivSet.set_shape_setitemc                    sl   t |tjtjfr*t|| jk | j| S t |tjs:t| j|j	 }t |t
jrX|fS tt| |S dS )zGOverload _get_shape to retrieve the shape of SetItem IR nodes.
        N)r;   r   r   r   r   r   r   rO   r   r   r   rE   r   r   r   )rf   r   r   r   r8   r9   r     s    
zSymbolicEquivSet._get_shape)NNNNNNNr   )N)NN)r   r   r   r   rg   r   ro   rm   r   r   r   r   r   r   r   r8   r8   r   r9   r     s&   
        -m!.r   c                   @   s   e Zd ZdZdd ZdS )WrapIndexMetaa  
      Array analysis should be able to analyze all the function
      calls that it adds to the IR.  That way, array analysis can
      be run as often as needed and you should get the same
      equivalencies.  One modification to the IR that array analysis
      makes is the insertion of wrap_index calls.  Thus, repeated
      array analysis passes should be able to analyze these wrap_index
      calls.  The difficulty of these calls is that the equivalence
      class of the left-hand side of the assignment is not present in
      the arguments to wrap_index in the right-hand side.  Instead,
      the equivalence class of the wrap_index output is a combination
      of the wrap_index args.  The important thing to
      note is that if the equivalence classes of the slice size
      and the dimension's size are the same for two wrap index
      calls then we can be assured of the answer being the same.
      So, we maintain the wrap_map dict that maps from a tuple
      of equivalence class ids for the slice and dimension size
      to some new equivalence class id for the output size.
      However, when we are analyzing the first such wrap_index
      call we don't have a variable there to associate to the
      size since we're in the process of analyzing the instruction
      that creates that mapping.  So, instead we return an object
      of this special class and analyze_inst will establish the
      connection between a tuple of the parts of this object
      below and the left-hand side variable.
    c                 C   s   || _ || _d S rB   )
slice_sizedim_size)rf   r   r   r8   r8   r9   rg   /  s    zWrapIndexMeta.__init__N)r   r   r   r   rg   r8   r8   r8   r9   r     s   r   c                   @   s  e Zd ZdZdd Zdd Zdd Zdd	d
Zdd Zdd Z	dd Z
dd Zdd ZG dd deZdd Zdd Zdd Zdd Zdd  Zdd"d#Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ Zd0d1 Zd2d3 Zd4d5 Zd6d7 Zd8d9 Zd:d; Z d<d= Z!d>d? Z"d@dA Z#dBdC Z$dDdE Z%dFdG Z&dHdI Z'dJdK Z(dLdM Z)dNdO Z*dPdQ Z+dRdS Z,dTdU Z-dVdW Z.dXdY Z/dZd[ Z0d\d] Z1d^d_ Z2d`da Z3dbdc Z4ddde Z5dfdg Z6dhdi Z7djdk Z8dldm Z9dndo Z:dpdq Z;drds Z<dtdu Z=dvdw Z>dxdy Z?dzd{ Z@d|d} ZAd~d ZBdd ZCdd ZDdd ZEdd ZFdd ZGdd ZHdd ZIdd ZJdd ZKdd ZLdd ZMdd ZNdd ZOdd ZPdd ZQdd ZRdd ZSdd ZTdd ZUdd ZVdd ZWdd ZXdd ZYdd ZZdd Z[dd Z\dddZ]dddZ^dd Z_dd Z`dd Zadd ZbdS )ArrayAnalysisr   c                 C   s:   || _ || _|| _|| _i | _i | _i | _i | _i | _d S rB   )	r/   r   r   	calltypes
equiv_setsZarray_attr_callsobject_attrsprependspruned_predecessors)rf   r/   r   r   r   r8   r8   r9   rg   >  s    zArrayAnalysis.__init__c                 C   s
   | j | S )zAReturn the equiv_set object of an block given its label.
        )r   )rf   Zblock_labelr8   r8   r9   r   O  s    zArrayAnalysis.get_equiv_setc                 C   s6   t  }|D ]&}| jD ]}| j| }||| qq
dS )zTake a set of variables in redefineds and go through all
        the currently existing equivalence sets (created in topo order)
        and remove that variable from all of them since it is multiply
        defined within the function.
        N)r   r   r   )rf   
redefinedsZunusedr[   Zeslabelesr8   r8   r9   remove_redefinedsT  s
    

zArrayAnalysis.remove_redefinedsNc                 C   s6  |dkr| j j}t| j j| j _|dkr4t| j}n|}t|| j j| j| j \| _| _	t
j}t
 jd7  _tjdkr~td| t| j d| tjdkrtdt| j  td| j t|}t||d}| |||| tjdkr|   tdt| j  td	| j t| j d
| tjdkr2td| dS )zrun array shape analysis on the given IR blocks, resulting in
        modified IR and finalized EquivSet for each block.
        Nr'   zStarting ArrayAnalysis:zbefore array analysiszArrayAnalysis variable types: zArrayAnalysis call types: )cfgz#ArrayAnalysis post variable types: zArrayAnalysis post call types: zafter array analysiszEnding ArrayAnalysis:)r   blocksr   _definitionsr   r   r   	arg_names	alias_mapZarg_aliasesr   aa_countr   ry   rz   r	   r   r   r   r   r   _run_on_blocksdump)rf   r   r   init_equiv_setZaa_count_saver   
topo_orderr8   r8   r9   run`  sH    


 zArrayAnalysis.runc           	      C   sN   |D ]D}t jdkrtd| || }|j}| |||||}| || qd S )Nrv   zProcessing block:)r   ry   rz   scope_determine_transform_combine_to_new_block)	rf   r  r   r   r  labelblockr  pending_transformsr8   r8   r9   r     s    

    zArrayAnalysis._run_on_blocksc                 C   sP   g }|D ]<\}}}|D ]}| | q| | |D ]}| | q4q||_dS )zWCombine the new instructions from previous pass into a new block
        body.
        N)r{   body)rf   r	  r
  Znew_bodyinstprepostinstrr8   r8   r9   r    s    
z#ArrayAnalysis._combine_to_new_blockc              	   C   s  d}| |}|| jkr$| j| }ng }tjdkr<td| |D ]\}	}
tjdkr^td|	|
 |	|krhq@|	| jkr@| j|	  }tjdkrtd| |	|f| jkr| j|	|f }|D ]&}t }| 	||||| | 
| q|dkr|}q@||}t }||j| | 
| q@|dkr"|}|| j|< g }|jD ]J}t }| 	|||||\}}t|dkrn| 
| ||||f q6|S )zGDetermine the transformation for each instruction in the block
        Nrv   zpreds:zp, q:zp in equiv_setsr   )Zpredecessorsr   r   ry   rz   r   rm   r   r   _analyze_instr   r   r   r   r  rN   r{   )rf   r   r	  r  r  r  r   predsZprunedpqZfrom_setZinstrsr  r   r
  r  r  r8   r8   r9   r    sf    







    



    
z"ArrayAnalysis._determine_transformc                 C   s   t d| j dS )z@dump per-block equivalence sets for debugging purposes.
        zArray Analysis: N)rz   r   rh   r8   r8   r9   r    s    zArrayAnalysis.dumpc                 C   s8   || j |j< |g| jj|j< t }|||| j| d S rB   )r   r   r   r   r   r   )rf   r   r   r   r   r   r8   r8   r9   _define  s    zArrayAnalysis._definec                   @   s   e Zd Zdd ZdS )zArrayAnalysis.AnalyzeResultc                 K   s
   || _ d S rB   )kwargs)rf   r  r8   r8   r9   rg     s    z$ArrayAnalysis.AnalyzeResult.__init__N)r   r   r   rg   r8   r8   r8   r9   AnalyzeResult  s   r  c           %         s  g }g }t jdkrtd ttjr̈j}j|j }	d }
t|	t	j
r^|	jdkr^d}
nhtjtjrj|}|rtt|tj d|jkr|jd }
d|jkr||jd  d|jkr||jd  d|jkr|jd _ntjtjtjfrj}
ntjtjrbjj}t|trNtd	d
 |D rN|}
nt|tr|f}
ndtjtjrt|	t	jjrt|	jt	jrj}
n,t|	t	jjrtdd |	j	D rƈj}
t|
tjrt|
jtr|
j tfdd
|
jD }
nt|
jtr|
f}
nd }
nzt|
tjrJtj|
j t	jrJ|
f}
nNt|
t!r"||j#|	 $|j}|dkr|j%|
j&|
j'f< ||fS t|	t	j
r|
d k	rt|
tjrtj|
j t	jj(rnD|
d kst|
tst|
tjr)|
s*||	j|
|}
nxt|	t	jrZ|
rt|	jt	jr*|t+|	|
|}
n<t|	t	jjrtdd |	j	D r*|t+|	|
|}
d}|
d k	r,||
}|r"||j#|	 nttj-tj.frbttj.rj/nj0}t1j2j|}|sg g fS |d d k	rLttj-tj.fsBt3|d _/|d }|jd }d|jkrt|jd }4j}|dkr5| |g fS |d k	rVjjj }tt|t	j
 |j}||g}jjjjg}6j ||}td|jk td|jk |jd }
|jd }t+|
}||ks>t35|
 || g fS |g fS n`ttj7r fdd}j8 t1t9j# }|st: }g }|D ]`}t|t;r|jkrt1t9j#|dd}t|tjr|j}|r|<| n
|<| qt=t>dd |}t=|?|} t+| dkrPt@| d }n$t+|dkrtt1t9j#t@|d }t|tjr|jAdkr|| nt|tjr*|jAdkr*t1t9j#|jB}!|!d k	r|!jtCkrt+|jDdkrt1t9j#|jDd }"|"d k	rt|"tjr|"jAdkr||" nht|tjr>|j}t|tsVt|tCr|rbjEnjF}#|#jGkrjG|# < ngjG|#< n.tHtIkrtItH }$|$j\}}||fS )Nrv   zanalyze_inst:r   r8   rK   r  r  r   c                 s   s   | ]}t |tV  qd S rB   r   )rG   r   r8   r8   r9   rI     s     z.ArrayAnalysis._analyze_inst.<locals>.<genexpr>c                 S   s   g | ]}t |tjtjfqS r8   r;   r   r<   IntegerLiteralru   r8   r8   r9   r   (  s   
z/ArrayAnalysis._analyze_inst.<locals>.<listcomp>c                 3   s   | ]}t | V  qd S rB   )r   r   ru   locr8   r9   rI   2  s     r   c                 S   s   g | ]}t |tjtjfqS r8   r  ru   r8   r8   r9   r   f  s   
Tr'   c           	         s  d }| j tjkr"j}j}d}n| j tjkr>j}j}d}j| jj }j| j	j }|d k	r
t
|tjr|t
|tjst
|tjr
t
|tjr
j}| j| j	f}||}|tt|| | |j|f< ttd| | |gj|f< d S )Nr'   r   )r   r   eqtruebrfalsebrner   r   r   r   r;   r   r<   rD   r  _make_assert_equivr{   r   Assignr   r   )	cond_defbrZotherbrZcond_vallhs_typrhs_typr  r2   asserts)cond_varr   r  r  r  rf   r8   r9   handle_call_binop  sD    





   z6ArrayAnalysis._analyze_inst.<locals>.handle_call_binop)Zlhs_onlyc                 S   s
   t | tS rB   )r;   r   )rr   r8   r8   r9   <lambda>      z-ArrayAnalysis._analyze_inst.<locals>.<lambda>r   r   )Jr   ry   rz   r;   r   r   targetr   r   r   rC   r   r   r   _analyze_exprr   r   r  r  extendr   r   Globalrw   r]   r   Arg
containersUniTupleZdtyper<   Tupler  r   r   r   rs   r   r   r   rD   r   _gen_shape_callrN   r   r   r   r   	index_varr   _index_to_shaperO   r   r   _broadcast_assert_shapesZBranchZcondr   r   r   r{   r   filter
differencer   r   funcboolr2   r  r  r   r   array_analysis_extensions)%rf   r  r  r   r  r   r  r  r   r   rK   resultZgvalueZlhs_indZneeds_definer   Ztarget_shapeZvalue_shapeZ
target_typZtarget_ndimshapesr   Zbroadcast_resultr%  rS   r'  r!  Zequivsr   r   Zvar_defZdefvarsZ	defconstsZ	glbl_bool	conditionZ	pruned_brr#   r8   )r&  r   r  r  r  r  rf   r9   r    s   







 



 
            
    




    

#
     




zArrayAnalysis._analyze_instc                 C   sB   d |j}zt| |}W n tk
r0   Y d S X t|||||S )Nz_analyze_op_{})rn   r   getattrAttributeErrorr   )rf   r  r   r   r   r   r   r8   r8   r9   r+    s    zArrayAnalysis._analyze_exprc           	      C   s  |j dkr0| |jjr0| |||j|jgi S |j dkrR||j}tj|dS |j dkrx| |jjrxtj|jdS | |jr t	|jj| j
}||j f| jkrtj| j||j f dS | j|j }g }| |||jd |}|| j||j f< tj||dS d S )NTrK   rK   )realimag)rK   r  )attr_isarrayr   r    _analyze_op_call_numpy_transposer  r   r   r  r   r   r   r   r2  r   )	rf   r  r   r   r   rK   Zcanonical_valuer   r  r8   r8   r9   _analyze_op_getattr  sD        
     z!ArrayAnalysis._analyze_op_getattrc                 C   s   t j|jdS NrA  )r   r  r   rf   r  r   r   r   r8   r8   r9   _analyze_op_cast/  s    zArrayAnalysis._analyze_op_castc                 C   sN   |j }| j|j }t|tjrJtt||jk t|	| t
j|dS d S rH  )r   r   r   r;   r   rD   r   rN   countr   r   r  )rf   r  r   r   r   r   r   r8   r8   r9   _analyze_op_exhaust_iter2  s    z&ArrayAnalysis._analyze_op_exhaust_iterstatic_literal_slice_partc           
      C   sV   t |t||}t ||}t|}	|t j|||d | |||	| ||	fS )Nr   r*  r  )	r   r   r   r   r   r  r{   r   r  )
rf   arg_valr  r  stmtsr   r   Zstatic_literal_slice_part_varZstatic_literal_slice_part_valZstatic_literal_slice_part_typr8   r8   r9   gen_literal_slice_part;  s"    

z$ArrayAnalysis.gen_literal_slice_partc           	      C   s"   | j || ||||dd^}}|S )NZstatic_slice_sizer   )rQ  )	rf   lhs_relrhs_relr  r  rP  r   Zthe_var_r8   r8   r9   gen_static_slice_sizeX  s    
z#ArrayAnalysis.gen_static_slice_sizec
                 C   s|   t |trtt|td|}
tjjtj	|||d}t
j}t|||| j|< |tj||
|d | |	|
|| |
|fS )NZexplicit_negr  rN  )r;   r   rO   r   r   r   r   r   r   r.   r   r=   r   r   r{   r   r  )rf   argZarg_relZarg_typsize_typr  r  dsizerP  r   explicit_neg_varZexplicit_neg_valexplicit_neg_typr8   r8   r9   gen_explicit_nege  s&      
   zArrayAnalysis.gen_explicit_negc                 C   sV  d}t |trF|dkr d}n&t |trd}t||}||krtjdkrRtd d}| |||	|
|\}}|dks|dkst|dkr||jd f|_n|jd |f|_|j| }|}|	|}n|dk rFd}tjdkrtd | 
||||||	||
|	\}}|dkr||jd f|_n|jd |f|_|j| }|}|	|}||||||fS )NFr   Trv   z.Replacing slice to hard-code known slice size.r'   z,Replacing slice due to known negative index.)r;   r   rA   r   ry   rz   rQ  rO   r2   r   r[  )rf   r   r#  rR  	dsize_relreplacement_sliceZslice_indexneed_replacementr  r  rP  r   rW  rX  knownZwilZliteral_varZliteral_typrY  rZ  r8   r8   r9   update_replacement_slice  sz    


    





z&ArrayAnalysis.update_replacement_slicec           -         s  |j tj|}tj|jd\}}t|dko8|dk tt|jdk |jd }	|jd }
j j }j|	j }j|
j }t	j
dkrtd| d  d	| d
|	 d|
 d| d| d|  t|}d}t|tjrdttd}td}|tj||d |td| |}	td}|	|jd f|_d}t	j
dkrdtd t|tjr }
|}|jd |
f|_d}t	j
dkrtd |	}|
} }t	j
dkrtd|d|d| |	||||d||| \}	}}}}}|
||||d||| \}
}}}}}t	j
dkrZtd| td| |sfd}nlttd}tjtjf}j|jj j|i }|j|< |tj||d j|j j|j< t	j
dkrtdd|d| |r&|r&t	j
dkrtd  ||||fS |dkrdt|t!rd" |d rd|d dkrd dfS tj}|}ttd}tj#j$t%j&|
|	d}t'|||j|< ||| |}t	j
dkrtd|t(| ttd tj)d!t*d}t+t*} j,| ||fi | |  fd"d#}!|!|	||\}"}#}$|!|
||\}%}&}'|tj||d |tj|d |$dk	r|tj|$|"d |'dk	r|tj|'|%d ttd$}(tj#j$t%j&|%|"d})t'||&|#j|)< |(||) |tj|)|(d t|t!rt	j
dkrXtd%j- d}*j-. D ]<\}+},|+d |d krf"|+d |d rf|,}* qqf|*dk	rt	j
dkrtd&|* /||*d  /|(|*d  n||(fj-|< |(|fS )'a  Reason about the size of a slice represented by the "index"
        variable, and return a variable that has this size data, or
        raise GuardException if it cannot reason about it.

        The computation takes care of negative values used in the slice
        with respect to the given dimensional size ("dsize").

        Extra statements required to produce the result are appended
        to parent function's stmts list.
        r   slicebuiltinsrv   r   r'   zslice_size index=z dsize=z index_def=z lhs=z rhs=z
 size_typ=z	 lhs_typ=z	 rhs_typ=Fr5   rN  Tz$Replacing slice because lhs is None.rR  rS  r\  z
lhs_known:z
rhs_known:Nr]  zafter rewriting negativesz'lhs and rhs known so return static sizer   r  size_relwrapr?   c                    sd   |sVt td}tj}t j|  gi }||| j|< |||fS | |d fS d S )Nr   )	r   r   r   r   r=   r   r   r  r   )r`   Zval_typr_  r   Zvar_typ	new_valuerX  r   r  r  rf   r1   Zwrap_varr8   r9   gen_wrap_if_not_known  s    

z7ArrayAnalysis.slice_size.<locals>.gen_wrap_if_not_knownZpost_wrap_slice_sizezsize_rel is tuplezestablishing equivalence to)0r  r   r   r   r   r   rN   r2   r   r   ry   rz   rk   rl   r;   r   rX   r   r   r   r   r{   r   r  r  r   r`  r=   r8  Zget_call_typer/   r   rU  rw   r   r   r   r   r   r   r   r-  r?   r
   resolve_function_typer   r   r   )-rf   r   rX  r   r  rP  Z	index_defr   r   r   r   rW  r#  r$  r]  r^  Zzero_varr5   rR  rS  r\  Z	lhs_knownZ	rhs_knownZreplacement_slice_varZnew_arg_typsZrs_calltypeZ	slice_typZorig_slice_typsize_varsize_valrc  Zwrap_deffntyrg  Zvar1Zvar1_typZvalue1Zvar2Zvar2_typZvalue2Zpost_wrap_size_varZpost_wrap_size_valZrel_map_entryZrmeZ	rme_tupler8   rf  r9   r     s     



8




     

    
	     

  

  
  
     
 


zArrayAnalysis.slice_sizec                    s  j |j }tt|tj j |j } |} |}t|tjrV|f}	|f}
nBtt|tj t	j
|\}
}t|dk tfdd|
D }	tt|t|	  kot|kn   g  fdd}g }g }d}t|	|||
D ]J\}}}}||||\}}|| |dk	r0d}|| q|| q|rt|d	krttd
|d j}tj||d j}tj|||d jd |j |j< n|d }nd}t|}ttdd |D   tdd |D }|tj|dfS )a  For indexing like var[index] (either write or read), see if
        the index corresponds to a range/slice shape.
        Returns a 2-tuple where the first item is either None or a ir.Var
        to be used to replace the index variable in the outer getitem or
        setitem instruction.  The second item is also a tuple returning
        the shape and prepending instructions.
        build_tuplec                 3   s   | ]} j |j V  qd S rB   r   r   ru   rh   r8   r9   rI     s     z0ArrayAnalysis._index_to_shape.<locals>.<genexpr>c                    s:   t | tjr|| S t | tjr.dS td d S )N)NNF)r;   r   rE   r   r   r   )r   r   rX  r   r  rf   rP  r8   r9   to_shape  s
    z/ArrayAnalysis._index_to_shape.<locals>.to_shapeFNTr'   Zreplacement_build_tupler   rN  c                 s   s   | ]}|d kV  qd S rB   r8   ru   r8   r8   r9   rI   ?  s     c                 s   s   | ]}|d k	r|V  qd S rB   r8   ru   r8   r8   r9   rI   @  s      rK   r  )r   r   r   r;   r   rC   r   rE   rD   r   r   rw   rN   rP   r{   r   r   r   r  r   rl  r   r]   r   r  )rf   r  r   r   Zind_varr   Zind_typZ	ind_shapeZ	var_shapeZseq_typsseqr   ro  Z
shape_listZindex_var_listZreplace_indexr4   rX  Zorig_indZ
shape_partZindex_var_partZreplacement_build_tuple_varZnew_build_tuplerK   r8   rn  r9   r4    sp    

(


 
zArrayAnalysis._index_to_shapec                 C   s2   |  |||j|j}|d d k	r*|d |_|d S r   )r4  r   r   )rf   r  r   r   r   r;  r8   r8   r9   _analyze_op_getitemD  s    
z!ArrayAnalysis._analyze_op_getitemc           	      C   s   |j }| j|j }t|tjsP| |||j |j}|d d k	rH|d |_|d S ||}t|j	t
rt|j	t|k  tj||j	 dS t|j	trtj||j	 dS td d S )Nr   r'   rA  F)r   r   r   r;   r   rD   r4  r3  r   r   r   r   rN   r   r  ra  )	rf   r  r   r   r   r   r   r;  rK   r8   r8   r9   _analyze_op_static_getitemJ  s&       

z(ArrayAnalysis._analyze_op_static_getitemc                 C   s:   t |jtk | |jjs(|jtjkr6tj	|jdS d S rH  )
r   r   UNARY_MAP_OPrE  r   r   r   r.   r   r  rI  r8   r8   r9   _analyze_op_unary\  s    zArrayAnalysis._analyze_op_unaryc                 C   s,   t |jtk | |||j|j|jg|jS rB   )r   r   BINARY_MAP_OP_analyze_broadcastr  r   r   rI  r8   r8   r9   _analyze_op_binopd  s       
 zArrayAnalysis._analyze_op_binopc                 C   s,   t |jtk | |||j|j|jg|jS rB   )r   r   INPLACE_BINARY_MAP_OPrw  r  r   r   rI  r8   r8   r9   _analyze_op_inplace_binopj  s       
 z'ArrayAnalysis._analyze_op_inplace_binopc                 C   s   |  |||j| d S rB   )rw  r  Z	list_varsrI  r8   r8   r9   _analyze_op_arrayexprp  s        z#ArrayAnalysis._analyze_op_arrayexprc           	         s    j D ]<}t|tjrt| j|j tjr| j|j jdkr d S qg } j D ]*}t	t
| j|}|d k	rt|| qN qqNt fdd|D }tj|tt| jdS tjt j dS )Nr'   c                    s   g | ]}t | jqS r8   )r   r   r  ru   r   r8   r9   r     s     z9ArrayAnalysis._analyze_op_build_tuple.<locals>.<listcomp>rK   r   rA  )r   r;   r   r   r   r   r   rC   r   r   r   r   r{   rw   r   r  r   r  )	rf   r  r   r   r   rr   Zconstsr   outr8   r|  r9   _analyze_op_build_tupleu  s(    


z%ArrayAnalysis._analyze_op_build_tuplec              	   C   sv  ddl m} |j}t| j|}t|tjtjfrLt	|j
rLtjt|jdS t|tjtjfrt|j
|r|j}| |||j
|j|t|jS t| j|| jd\}	}
d}t|
tjrt| j|
j tjr|
g|j }d}
d}n|j}d|
|	d	d
}	|	tkr| |||j|d S zt| |	}W n tk
r<   Y d S X t||||j|t|jd}|rn|dd  |_|S d S )Nr   )StencilFuncrA  r   FnumpyTz_analyze_op_call_{}_{}.rT  )r  r   r  r2   kwsr'   ) Znumba.stencils.stencilr  r8  r   r   r;   r   r-  ZFreeVarr   r   r   r  rw   r2   _analyze_stencilr  dictr  r   r   r   r   r   rC   rn   replaceUFUNC_MAP_OPrw  r>  r?  r   )rf   r  r   r   r   r  ZcalleeZ
callee_defr2   r   r   Zadded_mod_namer   r;  r8   r8   r9   _analyze_op_call  s|     
 	  

  
  zArrayAnalysis._analyze_op_callc           	      C   sT   t t|dk |d }| j|j }t t|tj ||}tj	|d |d dS )Nr'   r   r}  )
r   rN   r   r   r;   r   rC   r   r   r  )	rf   r  r   r  r2   r  r   r   rK   r8   r8   r9   _analyze_op_call_builtins_len  s    
z+ArrayAnalysis._analyze_op_call_builtins_lenc                 C   s   |j |dd    d S Nr'   )r   rf   r  r   r  r2   r  r8   r8   r9   :_analyze_op_call_numba_parfors_array_analysis_assert_equiv  s    zHArrayAnalysis._analyze_op_call_numba_parfors_array_analysis_assert_equivc                 C   s   t t|dk |d j}|d j}||}||}	||	f|jkr|j||	f }
t |
|jk |j|
 }t |g k tj|d fdS tjt||	dS dS )zX Analyze wrap_index calls added by a previous run of
            Array Analysis
        rv   r   r'   rA  N)	r   rN   r   rt   r   r   r   r  r   )rf   r  r   r  r2   r  r   r   Zslice_eqZdim_eqZwrap_indr   r8   r8   r9   8_analyze_op_call_numba_parfors_array_analysis_wrap_index  s    




zFArrayAnalysis._analyze_op_call_numba_parfors_array_analysis_wrap_indexc                 C   sL   d }t |dkr|d }nd|kr*|d }|r:tj|dS tjd|dd S )Nr   rK   rA  z'Must specify a shape for array creationr  )rN   r   r  r   UnsupportedRewriteError)rf   r  r   r  r2   r  Z	shape_varr8   r8   r9   _analyze_numpy_create_array  s    
z)ArrayAnalysis._analyze_numpy_create_arrayc                 C   s   |  |||||S rB   r  r  r8   r8   r9   _analyze_op_call_numpy_empty	  s        z*ArrayAnalysis._analyze_op_call_numpy_emptyc                 C   s   |  |||||S rB   r  r  r8   r8   r9   7_analyze_op_call_numba_np_unsafe_ndarray_empty_inferred	  s        zEArrayAnalysis._analyze_op_call_numba_np_unsafe_ndarray_empty_inferredc                 C   s   |  |||||S rB   r  r  r8   r8   r9   _analyze_op_call_numpy_zeros	  s        z*ArrayAnalysis._analyze_op_call_numpy_zerosc                 C   s   |  |||||S rB   r  r  r8   r8   r9   _analyze_op_call_numpy_ones	  s        z)ArrayAnalysis._analyze_op_call_numpy_onesc                 C   s\   t |dkr|d }n d|kr(|d }ntjd|dd|krH|d }n|}tj||fdS )Nr   Nz,Expect one argument (or 'N') to eye functionr  MrA  )rN   r   r  r   r  )rf   r  r   r  r2   r  r  r  r8   r8   r9   _analyze_op_call_numpy_eye"	  s    


z(ArrayAnalysis._analyze_op_call_numpy_eyec                 C   s(   t |dkst|d }tj||fdS Nr   rA  )rN   rO   r   r  )rf   r  r   r  r2   r  r  r8   r8   r9   _analyze_op_call_numpy_identity2	  s    z-ArrayAnalysis._analyze_op_call_numpy_identityc                 C   s   t |dkst|d }t|tjs(t| j|j }t|tjr|j	dkrd|krj|d }|
|dsjd S ||\}	}
|
|	|
rtj|	fdS n&|j	dkr||\}	tj|	|	fdS d S )Nr   rv   r   rA  r'   )rN   rO   r;   r   r   r   r   r   rC   r   r   r   r   r  )rf   r  r   r  r2   r  rH   Zatypr   rR   rS   r8   r8   r9   _analyze_op_call_numpy_diag9	  s"    

z)ArrayAnalysis._analyze_op_call_numpy_diagc                 C   sb   t |dkst|d }| j|j }t|tjr<tjddS t|tj	r^|
|r^tj|dS d S )Nr   )r'   rA  )rN   rO   r   r   r;   r   r<   r   r  rC   r   )rf   r  r   r2   r  r   r   r8   r8   r9   _analyze_numpy_array_likeN	  s    z'ArrayAnalysis._analyze_numpy_array_likec                 C   sp   t |dkst|d }| j|j }t|tjs4t|jdkrl||rl|j	dkr`t
j||dS t
j|dS d S )Nr'   r   Cr}  rA  )rN   rO   r   r   r;   r   rC   r   r   Zlayoutr   r  )rf   r  r   r  r2   r  r   r   r8   r8   r9   _analyze_op_call_numpy_ravelZ	  s    
z*ArrayAnalysis._analyze_op_call_numpy_ravelc                 C   s   |  ||||S rB   r  r  r8   r8   r9   _analyze_op_call_numpy_copyj	  s    z)ArrayAnalysis._analyze_op_call_numpy_copyc                 C   s   |  ||||S rB   r  r  r8   r8   r9   !_analyze_op_call_numpy_empty_likem	  s    z/ArrayAnalysis._analyze_op_call_numpy_empty_likec                 C   s   |  ||||S rB   r  r  r8   r8   r9   !_analyze_op_call_numpy_zeros_liker	  s    z/ArrayAnalysis._analyze_op_call_numpy_zeros_likec                 C   s   |  ||||S rB   r  r  r8   r8   r9    _analyze_op_call_numpy_ones_likew	  s    z.ArrayAnalysis._analyze_op_call_numpy_ones_likec                 C   s   |  ||||S rB   r  r  r8   r8   r9    _analyze_op_call_numpy_full_like|	  s    z.ArrayAnalysis._analyze_op_call_numpy_full_likec                 C   s   |  ||||S rB   r  r  r8   r8   r9   %_analyze_op_call_numpy_asfortranarray	  s    z3ArrayAnalysis._analyze_op_call_numpy_asfortranarrayc                 C   s  t |}|dkst|dkrH| j|d j }t|tjrHtj|d dS g }d}	t	dt |D ]R}
||
 }t
t| j|}t|tjr^|jdk r^|	dkr|
}	q^d}tj||jdq^|	dkr|d j}t|td|}tj| j|j< ttj|d d	|||}|| t	dt |D ]}
|
|	kr.qt|td|}tj| j|j< tjtj|||
 |}t|||}ttjtjtj| j|< || |}q|||	< tjt|dd  |d
S )Nr'   rv   rA  r   r   z7The reshape API may only include one negative argument.r  calc_size_varr4   rp  ) rN   rO   r   r   r;   r   rD   r   r  rW   r   r   r   r   r   r   r   r  r  r   r   r=   r   r   r>  r{   r   r   floordivr   r   rw   )rf   r  r   r  r2   r  rS   r   rP  Zneg_one_indexZ	arg_indexZreshape_argZreshape_arg_defrU   r  Zinit_calc_varZdiv_calc_size_varZ	new_binopZdiv_calcr8   r8   r9   _analyze_op_call_numpy_reshape	  sn    	
 

  

       

z,ArrayAnalysis._analyze_op_call_numpy_reshapec           
         s   |d } j |j }t|tjs(td||t|dkrRtj	t
tdS  fdd|dd  D }t|d t
rt|d }d |krd S fdd|D }	tj	t
|	dS )Nr   zInvalid np.transpose argumentr'   rA  c                    s   g | ]}t t j|qS r8   )r   r   r   rF   rh   r8   r9   r   	  s     zBArrayAnalysis._analyze_op_call_numpy_transpose.<locals>.<listcomp>c                    s   g | ]} | qS r8   r8   r   rA  r8   r9   r   	  s     )r   r   r;   r   rC   rO   r   rN   r   r  rw   reversedr   )
rf   r  r   r  r2   r  Zin_arrr   Zaxesretr8   )rf   rK   r9   rF  	  s$     
z.ArrayAnalysis._analyze_op_call_numpy_transposec                 C   s    t |dkrtjt|dS d S r  )rN   r   r  rw   r  r8   r8   r9   "_analyze_op_call_numpy_random_rand	  s    z0ArrayAnalysis._analyze_op_call_numpy_random_randc                 C   s   |  |||||S rB   )r  r  r8   r8   r9   #_analyze_op_call_numpy_random_randn	  s        z1ArrayAnalysis._analyze_op_call_numpy_random_randnc                 C   s8   d|krt j|d dS t||kr4t j|| dS d S )Nr4   rA  )r   r  rN   )rf   posr  r   r2   r  r8   r8   r9   "_analyze_op_numpy_random_with_size	  s
    z0ArrayAnalysis._analyze_op_numpy_random_with_sizec                 C   s   |  d||||S r@   r  r  r8   r8   r9   "_analyze_op_call_numpy_random_ranf	  s        z0ArrayAnalysis._analyze_op_call_numpy_random_ranfc                 C   s   |  d||||S r@   r  r  r8   r8   r9   +_analyze_op_call_numpy_random_random_sample
  s        z9ArrayAnalysis._analyze_op_call_numpy_random_random_samplec                 C   s   |  d||||S r@   r  r  r8   r8   r9   $_analyze_op_call_numpy_random_sample
  s        z2ArrayAnalysis._analyze_op_call_numpy_random_samplec                 C   s   |  d||||S r@   r  r  r8   r8   r9   $_analyze_op_call_numpy_random_random
  s        z2ArrayAnalysis._analyze_op_call_numpy_random_randomc                 C   s   |  d||||S r@   r  r  r8   r8   r9   -_analyze_op_call_numpy_random_standard_normal
  s        z;ArrayAnalysis._analyze_op_call_numpy_random_standard_normalc                 C   s   |  d||||S r  r  r  r8   r8   r9   '_analyze_op_call_numpy_random_chisquare
  s        z5ArrayAnalysis._analyze_op_call_numpy_random_chisquarec                 C   s   |  d||||S r  r  r  r8   r8   r9   %_analyze_op_call_numpy_random_weibull$
  s        z3ArrayAnalysis._analyze_op_call_numpy_random_weibullc                 C   s   |  d||||S r  r  r  r8   r8   r9   #_analyze_op_call_numpy_random_power+
  s        z1ArrayAnalysis._analyze_op_call_numpy_random_powerc                 C   s   |  d||||S r  r  r  r8   r8   r9   '_analyze_op_call_numpy_random_geometric2
  s        z5ArrayAnalysis._analyze_op_call_numpy_random_geometricc                 C   s   |  d||||S r  r  r  r8   r8   r9   )_analyze_op_call_numpy_random_exponential9
  s        z7ArrayAnalysis._analyze_op_call_numpy_random_exponentialc                 C   s   |  d||||S r  r  r  r8   r8   r9   %_analyze_op_call_numpy_random_poisson@
  s        z3ArrayAnalysis._analyze_op_call_numpy_random_poissonc                 C   s   |  d||||S r  r  r  r8   r8   r9   &_analyze_op_call_numpy_random_rayleighG
  s        z4ArrayAnalysis._analyze_op_call_numpy_random_rayleighc                 C   s   |  d||||S Nrv   r  r  r8   r8   r9   $_analyze_op_call_numpy_random_normalN
  s        z2ArrayAnalysis._analyze_op_call_numpy_random_normalc                 C   s   |  d||||S r  r  r  r8   r8   r9   %_analyze_op_call_numpy_random_uniformU
  s        z3ArrayAnalysis._analyze_op_call_numpy_random_uniformc                 C   s   |  d||||S r  r  r  r8   r8   r9   "_analyze_op_call_numpy_random_beta\
  s        z0ArrayAnalysis._analyze_op_call_numpy_random_betac                 C   s   |  d||||S r  r  r  r8   r8   r9   &_analyze_op_call_numpy_random_binomialc
  s        z4ArrayAnalysis._analyze_op_call_numpy_random_binomialc                 C   s   |  d||||S r  r  r  r8   r8   r9   _analyze_op_call_numpy_random_fj
  s        z-ArrayAnalysis._analyze_op_call_numpy_random_fc                 C   s   |  d||||S r  r  r  r8   r8   r9   #_analyze_op_call_numpy_random_gammaq
  s        z1ArrayAnalysis._analyze_op_call_numpy_random_gammac                 C   s   |  d||||S r  r  r  r8   r8   r9   '_analyze_op_call_numpy_random_lognormalx
  s        z5ArrayAnalysis._analyze_op_call_numpy_random_lognormalc                 C   s   |  d||||S r  r  r  r8   r8   r9   %_analyze_op_call_numpy_random_laplace
  s        z3ArrayAnalysis._analyze_op_call_numpy_random_laplacec                 C   s   |  d||||S r  r  r  r8   r8   r9   %_analyze_op_call_numpy_random_randint
  s        z3ArrayAnalysis._analyze_op_call_numpy_random_randintc                 C   s   |  d||||S )N   r  r  r8   r8   r9   (_analyze_op_call_numpy_random_triangular
  s        z6ArrayAnalysis._analyze_op_call_numpy_random_triangularc              	      s   t |dkst|d j}t| j|d \}}t |}t|dk d}	d|krxt|d trf|d }	qt| j|d }	nt |dkrt| j|d }	tt|	t t|dk  fdd|D }
|	dk rt |
d |	 }	td|	  kot |
d k n   g }g }|dkr|
d } 	|
d }|
d tt |D ]H|	krp 	| }|rj|rj|| nd }n|  |
d }q:|| nxtt |
d D ]f|	kr|  fdd|
D }n0fdd|
D }|| || | |d }|| qtjt|t|g d	S )
Nr   axisr'   rl  c                    s   g | ]}  |qS r8   r   ru   r   r8   r9   r   
  s     zDArrayAnalysis._analyze_op_call_numpy_concatenate.<locals>.<listcomp>c                    s   g | ]}|  qS r8   r8   rG   rK   r   r8   r9   r   
  s     c                    s   g | ]}|  qS r8   r8   r  r   r8   r9   r   
  s     rp  )rN   rO   r  r   r   r   r;   r   r   r   poprW   	_sum_sizer{   _call_assert_equivr   r  rw   r   )rf   r  r   r  r2   r  rq  r   rS   r  r<  r%  	new_shaperK   rR   r4   sizesr8   )r   rZ   r9   "_analyze_op_call_numpy_concatenate
  s\    

$



 z0ArrayAnalysis._analyze_op_call_numpy_concatenatec                    sJ  t |dkst|d j}t| j|d \}}t |}t|dk d}	d|krxt|d trf|d }	qt| j|d }	nt |dkrt| j|d }	tt|	t t|dk  fdd|D }
| 	|| |}|
d }|	dk rt ||	 d }	td|	  ko
t |kn   t
|d|	 |g t
||	d   }tjt||dS )Nr   r  r'   rl  c                    s   g | ]}  |qS r8   r  ru   r  r8   r9   r   
  s     z>ArrayAnalysis._analyze_op_call_numpy_stack.<locals>.<listcomp>rp  )rN   rO   r  r   r   r   r;   r   r   r  r   r   r  rw   )rf   r  r   r  r2   r  rq  r   rS   r  r<  r%  rK   r  r8   r  r9   _analyze_op_call_numpy_stack
  s,    

"&z*ArrayAnalysis._analyze_op_call_numpy_stackc           
      C   s   t |dkstt| j|d \}}t |}t|dk | j|d j }	tt|	tj	 |	j
dk rt| |||||S d|d< | |||||S d S Nr'   r   rv   r  )rN   rO   r   r   r   r   r   r;   r   rC   r   r  r  
rf   r  r   r  r2   r  rq  r   rS   r   r8   r8   r9   _analyze_op_call_numpy_vstack
  s,    
        z+ArrayAnalysis._analyze_op_call_numpy_vstackc           
      C   s   t |dkstt| j|d \}}t |}t|dk | j|d j }	tt|	tj	 |	j
dk rld|d< nd|d< | |||||S r  )rN   rO   r   r   r   r   r   r;   r   rC   r   r  r  r8   r8   r9   _analyze_op_call_numpy_hstack
  s     

    z+ArrayAnalysis._analyze_op_call_numpy_hstackc                 C   s   t |dkstt| j|d \}}t |}t|dk | j|d j }	tt|	tj	 |	j
dkrd|d< | |||||}
t|
 tdgt|
jd  |
jd< |
S |	j
dkrd|d< | |||||S d|d< | |||||S d S )Nr'   r   r  rK   rv   )rN   rO   r   r   r   r   r   r;   r   rC   r   r  rw   r   r  r  )rf   r  r   r  r2   r  rq  r   rS   r   r;  r8   r8   r9   _analyze_op_call_numpy_dstack  sF    
    
        z+ArrayAnalysis._analyze_op_call_numpy_dstackc                 C   s   d S rB   r8   r  r8   r8   r9   _analyze_op_call_numpy_cumsum  s    z+ArrayAnalysis._analyze_op_call_numpy_cumsumc                 C   s   d S rB   r8   r  r8   r8   r9   _analyze_op_call_numpy_cumprod"  s    z,ArrayAnalysis._analyze_op_call_numpy_cumprodc                 C   s<   t |}d}|dkr|d }nd|kr.|d }tj|fdS )N2   rv   numrA  )rN   r   r  )rf   r  r   r  r2   r  rS   r  r8   r8   r9   _analyze_op_call_numpy_linspace&  s    
z-ArrayAnalysis._analyze_op_call_numpy_linspacec                    s  t |}|dkst|d j}ttfdd|D  fdd|D }dd |D }ttdd |D  |d d	kr|d	 d	krd S  fd
d|D }	|d d	kr|| |	d d |	d	 d g}
tjt|	d	 dd |	d	 dd   |
dS |d	 d	krJ|| |	d d |	d	 d g}
tjt|	d dd |
dS |d dkr|d	 dkr|| |	d d	 |	d	 d g}
tj|	d d |	d	 d	 f|
dS |d dkrd S )Nrv   r   c                    s   g | ]}  |jqS r8   rE  r   ru   rh   r8   r9   r   5  s     z<ArrayAnalysis._analyze_op_call_numpy_dot.<locals>.<listcomp>c                    s   g | ]} j |j qS r8   rm  ru   rh   r8   r9   r   6  s     c                 S   s   g | ]
}|j qS r8   r   )rG   tyr8   r8   r9   r   7  s     c                 s   s   | ]}|d kV  qdS )r   Nr8   ru   r8   r8   r9   rI   8  s     z;ArrayAnalysis._analyze_op_call_numpy_dot.<locals>.<genexpr>r'   c                    s   g | ]}  |qS r8   r  ru   r  r8   r9   r   ;  s     r   rp  )	rN   rO   r  r   r]   r  r   r  rw   )rf   r  r   r  r2   r  rS   Ztypsdimsr<  r%  r8   r   rf   r9   _analyze_op_call_numpy_dot1  sZ    
   "      z(ArrayAnalysis._analyze_op_call_numpy_dotc                 C   s   |j dd}|jj}t|tr&|f}g }	t|dkrFt|t|ksJtt||D ]2\}
}| j	|j
 }t|tjrT|
|krT|	| qTt|	}t|dk | ||||	}||	d }tj||dS )NZstandard_indexingr8   r   rp  )optionsrq   Z	kernel_irr   r;   r   rN   rO   rP   r   r   r   rC   r{   r   r  r   r   r  )rf   r  r   Zstencil_funcr  r2   r  Zstd_idx_arrsZkernel_arg_namesZrel_idx_arrsrV  r   r   rS   r%  rK   r8   r8   r9   r  X  s"    
 zArrayAnalysis._analyze_stencilc                 C   s&   t t|dk tj||d dS )Nr'   r   rA  )r   rN   r   r  r   r  r8   r8   r9   !_analyze_op_call_numpy_linalg_invm  s    z/ArrayAnalysis._analyze_op_call_numpy_linalg_invc                    s:  t tfdd|}t|dkr|jdkr܈j|d j }j|d j }|jdkrltj 	|d dS |jdkrtj 	|d dS z8 fdd	|D }	d
|	krW d
S t
|	d}
tj|
dW S  tk
r   Y d
S X t tfdd|}tt|dk dd	 |D }fdd	|D }t|}t|dk z fdd	|D }	W n4 tk
r   tj|d || |d Y S X g }d
|	krg }t|	D ]R\}}|d
kr|| }j|j } ||jd
|}|| n
|| q|}	| ||	|}|r6d|jkr$|jd }ng }|| |jd< |S )zInfer shape equivalence of arguments based on Numpy broadcast rules
        and return shape of output
        https://docs.scipy.org/doc/numpy/user/basics.broadcasting.html
        c                    s     | jS rB   )_istupler   rH   rh   r8   r9   r(  x  r)  z2ArrayAnalysis._analyze_broadcast.<locals>.<lambda>rv   r.   r   r'   rA  c                    s   g | ]}  |qS r8   r   ru   r  r8   r9   r     s     z4ArrayAnalysis._analyze_broadcast.<locals>.<listcomp>Nr8   c                    s     | jS rB   r  r  rh   r8   r9   r(    r)  c                 S   s   g | ]
}|j qS r8   r   ru   r8   r8   r9   r     s     c                    s   g | ]} j |j jqS r8   )r   r   r   ru   rh   r8   r9   r     s     c                    s   g | ]}  |qS r8   r   ru   r  r8   r9   r     s     rp  r  )r   r6  rN   r   r   r   rK  r   r  r   r   r   r   r   r  	enumerater2  r   r{   r5  r  )rf   r  r   r  r2   r   ZtupsZtup0typZtup1typr<  Zconcat_shapesZarrsr   r  max_dimr  Z
new_shapesrZ   sr   r   rK   r;  Zprev_prer8   r  r9   rw  s  s    




        z ArrayAnalysis._analyze_broadcastc              
   C   s   g }g }t dd |D }d}	t|D ]}
g }g }t||D ]T\}}|
t|k r<|t|d |
  }||}|dkr||}	q<|| || q<|g kr|	dk	st||	 |d || j|||||d ||d  q&tj	t
t|t|g dS )	zProduce assert_equiv for sizes in each dimension, taking into
        account of dimension coercion and constant size of 1.
        c                 S   s   g | ]}t |qS r8   r   r  r8   r8   r9   r     s     z:ArrayAnalysis._broadcast_assert_shapes.<locals>.<listcomp>Nr'   1r   r   rp  )r   rW   rP   rN   r   r{   rO   r  r   r  rw   r  r   )rf   r  r   r  r<  r   r%  r  r  Zconst_size_onerZ   r  Z
size_namesr   rK   r4   Z
const_sizer8   r8   r9   r5    sB    



    
z&ArrayAnalysis._broadcast_assert_shapesc                 C   s.   | j |||||d}t|dkr*|j|  |S )Nr  r'   )r  rN   r   )rf   r  r  r   r2   r   Zinstsr8   r8   r9   r    s        
z ArrayAnalysis._call_assert_equivc              	      s  t jdkrtd|| |d kr,dd |D }g }g }t||D ]v\}}	t jdkr\td||	 d}
|D ]6}t jdkrtd|||	| ||	|rdd}
 qqd|
s>||	 || q>t|dk rt jdkrtd	 g S d
d||}t	
||}t|}t	|td|}| j|j< t|g fdd|D  }tj|}t	|td|}t	jdt|d}tt} j||fi } |||| t	|td|}t	jj||g| i |d} ||tj| | j|< t	j|||dt	j|||dt	j|||dgS )Nrv   zmake_assert_equiv:c                 S   s   g | ]
}|j qS r8   r   ru   r8   r8   r9   r     s     z4ArrayAnalysis._make_assert_equiv.<locals>.<listcomp>zname, x:Fzis equiv to?Tz@Will not insert assert_equiv as args are known to be equivalent.zSizes of {} do not match on {}z, rU   c                    s   g | ]} j |j qS r8   rm  ru   rh   r8   r9   r     s     assertra   r  r  rN  )r   ry   rz   rP   r   r{   rN   rn   joinr   r   r   r^   r   r   r   r   rw   r\   Z
from_typesr-  ra   r
   r/   rh  r  r   r   r_   r   r   )rf   r  r  r   _argsr   r2   r   r   rr   seenr   rU   Zmsg_valZmsg_typZmsg_varZargtypsZtup_typZ
assert_varZ
assert_defrk  r1   r   r   r8   rh   r9   r    s`    




 

z ArrayAnalysis._make_assert_equivc              	   C   s^  t |tjr||}t |tjr0|}d }d }nZt |tjrJ|}d }d }n@tj|d|j}t|jt	d
|j|j}tjtj|}g }	d}
|rt|}||k r||| d  }t|D ]`}d}|r|| rt || tjr| j|| j }t |tjtjfr|| }d}nt || tr@t|| |j}n|| }t |tjsZtt|jt	d
|j||j}|t|||j | ||tj| d}|st|jt	d
|j||j}tj||d |j}d}
d | j|< |t|||j | ||tj| |	| q|
rV|rV|dt|||j | |||| t|	S )NrK   z{}_shapeFTz	{}_size{}r   )r;   r   r   r   r.  r   r>  r  r  r   rn   r   r   r/  r0  r=   rN   rW   r   r   rE   r   r   rO   r{   r   r  Zstatic_getitemr   r   rw   )rf   r   r   r   rK   r  Zattr_varZshape_attr_callZshape_attr_typZ	size_varsZuse_attr_varZnshapesrZ   skipr   ri  rj  getitemr8   r8   r9   r2  (  sv    
  
zArrayAnalysis._gen_shape_callc                 C   s"   | j | }t|tjjo |jdkS r@   )r   r;   r   ZnpytypesZArrayr   rf   varnamer   r8   r8   r9   rE  l  s    
zArrayAnalysis._isarrayc                 C   s   | j | }t|tjS rB   )r   r;   r   rD   r  r8   r8   r9   r  p  s    
zArrayAnalysis._istuplec                 C   s2   d}|D ]$}| |}|dkr$ dS ||7 }q|S )zzReturn the sum of the given list of sizes if they are all equivalent
        to some constant, or None otherwise.
        r   N)r   )rf   r   r  r  r4   rS   r8   r8   r9   r  t  s    

zArrayAnalysis._sum_size)NN)rM  )N)N)cr   r   r   r   rg   r   r   r  r   r  r  r  r  objectr  r  r+  rG  rJ  rL  rQ  rU  r[  r`  r   r4  rr  rs  ru  rx  rz  r{  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  rF  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  r  r  r  rw  r5  r  r  r2  rE  r  r  r8   r8   r8   r9   r   4  s   	
2D    
]  Z?	J	6'L#

>Dr   c                 C   s   g | ]
}|j qS r8   )r   )rG   r#   r8   r8   r9   r     s     r   )Ar  r   Z
numba.corer   r   r   r   r   Znumba.core.ir_utilsr   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   Znumba.core.analysisr   Znumba.core.typingr   r   rk   Znumba.core.extendingr   r+   ZUNKNOWN_CLASSZCONST_CLASSZufuncZ	MAP_TYPESr:  Zarray_creationZrandom_int_argsZrandom_1arg_sizeZrandom_2arg_sizelastZrandom_3arg_sizelastZrandom_callsr?   rA   ra   r  rb   r   r   r   r   r   ZNumpyRulesUnaryArrayOperatorZ_op_mapkeysr  rt  ZNumpyRulesArrayOperatorrv  ZNumpyRulesInplaceArrayOperatorry  Zsupported_ufuncsr  r8   r8   r8   r9   <module>   s   D		
/
@       0!                ^