a
    d=icK                     @   s&  d Z ddlZddlZddlZddlZddlZddlZddlZddlZddl	Z
ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ dd	lmZ eejej d
 ZdZdZdZdZdZdZdZdZ dZ!e" Z#G dd de$Z%dddZ&G dd de'Z(G dd de)Z*dd Z+dS )z/Downloads experiment data from TensorBoard.dev.    N)blob_pb2)experiment_pb2)export_service_pb2)util)	grpc_util)
tb_logging)tensor_utilz-_l    zmetadata.jsonzscalars.jsonztensors.jsonzblob_sequences.jsontensorsZblobsZblob_z.binc                   @   sZ   e Zd Z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dS )TensorBoardExportera  Exports all of the user's experiment data from TensorBoard.dev.

    Data is exported into a directory, with one file per experiment. Each
    experiment file is a sequence of time series, represented as a stream
    of JSON objects, one per line. Each JSON object includes a run name,
    tag name, `tensorboard.compat.proto.summary_pb2.SummaryMetadata` proto
    (base64-encoded, standard RFC 4648 alphabet), and set of points.
    Points are stored in three equal-length lists of steps, wall times (as
    seconds since epoch), and scalar values, for storage efficiency.

    Such streams of JSON objects may be conveniently processed with tools
    like jq(1).

    For example one line of an experiment file might read (when
    pretty-printed):

        {
          "points": {
            "steps": [0, 5],
            "values": [4.8935227394104, 2.5438034534454346],
            "wall_times": [1563406522.669238, 1563406523.0268838]
          },
          "run": "lr_1E-04,conv=1,fc=2",
          "summary_metadata": "CgkKB3NjYWxhcnMSC3hlbnQveGVudF8x",
          "tag": "xent/xent_1"
        }

    This is a time series with two points, both logged on 2019-07-17, one
    about 0.36 seconds after the other.
    c              
   C   sx   || _ || _tj| j}|r,tj|dd zt| j W n6 tyr } z|jtj	kr^t
 W Y d}~n
d}~0 0 dS )a`  Constructs a TensorBoardExporter.

        Args:
          reader_service_client: A TensorBoardExporterService stub instance.
          output_directory: Path to a directory into which to write data. The
            directory must not exist, to avoid stomping existing or concurrent
            output. Its ancestors will be created if needed.
        T)exist_okN)_api_outdirospathdirnamemakedirsmkdirOSErrorerrnoEEXISTOutputDirectoryExistsError)selfZreader_service_clientZoutput_directory
parent_dire r   n/home/droni/.local/share/virtualenvs/DPS-5Je3_V2c/lib/python3.9/site-packages/tensorboard/uploader/exporter.py__init__i   s    	zTensorBoardExporter.__init__Nc                 #   s  |du rt   }tjddddd}t| j||d}|D ]}|j}|j|jt	|j
t	|jd}t| j| t  tj t}t|d*}tj||dd |d W d   n1 s0    Y  z| ||}	t  fd	d
tttfD }
ttj t ttj t |	D ]4\}}|
| }tj||dd |d |  q*|V  W d   n1 s|0    Y  W q6 t j!y } z*|" t j#j$krt%|n W Y d}~q6d}~0 0 q6dS )ae  Executes the export flow.

        Args:
          read_time: A fixed timestamp from which to export data, as float seconds
            since epoch (like `time.time()`). Optional; defaults to the current
            time.

        Yields:
          After each experiment is successfully downloaded, the ID of that
          experiment, as a string.
        NT)create_timeupdate_timenamedescription)	fieldmask	read_time)r   r    r   r   x)	sort_keys
c              
      s(   i | ] }| ttj |d qS )r#   )enter_contextopenr   r   join).0filenameexperiment_dirstackr   r   
<dictcomp>   s   z.TensorBoardExporter.export.<locals>.<dictcomp>)&timer   ZExperimentMasklist_experimentsr   experiment_idr   r    r   Zformat_time_absoluter   r   _experiment_directoryr   r   r   r   r(   _FILENAME_METADATAr'   jsondumpwrite_request_json_data
contextlib	ExitStack_FILENAME_SCALARS_FILENAME_TENSORS_FILENAME_BLOB_SEQUENCES_DIRNAME_TENSORS_DIRNAME_BLOBSflushgrpcRpcErrorcodeZ
StatusCode	CANCELLEDGrpcTimeoutException)r   r"   Zexperiment_metadata_maskexperiments
experimentr1   Zexperiment_metadataZmetadata_filepathoutfiledataZfile_handlesblockr*   r   r   r+   r   export~   sb    


(


*
zTensorBoardExporter.exportc           	      c   s   t  }||_t|j| | jj|t	 d}|D ]}t
|j d}|j|j|d}d}|dr| |j|d< t}nB|dr| |j||d< t}n |dr| |j||d< t}|r4||fV  q4dS )a3  Given experiment id, generates JSON data and destination file name.

        The JSON data describes the run, tag, metadata, in addition to
          - Actual data in the case of scalars
          - Pointer to binary files in the case of blob sequences.

        For the case of blob sequences, this method has the side effect of
          downloading the contents of the blobs and writing them to files in
          a subdirectory of the experiment directory.

        Args:
          experiment_id: The id of the experiment to request data for.
          read_time: A fixed timestamp from which to export data, as float
            seconds since epoch (like `time.time()`). Optional; defaults to the
            current time.

        Yields:
          (JSON-serializable data, destination file name) tuples.
        metadataascii)runtagZsummary_metadataNpointsr	   blob_sequences)r   ZStreamExperimentDataRequestr1   r   set_timestampread_timestampr   ZStreamExperimentDatar   version_metadatabase64	b64encodeZtag_metadataZSerializeToStringdecoderun_nameZtag_nameZHasField_process_scalar_pointsrP   r:   _process_tensor_pointsr	   r;   _process_blob_sequence_pointsrQ   r<   )	r   r1   r"   requeststreamresponserL   Z	json_datar*   r   r   r   r7      sD    


z&TensorBoardExporter._request_json_datac                 C   s(   dd |j D }t|j|t|jdS )a  Process scalar data points.

        Args:
          points: `export_service_pb2.StreamExperimentDataResponse.ScalarPoints`
            proto.

        Returns:
          A JSON-serializable `dict` for the steps, wall_times and values of the
            scalar data points.
        c                 S   s   g | ]}|  d  qS g    eAZToNanosecondsr)   tr   r   r   
<listcomp>      z>TensorBoardExporter._process_scalar_points.<locals>.<listcomp>)steps
wall_timesvalues)rf   listre   rg   )r   rP   rf   r   r   r   rY      s
    z*TensorBoardExporter._process_scalar_pointsc                    s   dd |j D }t|j|dd}|d s.|S t j|} ||d d }dd |jD } fd	d|D }tjt	j
||g|R   ||d
< |S )a  Process tensor data points.

        Args:
          points: `export_service_pb2.StreamExperimentDataResponse.TensorPoints`
            proto.
          experiment_id: ID of the experiment that the `TensorPoints` is a part
            of.

        Returns:
          A JSON-serializable `dict` for the steps, wall_times and the path to
            the .npz files that contain the saved tensor values.
        c                 S   s   g | ]}|  d  qS r_   r`   ra   r   r   r   rc     rd   z>TensorBoardExporter._process_tensor_points.<locals>.<listcomp>N)re   rf   tensors_file_pathre   rf   r   c                 S   s   g | ]}t |qS r   )r   Zmake_ndarray)r)   Ztensor_protor   r   r   rc   +  s   c                    s   g | ]}  |qS r   )_fix_string_types)r)   r#   r   r   r   rc   /  rd   ri   )rf   rh   re   r2   r   _get_tensor_file_pathrg   npZsavezr   r   r(   )r   rP   r1   rf   json_objectr,   ri   Zndarraysr   rk   r   rZ     s$    z*TensorBoardExporter._process_tensor_pointsc                 C   s   |j tjkr|S |dS dS )a%  Change the dtype of text arrays to String rather than Object.

        np.savez ends up pickling np.object arrays, while it doesn't pickle
        strings.  The downside is that it needs to pad the length of each string
        in the array to the maximal length string.  We only want to do this
        type override in this final step of the export path.

        Args:
          ndarray: a tensor converted to an ndarray

        Returns:
          The original ndarray if not np.object, dtype converted to String
          if np.object.
        z|SN)Zdtyperm   Zobject_Zastype)r   Zndarrayr   r   r   rj   4  s    z%TensorBoardExporter._fix_string_typesc                 C   sR   d}t jtd| |rd| nd d }t jt j||sD|S |d7 }qdS )a#  Get a nonexistent path for a tensor value.

        Args:
          experiment_dir: Experiment directory.
          wall_time: Timestamp of the tensor (seconds since the epoch in double).

        Returns:
          A nonexistent path for the tensor, relative to the experiemnt_dir.
        r   z%.6fz_%d z.npz   N)r   r   r(   r=   exists)r   r,   Z	wall_timeindexZtensor_file_pathr   r   r   rl   H  s    
z)TensorBoardExporter._get_tensor_file_pathc           
      C   s   dd |j D }t|j|g d}|d }|jD ]T}g }|jD ]:}|jjtjj	krn| 
|jj|}	||	 q>|d q>|| q0|S )aA  Process blob sequence points.

        As a side effect, also downloads the binary contents of the blobs
        to respective files. The paths to the files relative to the
        experiment directory is encapsulated in the returned JSON object.

        Args:
          blob_sequences:
            `export_service_pb2.StreamDataResponse.BlobSequencePoints` proto.

        Returns:
          A JSON-serializable `dict` for the steps and wall_times, as well as
            the blob_file_paths, which are the relative paths to the downloaded
            blob contents.
        c                 S   s   g | ]}|  d  qS r_   r`   ra   r   r   r   rc   n  s   zETensorBoardExporter._process_blob_sequence_points.<locals>.<listcomp>)re   rf   blob_file_pathsrs   N)rf   rh   re   rg   entriesZblobstater   Z	BlobStateZBLOB_STATE_CURRENT_download_blobblob_idappend)
r   rQ   r1   rf   rn   rs   ZblobseqZseq_blob_file_pathsentryZ	blob_pathr   r   r   r[   ^  s&    

z1TensorBoardExporter._process_blob_sequence_pointsc           	      C   s   t | j|}tj|d}tj|tt| t	 }t
|d~}z*| jj|t dD ]}||j qRW nB tjy } z(td|| W Y d}~W d   dS d}~0 0 W d   n1 s0    Y  tj||S )ah  Download the blob via rpc.

        Args:
          blob_id: Id of the blob.
          experiment_id: Id of the experiment that the blob belongs to.

        Returns:
          If the blob is downloaded successfully:
            The path of the downloaded blob file relative to the experiment
            directory.
          Else:
            `None`.
        )rw   xbrK   z2Omitting blob (id: %s) due to download failure: %sN)r2   r   r   ZStreamBlobDataRequestr   r   r(   r>   _FILENAME_BLOBS_PREFIX_FILENAME_BLOBS_SUFFIXr'   r   ZStreamBlobDatar   rT   r6   rH   r@   rA   loggererrorrelpath)	r   rw   r1   r,   r\   Zblob_abspathfr^   Z	rpc_errorr   r   r   rv     s*    

Bz"TensorBoardExporter._download_blob)N)__name__
__module____qualname____doc__r   rJ   r7   rY   rZ   rj   rl   r[   rv   r   r   r   r   r
   I   s   
F<"&r
   c                 c   s   |du rt   }tjtd}t|j| |r:|j| | j	|t
 d}|D ]F}|jrn|jD ]
}|V  q`qP|jrtdt|jf qPtd| qPdS )ac  Yields all of the calling user's experiments.

    Args:
      api_client: A TensorBoardExporterService stub instance.
      fieldmask: An optional `experiment_pb2.ExperimentMask` value.
      read_time: A fixed timestamp from which to export data, as float seconds
        since epoch (like `time.time()`). Optional; defaults to the current
        time.

    Yields:
      For each experiment owned by the user, an `experiment_pb2.Experiment`
      value.

    Raises:
      RuntimeError: If the server returns experiment IDs but no experiments,
        as in an old, unsupported version of the protocol.
    N)limitrK   z4Server sent experiment_ids without experiments: <%r>zAStreamExperiments RPC returned response with no experiments: <%r>)r/   r   ZStreamExperimentsRequest
_MAX_INT64r   rR   rS   Zexperiments_maskZCopyFromZStreamExperimentsr   rT   rE   Zexperiment_idsRuntimeErrorrh   r}   warning)Z
api_clientr!   r"   r\   r]   r^   rF   r   r   r   r0     s.    


r0   c                   @   s   e Zd ZdS )r   N)r   r   r   r   r   r   r   r     s   r   c                       s   e Zd Z fddZ  ZS )rD   c                    s   t t| | || _d S )N)superrD   r   r1   )r   r1   	__class__r   r   r     s    zGrpcTimeoutException.__init__)r   r   r   r   __classcell__r   r   r   r   rD     s   rD   c                 C   s8   t |t }|r&tdjt||dtj| d| S )Nz>Unexpected characters ({bad_chars!r}) in experiment ID {eid!r})	bad_charsZeidzexperiment_%s)	frozenset_FILENAME_SAFE_CHARSr   formatsortedr   r   r(   )base_dirr1   r   r   r   r   r2     s    r2   )NN),r   rU   r8   r   r@   r4   r   stringr/   numpyrm   Ztensorboard.uploader.protor   r   r   Ztensorboard.uploaderr   Ztensorboard.utilr   r   r   r   ascii_lettersdigitsr   r   r3   r:   r;   r<   r=   r>   r{   r|   Z
get_loggerr}   objectr
   r0   
ValueErrorr   	ExceptionrD   r2   r   r   r   r   <module>   sD     d
,