Skip to content

Commit 088467a

Browse files
authored
Merge pull request PaddlePaddle#21 from Superjom/feature/add_storage
feature/add storage
2 parents 5c14a72 + 01ba483 commit 088467a

File tree

4 files changed

+216
-0
lines changed

4 files changed

+216
-0
lines changed

CMakeLists.txt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
cmake_minimum_required(VERSION 3.8)
2+
project(VisualDL)
3+
4+
set(CMAKE_CXX_STANDARD 11)
5+
6+
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
7+
include_directories(thirdparty/local/include)
8+
link_directories(thirdparty/local/lib)
9+
add_subdirectory(thirdparty/pybind11-2.2.1)
10+
11+
set(SOURCE_FILES
12+
visualdl/backend/storage/storage.cc visualdl/backend/storage/storage.h
13+
visualdl/backend/storage/storage.pb.h
14+
visualdl/backend/storage/storage.pb.cc
15+
)
16+
17+
add_library(storage visualdl/backend/storage/storage.cc
18+
visualdl/backend/storage/storage.pb.cc)
19+
add_executable(VisualDL ${SOURCE_FILES})

visualdl/backend/storage/storage.cc

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#include <fstream>
2+
#include <glog/logging.h>
3+
4+
#include "visualdl/backend/storage/storage.h"
5+
6+
namespace visualdl {
7+
8+
storage::Tablet *Storage::Add(const std::string &tag) {
9+
return &proto_.mutable_tablets()->at(tag);
10+
}
11+
12+
const storage::Tablet *Storage::Find(const std::string &tag) const {
13+
auto it = proto_.tablets().find(tag);
14+
if (it != proto_.tablets().end()) {
15+
return &it->second;
16+
}
17+
return nullptr;
18+
}
19+
20+
void Storage::Save(const std::string &path) const {
21+
std::ofstream file(path, file.binary | file.out);
22+
CHECK(file.is_open()) << "can't open path " << path;
23+
auto str = Serialize();
24+
file.write(str.c_str(), str.size());
25+
}
26+
27+
void Storage::Load(const std::string &path) {
28+
std::ifstream file(path, file.binary);
29+
CHECK(file.is_open()) << "can't open path " << path;
30+
size_t size = file.tellg();
31+
std::string buffer(size, ' ');
32+
file.seekg(0);
33+
file.read(&buffer[0], size);
34+
DeSerialize(buffer);
35+
}
36+
37+
std::string Storage::Serialize() const {
38+
return proto_.SerializeAsString();
39+
}
40+
41+
void Storage::DeSerialize(const std::string &data) {
42+
proto_.ParseFromString(data);
43+
}
44+
45+
} // namespace visualdl

visualdl/backend/storage/storage.h

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#ifndef VISUALDL_STORAGE_H
2+
#define VISUALDL_STORAGE_H
3+
4+
#include <string>
5+
#include <time.h>
6+
7+
#include "visualdl/backend/storage/storage.pb.h"
8+
9+
namespace visualdl {
10+
11+
class Storage final {
12+
public:
13+
/*
14+
* There should be only one Storage instance in memory.
15+
*/
16+
Storage &Global() {
17+
static Storage *instance = new Storage();
18+
return *instance;
19+
}
20+
21+
/*
22+
* Add a new tablet named `tag`, the newly added instance will be returned.
23+
*/
24+
storage::Tablet *Add(const std::string &tag);
25+
26+
/*
27+
* Search the tablet named `tag`, if not exist, return nullptr.
28+
*/
29+
const storage::Tablet *Find(const std::string &tag) const;
30+
31+
/*
32+
* Serialize this object to string and save it to a file.
33+
*/
34+
void Save(const std::string &path) const;
35+
36+
/*
37+
* Load the Protobuf message from a file.
38+
*/
39+
void Load(const std::string &path);
40+
41+
protected:
42+
/*
43+
* Serialize the Storage instance to string.
44+
*/
45+
std::string Serialize() const;
46+
47+
/*
48+
* De-serialize from a string and update this Storage instance.
49+
*/
50+
void DeSerialize(const std::string &data);
51+
52+
Storage() {
53+
// set time stamp
54+
time_t time0;
55+
time(&time0);
56+
proto_.set_timestamp(time0);
57+
}
58+
59+
private:
60+
storage::Storage proto_;
61+
};
62+
63+
} // namespace visualdl
64+
65+
#endif //VISUALDL_STORAGE_H
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
syntax = "proto3";
2+
package storage;
3+
4+
enum DataType {
5+
// single entry
6+
kInt32 = 0;
7+
kInt64 = 1;
8+
kFloat = 2;
9+
kDouble = 3;
10+
kString = 4;
11+
kBool = 5;
12+
// entrys
13+
kInt64s = 6;
14+
kFloats = 7;
15+
kDoubles = 8;
16+
kStrings = 9;
17+
kInt32s = 10;
18+
kBools = 11;
19+
}
20+
21+
// A data array, which type is `type`.
22+
message Entry {
23+
// if all the entries in a record share the same data type, ignore this field
24+
// and store type to `dtype` in `Record`.
25+
DataType dtype = 1;
26+
// single element
27+
int32 i32 = 2;
28+
int64 i64 = 3;
29+
string s = 4;
30+
float f = 5;
31+
double d = 6;
32+
bool b = 7;
33+
// array
34+
repeated int64 i64s = 8;
35+
repeated float fs = 9;
36+
repeated double ds = 10;
37+
repeated int32 i32s = 11;
38+
repeated bool bs = 12;
39+
}
40+
41+
message Record {
42+
Entry data = 1;
43+
int64 timestamp = 2;
44+
// store the count of writing operations to the tablet.
45+
int64 id = 3;
46+
DataType dtype = 4;
47+
// shape or some other meta infomation for this record, if all the records
48+
// share the same meta, just store one copy of meta in `Storage`, or create
49+
// a unique copy for each `Record`.
50+
Entry meta = 5;
51+
}
52+
53+
/*
54+
A Tablet stores the records of a component which type is `component` and indidates as `tag`.
55+
The records will be saved in a file which name contains `tag`. During the running period,
56+
`num_records` will be accumulated, and `num_samples` indicates the size of sample set the
57+
reservoir sampling algorithm will collect.
58+
*/
59+
message Tablet {
60+
// the kinds of the components that supported
61+
enum Type {
62+
kScalar = 0;
63+
kHistogram = 1;
64+
kGraph = 2;
65+
}
66+
// type of the component, different component should have different storage format.
67+
Type component = 1;
68+
// records the total count of records, each Write operation should increate this value.
69+
int64 num_records = 2;
70+
// indicate the number of instances to sample, this should be a constant value.
71+
int32 num_samples = 3;
72+
repeated Record records = 4;
73+
// store a meta infomation if all the records share.
74+
Entry meta = 5;
75+
// the unique identification for this `Tablet`.
76+
string tag = 6;
77+
}
78+
79+
/*
80+
The Storage stores all the records.
81+
*/
82+
message Storage {
83+
// tags to Tablet, should be thread safe if fix the keys after initialization.
84+
map<string, Tablet> tablets = 1;
85+
string dir = 2;
86+
int64 timestamp = 3;
87+
}

0 commit comments

Comments
 (0)