B
     \&                 @   sL   d dl mZ d dlmZ d dlZd dlZdd Zdd ZG dd	 d	e	Z
dS )
    )trace)
deprecatedNc             C   s   | d ks|d ks|d krd S |dkr4t |}|  g }| j}x2tt|ddD ]}|| |||d  9 }qPW |dkr|  t|S )NFr      )CN)listreverseitemsizerangelenappendtuple)dtypeshapeorderstridesr
   i r   /lib/python3.7/site-packages/numba/smartarray.py_o2s   s    
r   c             C   sX   |d ks|d | j krd}n|d | j kr0d}ntdt| ||}||krTtd|S )Nr   r   r   r   z3strides do not correspond to contiguous data layout)r
   
ValueErrorr   )r   r   r   r   s2r   r   r   _s2o   s    r   c               @   s0  e Zd ZdZdZd<ddZedd	 Zed
d Zedd Z	edd Z
edd Zd=ddZeddd Zeddd Zd>ddZeddd Zedd d! Zd"d# Zd$d% Zed&d' Zed?d(d)Zed*d+ Zed,d- Zed.d/ Zed0d1 Zd2d3 Zd4d5 Zd6d7 Zd8d9 Z d:d; Z!dS )@
SmartArrayz1An array type that supports host and GPU storage.)hostgpuNTr   c          
   C   s   || j krtd| |dk	s*|r&|s*td | _| _d | _| _| ||||t|||| |dkrtd| _| j}nd| _| j}|j	| _
|j| _|j| _|j| _|j| _dS )a]  Construct a SmartArray in the memory space defined by 'where'.
        Valid invocations:

        * SmartArray(obj=<array-like object>, copy=<optional-true-or-false>):

          to create a SmartArray from an existing array-like object.
          The 'copy' argument specifies whether to adopt or to copy it.

        * SmartArray(shape=<shape>, dtype=<dtype>, order=<order>)

          to create a new SmartArray from scratch, given the typical NumPy array
          attributes.

        (The optional 'where' argument specifies where to allocate the array
        initially. (Default: 'host')
        z"%s" is not a valid targetNFr   T)_targetsr   AssertionError_host_gpu_host_valid
_gpu_valid	_allocater   r   _shaper   _stridesr   _dtypendim_ndimsize_size)selfobjcopyr   r   r   wheretr   r   r   __init__.   s     
zSmartArray.__init__c             C   s   | j S )N)r$   )r+   r   r   r   r   T   s    zSmartArray.shapec             C   s   | j S )N)r%   )r+   r   r   r   r   W   s    zSmartArray.stridesc             C   s   | j S )N)r&   )r+   r   r   r   r   Z   s    zSmartArray.dtypec             C   s   | j S )N)r(   )r+   r   r   r   r'   ]   s    zSmartArray.ndimc             C   s   | j S )N)r*   )r+   r   r   r   r)   `   s    zSmartArray.sizec             C   sL   || j krtd| | | |dkr.| jS |dkr<| jS td| dS )z>Return the representation of 'self' in the given memory space.z"%s" is not a valid targetr   r   zunknown memory space "%s"N)r   r   _syncr   r    )r+   r.   r   r   r   getc   s    

  zSmartArray.getzget('host')c             C   s
   |  dS )Nr   )r2   )r+   r   r   r   r   m   s    zSmartArray.hostz
get('gpu')c             C   s
   |  dS )Nr   )r2   )r+   r   r   r   r   o   s    zSmartArray.gpuc             C   s   || j krtd| |dkrN| d | jdk	rt| jdkr| d n6|dkr| d | jdk	rt| jdkr| d dS )z@Mark the given location as changed, broadcast updates if needed.z"%s" is not a valid targetr   r   N   )r   r   _invalidater    sysgetrefcountr1   r   )r+   r.   r   r   r   mark_changedr   s    


zSmartArray.mark_changedzmark_changed('host')c             C   s
   |  dS )Nr   )r7   )r+   r   r   r   host_changed   s    zSmartArray.host_changedzmark_changed('gpu')c             C   s
   |  dS )Nr   )r7   )r+   r   r   r   gpu_changed   s    zSmartArray.gpu_changedc             G   s   |  d tj| jf| S )Nr   )r1   nparrayr   )r+   argsr   r   r   	__array__   s    
zSmartArray.__array__c             C   sn   |dkr:| j dkr*| dd| j| j| j | jsj|   n0| jdkr\| dd| j| j| j | jsj| 	  dS )z1Sync the data in one memory space with the other.r   Nr   )
r    r#   r   r   r   r"   _copy_to_gpur   r!   _copy_to_host)r+   r.   r   r   r   r1      s    


zSmartArray._syncc             C   s   |dkrd| _ nd| _dS )z,Mark the host / device array as out-of-date.r   FN)r"   r!   )r+   r.   r   r   r   r4      s    zSmartArray._invalidatec             C   s   |rt |}|dkrL|d k	r2t j|||d| _qt ||t|||| _n`ddlm} |d k	rt|t j	szt j|dd}|
|| _n$|d krt||d}||||| _d S )Nr   )r-   r   )devicearrayFr   )r:   r   r;   r   emptyr   Znumba.cuda.cudadrvr@   
isinstancendarrayZfrom_array_liker    r   ZDeviceNDArray)r+   r.   r,   r   r   r   r-   Zdar   r   r   r#      s    
zSmartArray._allocatec             C   s   | j | j d| _d S )NT)r    Zcopy_to_devicer   r"   )r+   r   r   r   r>      s    zSmartArray._copy_to_gpuc             C   s   | j | j d| _d S )NT)r    Zcopy_to_hostr   r!   )r+   r   r   r   r?      s    zSmartArray._copy_to_hostc             C   s    t | tjrt| ddS | S dS )z[If `value` is an ndarray, wrap it in a SmartArray,
        otherwise return `value` itself.F)r-   N)rB   r:   rC   r   )valuer   r   r   _maybe_wrap   s    zSmartArray._maybe_wrapc             C   s4   | j dkr"| dd| j| j| j | t| j |S )z9Transparently forward attribute access to the host array.Nr   )r   r#   r   r   r   rE   getattr)r+   namer   r   r   __getattr__   s    
zSmartArray.__getattr__c             C   s
   | j d S )Nr   )r   )r+   r   r   r   __len__   s    zSmartArray.__len__c             C   s.   t | t |k	rdS | | d|dkS )NFr   )typerE   r2   )r+   otherr   r   r   __eq__   s     zSmartArray.__eq__c             G   s   |  | dj| S )Nr   )rE   r2   __getitem__)r+   r<   r   r   r   rM      s    zSmartArray.__getitem__c             G   s   |  | dj| S )Nr   )rE   r2   __setitem__)r+   r<   r   r   r   rN      s    zSmartArray.__setitem__c             G   s   |  | dj| S )Nr   )rE   r2   astype)r+   r<   r   r   r   rO      s    zSmartArray.astype)NTNNNr   )r   )r   )NNNNT)"__name__
__module____qualname____doc__r   r0   propertyr   r   r   r'   r)   r2   r   r   r   r7   r8   r9   r=   r1   r   r4   r#   r>   r?   staticmethodrE   rH   rI   rL   rM   rN   rO   r   r   r   r   r   )   s<    
%


	 

r   )Znumba.tracingr   Znumba.errorsr   r5   Znumpyr:   r   r   objectr   r   r   r   r   <module>   s   