diff_() {}
explicit Blob(const int num, const int channels, const int height,
const int width);
- virtual ~Blob() {}
void Reshape(const int num, const int channels, const int height,
const int width);
inline int num() const { return num_; }
return *(cpu_diff() + offset(n, c, h, w));
}
+ inline const shared_ptr<SyncedMemory>& data() const {
+ CHECK(data_);
+ return data_;
+ }
+
+ inline const shared_ptr<SyncedMemory>& diff() const {
+ CHECK(diff_);
+ return diff_;
+ }
+
const Dtype* cpu_data() const;
const Dtype* gpu_data() const;
const Dtype* cpu_diff() const;
void FromProto(const BlobProto& proto);
void ToProto(BlobProto* proto, bool write_diff = false) const;
+ void AdoptData(const Blob& other);
+ void AdoptDiff(const Blob& other);
+
protected:
shared_ptr<SyncedMemory> data_;
shared_ptr<SyncedMemory> diff_;
}
template <typename Dtype>
+void Blob<Dtype>::AdoptData(const Blob& other) {
+ CHECK_EQ(count_, other.count());
+ data_ = other.data();
+}
+
+template <typename Dtype>
+void Blob<Dtype>::AdoptDiff(const Blob& other) {
+ CHECK_EQ(count_, other.count());
+ diff_ = other.diff();
+}
+
+template <typename Dtype>
void Blob<Dtype>::Update() {
// We will perform update based on where the data is located.
switch (data_->head()) {
template <typename Dtype>
Dtype FlattenLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {
- const Dtype* bottom_data = bottom[0]->cpu_data();
- Dtype* top_data = (*top)[0]->mutable_cpu_data();
- caffe_copy(count_, bottom_data, top_data);
+ (*top)[0]->AdoptData(*bottom[0]);
return Dtype(0.);
}
template <typename Dtype>
void FlattenLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,
const bool propagate_down, vector<Blob<Dtype>*>* bottom) {
- const Dtype* top_diff = top[0]->cpu_diff();
- Dtype* bottom_diff = (*bottom)[0]->mutable_cpu_diff();
- caffe_copy(count_, top_diff, bottom_diff);
+ (*bottom)[0]->AdoptDiff(*top[0]);
}
INSTANTIATE_CLASS(FlattenLayer);
template <typename Dtype>
Dtype FlattenLayer<Dtype>::Forward_gpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {
- const Dtype* bottom_data = bottom[0]->gpu_data();
- Dtype* top_data = (*top)[0]->mutable_gpu_data();
- caffe_gpu_copy(count_, bottom_data, top_data);
+ (*top)[0]->AdoptData(*bottom[0]);
return Dtype(0.);
}
template <typename Dtype>
void FlattenLayer<Dtype>::Backward_gpu(const vector<Blob<Dtype>*>& top,
const bool propagate_down, vector<Blob<Dtype>*>* bottom) {
- const Dtype* top_diff = top[0]->gpu_diff();
- Dtype* bottom_diff = (*bottom)[0]->mutable_gpu_diff();
- caffe_gpu_copy(count_, top_diff, bottom_diff);
+ (*bottom)[0]->AdoptDiff(*top[0]);
}
INSTANTIATE_CLASS(FlattenLayer);
template <typename Dtype>
Dtype SplitLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {
- const Dtype* bottom_data = bottom[0]->cpu_data();
for (int i = 0; i < top->size(); ++i) {
- if (i == 0 && (*top)[i] == bottom[0]) {
- continue;
- }
- Dtype* top_data = (*top)[i]->mutable_cpu_data();
- caffe_copy(count_, bottom_data, top_data);
+ (*top)[i]->AdoptData(*bottom[0]);
}
return Dtype(0.);
}
void SplitLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,
const bool propagate_down, vector<Blob<Dtype>*>* bottom) {
if (propagate_down) {
- const Dtype* top_diff = top[0]->cpu_diff();
- Dtype* bottom_diff = (*bottom)[0]->mutable_cpu_diff();
- // Initialize by copying first top blob diff to our diff, unless we're
- // doing in-place computation for the first blob, in which case the diff is
- // already initialized.
- if (top[0] != (*bottom)[0]) {
- caffe_copy(count_, top_diff, bottom_diff);
- }
+ (*bottom)[0]->AdoptDiff(*top[0]);
// Add remaining top blob diffs.
+ Dtype* bottom_diff = (*bottom)[0]->mutable_cpu_diff();
for (int i = 1; i < top.size(); ++i) {
- top_diff = top[i]->cpu_diff();
+ const Dtype* top_diff = top[i]->cpu_diff();
caffe_axpy(count_, Dtype(1.), top_diff, bottom_diff);
}
}
template <typename Dtype>
Dtype SplitLayer<Dtype>::Forward_gpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {
- const Dtype* bottom_data = bottom[0]->gpu_data();
for (int i = 0; i < top->size(); ++i) {
- if (i == 0 && (*top)[i] == bottom[0]) {
- continue;
- }
- Dtype* top_data = (*top)[i]->mutable_gpu_data();
- caffe_gpu_copy(count_, bottom_data, top_data);
+ (*top)[i]->AdoptData(*bottom[0]);
}
return Dtype(0.);
}
void SplitLayer<Dtype>::Backward_gpu(const vector<Blob<Dtype>*>& top,
const bool propagate_down, vector<Blob<Dtype>*>* bottom) {
if (propagate_down) {
- const Dtype* top_diff = top[0]->gpu_diff();
- Dtype* bottom_diff = (*bottom)[0]->mutable_gpu_diff();
- // Initialize by copying first top blob diff to our diff, unless we're
- // doing in-place computation for the first blob, in which case the diff is
- // already initialized.
- if (top[0] != (*bottom)[0]) {
- caffe_gpu_copy(count_, top_diff, bottom_diff);
- }
+ (*bottom)[0]->AdoptDiff(*top[0]);
// Add remaining top blob diffs.
+ Dtype* bottom_diff = (*bottom)[0]->mutable_gpu_diff();
for (int i = 1; i < top.size(); ++i) {
- top_diff = top[i]->gpu_diff();
+ const Dtype* top_diff = top[i]->gpu_diff();
caffe_gpu_axpy(count_, Dtype(1.), top_diff, bottom_diff);
}
}