• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright 2020 Huawei Technologies Co., Ltd
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "src/runtime/kernel/arm/fp32/convolution_depthwise_fp32.h"
18 #include "include/errorcode.h"
19 
20 using mindspore::lite::RET_ERROR;
21 using mindspore::lite::RET_INFER_INVALID;
22 using mindspore::lite::RET_OK;
23 
24 namespace mindspore::kernel {
Init()25 int ConvolutionDepthwiseCPUKernel::Init() {
26   CHECK_LESS_RETURN(in_tensors_.size(), C2NUM);
27   CHECK_LESS_RETURN(out_tensors_.size(), 1);
28   if (op_parameter_->is_train_session_) {
29     auto weight_tensor = in_tensors_.at(kWeightIndex);
30     CHECK_NULL_RETURN(weight_tensor);
31     int pack_weight_size = weight_tensor->Batch() * weight_tensor->Height() * weight_tensor->Width();
32     if (pack_weight_size >= std::numeric_limits<int>::max() / static_cast<int>(sizeof(float))) {
33       MS_LOG(ERROR) << "pack_weight_size is invalid, pack_weight_size: " << pack_weight_size;
34       return RET_ERROR;
35     }
36     set_workspace_size(pack_weight_size * sizeof(float));
37   }
38   auto ret = InitConvWeightBias();
39   if (ret != RET_OK) {
40     MS_LOG(ERROR) << "Convolution depthwise fp32 InitConvWeightBias failed.";
41     return RET_ERROR;
42   }
43   if (!InferShapeDone()) {
44     return RET_OK;
45   }
46   return ReSize();
47 }
48 
ReSize()49 int ConvolutionDepthwiseCPUKernel::ReSize() {
50   auto ret = ConvolutionBaseCPUKernel::Init();
51   if (ret != RET_OK) {
52     MS_LOG(ERROR) << "ConvolutionBaseCPUKernel::Init() return is:" << ret;
53     return ret;
54   }
55   conv_param_->thread_num_ = MSMIN(thread_count_, conv_param_->output_h_);
56   if (conv_param_->thread_num_ <= 0) {
57     MS_LOG(ERROR) << "conv_param_->thread_num_ must be greater than 0!";
58     return RET_ERROR;
59   }
60   return RET_OK;
61 }
62 
DoExecute(int task_id)63 int ConvolutionDepthwiseCPUKernel::DoExecute(int task_id) {
64   auto ret = ConvDw(output_ptr_, input_ptr_, reinterpret_cast<float *>(packed_weight_),
65                     reinterpret_cast<float *>(bias_data_), conv_param_, task_id);
66   return ret;
67 }
68 
ConvDwRun(void * cdata,int task_id,float lhs_scale,float rhs_scale)69 int ConvDwRun(void *cdata, int task_id, float lhs_scale, float rhs_scale) {
70   auto conv_dw = reinterpret_cast<ConvolutionDepthwiseCPUKernel *>(cdata);
71   auto ret = conv_dw->DoExecute(task_id);
72   if (ret != RET_OK) {
73     MS_LOG(ERROR) << "ConvolutionDepthwiseRun error task_id[" << task_id << "] error_code[" << ret << "]";
74     return RET_ERROR;
75   }
76   return RET_OK;
77 }
78 
Run()79 int ConvolutionDepthwiseCPUKernel::Run() {
80   if (RepackWeight() != RET_OK) {
81     MS_LOG(ERROR) << "Repack weight failed.";
82     return RET_ERROR;
83   }
84 
85   auto input_tensor = in_tensors_.at(kInputIndex);
86   input_ptr_ = reinterpret_cast<float *>(input_tensor->data());
87   MS_CHECK_FALSE(input_ptr_ == nullptr, RET_ERROR);
88   auto output_tensor = out_tensors_.at(kOutputIndex);
89   output_ptr_ = reinterpret_cast<float *>(output_tensor->data());
90   MS_CHECK_FALSE(output_ptr_ == nullptr, RET_ERROR);
91 
92   auto ret = ParallelLaunch(this->ms_context_, ConvDwRun, this, conv_param_->thread_num_);
93   if (ret != RET_OK) {
94     MS_LOG(ERROR) << "ConvDwRun error: error_code[" << ret << "]";
95     return RET_ERROR;
96   }
97   return RET_OK;
98 }
99 
PackWeight()100 void ConvolutionDepthwiseCPUKernel::PackWeight() {
101   auto weight_tensor = in_tensors_.at(kWeightIndex);
102   void *origin_weight = (op_parameter_->is_train_session_) ? weight_tensor->data() : origin_weight_;
103   MS_ASSERT(origin_weight != nullptr);
104   PackWeightKHWToHWKFp32(reinterpret_cast<float *>(origin_weight), reinterpret_cast<float *>(packed_weight_),
105                          weight_tensor->Height() * weight_tensor->Width(), weight_tensor->Batch());
106 }
107 
MallocWeightBiasData()108 int ConvolutionDepthwiseCPUKernel::MallocWeightBiasData() {
109   auto weight_tensor = in_tensors_.at(kWeightIndex);
110   int channel = weight_tensor->Batch();
111   int pack_weight_size = weight_tensor->Batch() * weight_tensor->Height() * weight_tensor->Width();
112   if (pack_weight_size >= std::numeric_limits<int>::max() / static_cast<int>(sizeof(float))) {
113     MS_LOG(ERROR) << "pack_weight_size is invalid, pack_weight_size: " << pack_weight_size;
114     return RET_ERROR;
115   }
116   if (!op_parameter_->is_train_session_) {
117     packed_weight_ = malloc(pack_weight_size * sizeof(float));
118     if (packed_weight_ == nullptr) {
119       MS_LOG(ERROR) << "Malloc buffer failed.";
120       return RET_ERROR;
121     }
122   }
123 
124   bias_data_ = malloc(channel * sizeof(float));
125   if (bias_data_ == nullptr) {
126     MS_LOG(ERROR) << "Malloc buffer failed.";
127     return RET_ERROR;
128   }
129   memset(bias_data_, 0, channel * sizeof(float));
130   return RET_OK;
131 }
132 }  // namespace mindspore::kernel
133