U
    d%                     @   sH   d dl Zd dlZd dlmZ d dlmZ d dlmZ G dd de	Z
dS )    N)	workspace)InferOpBlobDevicesAsDict)	viewitemsc                   @   s,   e Zd ZdZdd Zd	ddZd
ddZdS )DeviceCheckerzA device checker in Python to check consistency across multiple devices.

    This is not the most efficient way to check devices, as the Python interface
    will involve a lot of copies back and forth operations. Use at your own risk.
    c                 C   s   || _ || _d S )N)
_threshold_device_options)self	thresholdZdevice_options r
   @/tmp/pip-unpacked-wheel-ua33x9lu/caffe2/python/device_checker.py__init__   s    zDeviceChecker.__init__Nc              
      st  t   t }g }tdd t| jD ]\}} j| |pNt	 d }	t
|	 t|D ]0\}}
t j| t|
|	 j| | q`t  | fdd|D  t  q,d}tdt| jD ]}tt|D ]}|| | }|d | }tj||| j| jdst
d| j||   t
|  t
|  t
tt||  d	}qqt| |S )
a  Checks the operator with different device implementations.

        Inputs:
          op: the operator to be checked.
          inputs: the input data in numpy arrays.
          outputs_to_check: the outputs to check between devices.
          input_device_options: a mapping from input name to a device to use
            (instead of self._device_options)
        Outputs:
          boolean: True if it passes, False if it does not pass.
        _device_check_Tr   c                    s   g | ]}t  j| qS r
   )r   	FetchBloboutput).0idxopr
   r   
<listcomp>3   s   z-DeviceChecker.CheckSimple.<locals>.<listcomp>   ZatolZrtolDFailure in checking device option {} and output {}. The outputs are:F)copydeepcopyr   CurrentWorkspaceSwitchWorkspace	enumerater   device_optionCopyFromr   printFeedBlobinputnparraygetZRunOperatorOnceappendZResetWorkspacerangelenallcloser   formatr   flattenmaxabs)r   r   inputsZoutputs_to_checkZinput_device_optionsold_ws_nameresultsir   Z_input_device_optionsarrsuccessjxyr
   r   r   CheckSimple   sT    

 


  
zDeviceChecker.CheckSimplec              	      sr  |dkri } dkrt   t }g }|dkrDtdd |jD g } fdd|D }tdd | jD ]Z}t|D ]\}}	t||	| qt|jD ]}
|
j	
| qt| |dd |D  qhd}tdt|D ]}tt|D ]z}|| | }|d	 | }tj||| j| jd
std|||  t|  t|  ttt||  d}qqt| |S )ziChecks a network by inspecting all of its intermediate results, and
        see if things match.
        Nc                 S   s   g | ]}t |jqS r
   )listr   )r   r   r
   r
   r   r   W   s     z*DeviceChecker.CheckNet.<locals>.<listcomp>c                    s   g | ]}| kr|qS r
   r
   )r   bignorer
   r   r   X   s      r   Tc                 S   s   g | ]}t |qS r
   )r   r   )r   namer
   r
   r   r   b   s     r   r   r   r   F)setr   r   sumr   r   r   r   r    r   r   Z
RunNetOncer%   r&   r'   r"   r(   r   r   r)   r*   r+   r,   )r   netr-   Zblobs_to_checkr:   r.   r/   r   r;   r1   r   r2   r0   r3   r4   r5   r
   r9   r   CheckNetL   sL    


  
zDeviceChecker.CheckNet)N)NNN)__name__
__module____qualname____doc__r   r6   r?   r
   r
   r
   r   r   
   s
    
7r   )Znumpyr"   r   Zcaffe2.pythonr   Zcaffe2.python.corer   Zfuture.utilsr   objectr   r
   r
   r
   r   <module>   s
   