o
    @a                     @   s   d Z ddlmZ ddlmZ ddlmZ ddlmZ ddl	m
Z
 ddl	ZddlZdd eD Zh d	Zh d
Zh dZG dd de
ZG dd deZdS )z
This modules contains OpenMP-related stuff.
    * OMPDirective is used to represent OpenMP annotations in the AST
    * GatherOMPData turns OpenMP-like string annotations into metadata
    )TransformationN)PYTYPE_TO_CTYPE_TABLE)isstr)ASTc                 C   s   i | ]}|j |qS  )__name__).0tr   r   0/usr/lib/python3/dist-packages/pythran/openmp.py
<dictcomp>       r   >)   ompnonesimdatomiccancelcopyinmasternowaitsingleuntiedbarriercaptureorderedcollapsesectionstaskwait	mergeable	taskyieldcopyprivateinitializerlastprivatenum_threadsfirstprivatethreadprivateifforreadtaskfinalflushwritesharedupdatedeclaredefaultprivatesectioncriticalparallelschedule	reduction>   omp_inomp_outomp_initomp_origomp_priv>   r.   r/   r2   r4   r5   c                       s    e Zd ZdZ fddZ  ZS )OMPDirectiveaX  Turn a string into a context-dependent metadata.
    >>> o = OMPDirective("omp for private(a,b) shared(c)")
    >>> o.s
    'omp for private({},{}) shared({})'
    >>> [ type(dep) for dep in o.deps ]
    [<class 'gast.gast.Name'>, <class 'gast.gast.Name'>, <class 'gast.gast.Name'>]
    >>> [ dep.id for dep in o.deps ]
    ['a', 'b', 'c']
    c                    sL   t t   |sd S g  _g  _g  _ fdd}||d  _d _d S )Nc                    s  d}d}d}d}d}d }}|t | k rtd| |d }|r|d}	|t |	7 }|	tv r8|tt|	  7 }n|sH|r@|	tv sH|dkrc|	tv rc||	7 }|	tv }||	dkO }||	dkO }||	dkO }nmd	}
 j	
t|	t dd |r~ j
 j	d
  |r j
 j	d
  ||
7 }nB| | dkr|d7 }|d7 }|d7 }n/| | dkr|d8 }|d7 }|d7 }|dkrd}d }}n| | dv rd}|| | 7 }|d7 }|t | k s|S )z1A simple contextual "parser" for an OpenMP string r   Fz^([a-zA-Z_]\w*)Nr.   r0   r,   z{}(   )z,:)lenrematchgroup	typenamesr   declare_keywordskeywordsreserved_contexdepsappendastNameZLoadprivate_depsshared_deps)soutZ	par_countZ
curr_indexZin_reserved_contextZ
in_declareZ	in_sharedZ
in_privatemZwordvselfr   r
   tokenized   sl   


(z'OMPDirective.__init__.<locals>.tokenizer   )rI   rN   rM   )superr;   __init__rI   rM   rN   rO   _fields)rT   argsrU   	__class__rS   r
   rW   [   s   3
zOMPDirective.__init__)r   
__module____qualname____doc__rW   __classcell__r   r   rZ   r
   r;   O   s    r;   c                   @   s@   e Zd ZdZdZdZdd Zdd Zdd	 Zd
d Z	dd Z
dS )GatherOMPDatazEWalks node and collect string comments looking for OpenMP directives.)ZFunctionDefZReturnZDeleteZAssignZ	AugAssignZPrintZForZWhileZRaiseZ	TryExceptZ
TryFinallyZAssertZImportZ
ImportFromPassZBreak)bodyorelse	finalbodyc                 C   s4   t |  tjD ]}t| d| | j qt | _d S )NZvisit_)r   rW   r`   
statementssetattrattach_datalistcurrent)rT   rO   r   r   r
   rW      s   

zGatherOMPData.__init__c                 C   s   t |o	|jdS )Nzomp )r   value
startswithrT   noder   r   r
   isompdirective   s   zGatherOMPData.isompdirectivec                 C   s.   |  |jr| j|jj d S | | |S N)rn   rj   ri   rJ   rg   rl   r   r   r
   
visit_Expr   s
   
zGatherOMPData.visit_Exprc                 C   sH   |  |jr| t|j | ttdd |j|jS | 	|S )Nr?   )
rn   testZvisitrK   ExprIfConstantrb   rc   rg   rl   r   r   r
   visit_If   s   
zGatherOMPData.visit_Ifc                    s(  | j r| j D ]}t|}t|| qt | _ t|D ]"\}}|tjv r>|r>t	|d tj
r>| |d jr>|t  q| | t|t}dd t|D }|tj}|r|rddd |D  d}	t fdd|	D rt|t ttd	d
|gg }|D ]}
t||
 q|S )zcGeneric method called for visit_XXXX() with XXXX in
        GatherOMPData.statements list

        r=   c                 S   s   h | ]\}}|qS r   r   )r   n_r   r   r
   	<setcomp>   r   z,GatherOMPData.attach_data.<locals>.<setcomp>r<   c                 s   s    | ]}|j V  qd S ro   )rO   )r   dr   r   r
   	<genexpr>   s    z,GatherOMPData.attach_data.<locals>.<genexpr>)r3   r(   r1   c                 3   s    | ]}| v V  qd S ro   r   )r   rO   Z
sdirectiver   r
   rz      s    r?   N)ri   r;   metadataaddrh   rK   Ziter_fieldsr`   statement_lists
isinstancerr   rn   rj   rJ   ra   Zgeneric_visitget
isdisjointjoinanyclearrs   rt   )rT   rm   ZcurrZmdZ
field_nameZfieldZ
directivesfield_namesZhas_no_scopeZscopingZ	directiver   r{   r
   rg      s6   


zGatherOMPData.attach_dataN)r   r\   r]   r^   re   r~   rW   rn   rp   ru   rg   r   r   r   r
   r`      s    r`   )r^   Zpythran.passmanagerr   Zpythran.metadatar|   Zpythran.types.conversionr   Zpythran.utilsr   Zgastr   rK   rB   rE   rG   rF   rH   r;   r`   r   r   r   r
   <module>   s    ,	M