1 #ifndef CAFFE_BLOB_HPP_
2 #define CAFFE_BLOB_HPP_
8 #include "caffe/common.hpp"
9 #include "caffe/proto/caffe.pb.h"
10 #include "caffe/syncedmem.hpp"
12 const int kMaxBlobAxes = 32;
23 template <
typename Dtype>
27 : data_(), diff_(), count_(0), capacity_(0) {}
32 explicit Blob(
const vector<int>& shape);
51 void Reshape(
const vector<int>& shape);
52 void Reshape(
const BlobShape& shape);
53 void ReshapeLike(
const Blob& other);
54 inline string shape_string()
const {
56 for (
int i = 0; i < shape_.size(); ++i) {
57 stream << shape_[i] <<
" ";
59 stream <<
"(" << count_ <<
")";
62 inline const vector<int>& shape()
const {
return shape_; }
71 inline int shape(
int index)
const {
74 inline int num_axes()
const {
return shape_.size(); }
75 inline int count()
const {
return count_; }
85 inline int count(
int start_axis,
int end_axis)
const {
86 CHECK_LE(start_axis, end_axis);
87 CHECK_GE(start_axis, 0);
88 CHECK_GE(end_axis, 0);
89 CHECK_LE(start_axis, num_axes());
90 CHECK_LE(end_axis, num_axes());
92 for (
int i = start_axis; i < end_axis; ++i) {
103 inline int count(
int start_axis)
const {
104 return count(start_axis, num_axes());
119 CHECK_GE(axis_index, -num_axes())
120 <<
"axis " << axis_index <<
" out of range for " << num_axes()
121 <<
"-D Blob with shape " << shape_string();
122 CHECK_LT(axis_index, num_axes())
123 <<
"axis " << axis_index <<
" out of range for " << num_axes()
124 <<
"-D Blob with shape " << shape_string();
125 if (axis_index < 0) {
126 return axis_index + num_axes();
132 inline int num()
const {
return LegacyShape(0); }
134 inline int channels()
const {
return LegacyShape(1); }
136 inline int height()
const {
return LegacyShape(2); }
138 inline int width()
const {
return LegacyShape(3); }
139 inline int LegacyShape(
int index)
const {
140 CHECK_LE(num_axes(), 4)
141 <<
"Cannot use legacy accessors on Blobs with > 4 axes.";
144 if (index >= num_axes() || index < -num_axes()) {
153 inline int offset(
const int n,
const int c = 0,
const int h = 0,
154 const int w = 0)
const {
161 CHECK_GE(
width(), 0);
162 CHECK_LE(w,
width());
166 inline int offset(
const vector<int>& indices)
const {
167 CHECK_LE(indices.size(), num_axes());
169 for (
int i = 0; i < num_axes(); ++i) {
171 if (indices.size() > i) {
172 CHECK_GE(indices[i], 0);
173 CHECK_LT(indices[i], shape(i));
174 offset += indices[i];
188 void CopyFrom(
const Blob<Dtype>& source,
bool copy_diff =
false,
189 bool reshape =
false);
191 inline Dtype data_at(
const int n,
const int c,
const int h,
193 return cpu_data()[offset(n, c, h, w)];
196 inline Dtype diff_at(
const int n,
const int c,
const int h,
198 return cpu_diff()[offset(n, c, h, w)];
201 inline Dtype data_at(
const vector<int>& index)
const {
202 return cpu_data()[offset(index)];
205 inline Dtype diff_at(
const vector<int>& index)
const {
206 return cpu_diff()[offset(index)];
209 inline const shared_ptr<SyncedMemory>& data()
const {
214 inline const shared_ptr<SyncedMemory>& diff()
const {
219 const Dtype* cpu_data()
const;
220 void set_cpu_data(Dtype* data);
221 const int* gpu_shape()
const;
222 const Dtype* gpu_data()
const;
223 void set_gpu_data(Dtype* data);
224 const Dtype* cpu_diff()
const;
225 const Dtype* gpu_diff()
const;
226 Dtype* mutable_cpu_data();
227 Dtype* mutable_gpu_data();
228 Dtype* mutable_cpu_diff();
229 Dtype* mutable_gpu_diff();
231 void FromProto(
const BlobProto& proto,
bool reshape =
true);
232 void ToProto(BlobProto* proto,
bool write_diff =
false)
const;
267 bool ShapeEquals(
const BlobProto& other);
270 shared_ptr<SyncedMemory> data_;
271 shared_ptr<SyncedMemory> diff_;
272 shared_ptr<SyncedMemory> shape_data_;
277 DISABLE_COPY_AND_ASSIGN(Blob);
282 #endif // CAFFE_BLOB_HPP_