!41776 fix quant dynamic code check

Merge pull request !41776 from yeyunpeng2020/master_code_check
This commit is contained in:
i-robot 2022-09-14 03:00:22 +00:00 committed by Gitee
commit 66b4688222
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
23 changed files with 156 additions and 41 deletions

View File

@ -237,6 +237,7 @@ REG_INFER(LRN, PrimType_LRN, CommonInferShapeWithNHWC)
REG_INFER(L2Normalize, PrimType_L2NormalizeFusion, CommonInferShape)
REG_INFER(Neg, PrimType_Neg, CommonInferShape)
REG_INFER(NegGrad, PrimType_NegGrad, CommonGradInferShape)
REG_INFER(OnesLike, PrimType_OnesLike, CommonInferShape)
REG_INFER(PowerGrad, PrimType_PowerGrad, CommonGradInferShape)
REG_INFER(PReLU, PrimType_PReLUFusion, CommonInferShape)
REG_INFER(Reciprocal, PrimType_Reciprocal, CommonInferShape)

View File

@ -257,6 +257,10 @@ std::unique_ptr<Byte[]> Decrypt(const std::string &lib_path, size_t *decrypt_len
std::vector<char> int_buf(sizeof(int32_t));
auto decrypt_data = std::make_unique<Byte[]>(data_size);
if (decrypt_data == nullptr) {
MS_LOG(ERROR) << "decrypt_data is nullptr.";
return nullptr;
}
int32_t decrypt_block_len;
size_t offset = 0;

View File

@ -0,0 +1,52 @@
/**
* Copyright 2022 Huawei Technologies Co., Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "src/litert/kernel/cpu/fp32/oneslike_fp32.h"
#include "schema/model_generated.h"
#include "nnacl/base/zeroslike_base.h"
#include "src/litert/kernel_registry.h"
#include "include/errorcode.h"
using mindspore::kernel::KERNEL_ARCH;
using mindspore::lite::KernelRegistrar;
using mindspore::lite::RET_ERROR;
using mindspore::lite::RET_OK;
using mindspore::schema::PrimitiveType_OnesLike;
namespace mindspore::kernel {
int OnesLikeCPUKernel::Prepare() {
CHECK_LESS_RETURN(in_tensors_.size(), 1);
CHECK_LESS_RETURN(out_tensors_.size(), 1);
return RET_OK;
}
int OnesLikeCPUKernel::Run() {
auto output = out_tensors_[0];
CHECK_NULL_RETURN(output);
if (output->data_type() == kNumberTypeInt32) {
ApproximateOnesLike(static_cast<int *>(output->data()), output->ElementsNum());
} else if (output->data_type() == kNumberTypeFloat32) {
ApproximateOnesLike(static_cast<float *>(output->data()), output->ElementsNum());
}
return RET_OK;
}
REG_KERNEL(kCPU, kNumberTypeInt32, PrimitiveType_OnesLike, LiteKernelCreator<OnesLikeCPUKernel>)
REG_KERNEL(kCPU, kNumberTypeFloat32, PrimitiveType_OnesLike, LiteKernelCreator<OnesLikeCPUKernel>)
#ifdef ENABLE_FP16
REG_KERNEL(kCPU, kNumberTypeFloat16, PrimitiveType_OnesLike, LiteKernelCreator<OnesLikeCPUKernel>)
#endif
} // namespace mindspore::kernel

View File

@ -0,0 +1,46 @@
/**
* Copyright 2022 Huawei Technologies Co., Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MINDSPORE_LITE_SRC_RUNTIME_KERNEL_CPU_FP32_ONESLike_FP32_H_
#define MINDSPORE_LITE_SRC_RUNTIME_KERNEL_CPU_FP32_ONESLike_FP32_H_
#include <vector>
#include "src/litert/lite_kernel.h"
namespace mindspore::kernel {
class OnesLikeCPUKernel : public LiteKernel {
public:
OnesLikeCPUKernel(OpParameter *parameter, const std::vector<lite::Tensor *> &inputs,
const std::vector<lite::Tensor *> &outputs, const lite::InnerContext *ctx)
: LiteKernel(parameter, inputs, outputs, ctx) {}
~OnesLikeCPUKernel() = default;
int Prepare() override;
int ReSize() override { return 0; }
int Run() override;
private:
template <typename T>
void ApproximateOnesLike(T *output, int data_size) {
for (int i = 0; i < data_size; ++i) {
output[i] = 1;
}
return;
}
};
} // namespace mindspore::kernel
#endif // MINDSPORE_LITE_SRC_RUNTIME_KERNEL_CPU_FP32_ONESLike_FP32_H_

View File

@ -48,8 +48,8 @@ class DynamicQuantCPUKernel : public LiteKernel {
int8_t *int8_ptr_ = nullptr;
float *float32_ptr_ = nullptr;
float real_min_array_[8];
float real_max_array_[8];
float real_min_array_[8] = {0};
float real_max_array_[8] = {0};
float real_min_ = FLT_MAX;
float real_max_ = FLT_MIN;
int32_t src_dtype_{0};

View File

@ -34,7 +34,7 @@ class MatMulDynamicSdotInt8Kernel : public MatmulDynamicBaseInt8CPUKernel {
int MatMulDynamicArm64SdotPre(int task_id);
int MatMulDynamicArm64SdotImpl(int task_id);
private:
protected:
void InitParameter() override;
private:

View File

@ -276,7 +276,7 @@ bool MetaGraphSerializer::SerializeModel(const void *content, size_t size, const
if (encrypt_content == nullptr || encrypt_len == 0) {
MS_LOG(ERROR) << "Encrypt failed.";
model_fs_->close();
return RET_ERROR;
return false;
}
model_fs_->write(reinterpret_cast<const char *>(encrypt_content.get()), encrypt_len);
} else {
@ -284,7 +284,7 @@ bool MetaGraphSerializer::SerializeModel(const void *content, size_t size, const
}
if (model_fs_->bad()) {
MS_LOG(ERROR) << "Write model file failed: " << save_model_path_;
return RET_ERROR;
return false;
}
#ifndef _MSC_VER
chmod(save_model_path_.c_str(), S_IRUSR);

View File

@ -129,7 +129,6 @@ int PreprocessParser::ParseCalibratePath(const std::string &str, std::map<std::s
}
(*value)[name] = string_split.at(string_split.size() - 1);
} else {
auto name_str = string_split_quotation.at(0);
auto name = string_split.at(0);
for (size_t i = 1; i < string_split.size() - 1; ++i) {
name += ":" + string_split.at(i);

View File

@ -315,7 +315,7 @@ int PreInference(const schema::MetaGraphT &meta_graph, bool train_model) {
return RET_ERROR;
}
for (auto &tensor : model.GetInputs()) {
if (tensor.Shape().empty() || tensor.DataSize() <= 0 ||
if (tensor.Shape().empty() || tensor.DataSize() == 0 ||
std::find(tensor.Shape().begin(), tensor.Shape().end(), -1) != tensor.Shape().end()) {
MS_LOG(WARNING) << tensor.Name() << " is dynamic shape and will not be pre-infer.";
return RET_OK;

View File

@ -110,7 +110,7 @@ class BiasCorrectionStrategy {
int CalculatePerChannelMeans(const T *tensor_data, size_t elem_count, std::vector<int64_t> shapes,
std::vector<float> *per_channel_mean) const {
CHECK_NULL_RETURN(tensor_data);
MS_CHECK_GT(elem_count, 0, RET_ERROR);
MS_CHECK_TRUE_RET(elem_count != 0, RET_PARAM_INVALID);
// suppose the activation format: NHWC
MS_CHECK_TRUE_RET(!shapes.empty(), RET_ERROR);
auto channels = shapes[shapes.size() - 1];
@ -127,7 +127,7 @@ class BiasCorrectionStrategy {
}
sum += tensor_data[index];
}
MS_CHECK_GT(bucket_size, 0, RET_ERROR);
MS_CHECK_TRUE_RET(bucket_size != 0, RET_PARAM_INVALID);
sum = sum / bucket_size;
MS_CHECK_GT(static_cast<int>(per_channel_mean->size()), i, RET_ERROR);
per_channel_mean->at(i) = sum;

View File

@ -40,7 +40,7 @@ class CLEPattern : public opt::MultiplePatternProcessPass {
AnfNodePtr Process(const std::string &, const FuncGraphPtr &, const AnfNodePtr &, const EquivPtr &) const override;
std::unordered_map<std::string, VectorRef> DefinePatterns() const override;
std::vector<CombinationLayer> GetCombinationLayer() { return combination_layer_; }
std::vector<CombinationLayer> GetCombinationLayer() const { return combination_layer_; }
private:
VectorRef DefineConvWithConvPattern() const;

View File

@ -61,7 +61,7 @@ int CLEStrategy::CalcDataRange(const float *data, size_t element_cnt, const std:
std::vector<float> *ranges) {
CHECK_NULL_RETURN(data);
CHECK_NULL_RETURN(ranges);
std::vector<std::vector<int>> buckets_data_index;
std::vector<std::vector<size_t>> buckets_data_index;
auto ret = GetBucketAllIndex(dims, preferred_dim, &buckets_data_index);
if (ret != RET_OK) {
MS_LOG(ERROR) << "Get bucket all index failed.";
@ -75,6 +75,7 @@ int CLEStrategy::CalcDataRange(const float *data, size_t element_cnt, const std:
float range = 0;
for (size_t j = 0; j < bucket.size(); ++j) {
auto index = bucket[j];
MS_CHECK_LT(index, element_cnt, RET_ERROR);
range = std::max(range, std::abs(data[index]));
}
ranges->at(i) = range;

View File

@ -258,8 +258,9 @@ int DebugInfoManager::SetOriginStaticInfo(QuantDebugInfo *quant_debug_info, cons
}
int DebugInfoManager::SetQuantStaticInfo(const std::vector<mindspore::lite::Tensor *> &inputs,
OpParameter *op_parameter, int tensor_index, QuantDebugInfo *quant_debug_info,
const mindspore::lite::Tensor &tensor, const quant::DebugMode &debug_mode) {
const OpParameter *op_parameter, int tensor_index,
QuantDebugInfo *quant_debug_info, const mindspore::lite::Tensor &tensor,
const quant::DebugMode &debug_mode) {
MS_CHECK_TRUE_MSG(quant_debug_info != nullptr, RET_ERROR, "quant_debug_info is nullptr.");
auto preferred_dim =
mindspore::lite::WeightDecoder::GetPreferredDim(inputs, op_parameter, tensor_index, tensor.shape(), Version());

View File

@ -110,7 +110,7 @@ class DebugInfoManager {
int SetOriginStaticInfo(QuantDebugInfo *quant_debug_info, const mindspore::lite::Tensor &tensor,
const quant::DebugMode &debug_mode);
int SetQuantStaticInfo(const std::vector<mindspore::lite::Tensor *> &inputs, OpParameter *op_parameter,
int SetQuantStaticInfo(const std::vector<mindspore::lite::Tensor *> &inputs, const OpParameter *op_parameter,
int tensor_index, QuantDebugInfo *quant_debug_info, const mindspore::lite::Tensor &tensor,
const quant::DebugMode &debug_mode);
@ -199,7 +199,7 @@ class DebugInfoManager {
private:
// the key is {node_name, tensor_index}
std::map<PrimaryKey, QuantDebugInfo> origin_info_;
// Use vector to preserve ordert, There may be more nodes, such as QuantCast, bias etc.
// Use vector to preserve ordered, There may be more nodes, such as QuantCast, bias etc.
std::vector<QuantDebugInfo> compared_info_;
std::vector<QuantParamExtend> quant_params_;
std::vector<std::vector<QuantDebugInfo>> output_infos_;

View File

@ -113,6 +113,7 @@ int FSEEncoder::Compress(const ParameterPtr &weight, const std::vector<schema::Q
ret = NormalizeFrequency(&fse_quant, &table_log);
if (ret != RET_OK) {
MS_LOG(ERROR) << "Normalize frequency failed.";
free(fse_quant.symbol_table);
return ret;
}
FSEBitStream bs;

View File

@ -575,7 +575,6 @@ int FullQuantQuantizer::InitDeviceConfig(const FuncGraphPtr &func_graph) {
default:
MS_LOG(ERROR) << " Unsupported device " << param_->fullQuantParam.target_device;
return RET_ERROR;
break;
}
InitQMinMax();
calibrator_ =

View File

@ -227,11 +227,17 @@ int InsertQuantNodeManager::NewDynamicQuantNode(const FuncGraphPtr &graph, const
}
auto input = cnode->input(kInputIndex + kPrimitiveCOffset);
if (input->isa<mindspore::CNode>() || IsGraphInput(input)) {
InsertDynamicQuantWithIndex(graph, cnode, kInputIndex + kPrimitiveCOffset);
auto ret = InsertDynamicQuantWithIndex(graph, cnode, kInputIndex + kPrimitiveCOffset);
if (ret != RET_OK) {
MS_LOG(ERROR) << "Insert dynamic quant with index failed.";
}
}
auto weight = cnode->input(kWeightIndex + kPrimitiveCOffset);
if (weight->isa<mindspore::CNode>() || IsGraphInput(weight)) {
InsertDynamicQuantWithIndex(graph, cnode, kWeightIndex + kPrimitiveCOffset);
auto ret = InsertDynamicQuantWithIndex(graph, cnode, kWeightIndex + kPrimitiveCOffset);
if (ret != RET_OK) {
MS_LOG(ERROR) << "Insert dynamic quant with index failed.";
}
}
return RET_OK;
}

View File

@ -61,7 +61,7 @@ bool QuantStrategy::CanTensorQuantized(const CNodePtr &cnode, const AnfNodePtr &
auto ret = GetElementNumFromShape(ConvertShapeVectorToInt32(weight_shape), &total_shape_size);
if (ret != RET_OK) {
MS_LOG(ERROR) << "Get element num from shape failed.";
return ret;
return false;
}
if (total_shape_size < 0 || static_cast<size_t>(total_shape_size) <= min_quant_weight_size_) {
MS_LOG(INFO) << "shape_size " << total_shape_size << " less min_quant_weight_size_ " << min_quant_weight_size_;

View File

@ -133,13 +133,17 @@ int DoQuantDebug(const FuncGraphPtr &old_graph, const std::shared_ptr<ConverterP
auto quant_model = std::make_shared<mindspore::Model>();
CHECK_NULL_RETURN(quant_model);
size_t size = 0;
auto ret = BuildModelByFuncGraph(quant_model, old_graph, param, &size);
if (ret != kSuccess) {
auto status = BuildModelByFuncGraph(quant_model, old_graph, param, &size);
if (status != kSuccess) {
MS_LOG(ERROR) << "Build model failed";
return RET_ERROR;
}
std::map<std::string, OpParameter *> op_parameters;
FetchOpParameterFromFuncGraph(old_graph, &op_parameters);
auto ret = FetchOpParameterFromFuncGraph(old_graph, &op_parameters);
if (ret != RET_OK) {
MS_LOG(ERROR) << "Fetch op parameter from funcgraph failed";
return ret;
}
DebugInfoManager manager;
auto quant_lite_model = ParseLiteModel(old_graph, param);
@ -151,8 +155,8 @@ int DoQuantDebug(const FuncGraphPtr &old_graph, const std::shared_ptr<ConverterP
MS_LOG(ERROR) << "Origin lite model nullptr.";
return RET_ERROR;
}
auto status = manager.CompareOriginWithQuant(origin_model, quant_model, op_parameters, param, *origin_lite_model,
*quant_lite_model);
ret = manager.CompareOriginWithQuant(origin_model, quant_model, op_parameters, param, *origin_lite_model,
*quant_lite_model);
auto free_buffer = [&] {
for (auto parameter : op_parameters) {
if (parameter.second != nullptr) {
@ -162,10 +166,10 @@ int DoQuantDebug(const FuncGraphPtr &old_graph, const std::shared_ptr<ConverterP
}
op_parameters.clear();
};
if (status != RET_OK) {
if (ret != RET_OK) {
MS_LOG(ERROR) << "Compare origin with quant failed.";
free_buffer();
return status;
return ret;
}
free_buffer();
return RET_OK;

View File

@ -428,10 +428,9 @@ int GetDeConvPreferredDim(const PrimitivePtr &primitive, const std::vector<int>
if (prim->get_in_channel() == prim->get_group() && prim->get_out_channel() == prim->get_group()) {
// DepthWise-DeConv (CO\CI) KH KW 1
return 0;
} else {
// DeConv:CI KH KW CO
return dims.size() - 1;
}
// DeConv:CI KH KW CO
return dims.size() - 1;
}
int GetGatherPreferredDim(const CNodePtr &cnode) {
@ -546,9 +545,9 @@ bool CheckNodeInSet(const CNodePtr &cnode, const std::set<PrimitivePtr> &support
return false;
}
int DeQuantData(const mindspore::MSTensor *tensor, std::vector<double> *dequant_data, int preferred_dim) {
int DeQuantData(const mindspore::MSTensor *tensor, std::vector<double> *dequant_data) {
return DeQuantData(reinterpret_cast<const int8_t *>(tensor->Data().get()), tensor->ElementNum(),
tensor->QuantParams(), dequant_data, preferred_dim);
tensor->QuantParams(), dequant_data);
}
int GetElementNumFromShape(const std::vector<int> &dims, int *total_size) {
@ -562,7 +561,8 @@ int GetElementNumFromShape(const std::vector<int> &dims, int *total_size) {
}
int GetBucketAllIndex(const std::vector<int> &dims, int preferred_dim,
std::vector<std::vector<int>> *buckets_data_index) {
std::vector<std::vector<size_t>> *buckets_data_index) {
CHECK_NULL_RETURN(buckets_data_index);
int outer = 1;
for (int i = 0; i < preferred_dim; i++) {
outer *= dims[i];
@ -577,7 +577,7 @@ int GetBucketAllIndex(const std::vector<int> &dims, int preferred_dim,
}
for (int i = 0; i < bucket_count; i++) {
auto index = i * inner;
std::vector<int> bucket_index(inner * outer);
std::vector<size_t> bucket_index(inner * outer);
for (int j = 0; j < outer; j++) {
for (int k = 0; k < inner; k++) {
bucket_index[j * inner + k] = index + k;

View File

@ -68,7 +68,7 @@ int GetPreferredDim(const CNodePtr &cnode, int input_index, const std::vector<in
std::vector<int> ConvertShapeVectorToInt32(const ShapeVector &dims);
int DeQuantData(const mindspore::MSTensor *tensor, std::vector<double> *dequant_data, int preferred_dim = 0);
int DeQuantData(const mindspore::MSTensor *tensor, std::vector<double> *dequant_data);
int GetQuantType(const CNodePtr &cnode, schema::QuantType *quant_type);
@ -87,7 +87,7 @@ int GetCastNodeType(const FuncGraphPtr &func_graph, const CNodePtr &cnode, CastN
template <typename T>
int DeQuantData(const int8_t *tensor_data, int64_t elements_num, std::vector<mindspore::QuantParam> quant_params,
std::vector<T> *dequant_data, int preferred_dim = 0) {
std::vector<T> *dequant_data) {
if (quant_params.size() != 1) {
MS_LOG(ERROR) << "unexpected quant_params size: " << quant_params.size() << " only support per-layer now.";
return RET_ERROR;
@ -117,7 +117,7 @@ bool CheckNodeInSet(const CNodePtr &cnode, const std::set<PrimitivePtr> &support
int GetElementNumFromShape(const std::vector<int> &dims, int *total_size);
int GetBucketAllIndex(const std::vector<int> &dims, int preferred_dim,
std::vector<std::vector<int>> *buckets_data_index);
std::vector<std::vector<size_t>> *buckets_data_index);
bool CheckControlFlowType(const AnfNodePtr &node);
} // namespace mindspore::lite::quant
#endif // MINDSPORE_LITE_TOOLS_CONVERTER_QUANTIZER_QUANTIZE_UTIL_H_

View File

@ -158,7 +158,7 @@ class TensorCompressor {
auto tensor_info = weight->default_param()->cast<tensor::TensorPtr>();
CHECK_NULL_RETURN(tensor_info);
auto quant_data = static_cast<T *>(tensor_info->data().data());
auto elem_cnt = tensor_info->DataSize();
int elem_cnt = tensor_info->DataSize();
auto channel_cnt = quant_params.size();
if (channel_cnt == 0) {
MS_LOG(ERROR) << "quant_params is empty.";
@ -188,13 +188,13 @@ class TensorCompressor {
}
// nz values indexing && get coor
std::vector<size_t> coors(nz_cnt);
size_t coors_index = 0;
size_t prev_index = -1;
for (size_t di = 0; di < elem_cnt; di++) {
int coors_index = 0;
int prev_index = -1;
for (int di = 0; di < elem_cnt; di++) {
auto cur_channel = di / elem_perchannel;
auto zp = quant_params[cur_channel].zeroPoint;
auto nz_value = quant_data[di];
if (nz_value != zp || (di - prev_index) >= static_cast<size_t>((1 << coor_best_bit))) {
if (nz_value != zp || static_cast<size_t>(di - prev_index) >= (1u << coor_best_bit)) {
MS_ASSERT(coors_index < nz_cnt);
coors[coors_index++] = di - prev_index - 1;
prev_index = di;

View File

@ -576,6 +576,7 @@ int FetchOpParameterFromFuncGraph(const FuncGraphPtr &func_graph, std::map<std::
MS_LOG(ERROR) << cnode->fullname_with_scope() << " FetchOpParameterFromNode failed. ";
return ret;
}
CHECK_NULL_RETURN(parameter);
parameter->thread_num_ = 1;
op_parameters->emplace(std::pair<std::string, OpParameter *>(cnode->fullname_with_scope(), parameter));
}