forked from BVLC/caffe
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request BVLC#80 from andrei-pokrovsky/caffe-0.14
Add cudnn v4 batch normalization integration
- Loading branch information
Showing
7 changed files
with
355 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
#ifdef USE_CUDNN | ||
|
||
#include <vector> | ||
|
||
#include "caffe/filler.hpp" | ||
#include "caffe/layer.hpp" | ||
#include "caffe/util/im2col.hpp" | ||
#include "caffe/util/math_functions.hpp" | ||
#include "caffe/vision_layers.hpp" | ||
|
||
namespace caffe { | ||
|
||
template <typename Dtype> | ||
void CuDNNBatchNormLayer<Dtype>::LayerSetUp( | ||
const vector<Blob<Dtype>*>& bottom, | ||
const vector<Blob<Dtype>*>& top) { | ||
BatchNormLayer<Dtype>::LayerSetUp(bottom, top); | ||
|
||
cudnn::createTensor4dDesc<Dtype>(&bottom_desc_); | ||
cudnn::createTensor4dDesc<Dtype>(&top_desc_); | ||
cudnn::createTensor4dDesc<Dtype>(&scale_bias_mean_var_desc_); | ||
|
||
// currently only SPATIAL mode is supported (most commonly used mode) | ||
// If there's enough demand we can implement CUDNN_BATCHNORM_PER_ACTIVATION | ||
// though it's not currently implemented for the CPU layer | ||
mode_ = CUDNN_BATCHNORM_SPATIAL; | ||
|
||
if (this->blobs_.size() > 5) { | ||
LOG(INFO) << "Skipping parameter initialization"; | ||
} else { | ||
this->blobs_.resize(5); | ||
this->blobs_[0].reset(new Blob<Dtype>(1, bottom[0]->channels(), 1, 1)); | ||
this->blobs_[1].reset(new Blob<Dtype>(1, bottom[0]->channels(), 1, 1)); | ||
this->blobs_[2].reset(new Blob<Dtype>(1, 1, 1, 1)); | ||
this->blobs_[3].reset(new Blob<Dtype>(1, bottom[0]->channels(), 1, 1)); | ||
this->blobs_[4].reset(new Blob<Dtype>(1, bottom[0]->channels(), 1, 1)); | ||
|
||
shared_ptr<Filler<Dtype> > scale_filler( | ||
GetFiller<Dtype>(this->layer_param_.batch_norm_param().scale_filler())); | ||
scale_filler->Fill(this->blobs_[0].get()); | ||
|
||
shared_ptr<Filler<Dtype> > bias_filler( | ||
GetFiller<Dtype>(this->layer_param_.batch_norm_param().bias_filler())); | ||
bias_filler->Fill(this->blobs_[1].get()); | ||
|
||
for (int i = 2; i < 5; i++) { | ||
caffe_set(this->blobs_[i]->count(), Dtype(0), | ||
this->blobs_[i]->mutable_cpu_data()); | ||
} | ||
} | ||
|
||
handles_setup_ = true; | ||
} | ||
|
||
template <typename Dtype> | ||
void CuDNNBatchNormLayer<Dtype>::Reshape( | ||
const vector<Blob<Dtype>*>& bottom, | ||
const vector<Blob<Dtype>*>& top) { | ||
BatchNormLayer<Dtype>::Reshape(bottom, top); | ||
|
||
// set up main tensors | ||
cudnn::setTensor4dDesc<Dtype>( | ||
&bottom_desc_, bottom[0]->num(), | ||
bottom[0]->channels(), bottom[0]->height(), bottom[0]->width()); | ||
cudnn::setTensor4dDesc<Dtype>( | ||
&top_desc_, bottom[0]->num(), | ||
bottom[0]->channels(), bottom[0]->height(), bottom[0]->width()); | ||
|
||
// aux tensors for caching mean & invVar from fwd to bwd pass | ||
int C = bottom[0]->channels(); | ||
int H = bottom[0]->height(); | ||
int W = bottom[0]->width(); | ||
if (mode_ == CUDNN_BATCHNORM_SPATIAL) { | ||
save_mean_.Reshape(1, C, 1, 1); | ||
save_inv_var_.Reshape(1, C, 1, 1); | ||
} else if (mode_ == CUDNN_BATCHNORM_PER_ACTIVATION) { | ||
save_mean_.Reshape(1, C, H, W); | ||
save_inv_var_.Reshape(1, C, H, W); | ||
} else { | ||
LOG(FATAL) << "Unknown cudnnBatchNormMode_t"; | ||
} | ||
CUDNN_CHECK(cudnnDeriveBNTensorDescriptor(scale_bias_mean_var_desc_, | ||
bottom_desc_, mode_)); | ||
} | ||
|
||
template <typename Dtype> | ||
CuDNNBatchNormLayer<Dtype>::~CuDNNBatchNormLayer() { | ||
if (!handles_setup_) return; | ||
|
||
cudnnDestroyTensorDescriptor(bottom_desc_); | ||
cudnnDestroyTensorDescriptor(top_desc_); | ||
cudnnDestroyTensorDescriptor(scale_bias_mean_var_desc_); | ||
} | ||
|
||
INSTANTIATE_CLASS(CuDNNBatchNormLayer); | ||
} // namespace caffe | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
#ifdef USE_CUDNN | ||
#include <algorithm> | ||
#include <cfloat> | ||
#include <vector> | ||
|
||
#include "thrust/device_vector.h" | ||
|
||
#include "caffe/layer.hpp" | ||
#include "caffe/util/math_functions.hpp" | ||
#include "caffe/vision_layers.hpp" | ||
|
||
namespace caffe { | ||
|
||
template <typename Dtype> | ||
void CuDNNBatchNormLayer<Dtype>::Forward_gpu( | ||
const vector<Blob<Dtype>*>& bottom, | ||
const vector<Blob<Dtype>*>& top) { | ||
const Dtype* bottom_data = bottom[0]->gpu_data(); | ||
const Dtype* scale_data = this->blobs_[0]->gpu_data(); | ||
const Dtype* bias_data = this->blobs_[1]->gpu_data(); | ||
|
||
Dtype* top_data = top[0]->mutable_gpu_data(); | ||
Dtype* save_mean = save_mean_.mutable_gpu_data(); | ||
Dtype* save_inv_var = save_inv_var_.mutable_gpu_data(); | ||
|
||
if (this->phase_ == TRAIN) { | ||
// Call Batch normalization forward | ||
CUDNN_CHECK(cudnnBatchNormalizationForwardTraining( | ||
Caffe::cudnn_handle(), | ||
mode_, | ||
cudnn::dataType<Dtype>::one, | ||
cudnn::dataType<Dtype>::zero, | ||
bottom_desc_, | ||
bottom_data, | ||
bottom_desc_, | ||
top_data, | ||
scale_bias_mean_var_desc_, | ||
scale_data, | ||
bias_data, | ||
1-this->moving_average_fraction_, | ||
this->blobs_[3]->mutable_gpu_data(), // mean | ||
this->blobs_[4]->mutable_gpu_data(), // variance | ||
epsilon_, | ||
save_mean, | ||
save_inv_var)); | ||
} else if (this->phase_ == TEST) { | ||
CUDNN_CHECK(cudnnBatchNormalizationForwardInference( | ||
Caffe::cudnn_handle(), | ||
mode_, | ||
cudnn::dataType<Dtype>::one, | ||
cudnn::dataType<Dtype>::zero, | ||
bottom_desc_, | ||
bottom_data, | ||
bottom_desc_, | ||
top_data, | ||
scale_bias_mean_var_desc_, | ||
scale_data, | ||
bias_data, | ||
this->blobs_[3]->gpu_data(), // mean | ||
this->blobs_[4]->gpu_data(), // variance | ||
epsilon_)); | ||
} else { | ||
LOG(FATAL) << "Unknown phase"; | ||
} | ||
} | ||
|
||
template <typename Dtype> | ||
void CuDNNBatchNormLayer<Dtype>::Backward_gpu( | ||
const vector<Blob<Dtype>*>& top, | ||
const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom) { | ||
const Dtype* top_data = top[0]->gpu_data(); | ||
const Dtype* top_diff = top[0]->gpu_diff(); | ||
const Dtype* bottom_data = bottom[0]->gpu_data(); | ||
const Dtype* save_mean = save_mean_.gpu_data(); | ||
const Dtype* save_inv_var = save_inv_var_.gpu_data(); | ||
|
||
Dtype* bottom_diff = bottom[0]->mutable_gpu_diff(); | ||
const Dtype* scale_data = this->blobs_[0]->gpu_data(); | ||
Dtype* scale_diff = this->blobs_[0]->mutable_gpu_diff(); | ||
Dtype* bias_diff = this->blobs_[1]->mutable_gpu_diff(); | ||
|
||
// call Batch Normalization Backward | ||
CUDNN_CHECK(cudnnBatchNormalizationBackward( | ||
Caffe::cudnn_handle(), | ||
mode_, | ||
cudnn::dataType<Dtype>::one, | ||
cudnn::dataType<Dtype>::zero, | ||
bottom_desc_, | ||
bottom_data, | ||
bottom_desc_, | ||
top_diff, | ||
bottom_desc_, | ||
bottom_diff, | ||
scale_bias_mean_var_desc_, | ||
scale_data, | ||
scale_diff, | ||
bias_diff, | ||
this->epsilon_, | ||
save_mean, | ||
save_inv_var)); | ||
} | ||
|
||
INSTANTIATE_LAYER_GPU_FUNCS(CuDNNBatchNormLayer); | ||
|
||
} // namespace caffe | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters