U
    VcgS                     @   s  d Z ddl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ZdZd: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 d!Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ Z d0d1 Z!d2d3 Z"d4d5 Z#d6d7 Z$G d8d9 d9ej%Z&dS )=a  An implementation of DataProvider that serves tfdbg v2 data.

This implementation is:
  1. Based on reading data from a DebugEvent file set on the local filesystem.
  2. Implements only the relevant methods for the debugger v2 plugin, including
     - list_runs()
     - read_blob_sequences()
     - read_blob()

This class is a short-term hack. To be used in production, it awaits integration
with a more complete implementation of DataProvider such as
MultiplexerDataProvider.
    N)provider)debug_data_multiplexerzdebugger-v2ZalertsZexecution_digestsZexecution_dataZgraphexec_digestsZgraphexec_dataZ
graph_infoZgraph_op_infoZsource_file_listZsource_fileZstack_framesc                 C   s4   dt ||f }|dk	r"|d| 7 }tj| g|gdS )aQ  Create a RunTagFilter for Alerts.

    Args:
      run: tfdbg2 run name.
      begin: Beginning index of alerts.
      end: Ending index of alerts.
      alert_type: Optional alert type, used to restrict retrieval of alerts
        data to a single type of alerts.

    Returns:
      `RunTagFilter` for the run and range of Alerts.
    %s_%d_%dNz_%srunstags)ALERTS_BLOB_TAG_PREFIXr   RunTagFilter)runbeginend
alert_typetag r   W/tmp/pip-unpacked-wheel-g8kmtpbc/tensorboard/plugins/debugger_v2/debug_data_provider.pyalerts_run_tag_filter2   s    r   c                 C   sh   |  dd\}}|ttd }| dd}t|d }t|d }d}t|dkr\|d }||||fS )a  Parse the BLOB key for Alerts.

    Args:
      blob_key: The BLOB key to parse. By contract, it should have the format:
       - `${ALERTS_BLOB_TAG_PREFIX}_${begin}_${end}.${run_id}` when there is no
         alert type filter.
       - `${ALERTS_BLOB_TAG_PREFIX}_${begin}_${end}_${alert_filter}.${run_id}`
         when there is an alert type filter.

    Returns:
      - run ID
      - begin index
      - end index
      - alert_type: alert type string used to filter retrieved alert data.
          `None` if no filtering is used.
    .   N_      )splitlenr   int)blob_keykey_bodyr
   Z	key_itemsr   r   r   r   r   r   _parse_alerts_blob_keyE   s    r   c                 C   s   t j| gdt||f gdS )a  Create a RunTagFilter for ExecutionDigests.

    This differs from `execution_data_run_tag_filter()` in that it is for
    the small-size digest objects for execution debug events, instead of the
    full-size data objects.

    Args:
      run: tfdbg2 run name.
      begin: Beginning index of ExecutionDigests.
      end: Ending index of ExecutionDigests.

    Returns:
      `RunTagFilter` for the run and range of ExecutionDigests.
    r   r   )r   r	   !EXECUTION_DIGESTS_BLOB_TAG_PREFIXr
   r   r   r   r   r   execution_digest_run_tag_filtera   s    r   c                 C   sN   |  dd\}}|ttd }t| dd }t| dd }|||fS )a  Parse the BLOB key for ExecutionDigests.

    This differs from `_parse_execution_data_blob_key()` in that it is for
    the small-size digest objects for execution debug events, instead of the
    full-size data objects.

    Args:
      blob_key: The BLOB key to parse. By contract, it should have the format:
       `${EXECUTION_DIGESTS_BLOB_TAG_PREFIX}_${begin}_${end}.${run_id}`

    Returns:
      - run ID
      - begin index
      - end index
    r   r   Nr   r   )r   r   r   r   r   r   r
   r   r   r   r   r    _parse_execution_digest_blob_keyv   s
    r!   c                 C   s   t j| gdt||f gdS )a  Create a RunTagFilter for Execution data objects.

    This differs from `execution_digest_run_tag_filter()` in that it is
    for the detailed data objects for execution, instead of the digests.

    Args:
      run: tfdbg2 run name.
      begin: Beginning index of Execution.
      end: Ending index of Execution.

    Returns:
      `RunTagFilter` for the run and range of ExecutionDigests.
    r   r   )r   r	   EXECUTION_DATA_BLOB_TAG_PREFIXr   r   r   r   execution_data_run_tag_filter   s    r#   c                 C   sN   |  dd\}}|ttd }t| dd }t| dd }|||fS )a  Parse the BLOB key for Execution data objects.

    This differs from `_parse_execution_digest_blob_key()` in that it is
    for the deatiled data objects for execution, instead of the digests.

    Args:
      blob_key: The BLOB key to parse. By contract, it should have the format:
       `${EXECUTION_DATA_BLOB_TAG_PREFIX}_${begin}_${end}.${run_id}`

    Returns:
      - run ID
      - begin index
      - end index
    r   r   Nr   r   )r   r   r"   r   r    r   r   r   _parse_execution_data_blob_key   s
    r$   c                 C   s,   |dk	rt dtj| gdt||f gdS )a  Create a RunTagFilter for GraphExecutionTraceDigests.

    This differs from `graph_execution_data_run_tag_filter()` in that it is for
    the small-size digest objects for intra-graph execution debug events, instead
    of the full-size data objects.

    Args:
      run: tfdbg2 run name.
      begin: Beginning index of GraphExecutionTraceDigests.
      end: Ending index of GraphExecutionTraceDigests.

    Returns:
      `RunTagFilter` for the run and range of GraphExecutionTraceDigests.
    NzTtrace_id support for graph_execution_digest_run_tag_filter() is not implemented yet.r   r   )NotImplementedErrorr   r	   'GRAPH_EXECUTION_DIGESTS_BLOB_TAG_PREFIXr
   r   r   Ztrace_idr   r   r   %graph_execution_digest_run_tag_filter   s    r(   c                 C   sN   |  dd\}}|ttd }t| dd }t| dd }|||fS )a  Parse the BLOB key for GraphExecutionTraceDigests.

    This differs from `_parse_graph_execution_data_blob_key()` in that it is for
    the small-size digest objects for intra-graph execution debug events,
    instead of the full-size data objects.

    Args:
      blob_key: The BLOB key to parse. By contract, it should have the format:
       `${GRAPH_EXECUTION_DIGESTS_BLOB_TAG_PREFIX}_${begin}_${end}.${run_id}`

    Returns:
      - run ID
      - begin index
      - end index
    r   r   Nr   r   )r   r   r&   r   r    r   r   r   &_parse_graph_execution_digest_blob_key   s
    r)   c                 C   s,   |dk	rt dtj| gdt||f gdS )a  Create a RunTagFilter for GraphExecutionTrace.

    This method differs from `graph_execution_digest_run_tag_filter()` in that
    it is for full-sized data objects for intra-graph execution events.

    Args:
      run: tfdbg2 run name.
      begin: Beginning index of GraphExecutionTrace.
      end: Ending index of GraphExecutionTrace.

    Returns:
      `RunTagFilter` for the run and range of GraphExecutionTrace.
    NzRtrace_id support for graph_execution_data_run_tag_filter() is not implemented yet.r   r   )r%   r   r	   $GRAPH_EXECUTION_DATA_BLOB_TAG_PREFIXr'   r   r   r   #graph_execution_data_run_tag_filter   s    r+   c                 C   sN   |  dd\}}|ttd }t| dd }t| dd }|||fS )a  Parse the BLOB key for GraphExecutionTrace.

    This method differs from `_parse_graph_execution_digest_blob_key()` in that
    it is for full-sized data objects for intra-graph execution events.

    Args:
      blob_key: The BLOB key to parse. By contract, it should have the format:
       `${GRAPH_EXECUTION_DATA_BLOB_TAG_PREFIX}_${begin}_${end}.${run_id}`

    Returns:
      - run ID
      - begin index
      - end index
    r   r   Nr   r   )r   r   r*   r   r    r   r   r   $_parse_graph_execution_data_blob_key	  s
    r,   c                 C   s(   |st dtj| gdt||f gdS )aw  Create a RunTagFilter for graph op info.

    Args:
      run: tfdbg2 run name.
      graph_id: Debugger-generated ID of the graph. This is assumed to
        be the ID of the graph that immediately encloses the op in question.
      op_name: Name of the op in question. (e.g., "Dense_1/MatMul")

    Returns:
      `RunTagFilter` for the run and range of graph op info.
    #graph_id must not be None or empty.z%s_%s_%sr   )
ValueErrorr   r	   GRAPH_OP_INFO_BLOB_TAG_PREFIX)r
   graph_idop_namer   r   r   graph_op_info_run_tag_filter   s    r2   c                 C   sR   |  d}| |d d }| d| }|ttd }|dd\}}}|||fS )a  Parse the BLOB key for graph op info.

    Args:
      blob_key: The BLOB key to parse. By contract, it should have the format:
       `${GRAPH_OP_INFO_BLOB_TAG_PREFIX}_${graph_id}_${op_name}.${run_name}`,
      wherein
        - `graph_id` is a UUID
        - op_name conforms to the TensorFlow spec:
          `^[A-Za-z0-9.][A-Za-z0-9_.\/>-]*$`
        - `run_name` is assumed to contain no dots (`'.'`s).

    Returns:
      - run name
      - graph_id
      - op name
    r   r   Nr   r   )rindexr   r/   r   )r   Zlast_dot_indexr
   r   r   r0   r1   r   r   r   _parse_graph_op_info_blob_key4  s    
r4   c                 C   s&   |st dtj| gdt|f gdS )zCreate a RunTagFilter for graph info.

    Args:
      run: tfdbg2 run name.
      graph_id: Debugger-generated ID of the graph in question.

    Returns:
      `RunTagFilter` for the run and range of graph info.
    r-   z%s_%sr   )r.   r   r	   GRAPH_INFO_BLOB_TAG_PREFIX)r
   r0   r   r   r   graph_info_run_tag_filterO  s    
r6   c                 C   s*   |  d\}}|ttd d }||fS )zParse the BLOB key for graph info.

    Args:
      blob_key: The BLOB key to parse. By contract, it should have the format:
       `${GRAPH_INFO_BLOB_TAG_PREFIX}_${graph_id}.${run_name}`,

    Returns:
      - run name
      - graph_id
    r   r   N)r   r   r5   )r   r   r
   r0   r   r   r   _parse_graph_info_blob_keya  s    r7   c                 C   s   t j| gtgdS )zCreate a RunTagFilter for listing source files.

    Args:
      run: tfdbg2 run name.

    Returns:
      `RunTagFilter` for listing the source files in the tfdbg2 run.
    r   )r   r	   SOURCE_FILE_LIST_BLOB_TAG)r
   r   r   r   source_file_list_run_tag_filterq  s    	r9   c                 C   s   | |  dd d S )zParse the BLOB key for source file list.

    Args:
      blob_key: The BLOB key to parse. By contract, it should have the format:
       `${SOURCE_FILE_LIST_BLOB_TAG}.${run_id}`

    Returns:
      - run ID
    r   r   N)indexr   r   r   r    _parse_source_file_list_blob_key}  s    
r<   c                 C   s   t j| gdt|f gdS )a  Create a RunTagFilter for listing source files.

    Args:
      run: tfdbg2 run name.
      index: The index for the source file of which the content is to be
        accessed.

    Returns:
      `RunTagFilter` for accessing the content of the source file.
    z%s_%dr   )r   r	   SOURCE_FILE_BLOB_TAG_PREFIX)r
   r:   r   r   r   source_file_run_tag_filter  s    r>   c                 C   s0   |  dd\}}t|ttd d }||fS )a  Parse the BLOB key for accessing the content of a source file.

    Args:
      blob_key: The BLOB key to parse. By contract, it should have the format:
       `${SOURCE_FILE_BLOB_TAG_PREFIX}_${index}.${run_id}`

    Returns:
      - run ID, as a str.
      - File index, as an int.
    r   r   N)r   r   r   r=   )r   r   r
   r:   r   r   r   _parse_source_file_blob_key  s    r?   c                 C   s    t j| gtd d| gdS )zCreate a RunTagFilter for querying stack frames.

    Args:
      run: tfdbg2 run name.
      stack_frame_ids: The stack_frame_ids being requested.

    Returns:
      `RunTagFilter` for accessing the content of the source file.
    r   r   )r   r	   STACK_FRAMES_BLOB_TAG_PREFIXjoin)r
   stack_frame_idsr   r   r   stack_frames_run_tag_filter  s    
rC   c                 C   s6   |  dd\}}|ttd d }| d}||fS )aB  Parse the BLOB key for source file list.

    Args:
      blob_key: The BLOB key to parse. By contract, it should have the format:
       `${STACK_FRAMES_BLOB_TAG_PREFIX}_` +
       `${stack_frame_id_0}_..._${stack_frame_id_N}.${run_id}`

    Returns:
      - run ID
      - The stack frame IDs as a tuple of strings.
    r   r   Nr   )r   r   r@   )r   r   r
   rB   r   r   r   _parse_stack_frames_blob_key  s    
rD   c                       s   e Zd ZdZ fddZdddZdd Zddd	d
dZddddddZddd	ddZ	ddddddZ
dddZ  ZS )LocalDebuggerV2DataProviderzA DataProvider implementation for tfdbg v2 data on local filesystem.

    In this implementation, `experiment_id` is assumed to be the path to the
    logdir that contains the DebugEvent file set.
    c                    s   t t|   t|| _dS )zConstructor of LocalDebuggerV2DataProvider.

        Args:
          logdir: Path to the directory from which the tfdbg v2 data will be
            loaded.
        N)superrE   __init__r   ZDebuggerV2EventMultiplexer_multiplexer)selfZlogdir	__class__r   r   rG     s    z$LocalDebuggerV2DataProvider.__init__Nc                   s    fdd j  D S )zList runs available.

        Args:
          experiment_id: currently unused, because the backing
            DebuggerV2EventMultiplexer does not accommodate multiple experiments.

        Returns:
          Run names as a list of str.
        c                    s"   g | ]}t j|| |d qS ))Zrun_idrun_name
start_time)r   ZRun_get_first_event_timestamp).0r
   rI   r   r   
<listcomp>  s   z9LocalDebuggerV2DataProvider.list_runs.<locals>.<listcomp>)rH   Runs)rI   ctxexperiment_idr   rP   r   	list_runs  s    

z%LocalDebuggerV2DataProvider.list_runsc              
   C   s<   z| j |W S  tk
r6 } z
W Y d S d }~X Y nX d S N)rH   ZFirstEventTimestampr.   )rI   rL   er   r   r   rN     s    z6LocalDebuggerV2DataProvider._get_first_event_timestamp)run_tag_filterc                C   s   ~~~t dd S Nz1Debugger V2 DataProvider doesn't support scalars.	TypeErrorrI   rS   rT   plugin_namerX   r   r   r   list_scalars  s    z(LocalDebuggerV2DataProvider.list_scalars)
downsamplerX   c                C   s   ~~~~t dd S rY   rZ   )rI   rS   rT   r]   r_   rX   r   r   r   read_scalars  s    	z(LocalDebuggerV2DataProvider.read_scalarsc                C   s   ~~~t  d S rV   )r%   r\   r   r   r   list_blob_sequences  s    z/LocalDebuggerV2DataProvider.list_blob_sequencesc          
      C   s   ~~|t krtd| |jd kr*td|jd kr<tdt }| j }|jD ]h}||kr`qRt ||< |jD ]H}	|	tt	t
ttttttf	s|	tfkrptjd|	|f dg|| |	< qpqR|S )NzUnsupported plugin_name: %sz<run_tag_filter.runs is expected to be specified, but is not.z<run_tag_filter.tags is expected to be specified, but is not.z%s.%sr;   )PLUGIN_NAMEr.   r   r   dictrH   rR   
startswithr   r   r"   r&   r*   r5   r/   r=   r@   r8   r   ZBlobReference)
rI   rS   rT   r]   r_   rX   outputZexisting_runsr
   r   r   r   r   read_blob_sequences  sF    	





z/LocalDebuggerV2DataProvider.read_blob_sequencesc                C   s  | tr4t|\}}}}t| jj||||dS | trbt|\}}}t| j	|||S | t
rt|\}}}t| j|||S | trt|\}}}t| j|||S | trt|\}}}t| j|||S | trt|\}}t| j||S | trHt|\}}}t| j|||S | trnt|}t| j|S | trt|\}}	t| j||	S | trt |\}}
t| j!||
S t"d| d S )N)Zalert_type_filterzUnrecognized blob_key: %s)#rd   r   r   jsondumpsrH   ZAlertsr   r!   ZExecutionDigestsr"   r$   ZExecutionDatar&   r)   ZGraphExecutionDigestsr*   r,   ZGraphExecutionDatar5   r7   Z	GraphInfor/   r4   ZGraphOpInfor8   r<   ZSourceFileListr=   r?   ZSourceLinesr@   rD   ZStackFramesr.   )rI   rS   r   r
   r   r   r   r0   r1   r:   rB   r   r   r   	read_blobB  s`    
   



z%LocalDebuggerV2DataProvider.read_blob)N)N)N)N)N)N)__name__
__module____qualname____doc__rG   rU   rN   r^   r`   ra   rf   ri   __classcell__r   r   rJ   r   rE     s.   
   	 .rE   )N)N)N)'rm   rg   Ztensorboard.datar   Ztensorboard.plugins.debugger_v2r   rb   r   r   r"   r&   r*   r5   r/   r8   r=   r@   r   r   r   r!   r#   r$   r(   r)   r+   r,   r2   r4   r6   r7   r9   r<   r>   r?   rC   rD   ZDataProviderrE   r   r   r   r   <module>   sF   


