B
      ›\(  ã               @   sx   d dl mZmZ d dlmZ d dlmZmZ G dd„ deƒZ	G dd„ deƒZ
dd	„ Zd
ZdZdZdZG dd„ deƒZdS )é    )Úprint_functionÚabsolute_import)Údeque)ÚcgutilsÚtypesc               @   s:   e Zd ZdZdd„ Zdd„ Zddd„Zd	d
„ Zdd„ ZdS )Ú
DataPackerz¨
    A helper to pack a number of typed arguments into a data structure.
    Omitted arguments (i.e. values with the type `Omitted`) are automatically
    skipped.
    c                st   ˆ | _ || _‡ fdd„|D ƒ| _g | _g | _xBt|ƒD ]6\}}t|tjƒs6| j 	|¡ | j 	| j|  
¡ ¡ q6W d S )Nc                s   g | ]}ˆ   |¡‘qS © )Úlookup)Ú.0Úty)Údmmr   ú5lib/python3.7/site-packages/numba/datamodel/packer.pyú
<listcomp>   s    z'DataPacker.__init__.<locals>.<listcomp>)Ú_dmmÚ	_fe_typesÚ_modelsÚ	_pack_mapZ	_be_typesÚ	enumerateÚ
isinstancer   ZOmittedÚappendZget_data_type)Úselfr   Zfe_typesÚir   r   )r   r   Ú__init__   s    zDataPacker.__init__c                s$   ‡ ‡‡fdd„ˆj D ƒ}t ˆ |¡S )zE
        Return the given values packed as a data structure.
        c                s"   g | ]}ˆj |  ˆ ˆ| ¡‘qS r   )r   Úas_data)r
   r   )Úbuilderr   Úvaluesr   r   r   !   s   z&DataPacker.as_data.<locals>.<listcomp>)r   r   Zmake_anonymous_struct)r   r   r   Zelemsr   )r   r   r   r   r      s    
zDataPacker.as_dataNc       	      C   sh   g }x^t | jƒD ]P\}}t ||d|¡}| j|  ||¡}|d krX| | j| |f¡ q|||< qW |S )Nr   )r   r   r   Zgep_inboundsr   Zload_from_data_pointerr   r   )	r   r   ÚptrÚformal_listÚresr   Zi_formalZelem_ptrÚvalr   r   r   Ú_do_load%   s    zDataPacker._do_loadc             C   s   |   ||¡S )zK
        Load the packed values and return a (type, value) tuples.
        )r    )r   r   r   r   r   r   Úload0   s    zDataPacker.loadc             C   s   |   |||¡ dS )zƒ
        Load the packed values into a sequence indexed by formal
        argument number (skipping any Omitted position).
        N)r    )r   r   r   r   r   r   r   Ú	load_into6   s    zDataPacker.load_into)N)	Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r    r!   r"   r   r   r   r   r   	   s   
r   c               @   sF   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zddd„Ze	dd„ ƒZ
dS )Ú	ArgPackera  
    Compute the position for each high-level typed argument.
    It flattens every composite argument into primitive types.
    It maintains a position map for unflattening the arguments.

    Since struct (esp. nested struct) have specific ABI requirements (e.g.
    alignemnt, pointer address-space, ...) in different architecture (e.g.
    OpenCL, CUDA), flattening composite argument types simplifes the call
    setup from the Python side.  Functions are receiving simple primitive
    types and there are only a handful of these.
    c             C   sp   || _ || _t|ƒ| _g | _g }x2|D ]*}| j  |¡}| j |¡ | | ¡ ¡ q&W t|ƒ| _	t
t|ƒƒ| _d S )N)r   Z_fe_argsÚlenÚ_nargsÚ_dm_argsr	   r   Zget_argument_typeÚ_UnflattenerÚ_unflattenerÚlistÚ_flattenÚ_be_args)r   r   Zfe_argsZargtysr   Údmr   r   r   r   K   s    


zArgPacker.__init__c                sV   t |ƒ| jkr$td| jt |ƒf ƒ‚|s,dS ‡ fdd„t| j|ƒD ƒ}tt|ƒƒ}|S )z$Flatten all argument values
        z+invalid number of args: expected %d, got %dr   c                s   g | ]\}}|  ˆ |¡‘qS r   )Zas_argument)r
   r0   r   )r   r   r   r   c   s   z*ArgPacker.as_arguments.<locals>.<listcomp>)r(   r)   Ú	TypeErrorÚzipr*   Útupler.   )r   r   r   Úargsr   )r   r   Úas_argumentsY   s    
zArgPacker.as_argumentsc                s*   | j  |¡}‡ fdd„t| j|ƒD ƒ}|S )z&Unflatten all argument values
        c                s   g | ]\}}|  ˆ |¡‘qS r   )Zfrom_argument)r
   r0   r   )r   r   r   r   o   s   z,ArgPacker.from_arguments.<locals>.<listcomp>)r,   Ú	unflattenr2   r*   )r   r   r4   Úvaltreer   r   )r   r   Úfrom_argumentsj   s    
zArgPacker.from_argumentsc             C   s4   | j  |¡}x"t||ƒD ]\}}|  ||¡ qW dS )z9Assign names for each flattened argument values.
        N)r,   r6   r2   Ú_assign_names)r   r4   Únamesr7   ÚavalZanamer   r   r   Úassign_namesu   s    zArgPacker.assign_namesr   c             C   sj   t |ttfƒr<xVt|ƒD ]\}}| j||||f d qW n*d tt|ƒ¡}||g}d tt	|ƒ¡|_
d S )N)ÚdepthÚ.)r   r3   r-   r   r9   ÚjoinÚmapÚstrÚfilterÚboolÚname)r   Zval_or_nestedrD   r=   Úposr;   ZpostfixÚpartsr   r   r   r9   }   s    zArgPacker._assign_namesc             C   s   t dd„ | jD ƒƒS )z\Return a list of LLVM types that are results of flattening
        composite types.
        c             s   s   | ]}|d kr|V  qdS )r   Nr   )r
   r   r   r   r   ú	<genexpr>‹   s    z+ArgPacker.argument_types.<locals>.<genexpr>)r3   r/   )r   r   r   r   Úargument_types†   s    zArgPacker.argument_typesN)r   )r#   r$   r%   r&   r   r5   r8   r<   r9   ÚpropertyrH   r   r   r   r   r'   >   s   
	r'   c                s   ‡ fdd„‰ ˆ | ƒS )z3
    Flatten nested iterable of (tuple, list).
    c             3   s@   x:| D ]2}t |ttfƒr2xˆ |ƒD ]
}|V  q"W q|V  qW d S )N)r   r3   r-   )Úiterabler   Új)Úrecr   r   rL   ’   s
    
z_flatten.<locals>.recr   )rJ   r   )rL   r   r.   Ž   s    r.   é   é   é   é   c               @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	r+   zè
    An object used to unflatten nested sequences after a given pattern
    (an arbitrarily nested sequence).
    The pattern shows the nested sequence shape desired when unflattening;
    the values it contains are irrelevant.
    c             C   s   |   |¡| _d S )N)Ú_build_unflatten_codeÚ_code)r   Úpatternr   r   r   r   ©   s    z_Unflattener.__init__c                s   g ‰ ‡ ‡fdd„‰ˆ|ƒ ˆ S )zzBuild the unflatten opcode sequence for the given *iterable* structure
        (an iterable of nested sequences).
        c                s`   xZ| D ]R}t |ttfƒrNt|ƒdkrBˆ  t¡ ˆ|ƒ ˆ  t¡ qXˆ  t¡ qˆ  t¡ qW d S )Nr   )	r   r3   r-   r(   r   Ú
_PUSH_LISTÚ_POPÚ_APPEND_EMPTY_TUPLEÚ_APPEND_NEXT_VALUE)rJ   r   )ÚcoderL   r   r   rL   ±   s    

z/_Unflattener._build_unflatten_code.<locals>.recr   )r   rJ   r   )rX   rL   r   rQ   ¬   s    z"_Unflattener._build_unflatten_codec             C   s¢   t |ƒ}g }|}g }xp| jD ]f}|tkrF| |¡ | g ¡ |d }q|tkr^| | ¡ ¡ q|tkrr| d¡ q|tkr| ¡ }qW |r’t	|ƒ‚|ržt	|ƒ‚|S )z*Rebuild a nested tuple structure.
        éÿÿÿÿr   )
r   rR   rT   r   rW   ÚpopleftrV   rU   ÚpopÚAssertionError)r   ZflatiterZvalsr   ZcurÚstackÚopr   r   r   r6   À   s$    


z_Unflattener.unflattenN)r#   r$   r%   r&   r   rQ   r6   r   r   r   r   r+   ¡   s   r+   N)Z
__future__r   r   Úcollectionsr   Znumbar   r   Úobjectr   r'   r.   rT   rW   rV   rU   r+   r   r   r   r   Ú<module>   s   5P