提交 71686318 编写于 作者: Y Yan Chunwei 提交者: GitHub

Merge pull request #50 from ChunweiYan/feature/support_pytorch_demo

import onnx
import json
from google.protobuf.json_format import MessageToJson
import onnx
def reorganize_inout(json_obj, key):
"""
......
import pprint
import random
import re
import urllib
from tempfile import NamedTemporaryFile
......@@ -22,13 +23,13 @@ def get_scalar_tags(storage, mode):
result[mode] = {}
for tag in tags:
result[mode][tag] = {
'displayName': reader.scalar(tag).caption(),
'displayName': tag,
'description': "",
}
return result
def get_scalar(storage, mode, tag):
def get_scalar(storage, mode, tag, num_records=100):
with storage.mode(mode) as reader:
scalar = reader.scalar(tag)
......@@ -36,8 +37,12 @@ def get_scalar(storage, mode, tag):
ids = scalar.ids()
timestamps = scalar.timestamps()
result = zip(timestamps, ids, records)
return result
data = zip(timestamps, ids, records)
if len(data) <= num_records:
return data
samples = sorted(random.sample(xrange(len(data)), num_records))
return [data[i] for i in samples]
def get_image_tags(storage):
......@@ -77,7 +82,9 @@ def get_image_tag_steps(storage, mode, tag):
for step_index in range(image.num_records()):
record = image.record(step_index, sample_index)
shape = record.shape()
assert shape, "%s,%s" % (mode, tag)
# TODO(ChunweiYan) remove this trick, some shape will be empty
if not shape: continue
# assert shape, "%s,%s" % (mode, tag)
query = urllib.urlencode({
'sample': 0,
'index': step_index,
......@@ -94,7 +101,7 @@ def get_image_tag_steps(storage, mode, tag):
return res
def get_invididual_image(storage, mode, tag, step_index):
def get_invididual_image(storage, mode, tag, step_index, max_size=80):
with storage.mode(mode) as reader:
res = re.search(r".*/([0-9]+$)", tag)
# remove suffix '/x'
......@@ -105,9 +112,16 @@ def get_invididual_image(storage, mode, tag, step_index):
image = reader.image(tag)
record = image.record(step_index, offset)
shape = record.shape()
data = np.array(record.data(), dtype='uint8').reshape(record.shape())
tempfile = NamedTemporaryFile(mode='w+b', suffix='.png')
with Image.fromarray(data) as im:
size = max(shape[0], shape[1])
if size > max_size:
scale = max_size * 1. / size
scaled_shape = (int(shape[0]*scale), int(shape[1]*scale))
im = im.resize(scaled_shape)
im.save(tempfile)
tempfile.seek(0, 0)
return tempfile
......
import lib
import pprint
import unittest
import lib
import storage
import pprint
from storage_mock import add_scalar, add_image
from storage_mock import add_image, add_scalar
class LibTest(unittest.TestCase):
......@@ -28,7 +29,7 @@ class LibTest(unittest.TestCase):
def test_modes(self):
modes = lib.get_modes(self.reader)
self.assertEqual(sorted(modes), sorted(["train", "test", "valid"]))
self.assertEqual(sorted(modes), sorted(["default", "train", "test", "valid"]))
def test_scalar(self):
......
......@@ -7,13 +7,12 @@ from optparse import OptionParser
from flask import (Flask, Response, redirect, request, send_file,
send_from_directory)
import graph
import lib
import storage
import visualdl.mock.data as mock_data
import visualdl.mock.tags as mock_tags
from visualdl.log import logger
import storage
import graph
app = Flask(__name__, static_url_path="")
# set static expires in a short time to reduce browser's memory usage.
......@@ -51,7 +50,7 @@ server_path = os.path.abspath(os.path.dirname(sys.argv[0]))
static_file_path = "./frontend/dist/"
mock_data_path = "./mock_data/"
storage = storage.StorageReader(options.logdir)
log_reader = storage.LogReader(options.logdir)
# return data
......@@ -88,8 +87,7 @@ def logdir():
@app.route('/data/runs')
def runs():
modes = storage.modes()
result = gen_result(0, "", lib.get_modes())
result = gen_result(0, "", lib.get_modes(log_reader))
return Response(json.dumps(result), mimetype='application/json')
......@@ -100,7 +98,7 @@ def scalar_tags():
if is_debug:
result = mock_tags.data()
else:
result = lib.get_scalar_tags(storage, mode)
result = lib.get_scalar_tags(log_reader, mode)
print 'scalar tags (mode: %s)' % mode, result
result = gen_result(0, "", result)
return Response(json.dumps(result), mimetype='application/json')
......@@ -109,7 +107,7 @@ def scalar_tags():
@app.route("/data/plugin/images/tags")
def image_tags():
mode = request.args.get('run')
result = lib.get_image_tags(storage)
result = lib.get_image_tags(log_reader)
print 'image tags (mode: %s)'%mode, result
result = gen_result(0, "", result)
return Response(json.dumps(result), mimetype='application/json')
......@@ -123,7 +121,7 @@ def scalars():
if is_debug:
result = mock_data.sequence_data()
else:
result = lib.get_scalar(storage, run, tag)
result = lib.get_scalar(log_reader, run, tag)
result = gen_result(0, "", result)
return Response(json.dumps(result), mimetype='application/json')
......@@ -132,11 +130,9 @@ def scalars():
@app.route('/data/plugin/images/images')
def images():
mode = request.args.get('run')
# TODO(ChunweiYan) update this when frontend fix the field name
#tag = request.args.get('tag')
tag = request.args.get('displayName')
tag = request.args.get('tag')
result = lib.get_image_tag_steps(storage, mode, tag)
result = lib.get_image_tag_steps(log_reader, mode, tag)
result = gen_result(0, "", result)
return Response(json.dumps(result), mimetype='application/json')
......@@ -149,7 +145,7 @@ def individual_image():
step_index = int(request.args.get('index')) # index of step
offset = 0
imagefile = lib.get_invididual_image(storage, mode, tag, step_index)
imagefile = lib.get_invididual_image(log_reader, mode, tag, step_index)
response = send_file(
imagefile, as_attachment=True, attachment_filename='img.png')
return response
......@@ -163,4 +159,4 @@ def graph():
if __name__ == '__main__':
logger.info(" port=" + str(options.port))
app.run(debug=True, host=options.host, port=options.port)
app.run(debug=False, host=options.host, port=options.port)
......@@ -22,6 +22,7 @@ PYBIND11_PLUGIN(core) {
new (&instance) vs::LogReader(dir);
})
.def("as_mode", &vs::LogReader::AsMode)
.def("set_mode", &vs::LogReader::SetMode)
.def("modes", [](vs::LogReader& self) { return self.storage().modes(); })
.def("tags", &vs::LogReader::tags)
// clang-format off
......@@ -46,6 +47,7 @@ PYBIND11_PLUGIN(core) {
[](vs::LogWriter& instance, const std::string& dir, int sync_cycle) {
new (&instance) vs::LogWriter(dir, sync_cycle);
})
.def("set_mode", &vs::LogWriter::SetMode)
.def("as_mode", &vs::LogWriter::AsMode)
// clang-format off
WRITER_ADD_SCALAR(float)
......
......@@ -14,9 +14,15 @@ public:
storage_.SetDir(dir);
storage_.meta.cycle = sync_cycle;
}
LogWriter(const LogWriter& other) {
storage_ = other.storage_;
mode_ = other.mode_;
storage_ = other.storage_;
}
void SetMode(const std::string& mode) {
mode_ = mode;
storage_.AddMode(mode);
}
LogWriter AsMode(const std::string& mode) {
......@@ -47,6 +53,8 @@ class LogReader {
public:
LogReader(const std::string& dir) : reader_(dir) {}
void SetMode(const std::string& mode) { mode_ = mode; }
LogReader AsMode(const std::string& mode) {
auto tmp = *this;
tmp.mode_ = mode;
......@@ -122,6 +130,9 @@ struct Scalar {
void AddRecord(int id, T value) {
auto record = tablet_.AddRecord();
record.SetId(id);
time_t time = std::time(nullptr);
record.SetTimeStamp(time);
auto entry = record.template AddData<T>();
entry.Set(value);
}
......
......@@ -31,6 +31,8 @@ TEST(Scalar, write) {
// check the first entry of first record
ASSERT_EQ(record.front(), 12);
ASSERT_TRUE(!reader.storage().modes().empty());
// check tags
ASSERT_EQ(reader_.all_tags().size(), 1);
auto tags = reader.tags("scalar");
......@@ -79,4 +81,31 @@ TEST(Image, test) {
CHECK_EQ(image2read.num_records(), num_steps);
}
TEST(Scalar, more_than_one_mode) {
const auto dir = "./tmp/sdk_multi_mode";
LogWriter log(dir, 20);
std::vector<components::Scalar<float>> scalars;
for (int i = 0; i < 1; i++) {
std::stringstream ss;
ss << "mode-" << i;
auto mode = ss.str();
auto writer = log.AsMode(mode);
ASSERT_EQ(writer.storage().dir(), dir);
LOG(INFO) << "origin dir: " << dir;
LOG(INFO) << "changed dir: " << writer.storage().dir();
auto tablet = writer.AddTablet("add/scalar0");
scalars.emplace_back(tablet);
}
for (int i = 0; i < 1; i++) {
auto& scalar = scalars[i];
for (int j = 0; j < 100; j++) {
scalar.AddRecord(j, (float)j);
}
}
}
} // namespace visualdl
......@@ -16,8 +16,8 @@ class LogReader(object):
self.reader = reader if reader else core.LogReader(dir)
def mode(self, mode):
LogReader.cur_mode = self.as_mode(mode)
return LogReader.cur_mode
self.reader.set_mode(mode)
return self
def as_mode(self, mode):
tmp = LogReader(dir, self.reader.as_mode(mode))
......@@ -41,10 +41,10 @@ class LogReader(object):
return self.reader.get_image(tag)
def __enter__(self):
return LogReader.cur_mode
return self
def __exit__(self, type, value, traceback):
pass
self.reader.set_mode("default")
class LogWriter(object):
......@@ -57,8 +57,8 @@ class LogWriter(object):
self.writer = writer if writer else core.LogWriter(dir, sync_cycle)
def mode(self, mode):
LogWriter.cur_mode = self.as_mode(mode)
return LogWriter.cur_mode
self.writer.set_mode(mode)
return self
def as_mode(self, mode):
LogWriter.cur_mode = LogWriter(self.dir, self.sync_cycle, self.writer.as_mode(mode))
......@@ -76,7 +76,7 @@ class LogWriter(object):
return self.writer.new_image(tag, num_samples, step_cycle)
def __enter__(self):
return LogWriter.cur_mode
return self
def __exit__(self, type, value, traceback):
pass
self.writer.set_mode("default")
import random
import time
import unittest
from PIL import Image
import numpy as np
from PIL import Image
import storage
......@@ -115,6 +115,22 @@ class StorageTest(unittest.TestCase):
scalar = reader.scalar("model/scalar/average")
self.assertEqual(scalar.caption(), "train")
def test_modes(self):
dir = "./tmp/storagetest0"
store = storage.LogWriter(
self.dir, sync_cycle=1)
scalars = []
for i in range(10):
with store.mode("mode-%d" % i) as writer:
scalar = writer.scalar("add/scalar0")
scalars.append(scalar)
for scalar in scalars[:-1]:
for i in range(10):
scalar.add_record(i, float(i))
if __name__ == '__main__':
......
......@@ -13,7 +13,6 @@
#include "visualdl/utils/guard.h"
namespace visualdl {
static const std::string meta_file_name = "storage.meta";
static std::string meta_path(const std::string& dir) {
......@@ -43,6 +42,7 @@ struct Storage {
mutable SimpleSyncMeta meta;
Storage() {
dir_ = std::make_shared<std::string>();
data_ = std::make_shared<storage::Storage>();
tablets_ = std::make_shared<std::map<std::string, storage::Tablet>>();
modes_ = std::make_shared<std::set<std::string>>();
......@@ -51,7 +51,9 @@ struct Storage {
data_->set_timestamp(t);
}
Storage(const Storage& other)
: data_(other.data_), tablets_(other.tablets_), modes_(other.modes_) {}
: data_(other.data_), tablets_(other.tablets_), modes_(other.modes_) {
dir_ = other.dir_;
}
// write operations
void AddMode(const std::string& x) {
......@@ -72,13 +74,23 @@ struct Storage {
return Tablet(&(*tablets_)[x], this);
}
void SetDir(const std::string& dir) { dir_ = dir; }
void PersistToDisk() { PersistToDisk(dir_); }
void SetDir(const std::string& dir) { *dir_ = dir; }
std::string dir() const { return *dir_; }
void PersistToDisk() {
CHECK(!dir_->empty()) << "dir should be set.";
fs::TryRecurMkdir(*dir_);
fs::SerializeToFile(*data_, meta_path(*dir_));
for (auto tag : data_->tags()) {
auto it = tablets_->find(tag);
CHECK(it != tablets_->end()) << "tag " << tag << " not exist.";
fs::SerializeToFile(it->second, tablet_path(*dir_, tag));
}
}
/*
* Save memory to disk.
*/
void PersistToDisk(const std::string& dir) {
// LOG(INFO) << "persist to disk " << dir;
CHECK(!dir.empty()) << "dir should be set.";
fs::TryRecurMkdir(dir);
......@@ -95,13 +107,11 @@ struct Storage {
protected:
void AddTag(const std::string& x) {
*data_->add_tags() = x;
LOG(INFO) << "add tag " << x;
LOG(INFO) << "tag.size " << data_->tags_size();
WRITE_GUARD
}
private:
std::string dir_;
std::shared_ptr<std::string> dir_;
std::shared_ptr<std::map<std::string, storage::Tablet>> tablets_;
std::shared_ptr<storage::Storage> data_;
std::shared_ptr<std::set<std::string>> modes_;
......
......@@ -100,7 +100,7 @@ struct TabletReader {
// read operations.
std::string tag() const { return data_.tag(); }
Tablet::Type type() const { return Tablet::Type(data_.component()); }
int64_t total_records() const { return data_.total_records(); }
int64_t total_records() const { return data_.records_size(); }
int32_t num_samples() const { return data_.num_samples(); }
RecordReader record(int i) const { return RecordReader(data_.records(i)); }
template <typename T>
......
......@@ -67,9 +67,6 @@ static void NormalizeImage(Uint8Image* image,
scale = (image_max < kZeroThreshold ? 0.0f : 255.0f) / image_max;
offset = 0.0f;
}
LOG(INFO) << "scale " << scale;
// Transform image, turning nonfinite values to bad_color
for (int i = 0; i < depth; i++) {
auto tmp = scale * values.row(i).array() + offset;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册