B
    \t                 @   s  d dl mZ ddlmZmZ ddlmZ ddlmZmZm	Z	 ddlm
Z
 ddlmZmZ ddlmZ dd	lmZ dd
lmZ ddlmZ dZdZdZdZdZdZdZdZdZdd ZdZdZdZdZdZ dZ!dZ"dZ#dZ$d Z%d!Z&d"Z'e"e#e$e%e&e'd#Z(d$d%d&d'd(d)d#Z)d*Z*d+Z+d,Z,d-Z-d.Z.d/d0 Z/dd3d4Z0dd5d6Z1d7d8 Z2d9d: Z3d;d< Z4dd=d>Z5G d?d@ d@ej6Z7dAdB Z8dCdD Z9dEdF Z:dGdH Z;dIdJ Z<dKdL Z=G dMdN dNe>Z?G dOdP dPe?Z@G dQdR dRe?ZAdSdT ZBdUdV ZCdWdX ZDdYdZ ZEd[d\ ZFd]d^ ZGd_d`dadbdcdddeZHdfdg ZIdhdi ZJdjdk ZKdldm ZLddodpZMddqdrZNdsdt ZOe-e
jPe.e*duZQeNdveQg dwZReNdxeQZSeNdyeTeQe
jPdzeReSgdwZUeNd{ZVeMd|ejWgd}ZXeNd~eQZYeNdeQZZeNdeQg d}Z[eMdeQe\ ej]ej^eUeYeZe[ej_gdwZ`dZaeRjbce` e[jbce` dnS )    )absolute_import   )CompileErrorerror)	ExprNodes)IntNodeNameNodeAttributeNode)Options)UtilityCodeTempitaUtilityCode)CythonUtilityCode)Buffer)
PyrexTypes)
ModuleNodezStart must not be given.z3Axis specification only allowed in the 'step' slot.z.Step must be omitted, 1, or a valid specifier.z>Cannot specify an array that is both C and Fortran contiguous.zInvalid axis specification.z+Variable was not cimported from cython.viewz=no expressions allowed in axis spec, only names and literals.z<Invalid axis specification for a C/Fortran contiguous array.zdCannot check if memoryview %s is initialized without the GIL, consider using initializedcheck(False)c              G   s   dd |  S )Nz(%s)|)join)flags r   9lib/python3.7/site-packages/Cython/Compiler/MemoryView.pyconcat_flags   s    r   ZPyBUF_FORMATz#(PyBUF_C_CONTIGUOUS | PyBUF_FORMAT)z#(PyBUF_F_CONTIGUOUS | PyBUF_FORMAT)z%(PyBUF_ANY_CONTIGUOUS | PyBUF_FORMAT)ZPyBUF_FULL_ROZPyBUF_RECORDS_ROZ__Pyx_MEMVIEW_DIRECTZ__Pyx_MEMVIEW_PTRZ__Pyx_MEMVIEW_FULLZ__Pyx_MEMVIEW_CONTIGZ__Pyx_MEMVIEW_STRIDEDZ__Pyx_MEMVIEW_FOLLOW)directptrfullcontigstridedfollowdpfcs_z{ 0, 0, { 0 }, { 0 }, { 0 } }
memoryviewZ__pyx_memoryview_typeZ__pyx_memoryview_objZ__Pyx_memviewslicec             C   s    | d|   | d|   d S )Nz%s.data = NULL;z%s.memview = NULL;)putln)Zmv_cnamecoder   r   r   put_init_entryG   s    r&   FTc       	   	   C   s|   |j jst| p| }|r*| }n(|jj|dd}|d||	|f  t
| ||||||d |sx|j| dS )zEWe can avoid decreffing the lhs if we know it is the first assignmentF)
manage_refz%s = %s;)have_gilfirst_assignmentN)typeZis_memoryviewsliceAssertionErrorresult_in_tempZ	is_simpleresult	funcstateallocate_tempr$   Z	result_asput_assign_to_memviewslicerelease_temp)		lhs_cnameZlhs_typeZlhs_posrhsr%   r(   r)   Z
pretty_rhsZrhstmpr   r   r   put_acquire_memoryviewsliceP   s    

r4   c             C   s:   |s|j | |d | s$|| |d| |f  d S )N)r(   z%s = %s;)Zput_xdecref_memoryviewslicer,   Zmake_owned_memoryviewslicer$   )r2   r3   Z	rhs_cnameZmemviewslicetyper%   r(   r)   r   r   r   r0   e   s
    
r0   c             C   sD   t | \}}|rtS |rtS t|  \}}d|ks8d|kr<tS tS d S )Nr   r   )is_cf_contigmemview_c_contiguousmemview_f_contiguouszipmemview_full_accessmemview_strided_access)specsis_c_contigis_f_contigaccesspackingr   r   r   get_buf_flagsp   s    r@   c             C   s$   dg| }| | j t| j|S )N)r   r   )extendaxesr   ZMemoryViewSliceTypedtype)ZmemoryviewtypenrB   r   r   r   insert_newaxes   s    
rE   c             C   s<   t | j|j }| j|jk r*t| ||fS | t||fS d S )N)absndimrE   )srcdstrD   r   r   r   broadcast_types   s    rJ   c             C   s   | j r| jjrdS | tjkr dS | jrT| jdkrTx| jjD ]}t	|j
s:dS q:W dS | jp| jrx|dk rxt	| j|d p| jp| jp| jp| jot	| jS )z
    Return whether type dtype can be used as the base type of a
    memoryview slice.

    We support structs, numeric types and objects
    FZstructT   r   )Z
is_complexZ	real_typeZis_intr   Zc_bint_typeZ	is_structZkindscopeZvar_entriesvalid_memslice_dtyper*   Zis_errorZis_arrayZ	base_typeZ
is_numericis_pyobjectZis_fusedZ
is_typedefZtypedef_base_type)rC   imemberr   r   r   rM      s     

rM   c               @   sJ   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d ZdddZ	dd Z
dS )MemoryViewSliceBufferEntryz
    May be used during code generation time to be queried for
    shape/strides/suboffsets attributes, or to perform indexing or slicing.
    c             C   sD   || _ |j| _|j| _d| j | _| j jj}t|| _|   d S )Nz%s.data)	entryr*   cnamebuf_ptrrC   r   ZCPtrTypeZbuf_ptr_typeZinit_attributes)selfrR   rC   r   r   r   __init__   s    
z#MemoryViewSliceBufferEntry.__init__c             C   s
   |  dS )Nz%s.suboffsets[%d])_for_all_ndim)rU   r   r   r   get_buf_suboffsetvars   s    z0MemoryViewSliceBufferEntry.get_buf_suboffsetvarsc             C   s
   |  dS )Nz%s.strides[%d])rW   )rU   r   r   r   get_buf_stridevars   s    z-MemoryViewSliceBufferEntry.get_buf_stridevarsc             C   s
   |  dS )Nz%s.shape[%d])rW   )rU   r   r   r   get_buf_shapevars   s    z,MemoryViewSliceBufferEntry.get_buf_shapevarsc                s&    fddt | jjD }| ||S )Nc                s$   g | ]\}\}}| | ||fqS r   r   ).0dimr>   r?   )index_cnamesr   r   
<listcomp>   s   zJMemoryViewSliceBufferEntry.generate_buffer_lookup_code.<locals>.<listcomp>)	enumerater*   rB   _generate_buffer_lookup_code)rU   r%   r]   rB   r   )r]   r   generate_buffer_lookup_code   s    
z6MemoryViewSliceBufferEntry.generate_buffer_lookup_codeTc             C   s  | j }| jj }x|D ]\}}}}	d| j|f }
d| j|f }d| j|f }t||	}|dkr~|jt d||||f }nr|dkrd|||f }d||f }nN|d	krd
|||f }n6|dkrd|||f }n|dkst	|d|||f }d||f }qW |rd||f S |S )zl
        Generate a single expression that indexes the memory view slice
        in each dimension.
        z%s.shape[%d]z%s.strides[%d]z%s.suboffsets[%d])genericgeneric_contiguousz-__pyx_memviewslice_index_full(%s, %s, %s, %s)indirectz(%s + %s * %s)z(*((char **) %s) + %s)indirect_contiguousz(*((char **) %s + %s) + %s)r   
contiguousz((char *) (((%s *) %s) + %s))z( /* dim=%d */ %s )z((%s *) %s))
rT   r*   rC   empty_declaration_coderS   get_memoryview_flagZglobalstateZuse_utility_codememviewslice_index_helpersr+   )rU   r%   rB   Zcast_resultZbufp	type_declr\   indexr>   r?   shapeZstrideZ	suboffsetflagr   r   r   r`      s0    
z7MemoryViewSliceBufferEntry._generate_buffer_lookup_codec          	      s  | j } dt    dt    | tdd | jjD }g  fdd}	d}
d}xx|D ]n}|jrx&d	D ]\}} d
||||f  qzW |d7 }qh|
d7 }
| jj|
 \}} |j	}t
|tjrbtt }xDd D ]8}t||}|j  }|d| < |r| nd||< qW |d sT|d sT|d sT||d< d}nd}|d7 }nX| }|dk}|r|dk}|dkrt|j	dS tt t|d t|d d}d}tj|d|d\}} | qhW r jd  dS )a  
        Slice a memoryviewslice.

        indices     - list of index nodes. If not a SliceNode, or NoneNode,
                      then it must be coercible to Py_ssize_t

        Simply call __pyx_memoryview_slice_memviewslice with the right
        arguments, unless the dimension is omitted or a bare ':', in which
        case we copy over the shape/strides/suboffsets attributes directly
        for that dimension.
        z%(dst)s.data = %(src)s.data;z"%(dst)s.memview = %(src)s.memview;c             s   s   | ]\}}|d kV  qdS )r   Nr   )r[   r>   r?   r   r   r   	<genexpr>  s    zHMemoryViewSliceBufferEntry.generate_buffer_slice_code.<locals>.<genexpr>c                 s6   s. j jtjdd}  d|   |  d S )NF)r'   z%s = -1;r   )r.   r/   r   Z
c_int_typer$   append)Zsuboffset_dim)r%   suboffset_dim_tempr   r   get_suboffset_dim  s
    
zPMemoryViewSliceBufferEntry.generate_buffer_slice_code.<locals>.get_suboffset_dimr   ))rl   r   )stridesr   )
suboffsetsrr   z%s.%s[%d] = %d;r   zstart stop stepZhave_0Z
have_startZ	have_stopZ	have_stepr>   ZSimpleSliceZ
ToughSlicer   r   z7All preceding dimensions must be indexed and not sliced
wraparoundboundscheck)rv   rw   Z
SliceIndexzMemoryView_C.c)contextN)rS   r$   localsZput_incref_memoryviewsliceallr*   rB   is_none
error_gotopos
isinstancer   	SliceNodedictsplitgetattrr-   r   intr   Zload_as_stringZputr.   r1   )rU   r%   indicesrI   r(   have_slicesZ
directivesrH   Zall_dimensions_directrq   r\   Znew_ndimrk   Zattribvaluer>   r?   r|   r   r!   idxZhave_idxZ	util_namerd   rb   r"   implr   )r%   rp   r   generate_buffer_slice_code   sZ    





z5MemoryViewSliceBufferEntry.generate_buffer_slice_codeN)T)__name__
__module____qualname____doc__rV   rX   rY   rZ   ra   r`   r   r   r   r   r   rQ      s   
.rQ   c             C   s   t | }t j| |||dS )N)startstopstep)r   ZNoneNoder   )r}   Znoner   r   r   empty_sliceS  s    
r   c             C   s   g }d}d}dd | D }t | t | }xr| D ]j}t|tjrd}t|j}|r^|| q|| d }	||g|	  d}q0|p|jp|j	}|| q0W t |t | }
|
|k rd}||
 }	|t| d jg|	  |||fS )NFc             S   s   g | ]}|j r|qS r   )r{   )r[   Znewaxisr   r   r   r^   ^  s    zunellipsify.<locals>.<listcomp>Tr   rr   )
lenr~   r   ZEllipsisNoder   r}   ro   rA   Zis_slicer{   )r   rG   r-   Zseen_ellipsisr   ZnewaxesZ	n_indicesrk   Z
full_sliceZnslicesZresult_lengthr   r   r   unellipsifyY  s,    

r   c             C   s   | dkr|dkrdS | dkr(|dkr(dS | dkr<|dkr<dS | dkrP|dkrPdS | d	krd|dkrdd
S | |fdks|t | |fdS d S )Nr   )r   r   rb   r   rc   r   rd   re   r   r   )r   r   rf   )r+   )r>   r?   r   r   r   rh   y  s    rh   c             C   s   | dkst d| |f S )N)CFz!__pyx_memviewslice_is_contig_%s%d)r+   )contig_typerG   r   r   r   get_is_contig_func_name  s    r   c             C   s.   | dkst tt|| d}td|tgd}|S )N)r   r   )rG   r   ZMemviewSliceCheckContig)requires)r+   r   rx   load_memview_c_utilityis_contig_utility)r   rG   r   Zutilityr   r   r   get_is_contig_utility  s    r   c             C   s,   | j s| jrt| |||S t| |||S d S )N)r<   r=   ContigSliceIterStridedSliceIter)
slice_typeslice_resultrG   r%   r   r   r   
slice_iter  s    r   c               @   s   e Zd Zdd ZdS )	SliceIterc             C   s   || _ || _|| _|| _d S )N)r   r   r%   rG   )rU   r   r   rG   r%   r   r   r   rV     s    zSliceIter.__init__N)r   r   r   rV   r   r   r   r   r     s   r   c               @   s   e Zd Zdd Zdd ZdS )r   c                st    j }|   jj }d fddt jD }|d|  |d |d|| j	f  |d dS )	Nz * c             3   s   | ]}d  j |f V  qdS )z%s.shape[%d]N)r   )r[   rO   )rU   r   r   rn     s   z.ContigSliceIter.start_loops.<locals>.<genexpr>z"Py_ssize_t __pyx_temp_extent = %s;zPy_ssize_t __pyx_temp_idx;z(%s *__pyx_temp_pointer = (%s *) %s.data;zPfor (__pyx_temp_idx = 0; __pyx_temp_idx < __pyx_temp_extent; __pyx_temp_idx++) {Z__pyx_temp_pointer)
r%   begin_blockr   rC   rg   r   rangerG   r$   r   )rU   r%   rj   Z
total_sizer   )rU   r   start_loops  s    

zContigSliceIter.start_loopsc             C   s&   | j d | j d | j   d S )Nz__pyx_temp_pointer += 1;})r%   r$   	end_block)rU   r   r   r   	end_loops  s    zContigSliceIter.end_loopsN)r   r   r   r   r   r   r   r   r   r     s   r   c               @   s   e Zd Zdd Zdd ZdS )r   c             C   s   | j }|  xVt| jD ]H}|| j|f}|d|  |d|  |d|  |d|  qW |d| j  xFt| jD ]8}|dkr|d||d f  |d	||||f  qW d
| jd  S )Nz/Py_ssize_t __pyx_temp_extent_%d = %s.shape[%d];z1Py_ssize_t __pyx_temp_stride_%d = %s.strides[%d];zchar *__pyx_temp_pointer_%d;zPy_ssize_t __pyx_temp_idx_%d;z__pyx_temp_pointer_0 = %s.data;r   z.__pyx_temp_pointer_%d = __pyx_temp_pointer_%d;r   z\for (__pyx_temp_idx_%d = 0; __pyx_temp_idx_%d < __pyx_temp_extent_%d; __pyx_temp_idx_%d++) {z__pyx_temp_pointer_%d)r%   r   r   rG   r   r$   )rU   r%   rO   tr   r   r   r     s    zStridedSliceIter.start_loopsc             C   sJ   | j }x6t| jd ddD ] }|d||f  |d qW |  d S )Nr   rr   z.__pyx_temp_pointer_%d += __pyx_temp_stride_%d;r   )r%   r   rG   r$   r   )rU   r%   rO   r   r   r   r     s
    zStridedSliceIter.end_loopsN)r   r   r   r   r   r   r   r   r   r     s   r   c             C   s    | j rd}nd}d|  |f S )Nr    r   z!__pyx_memoryview_copy_slice_%s_%s)r<   Zspecialization_suffix)ZmemviewZc_or_fr   r   r   copy_c_or_fortran_cname  s
    r   c             C   s   |j |j kr0|j jr"|j j|j ks0t| d d S t|jt|jkrRt| d d S |jsl|jslt| d d S x(|jD ]\}}|dkrtt| d d S qtW |jrd}t}n|jrd}t	}t
dtt||j  ||jt|t|j jd	tgd
S )Nzdtypes must be the same!z!number of dimensions must be samez%to_memview must be c or f contiguous.r   z2cannot handle 'full' or 'ptr' access at this time.r    fortranZCopyContentsUtility)modeZ
dtype_declcontig_flagrG   Z
func_cnameZdtype_is_object)rx   r   )rC   Zis_constZconst_base_typer   r   rB   r<   r=   r6   r7   r   r   rx   rg   rG   r   r   rN   copy_contents_new_utility)r}   Zfrom_memviewZ
to_memviewr>   r?   r   r   r   r   r   get_copy_new_utility  s>    



r   c                s  |   jj}|  |j t fdddD }t fdddD }d\}}d\}}|d }	}
g }xt|D ]\}}|jjst	|jj
t|jjst	|jj
t|jjr|||f qnt|jtr|j| d	krt	|jj
t||	d
f qnt|jttfr@t| |j}|jtkr0|t|j  nt	|jj
tqnt	|jj
tqnW d}d}xLt|D ]@\}\}}|d
krd|rt	|jj
t|}|df||< d}qdW |r|t|d	 krd}n0d}|r||d	  d dkrt	|| j
d|r:d}x8tt|D ](\}\}}|dkrt|| d	 }qW |d	 }t|| }xnt||| D ]Z\}\}}|d	 | }|dkrt	|| j
d|dkrt	|| j
d||
f||< q`W |r|d \}}|df|d< tdd |D ||| |S )z
    get_axes_specs(env, axes) -> list of (access, packing) specs for each axis.
    access is one of 'full', 'ptr' or 'direct'
    packing is one of 'contig', 'strided' or 'follow'
    c                s   g | ]}  |qS r   )lookup)r[   name)	viewscoper   r   r^     s   z"get_axes_specs.<locals>.<listcomp>)r   r   r   c                s   g | ]}  |qS r   )r   )r[   r   )r   r   r   r^     s   )r   r   r   )FF)r   r   r   r   Zcfcontigr   Fr   T)r   r   z>Fortran contiguous specifier must follow an indirect dimensionrr   )r   r   r   z>Indirect dimension may not follow Fortran contiguous dimensionzDimension may not be contiguousc             S   s   g | ]}|j jqS r   )r   r}   )r[   axisr   r   r   r^   w  s    )global_scoperx   cython_scopeload_cythonscoper   tupler_   r   r{   r   r}   	START_ERRr   STOP_ERRr   ro   r~   r   Zcompile_time_valueSTEP_ERRr   r	   _get_resolved_specr   view_constant_to_access_packingINVALID_ERRBOTH_CF_ERRr   reversedvalidate_axes_specs)envrB   Zcythonscopeaccess_specspacking_specsr=   r<   Zdefault_accessZdefault_packingZ	cf_accessZ
cf_packingZ
axes_specsr   r   rR   Z
contig_dimZ	is_contigr>   r?   r   r   ar   r   )r   r   get_axes_specs  s    






	



r   c             C   s    t |tjkrt| d dS dS )NzGMore dimensions than the maximum number of buffer dimensions were used.FT)r   r
   buffer_max_dimsr   )r}   rB   r   r   r   validate_axes  s    
r   c             C   s   d }}t | dkr$| dgkr$d}nb| d dkrPtdd | d d D rPd}n6t | dkr| d dkrtd	d | dd  D rd}||fS )
NFr   )r   r   Trr   c             s   s   | ]}|d kV  qdS ))r   r   Nr   )r[   r   r   r   r   rn     s    zis_cf_contig.<locals>.<genexpr>r   c             s   s   | ]}|d kV  qdS ))r   r   Nr   )r[   r   r   r   r   rn     s    )r   rz   )r;   r<   r=   r   r   r   r5     s    r5   c             C   s>   t | \}}|rdS |rdS x| D ]\}}|dkr"dS q"W dS )Nr    r   )r   r   r   r   )r5   )r;   r<   r=   r>   r?   r   r   r   get_mode  s    r   )r   r   )r   r   )r   r   )r   r   )r   r   )r   r   )rb   r   rd   rc   rf   re   c             C   sR  d}d}d } } }}	d}
x$t |D ]\}\}}|dkr&|}
q&W xt t| |D ]\}\}\}}||krt||ks~t|d|dkrd}n|d	kr|rt|d
|
d t|d f}||kr|dkr|
d t|d krd| }nd|d  }t|d| |dk}n0|dkr>|r(t|d|s>|s>t|d|dkrTd}qTW d S )N)r   r   r   )r   r   r   Frr   r   zInvalid axes specification.r   Tr   z1Only one direct contiguous axis may be specified.r   zdimensions %d and %dzdimension %dr   z$Only %s may be contiguous and directr   zAA memoryview cannot have both follow and strided axis specifiers.z$Invalid use of the follow specifier.)r   r   )r_   r8   r   r   )Z	positionsr;   r<   r=   r   r   Z
has_contigZ
has_followZhas_stridedZhas_generic_contigZlast_indirect_dimensionr   r>   r?   r}   Zvalid_contig_dimsZdimsr   r   r   r     s<    "







r   c             C   s8   t |trt| |S t |tr(t| |S t|jtd S )N)r~   r   _resolve_NameNoder	   _resolve_AttributeNoder   r}   r   )r   specr   r   r   r     s
    



r   c             C   sd   y|  |jj}W n  tk
r2   t|jtY nX |  jjj	}| |}|d kr`t|jt
|S )N)r   r   AttributeErrorr   r}   r   r   rx   r   r   NOT_CIMPORTED_ERR)r   nodeZresolved_namer   rR   r   r   r   r     s    
r   c             C   s   g }x"t |tr&|d|j |j}qW t |trB|d|j nt|jt	|d d }|sbt
| }x6|D ].}||}|r|jst|jd| |j}qlW ||d }|st|jd|d  |S )Nr   rr   zundeclared name not builtin: %szNo such attribute '%s')r~   r	   insertZ	attributeobjr   r   r   r}   EXPR_ERRr+   r   Z	as_module)r   r   pathmodnamesrL   modnamemodrR   r   r   r   r     s(    





r   Nc             K   s   t j| dfd|i|S )NzMemoryView.pyxrx   )r   load)util_code_namerx   kwargsr   r   r   load_memview_cy_utility  s    r   c             K   s4   |d krt j| df|S tj| dfd|i|S d S )NzMemoryView_C.crx   )r   r   r   )r   rx   r   r   r   r   r     s    r   c             C   s&   |   jj}|  d|jd_d S )NTarray_cwrapper)r   rx   r   r   r   r   Zused)r   r   r   r   r   use_cython_array_utility_code!  s    r   )Zmemview_struct_nameZmax_dimsZmemviewslice_nameZmemslice_initZMemviewSliceStruct)rx   r   ZAtomicsZMemviewSliceInit)ZBUF_MAX_NDIMSZMemviewSliceIndexZBufferFormatFromTypeInfo)r   ZMemviewSliceIsContigZOverlappingSlicesZMemviewSliceCopyTemplatezView.MemoryView)Zarrayr#   r   rb   r   rd   rf   re   )FT)FF)r   )N)N)dZ
__future__r   ZErrorsr   r    r   r   r   r	   r
   ZCoder   r   r   r   r   r   r   r   r   r   r   r   r   ZCF_ERRZERR_UNINITIALIZEDr   Zformat_flagr6   r7   Zmemview_any_contiguousr9   r:   ZMEMVIEW_DIRECTZMEMVIEW_PTRZMEMVIEW_FULLZMEMVIEW_CONTIGZMEMVIEW_STRIDEDZMEMVIEW_FOLLOWZ_spec_to_constZ_spec_to_abbrevZmemslice_entry_initZmemview_nameZmemview_typeptr_cnameZmemview_objstruct_cnameZmemviewslice_cnamer&   r4   r0   r@   rE   rJ   rM   ZBufferEntryrQ   r   r   rh   r   r   r   objectr   r   r   r   r   r   r   r5   r   r   r   r   r   r   r   r   r   r   rx   Zmemviewslice_declare_codeZatomic_utilityr   Zmemviewslice_init_coderi   Z_typeinfo_to_format_codeZtypeinfo_to_format_coder   Zoverlapping_utilityr   ZGetAndReleaseBufferUtilityCodeZbuffer_struct_declare_codeZbuffer_formats_declare_codeZcapsule_utility_codeZview_utility_codeZview_utility_whitelistr   ro   r   r   r   r   <module>   s   




! % !
%r	.	





