void ConvBaseOperator::reshapeImageDescriptors() { hl_tensor_reshape(imageDesc_, 1, channels_, imageH_, imageW_, channels_ * imageH_ * imageW_, imageH_ * imageW_, imageW_, 1); hl_tensor_reshape(outputDesc_, 1, numFilters_, outputH_, outputW_, numFilters_ * outputH_ * outputW_, outputH_ * outputW_, outputW_, 1); hl_reset_convolution_descriptor(convDesc_, imageDesc_, filterDesc_, paddingY_, padding_, strideY_, stride_); }
void CudnnConvLayer::forward(PassType passType) { Layer::forward(passType); int batchSize = getInput(0).getBatchSize(); resetOutput(batchSize, calOutputSize()); for (size_t i = 0; i != inputLayers_.size(); ++i) { projections_[i]->forward(&getInput(i), &getOutput(), passType); } if (biases_) { REGISTER_TIMER_INFO("CudnnConvBiasTimer", getName().c_str()); int batchSize = inputLayers_[0]->getOutputValue()->getHeight(); hl_tensor_reshape(outputDesc_, batchSize, numFilters_ / groups_[0], outputH_[0], outputW_[0], numFilters_ * outputH_[0] * outputW_[0], outputH_[0] * outputW_[0], outputW_[0], 1); outputOffset_ = getOutputValue()->getWidth() / groups_[0]; for (int g = 0; g < groups_[0]; ++g) { real *biasData = biases_->getW()->getData() + biasOffset_ * g; real *outData = getOutputValue()->getData() + outputOffset_ * g; hl_convolution_forward_add_bias(biasDesc_, biasData, outputDesc_, outData); } } forwardActivation(); }
bool CudnnConvLayer::init(const LayerMap &layerMap, const ParameterMap ¶meterMap) { if (!ConvBaseLayer::init(layerMap, parameterMap)) return false; CHECK(useGpu_) << "CudnnConvLayer only support gpu"; CHECK_EQ(inputLayers_.size(), parameters_.size()); projections_.reserve(inputLayers_.size()); projConf_.reserve(inputLayers_.size()); numFilters_ = config_.num_filters(); CHECK(config_.shared_biases()); for (size_t i = 0; i < inputLayers_.size(); i++) { ProjectionConfig* conf = new ProjectionConfig(); conf->set_type("conv"); conf->set_num_filters(numFilters_); ConvConfig* convConf = conf->mutable_conv_conf(); *convConf = *(config_.mutable_inputs(i)->mutable_conv_conf()); conf->set_input_size(getPrev(i)->getSize()); conf->set_output_size(getSize()); projConf_.emplace_back(conf); projections_.emplace_back(Projection::create(*projConf_[i], parameters_[i], useGpu_)); } if (biases_.get() && sharedBiases_) { hl_create_tensor_descriptor(&biasDesc_); hl_create_tensor_descriptor(&outputDesc_); hl_tensor_reshape(biasDesc_, 1, numFilters_ / groups_[0], 1, 1); biasOffset_ = numFilters_ / groups_[0]; } return true; }
void ConvBaseProjection::reshapeTensorDesc(int batchSize) { // The stride between two consecutive samples in the output of ConvProjection // may not be numFilters_ * outputH_ * outputW_ (conv) or // channels_ * imageH_ * imageW_ (deconv) // for example, in the case of layer ConcatenateLayer2 with two // ConvProjection, the stride is the output_size of layer ConcatenateLayer2. // So the calculation of nStride is different from CudnnConvLayer. size_t nStrideImage, nStrideOutput; if (isDeconv_) { nStrideImage = out_->value->getStride(); nStrideOutput = numFilters_ * outputH_ * outputW_; } else { nStrideImage = channels_ * imageH_ * imageW_; nStrideOutput = out_->value->getStride(); } hl_tensor_reshape(imageDesc_, batchSize, channels_ / groups_, imageH_, imageW_, nStrideImage, imageH_ * imageW_, imageW_, 1); hl_tensor_reshape(outputDesc_, batchSize, numFilters_ / groups_, outputH_, outputW_, nStrideOutput, outputH_ * outputW_, outputW_, 1); hl_reset_convolution_descriptor(convDesc_, imageDesc_, filterDesc_, paddingH_, paddingW_, strideH_, strideW_, dilationH_, dilationW_); }