in caffe/src/caffe/layers/octree_base_conv_layer.cpp [137:220]
void OctreeBaseConvLayer<Dtype>::Reshape(const vector<Blob<Dtype>*>& bottom,
const vector<Blob<Dtype>*>& top) {
// a workaround for the first time reshape
if (top[0]->count() == 0) {
vector<int> top_shape = bottom[0]->shape();
top_shape[1] = num_output_;
top_shape[2] = 8;
top[0]->Reshape(top_shape);
return;
}
// set octree_batch_
bool octree_in = bottom.size() == 2;
Blob<Dtype>& the_octree = octree_in ? *bottom[1] : Octree::get_octree(Dtype(0));
octree::set_octree_parser(octree_batch_, the_octree);
// check bottom shape
int bottom_h = bottom[0]->shape(2);
int nnum = octree_batch_.info().node_num(curr_depth_);
if (nnum != 0) {
CHECK_EQ(bottom_h, nnum)
<< "The octree node number is inconsistent in " << this->layer_param_.name()
<< ", and the curr_depth_ = " << curr_depth_;
} else {
CHECK_EQ(bottom_h, 1);
LOG(INFO) << "Warning in layer" << this->layer_param().name()
<< ": This octree layer is empty";
}
// compute top shape
int top_blob_depth = curr_depth_;
if (stride_ == 2) {
if (is_deconvolution_layer()) top_blob_depth++;
else top_blob_depth--;
CHECK(0 <= top_blob_depth && top_blob_depth <= octree_batch_.info().depth())
<< "Error in " << this->layer_param_.name() << ": top_blob_depth "
<< top_blob_depth << "- octree_depth " << octree_batch_.info().depth();
}
int top_h = octree_batch_.info().node_num(top_blob_depth);
if (top_h == 0) top_h = 1;
vector<int> top_shape{ 1, num_output_, top_h, 1 };
top[0]->Reshape(top_shape);
// reshape workspce
workspace_depth_ = curr_depth_;
if (is_deconvolution_layer() && stride_ == 2) workspace_depth_++;
workspace_h_ = bottom_h;
if (stride_ == 2) {
if (is_deconvolution_layer()) workspace_h_ = top_h >> 3;
else workspace_h_ = bottom_h >> 3;
}
workspace_n_ = 1;
workspace_ha_ = workspace_h_;
// In some other layers, such as octree_pooling, the workspace blob is also
// resized, without considering the get_workspace_maxsize(), the actual
// size of workspace might be larger than get_workspace_maxsize(), so
// calculate the MAX_SIZE from get_workspace_maxsize() and its original count()
const int MAX_SIZE = std::max(Octree::get_workspace_maxsize(), workspace_->count());
int ideal_size = workspace_h_ * kernel_dim_;
if (ideal_size > MAX_SIZE && !is_1x1_) {
workspace_n_ = (ideal_size + MAX_SIZE - 1) / MAX_SIZE;
workspace_ha_ = (workspace_h_ + workspace_n_ - 1) / workspace_n_;
}
workspace_->Reshape(vector<int> { 1, kernel_dim_, workspace_ha_, 1 });
// reshape result_buffer_
if (workspace_n_ > 1) {
result_buffer_->Reshape(vector<int> { conv_out_channels_, workspace_ha_ });
}
// reshape data_buffer_
if (stride_ == 2) {
data_buffer_shape_ = vector<int> { 1, conv_out_channels_, workspace_h_, 1 };
data_buffer_->Reshape(data_buffer_shape_);
}
// Set up the all ones "bias multiplier" for adding biases by BLAS
if (bias_term_) {
bias_multiplier_h_ = is_deconvolution_layer() ? top_h : workspace_h_;
bias_multiplier_.Reshape(vector<int> { bias_multiplier_h_ });
caffe_set(bias_multiplier_.count(), Dtype(1),
bias_multiplier_.mutable_cpu_data());
}
}