Caffe2 - C++ API
A deep learning, cross platform ML framework
blob_serialization.cc
1 #include "caffe2/core/blob_serialization.h"
2 
3 #include <sstream>
4 #include <mutex>
5 
6 #include "caffe2/core/blob.h"
7 #include "caffe2/utils/proto_utils.h"
8 
9 CAFFE2_DEFINE_int(
10  caffe2_tensor_chunk_size,
11  1000000,
12  "Chunk size to split tensor data into");
13 
14 CAFFE2_DEFINE_int(
15  caffe2_max_tensor_serializer_threads,
16  16,
17  "Maximal number of threads that can be used for tensor serialization");
18 
19 CAFFE2_DEFINE_bool(
20  caffe2_serialize_fp16_as_bytes,
21  false,
22  "Serialize FLOAT16 tensors using byte_data field");
23 
24 namespace caffe2 {
32  public:
33  StringSerializer() {}
34  ~StringSerializer() {}
39  void Serialize(
40  const Blob& blob,
41  const string& name,
42  SerializationAcceptor acceptor) override {
43  CAFFE_ENFORCE(blob.IsType<std::string>());
44 
45  BlobProto blob_proto;
46  blob_proto.set_name(name);
47  blob_proto.set_type("std::string");
48  blob_proto.set_content(blob.template Get<std::string>());
49  acceptor(name, blob_proto.SerializeAsString());
50  }
51 };
52 
58  public:
59  void Deserialize(const BlobProto& proto, Blob* blob) override {
60  *blob->GetMutable<std::string>() = proto.content();
61  }
62 };
63 
64 // The blob serialization member function implementation.
66  const string& name,
67  BlobSerializerBase::SerializationAcceptor acceptor,
68  int chunk_size) const {
69  std::unique_ptr<BlobSerializerBase> serializer(CreateSerializer(meta_.id()));
70  CAFFE_ENFORCE(serializer, "No known serializer for ", meta_.name());
71  serializer->SerializeWithChunkSize(*this, name, acceptor, chunk_size);
72 }
73 
74 // The blob serialization member function implementation.
75 std::string Blob::Serialize(const string& name) const {
76  std::string data;
77  BlobSerializerBase::SerializationAcceptor acceptor = [&data](
78  const std::string&, const std::string& blob) {
79  DCHECK(data.empty()); // should be called once with kNoChunking
80  data = blob;
81  };
82  this->Serialize(name, acceptor, kNoChunking);
83  return data;
84 }
85 
86 // Specialization for StoreDeviceDetail for CPU - nothing needs to be done.
87 template <>
89  const Tensor<CPUContext>& /*input*/,
90  TensorProto* /*proto*/) {}
91 
92 // The actual serialization registry objects.
93 CAFFE_DEFINE_TYPED_REGISTRY(
94  BlobSerializerRegistry,
95  CaffeTypeId,
97  std::unique_ptr);
98 
99 CAFFE_DEFINE_REGISTRY(BlobDeserializerRegistry, BlobDeserializerBase);
100 
101 void Blob::Deserialize(const string& content) {
102  BlobProto blob_proto;
103  CAFFE_ENFORCE(
104  blob_proto.ParseFromString(content),
105  "Cannot parse content into a BlobProto.");
106  Deserialize(blob_proto);
107 }
108 
109 void Blob::Deserialize(const BlobProto& blob_proto) {
110  if (blob_proto.type() == kTensorBlobType) {
111  // This is a tensor object. Depending on the device type, we will
112  // use the corresponding TensorDeserializer.
113  auto deserializer = CreateDeserializer(
114  "Tensor" +
115  DeviceTypeName(blob_proto.tensor().device_detail().device_type()));
116  // Tensor's deserializer should always be registered, but we will double
117  // check if it is not null anyway.
118  CAFFE_ENFORCE(deserializer.get());
119  deserializer->Deserialize(blob_proto, this);
120  } else {
121  auto deserializer = CreateDeserializer(blob_proto.type());
122  CAFFE_ENFORCE(
123  deserializer.get(),
124  "No registered deserializer for type ",
125  blob_proto.type());
126  deserializer->Deserialize(blob_proto, this);
127  }
128 }
129 
130 namespace {
131 // Serialize TensorCPU.
132 REGISTER_BLOB_SERIALIZER(
133  (TypeMeta::Id<TensorCPU>()),
135 REGISTER_BLOB_DESERIALIZER(TensorCPU, TensorDeserializer<CPUContext>);
136 // Serialize std::string
137 REGISTER_BLOB_SERIALIZER((TypeMeta::Id<std::string>()), StringSerializer);
138 REGISTER_BLOB_DESERIALIZER(std::string, StringDeserializer);
139 } // namespace
140 } // namespace caffe2
Blob is a general container that hosts a typed pointer.
Definition: blob.h:25
TensorSerializer is the serializer for Tensors.
BlobDeserializerBase is an abstract class that deserializes a blob from a BlobProto or a TensorProto...
StringSerializer is the serializer for String.
void Serialize(const string &name, BlobSerializerBase::SerializationAcceptor acceptor, int chunk_size=kDefaultChunkSize) const
Serializes the current blob, if possible.
TensorDeserializer is the deserializer for Tensors.
A global dictionary that holds information about what Caffe2 modules have been loaded in the current ...
T * GetMutable(bool *is_new_object=nullptr)
Gets a mutable pointer to the stored object.
Definition: blob.h:101
void Deserialize(const string &content)
Deserializes from a string containing either BlobProto or TensorProto.
bool IsType() const
Checks if the content stored in the blob is of type T.
Definition: blob.h:58
void Serialize(const Blob &blob, const string &name, SerializationAcceptor acceptor) override
Serializes a Blob.
StringDeserializer is the deserializer for Strings.
BlobSerializerBase is an abstract class that serializes a blob to a string.