| 7 | |
| 8 | template <typename Dtype> |
| 9 | void Im2colLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom, |
| 10 | const vector<Blob<Dtype>*>& top) { |
| 11 | ConvolutionParameter conv_param = this->layer_param_.convolution_param(); |
| 12 | force_nd_im2col_ = conv_param.force_nd_im2col(); |
| 13 | const int input_num_dims = bottom[0]->shape().size(); |
| 14 | channel_axis_ = bottom[0]->CanonicalAxisIndex(conv_param.axis()); |
| 15 | const int first_spatial_dim = channel_axis_ + 1; |
| 16 | num_spatial_axes_ = input_num_dims - first_spatial_dim; |
| 17 | CHECK_GE(num_spatial_axes_, 1); |
| 18 | vector<int> dim_blob_shape(1, num_spatial_axes_); |
| 19 | // Setup filter kernel dimensions (kernel_shape_). |
| 20 | kernel_shape_.Reshape(dim_blob_shape); |
| 21 | int* kernel_shape_data = kernel_shape_.mutable_cpu_data(); |
| 22 | if (conv_param.has_kernel_h() || conv_param.has_kernel_w()) { |
| 23 | CHECK_EQ(num_spatial_axes_, 2) |
| 24 | << "kernel_h & kernel_w can only be used for 2D convolution."; |
| 25 | CHECK_EQ(0, conv_param.kernel_size_size()) |
| 26 | << "Either kernel_size or kernel_h/w should be specified; not both."; |
| 27 | kernel_shape_data[0] = conv_param.kernel_h(); |
| 28 | kernel_shape_data[1] = conv_param.kernel_w(); |
| 29 | } else { |
| 30 | const int num_kernel_dims = conv_param.kernel_size_size(); |
| 31 | CHECK(num_kernel_dims == 1 || num_kernel_dims == num_spatial_axes_) |
| 32 | << "kernel_size must be specified once, or once per spatial dimension " |
| 33 | << "(kernel_size specified " << num_kernel_dims << " times; " |
| 34 | << num_spatial_axes_ << " spatial dims);"; |
| 35 | for (int i = 0; i < num_spatial_axes_; ++i) { |
| 36 | kernel_shape_data[i] = |
| 37 | conv_param.kernel_size((num_kernel_dims == 1) ? 0 : i); |
| 38 | } |
| 39 | } |
| 40 | for (int i = 0; i < num_spatial_axes_; ++i) { |
| 41 | CHECK_GT(kernel_shape_data[i], 0) << "Filter dimensions must be nonzero."; |
| 42 | } |
| 43 | // Setup stride dimensions (stride_). |
| 44 | stride_.Reshape(dim_blob_shape); |
| 45 | int* stride_data = stride_.mutable_cpu_data(); |
| 46 | if (conv_param.has_stride_h() || conv_param.has_stride_w()) { |
| 47 | CHECK_EQ(num_spatial_axes_, 2) |
| 48 | << "stride_h & stride_w can only be used for 2D convolution."; |
| 49 | CHECK_EQ(0, conv_param.stride_size()) |
| 50 | << "Either stride or stride_h/w should be specified; not both."; |
| 51 | stride_data[0] = conv_param.stride_h(); |
| 52 | stride_data[1] = conv_param.stride_w(); |
| 53 | } else { |
| 54 | const int num_stride_dims = conv_param.stride_size(); |
| 55 | CHECK(num_stride_dims == 0 || num_stride_dims == 1 || |
| 56 | num_stride_dims == num_spatial_axes_) |
| 57 | << "stride must be specified once, or once per spatial dimension " |
| 58 | << "(stride specified " << num_stride_dims << " times; " |
| 59 | << num_spatial_axes_ << " spatial dims);"; |
| 60 | const int kDefaultStride = 1; |
| 61 | for (int i = 0; i < num_spatial_axes_; ++i) { |
| 62 | stride_data[i] = (num_stride_dims == 0) ? kDefaultStride : |
| 63 | conv_param.stride((num_stride_dims == 1) ? 0 : i); |
| 64 | CHECK_GT(stride_data[i], 0) << "Stride dimensions must be nonzero."; |
| 65 | } |
| 66 | } |
nothing calls this directly
no test coverage detected