storage.py 9.9 KB
Newer Older
J
Jeff Wang 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
# Copyright (c) 2017 VisualDL Authors. All Rights Reserve.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# =======================================================================

Y
Yan Chunwei 已提交
16 17 18
from __future__ import absolute_import

from visualdl import core
S
superjom 已提交
19 20

dtypes = ("float", "double", "int32", "int64")
J
Jeff Wang 已提交
21
EMBEDDING_TAG = 'embedding'
S
superjom 已提交
22

T
Thuan Nguyen 已提交
23

Y
Yan Chunwei 已提交
24 25
def check_tag_name_valid(tag):
    assert '%' not in tag, "character % is a reserved word, it is not allowed in tag."
J
Jeff Wang 已提交
26
    assert tag != EMBEDDING_TAG, "embedding is a reserved word, it is not allowed in tag."
Y
Yan Chunwei 已提交
27

T
Thuan Nguyen 已提交
28

Y
Yan Chunwei 已提交
29 30 31
def check_mode_name_valid(tag):
    for char in ['%', '/']:
        assert char not in tag, "character %s is a reserved word, it is not allowed in mode." % char
S
superjom 已提交
32

T
Thuan Nguyen 已提交
33

34
class LogReader(object):
Q
Qiao Longfei 已提交
35
    """LogReader is a Python wrapper to read and analysis the data that
36
    saved with data format defined in storage.proto. A User can get
Q
Qiao Longfei 已提交
37 38 39
    Scalar Reader/Image Reader/Histogram Reader from this module and use
    them to reade the data you need.
    """
S
superjom 已提交
40

S
superjom 已提交
41
    def __init__(self, dir, reader=None):
Q
Qiao Longfei 已提交
42 43 44 45 46
        """
        create a LogReader
        :param dir: the dir where log file is.
        :param reader: create a new LogReader with a formal one
        """
S
superjom 已提交
47
        self.dir = dir
48
        self.reader = reader if reader else core.LogReader(dir)
S
superjom 已提交
49

S
superjom 已提交
50
    def mode(self, mode):
Q
Qiao Longfei 已提交
51 52 53
        """
        Set the current mode of reader.

54 55 56 57
        :param mode: The log reader will read the data grouped by mode.
        :type mode: basestring
        :return: the log reader itself
        :rtype: LogReader
Q
Qiao Longfei 已提交
58
        """
Y
Yan Chunwei 已提交
59
        check_mode_name_valid(mode)
S
superjom 已提交
60 61
        self.reader.set_mode(mode)
        return self
S
superjom 已提交
62

S
superjom 已提交
63
    def as_mode(self, mode):
Q
Qiao Longfei 已提交
64 65
        """
        create a new LogReader with mode and return it to user.
66 67 68 69 70

        :param mode: The log reader will read the data grouped by mode.
        :type mode: basestring
        :return: a new log reader instance
        :rtype: LogReader
Q
Qiao Longfei 已提交
71
        """
Y
Yan Chunwei 已提交
72
        check_mode_name_valid(mode)
73
        tmp = LogReader(dir, self.reader.as_mode(mode))
S
superjom 已提交
74 75 76
        return tmp

    def modes(self):
Q
Qiao Longfei 已提交
77 78
        """
        Get all modes of the log file
79 80 81

        :return: a list of all modes
        :rtype: list
Q
Qiao Longfei 已提交
82
        """
S
superjom 已提交
83 84
        return self.reader.modes()

Q
Qiao Longfei 已提交
85 86 87
    def tags(self, component):
        """
        Get all tags from the current log file for one kind of component
88 89

        :param component:  scalar|histogram|image
Q
Qiao Longfei 已提交
90
        :return: all the tags
91
        :type: list
Q
Qiao Longfei 已提交
92 93
        """
        return self.reader.tags(component)
S
superjom 已提交
94 95

    def scalar(self, tag, type='float'):
Q
Qiao Longfei 已提交
96 97
        """
        Get a scalar reader with tag and data type
98 99 100

        :param tag:  The reader will read the scalar data marked with tag
        :type tag: basestring
Q
Qiao Longfei 已提交
101
        """
Y
Yan Chunwei 已提交
102
        check_tag_name_valid(tag)
S
superjom 已提交
103 104 105 106 107 108 109
        type2scalar = {
            'float': self.reader.get_scalar_float,
            'double': self.reader.get_scalar_double,
            'int': self.reader.get_scalar_int,
        }
        return type2scalar[type](tag)

S
superjom 已提交
110
    def image(self, tag):
Q
Qiao Longfei 已提交
111 112
        """
        Get a image reader with tag
113 114 115

        :param tag:  The reader will read the image data marked with tag
        :type tag: basestring
Q
Qiao Longfei 已提交
116
        """
Y
Yan Chunwei 已提交
117
        check_tag_name_valid(tag)
S
superjom 已提交
118 119
        return self.reader.get_image(tag)

120
    def histogram(self, tag, type='float'):
Q
Qiao Longfei 已提交
121 122
        """
        Get a histogram reader with tag and data type
123 124 125

        :param tag:  The reader will read the histogram data marked with tag
        :type tag: basestring
Q
Qiao Longfei 已提交
126
        """
127 128 129 130 131
        type2scalar = {
            'float': self.reader.get_histogram_float,
            'double': self.reader.get_histogram_double,
            'int': self.reader.get_histogram_int,
        }
Y
Yan Chunwei 已提交
132
        check_tag_name_valid(tag)
133 134
        return type2scalar[type](tag)

J
Jeff Wang 已提交
135
    def text(self, tag):
J
Jeff Wang 已提交
136 137 138 139 140 141
        """
        Get a text reader with tag

        :param tag:  The reader will read the text data marked with tag
        :type tag: basestring
        """
J
Jeff Wang 已提交
142 143 144
        check_tag_name_valid(tag)
        return self.reader.get_text(tag)

J
Jeff Wang 已提交
145
    def embedding(self):
J
Jeff Wang 已提交
146 147 148
        """
        Get the embedding reader.
        """
J
Jeff Wang 已提交
149
        return self.reader.get_embedding(EMBEDDING_TAG)
J
Jeff Wang 已提交
150

N
Nicky Chan 已提交
151 152 153 154 155 156 157 158 159 160
    def audio(self, tag):
        """
        Get an audio reader with tag

        :param tag:  The reader will read the audio data marked with tag
        :type tag: basestring
        """
        check_tag_name_valid(tag)
        return self.reader.get_audio(tag)

S
superjom 已提交
161
    def __enter__(self):
S
superjom 已提交
162
        return self
S
superjom 已提交
163 164

    def __exit__(self, type, value, traceback):
S
superjom 已提交
165
        self.reader.set_mode("default")
S
superjom 已提交
166

S
superjom 已提交
167

168
class LogWriter(object):
Q
Qiao Longfei 已提交
169
    """LogWriter is a Python wrapper to write data to log file with the data
170
    format defined in storage.proto. A User can get Scalar Reader/Image Reader/
Q
Qiao Longfei 已提交
171
    Histogram Reader from this module and use them to write the data to log file.
J
Jeff Wang 已提交
172 173 174 175 176 177 178 179 180

    :param dir: The directory path to the saved log files.
    :type dir: basestring
    :param sync_cycle: Specify how often should the system store data into the file system.
        Typically adding a record requires 6 operations.
        System will save the data into the file system once operations count reaches sync_cycle.
    :type sync_cycle: integer
    :return: a new LogWriter instance
    :rtype: LogWriter
Q
Qiao Longfei 已提交
181
    """
S
superjom 已提交
182

S
superjom 已提交
183 184
    cur_mode = None

S
superjom 已提交
185 186 187
    def __init__(self, dir, sync_cycle, writer=None):
        self.dir = dir
        self.sync_cycle = sync_cycle
188
        self.writer = writer if writer else core.LogWriter(dir, sync_cycle)
S
superjom 已提交
189

S
superjom 已提交
190
    def mode(self, mode):
191 192 193 194 195 196 197 198
        """
        Set the current mode of writer.

        :param mode: The logger will group data under mode.
        :type mode: basestring
        :return: a new LogWriter instance with mode
        :rtype: LogWriter
        """
Y
Yan Chunwei 已提交
199
        check_mode_name_valid(mode)
S
superjom 已提交
200 201
        self.writer.set_mode(mode)
        return self
S
superjom 已提交
202

S
superjom 已提交
203
    def as_mode(self, mode):
Q
Qiao Longfei 已提交
204 205
        """
        create a new LogWriter with mode and return it.
206 207 208 209 210

        :param mode: The logger will group data under mode.
        :type mode: basestring
        :return: the logWriter itself
        :rtype: LogWriter
Q
Qiao Longfei 已提交
211
        """
Y
Yan Chunwei 已提交
212
        check_mode_name_valid(mode)
T
Thuan Nguyen 已提交
213 214
        LogWriter.cur_mode = LogWriter(self.dir, self.sync_cycle,
                                       self.writer.as_mode(mode))
215
        return LogWriter.cur_mode
S
superjom 已提交
216 217

    def scalar(self, tag, type='float'):
Q
Qiao Longfei 已提交
218 219
        """
        Create a scalar writer with tag and type to write scalar data.
220 221 222

        :param tag: The scalar writer will label the data with tag
        :type tag: basestring
223 224
        :return: A scalar writer to handle step and value records
        :rtype: ScalarWriter
Q
Qiao Longfei 已提交
225
        """
Y
Yan Chunwei 已提交
226
        check_tag_name_valid(tag)
S
superjom 已提交
227 228 229 230 231 232
        type2scalar = {
            'float': self.writer.new_scalar_float,
            'double': self.writer.new_scalar_double,
            'int': self.writer.new_scalar_int,
        }
        return type2scalar[type](tag)
S
superjom 已提交
233

Y
Yan Chunwei 已提交
234
    def image(self, tag, num_samples, step_cycle=1):
Q
Qiao Longfei 已提交
235 236
        """
        Create an image writer that used to write image data.
237 238 239

        :param tag: The image writer will label the image with tag
        :type tag: basestring
240 241 242 243 244 245
        :param num_samples: how many samples to take in a step.
        :type num_samples: integer
        :param step_cycle: store every `step_cycle` as a record.
        :type step_cycle: integer
        :return: A image writer to sample images
        :rtype: ImageWriter
Q
Qiao Longfei 已提交
246
        """
Y
Yan Chunwei 已提交
247
        check_tag_name_valid(tag)
S
superjom 已提交
248
        return self.writer.new_image(tag, num_samples, step_cycle)
S
superjom 已提交
249

250
    def histogram(self, tag, num_buckets, type='float'):
Q
Qiao Longfei 已提交
251 252 253
        """
        Create a histogram writer that used to write
        histogram related data.
254 255 256

        :param tag: The histogram writer will label the data with tag
        :type tag: basestring
257 258
        :return: A histogram writer to record distribution
        :rtype: HistogramWriter
Q
Qiao Longfei 已提交
259
        """
Y
Yan Chunwei 已提交
260
        check_tag_name_valid(tag)
261 262 263 264 265 266 267
        types = {
            'float': self.writer.new_histogram_float,
            'double': self.writer.new_histogram_double,
            'int': self.writer.new_histogram_int,
        }
        return types[type](tag, num_buckets)

N
Nicky Chan 已提交
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283
    def audio(self, tag, num_samples, step_cycle=1):
        """
        Create an audio writer that used to write audio data.

        :param tag: The audio writer will label the audio with tag
        :type tag: basestring
        :param num_samples: how many samples to take in a step.
        :type num_samples: integer
        :param step_cycle: store every `step_cycle` as a record.
        :type step_cycle: integer
        :return: A audio writer to sample audio
        :rtype: AudioWriter
        """
        check_tag_name_valid(tag)
        return self.writer.new_audio(tag, num_samples, step_cycle)

J
Jeff Wang 已提交
284
    def text(self, tag):
J
Jeff Wang 已提交
285 286 287 288 289 290 291 292 293
        """
        Create a text writer that used to write
        text related data.

        :param tag: The text writer will label the data with tag
        :type tag: basestring
        :return: A text writer to record distribution
        :rtype: TextWriter
        """
J
Jeff Wang 已提交
294 295 296
        check_tag_name_valid(tag)
        return self.writer.new_text(tag)

J
Jeff Wang 已提交
297
    def embedding(self):
J
Jeff Wang 已提交
298 299 300 301 302 303 304
        """
        Create an embedding writer that is used to write
        embedding data.

        :return: An embedding writer to record embedding data
        :rtype: embeddingWriter
        """
J
Jeff Wang 已提交
305
        return self.writer.new_embedding(EMBEDDING_TAG)
J
Jeff Wang 已提交
306

J
Jeff Wang 已提交
307
    def save(self):
J
Jeff Wang 已提交
308 309 310
        """
        Force the VisualDL to sync with the file system.
        """
J
Jeff Wang 已提交
311 312
        self.writer.save()

S
superjom 已提交
313
    def __enter__(self):
S
superjom 已提交
314
        return self
S
superjom 已提交
315 316

    def __exit__(self, type, value, traceback):
S
superjom 已提交
317
        self.writer.set_mode("default")