B
    !`a                 @   st   d Z ddlmZ ddlmZ ddlmZ ddlZddlmZ dZdZ	d	Z
d
d Zdd Zdd ZG dd deZdS )zCA wrapper around DebugDataReader used for retrieving tfdbg v2 data.    )absolute_import)division)print_functionN)errorsZ__default_debugger_run__i     c                s6   t    fdd}t j|dd}|   |fS )a  Run a target task repeatedly in the background.

    In the context of this module, `target` is the `update()` method of the
    underlying reader for tfdbg2-format data.
    This method is mocked by unit tests for deterministic behaviors during
    testing.

    Args:
      target: The target task to run in the background, a callable with no args.
      interval_sec: Time interval between repeats, in seconds.

    Returns:
      - A `threading.Event` object that can be used to interrupt an ongoing
          waiting interval between successive runs of `target`. To interrupt the
          interval, call the `set()` method of the object.
      - The `threading.Thread` object on which `target` is run repeatedly.
    c                  s"   x        qW d S )N)waitclear )eventinterval_sectargetr	   e/home/dcms/DCMS/lib/python3.7/site-packages/tensorboard/plugins/debugger_v2/debug_data_multiplexer.py_run_repeatedly?   s    
z5run_repeatedly_in_background.<locals>._run_repeatedlyT)r   daemon)	threadingEventThreadstart)r   r   r   threadr	   )r
   r   r   r   run_repeatedly_in_background+   s
    r   c          
   C   sT   ddl m} t| |jr@d| j| j| j| j| j| j	| j
| jd	S tdt|  d S )Nr   )debug_events_monitorsInfNanAlert)	
alert_typeop_typeoutput_slotsizenum_neg_infnum_pos_infnum_nanexecution_indexgraph_execution_trace_indexzUnrecognized alert subtype: %s)tensorflow.python.debug.libr   
isinstancer   r   r   r   r   r   r   r   r    	TypeErrortype)alertr   r	   r	   r   _alert_to_jsonK   s    
r&   c             C   s0   d}d| kr$|  d\}}t|}n| }||fS )z@Helper function that extracts op name and slot from tensor name.r   :)splitint)Ztensor_namer   op_namer	   r	   r   parse_tensor_nameb   s    
r+   c               @   s   e Zd ZdZdd Zd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d Zd*ddZd+ddZdd Zdd Zdd  Zd!d" Zd#d$ Zd%d& Zd'd( ZdS ),DebuggerV2EventMultiplexera  A class used for accessing tfdbg v2 DebugEvent data on local filesystem.

    This class is a short-term hack, mirroring the EventMultiplexer for the main
    TensorBoard plugins (e.g., scalar, histogram and graphs.) As such, it only
    implements the methods relevant to the Debugger V2 pluggin.

    TODO(cais): Integrate it with EventMultiplexer and use the integrated class
    from MultiplexerDataProvider for a single path of accessing debugger and
    non-debugger data.
    c             C   s(   || _ d| _t | _d| _|   dS )zConstructor for the `DebugEventMultiplexer`.

        Args:
          logdir: Path to the directory to load the tfdbg v2 data from.
        N)_logdir_readerr   Lock_reader_lock_reload_needed_event_tryCreateReader)selfZlogdirr	   r	   r   __init__y   s
    
z#DebuggerV2EventMultiplexer.__init__c          	   C   s   | j r
dS | j | j syddlm} ddlm} W n tk
rH   dS X y|| j| _ W n& tk
rp   dS  t	k
r   dS X |j
| j tdg| _t| j jt\| _}W dQ R X dS )a*  Try creating reader for tfdbg2 data in the logdir.

        If the reader has already been created, a new one will not be created and
        this function is a no-op.

        If a reader has not been created, create it and start periodic calls to
        `update()` on a separate thread.
        Nr   )debug_events_reader)r   )limit)r.   r0   r!   r5   r   ImportErrorZDebugDataReaderr-   AttributeError
ValueErrorInfNanMonitorDEFAULT_PER_TYPE_ALERT_LIMIT	_monitorsr   updateDEFAULT_RELOAD_INTERVAL_SECr1   )r3   r5   r   _r	   r	   r   r2      s(    	z+DebuggerV2EventMultiplexer._tryCreateReaderc             C   s   | j r| j   dS )a(  If a reader exists and has started period updating, unblock the update.

        The updates are performed periodically with a sleep interval between
        successive calls to the reader's update() method. Calling this method
        interrupts the sleep immediately if one is ongoing.
        N)r1   set)r3   r	   r	   r   _reloadReader   s    z(DebuggerV2EventMultiplexer._reloadReaderc             C   s4   | j dkrtd|tkr*tdt|f | j  S )aW  Return the timestamp of the first DebugEvent of the given run.

        This may perform I/O if no events have been loaded yet for the run.

        Args:
          run: A string name of the run for which the timestamp is retrieved.
            This currently must be hardcoded as `DEFAULT_DEBUGGER_RUN_NAME`,
            as each logdir contains at most one DebugEvent file set (i.e., a
            run of a tfdbg2-instrumented TensorFlow program.)

        Returns:
            The wall_time of the first event of the run, which will be in seconds
            since the epoch as a `float`.
        NzNo tfdbg2 runs exists.z&Expected run name to be %s, but got %s)r.   r9   DEFAULT_DEBUGGER_RUN_NAMEZstarting_wall_time)r3   runr	   r	   r   FirstEventTimestamp   s    
z.DebuggerV2EventMultiplexer.FirstEventTimestampc             C   s   t dd S )NzLDebugDataMultiplexer.PluginRunToTagToContent() has not been implemented yet.)NotImplementedError)r3   Zplugin_namer	   r	   r   PluginRunToTagToContent   s    z2DebuggerV2EventMultiplexer.PluginRunToTagToContentc             C   s*   |    | jr"|   tdg iiS i S dS )a  Return all the tfdbg2 run names in the logdir watched by this instance.

        The `Run()` method of this class is specialized for the tfdbg2-format
        DebugEvent files.

        As a side effect, this method unblocks the underlying reader's period
        reloading if a reader exists. This lets the reader update at a higher
        frequency than the default one with 30-second sleeping period between
        reloading when data is being queried actively from this instance.
        Note that this `Runs()` method is used by all other public data-access
        methods of this class (e.g., `ExecutionData()`, `GraphExecutionData()`).
        Hence calls to those methods will lead to accelerated data reloading of
        the reader.

        Returns:
          If tfdbg2-format data exists in the `logdir` of this object, returns:
              ```
              {runName: { "debugger-v2": [tag1, tag2, tag3] } }
              ```
              where `runName` is the hard-coded string `DEFAULT_DEBUGGER_RUN_NAME`
              string. This is related to the fact that tfdbg2 currently contains
              at most one DebugEvent file set per directory.
          If no tfdbg2-format data exists in the `logdir`, an empty `dict`.
        zdebugger-v2N)r2   r.   rA   rB   )r3   r	   r	   r   Runs   s    
zDebuggerV2EventMultiplexer.Runsc             C   sb   |dk rt d| ||kr0t d||f |dkrR||k rRt d||f |dk r^|}|S )Nr   zInvalid begin index (%d)z!end index (%d) out of bounds (%d)z9end index (%d) is unexpectedly less than begin index (%d))r   InvalidArgumentError)r3   beginendZtotal_countr	   r	   r   _checkBeginEndIndices  s    
z0DebuggerV2EventMultiplexer._checkBeginEndIndicesNc          
   C   s   ddl m} |  }||kr dS g }t }t }	xP| jD ]F}
|
 }|sJq8|| t|
|jrfd}nd}t	|||< ||	|< q8W t	|}|dk	r||krt
d| |	| }| ||t	|}|||||tdd ||| D d	S )
a  Get alerts from the debugged TensorFlow program.

        Args:
          run: The tfdbg2 run to get Alerts from.
          begin: Beginning alert index.
          end: Ending alert index.
          alert_type_filter: Optional filter string for alert type, used to
            restrict retrieved alerts data to a single type. If used,
            `begin` and `end` refer to the beginning and ending indices within
            the filtered alert type.
        r   )r   Nr   Z__MiscellaneousAlert__z8Filtering of alerts failed: alert type %s does not existc             S   s   g | ]}t |qS r	   )r&   ).0r%   r	   r	   r   
<listcomp>Q  s    z5DebuggerV2EventMultiplexer.Alerts.<locals>.<listcomp>)rI   rJ   r   
num_alertsalerts_breakdownZper_type_alert_limitalerts)r!   r   rG   dictr<   rP   extendr"   r:   lenr   rH   rK   r;   )r3   rC   rI   rJ   Zalert_type_filterr   runsrP   rO   Zalerts_by_typeZmonitorZmonitor_alertsr   rN   r	   r	   r   Alerts  s@    
z!DebuggerV2EventMultiplexer.Alertsc             C   sX   |   }||krdS | jjdd}| ||t|}||t|dd ||| D dS )a>  Get ExecutionDigests.

        Args:
          run: The tfdbg2 run to get `ExecutionDigest`s from.
          begin: Beginning execution index.
          end: Ending execution index.

        Returns:
          A JSON-serializable object containing the `ExecutionDigest`s and
          related meta-information
        NT)digestc             S   s   g | ]}|  qS r	   )to_json)rL   rV   r	   r	   r   rM   l  s    z?DebuggerV2EventMultiplexer.ExecutionDigests.<locals>.<listcomp>)rI   rJ   num_digestsexecution_digests)rG   r.   
executionsrK   rS   )r3   rC   rI   rJ   rT   rY   r	   r	   r   ExecutionDigestsT  s    z+DebuggerV2EventMultiplexer.ExecutionDigestsc             C   sh   |   }||krdS | jjdd}| ||t|}||| }| jjd||d}||dd |D dS )	a`  Get Execution data objects (Detailed, non-digest form).

        Args:
          run: The tfdbg2 run to get `ExecutionDigest`s from.
          begin: Beginning execution index.
          end: Ending execution index.

        Returns:
          A JSON-serializable object containing the `ExecutionDigest`s and
          related meta-information
        NT)rV   F)rV   rI   rJ   c             S   s   g | ]}|  qS r	   )rW   )rL   Z	executionr	   r	   r   rM     s    z<DebuggerV2EventMultiplexer.ExecutionData.<locals>.<listcomp>)rI   rJ   rZ   )rG   r.   rZ   rK   rS   )r3   rC   rI   rJ   rT   rY   rZ   r	   r	   r   ExecutionDatap  s    z(DebuggerV2EventMultiplexer.ExecutionDatac             C   sh   |   }||krdS |dk	r$td| jjdd}| ||t|}||t|dd ||| D dS )a`  Get `GraphExecutionTraceDigest`s.

        Args:
          run: The tfdbg2 run to get `GraphExecutionTraceDigest`s from.
          begin: Beginning graph-execution index.
          end: Ending graph-execution index.

        Returns:
          A JSON-serializable object containing the `ExecutionDigest`s and
          related meta-information
        NzFtrace_id support for GraphExecutionTraceDigest is not implemented yet.T)rV   c             S   s   g | ]}|  qS r	   )rW   )rL   rV   r	   r	   r   rM     s    zDDebuggerV2EventMultiplexer.GraphExecutionDigests.<locals>.<listcomp>)rI   rJ   rX   Zgraph_execution_digests)rG   rE   r.   graph_execution_tracesrK   rS   )r3   rC   rI   rJ   trace_idrT   Zgraph_exec_digestsr	   r	   r   GraphExecutionDigests  s    z0DebuggerV2EventMultiplexer.GraphExecutionDigestsc             C   sl   |   }||krdS |dk	r$td| jjdd}| ||t|}| jjd||d}||dd |D d	S )
aT  Get `GraphExecutionTrace`s.

        Args:
          run: The tfdbg2 run to get `GraphExecutionTrace`s from.
          begin: Beginning graph-execution index.
          end: Ending graph-execution index.

        Returns:
          A JSON-serializable object containing the `ExecutionDigest`s and
          related meta-information
        NzDtrace_id support for GraphExecutionTraceData is not implemented yet.T)rV   F)rV   rI   rJ   c             S   s   g | ]}|  qS r	   )rW   )rL   Z
graph_execr	   r	   r   rM     s    zADebuggerV2EventMultiplexer.GraphExecutionData.<locals>.<listcomp>)rI   rJ   graph_executions)rG   rE   r.   r]   rK   rS   )r3   rC   rI   rJ   r^   rT   digestsr`   r	   r	   r   GraphExecutionData  s    z-DebuggerV2EventMultiplexer.GraphExecutionDatac             C   sP   |   }||krdS y| j|}W n" tk
rF   td| Y nX | S )a  Get the information regarding a TensorFlow graph.

        Args:
          run: Name of the run.
          graph_id: Debugger-generated ID of the graph in question.
            This information is available in the return values
            of `GraphOpInfo`, `GraphExecution`, etc.

        Returns:
          A JSON-serializable object containing the information regarding
            the TensorFlow graph.

        Raises:
          NotFoundError if the graph_id is not known to the debugger.
        NzThere is no graph with ID "%s")rG   r.   graph_by_idKeyErrorr   NotFoundErrorrW   )r3   rC   graph_idrT   graphr	   r	   r   	GraphInfo  s    z$DebuggerV2EventMultiplexer.GraphInfoc          
   C   sB  |   }||krdS y| j|}W n" tk
rF   td| Y nX y||}W n& tk
r|   td||f Y nX | ||}xP|d D ]D}y||d }	W n tk
r   d}	Y nX |	r| |	||d< qW x`|d D ]T}
xN|
D ]F}y||d }W n tk
r    d}Y nX |r| |||d< qW qW |S )ab  Get the information regarding a graph op's creation.

        Args:
          run: Name of the run.
          graph_id: Debugger-generated ID of the graph that contains
            the op in question. This ID is available from other methods
            of this class, e.g., the return value of `GraphExecutionDigests()`.
          op_name: Name of the op.

        Returns:
          A JSON-serializable object containing the information regarding
            the op's creation and its immediate inputs and consumers.

        Raises:
          NotFoundError if the graph_id or op_name does not exist.
        NzThere is no graph with ID "%s"z/There is no op named "%s" in graph with ID "%s"inputsr*   data	consumers)rG   r.   rc   rd   r   re   Zget_op_creation_digest_opCreationDigestToDataObject)r3   rC   rf   r*   rT   rg   op_creation_digestZdata_objectZ
input_specZinput_op_digestZslot_consumer_specsZconsumer_specrV   r	   r	   r   GraphOpInfo  sH    


z&DebuggerV2EventMultiplexer.GraphOpInfoc             C   s   |d krd S |  }|d= | |j|d< |j|d< |d= g |d< x2|jpLg D ]$}t|\}}|d ||d qNW g |d< x"t|d D ]}|d g  qW x4||d D ]"\}}	}
|d | |	|
d	 qW |S )
Nrf   	graph_idsnum_outputsinput_namesri   )r*   r   rk   r*   )r*   Z
input_slot)	rW   _getGraphStackIdsrf   rp   rq   r+   appendrangeZget_op_consumers)r3   rm   rg   Zjson_objectZinput_tensor_nameZinput_op_namer   r?   Zsrc_slotZconsumer_op_nameZdst_slotr	   r	   r   rl   '  s*    
z8DebuggerV2EventMultiplexer._opCreationDigestToDataObjectc             C   s>   |g}| j |}x&|jr8|d|j | j |j}qW |S )aL  Retrieve the IDs of all outer graphs of a graph.

        Args:
          graph_id: Id of the graph being queried with respect to its outer
            graphs context.

        Returns:
          A list of graph_ids, ordered from outermost to innermost, including
            the input `graph_id` argument as the last item.
        r   )r.   rc   Zouter_graph_idinsert)r3   rf   ro   rg   r	   r	   r   rr   D  s    z,DebuggerV2EventMultiplexer._getGraphStackIdsc             C   s   |   }||krd S | j S )N)rG   r.   source_file_list)r3   rC   rT   r	   r	   r   SourceFileListV  s    z)DebuggerV2EventMultiplexer.SourceFileListc             C   sd   |   }||krd S y| j | \}}W n" tk
rL   td| Y nX ||| j||dS )Nz(There is no source-code file at index %d)	host_name	file_pathlines)rG   r.   rv   
IndexErrorr   re   Zsource_lines)r3   rC   indexrT   rx   ry   r	   r	   r   SourceLines\  s    z&DebuggerV2EventMultiplexer.SourceLinesc             C   sZ   |   }||krd S g }x8|D ]0}|| jjkr<td| || jj|  qW d|iS )Nz"Cannot find stack frame with ID %sstack_frames)rG   r.   Z_stack_frame_by_idr   re   rs   )r3   rC   Zstack_frame_idsrT   r~   Zstack_frame_idr	   r	   r   StackFramesl  s    

z&DebuggerV2EventMultiplexer.StackFrames)N)N)N)__name__
__module____qualname____doc__r4   r2   rA   rD   rF   rG   rK   rU   r[   r\   r_   rb   rh   rn   rl   rr   rw   r}   r   r	   r	   r	   r   r,   m   s(   
2
+
5
!
#?r,   )r   
__future__r   r   r   r   Ztensorboardr   rB   r;   r>   r   r&   r+   objectr,   r	   r	   r	   r   <module>   s    