fix dynamic_pointer_cast to cast && avoid int mul overflow

This commit is contained in:
yeyunpeng2020 2021-10-28 11:41:02 +08:00
parent b7af2b0cf7
commit 27c4815fc2
6 changed files with 35 additions and 32 deletions

View File

@ -77,7 +77,7 @@
#include "tools/optimizer/format/to_nchw_format.h"
#include "tools/optimizer/format/to_nhwc_format.h"
#include "tools/converter/adapter/acl_pass.h"
#include "tools/converter/quantizer/parameter_optimizer.h"
#include "tools/converter/quantizer/parameter_tunner.h"
using std::string;
namespace mindspore::lite {

View File

@ -20,6 +20,7 @@
#include "include/errorcode.h"
#include "src/common/log_adapter.h"
#include "src/common/log_util.h"
#include "nnacl/op_base.h"
namespace mindspore::lite::quant {
int FSEDecoder::FSECreateStatesForDecoding(const uint32_t *symbol_frequency, int symbol_frequency_count, int table_log,
@ -117,6 +118,7 @@ int FSEDecoder::DeCompress(const schema::Tensor &src_tensor, Tensor *dst_tensor)
float *output = static_cast<float *>(dst_tensor->data());
CHECK_NULL_RETURN(output);
int out_sz = dst_tensor->ElementsNum();
MS_CHECK_GT(out_sz, 0, RET_ERROR);
// deserialize from `data`:
BitStream bs;

View File

@ -379,7 +379,7 @@ STATUS Calibrator::ComputeThreshold() {
bool already_computed = false;
auto input = cnode->input(i + 1);
if (input->isa<mindspore::CNode>()) {
auto input_cnode = std::dynamic_pointer_cast<mindspore::CNode>(input);
auto input_cnode = input->cast<CNodePtr>();
for (const auto &outputs_diverg_info : outputs_diverg_info_) {
if (already_computed) {
break;
@ -523,12 +523,12 @@ STATUS FullQuantQuantizer::DoWeightQuant(const std::string &op_name, const AnfNo
MS_LOG(ERROR) << "not a parameter";
return RET_PARAM_INVALID;
}
auto parameter = std::dynamic_pointer_cast<Parameter>(weight);
auto parameter = weight->cast<ParameterPtr>();
if (parameter == nullptr) {
MS_LOG(ERROR) << weight->fullname_with_scope() << " can not cast to Parameter";
return RET_NULL_PTR;
}
tensor::TensorPtr tensor_info = std::dynamic_pointer_cast<tensor::Tensor>(parameter->default_param());
auto tensor_info = parameter->default_param()->cast<tensor::TensorPtr>();
if (tensor_info == nullptr) {
MS_LOG(ERROR) << weight->fullname_with_scope() << " can not get value";
return RET_NULL_PTR;
@ -567,10 +567,10 @@ STATUS FullQuantQuantizer::DoBiasQuant(const AnfNodePtr &bias, const PrimitivePt
MS_LOG(ERROR) << "null pointer!";
return RET_NULL_PTR;
}
auto bias_parameter_ptr = std::dynamic_pointer_cast<Parameter>(bias);
auto bias_parameter_ptr = bias->cast<ParameterPtr>();
MS_ASSERT(bias_parameter_ptr != nullptr);
auto bias_default_param = bias_parameter_ptr->default_param();
auto bias_param = std::dynamic_pointer_cast<tensor::Tensor>(bias_default_param);
auto bias_param = bias_default_param->cast<tensor::TensorPtr>();
MS_ASSERT(bias_parameter != nullptr);
auto quant_param_holder = GetCNodeQuantHolder(primitive);
MS_CHECK_TRUE_MSG(quant_param_holder != nullptr, RET_NULL_PTR, "quant_param_holder is nullptr.");
@ -735,7 +735,7 @@ STATUS FullQuantQuantizer::QuantNodeSimpleOp(const CNodePtr &cnode) {
return ret;
}
} else if (input_node->isa<mindspore::CNode>()) {
auto input_cnode = std::dynamic_pointer_cast<mindspore::CNode>(input_node);
auto input_cnode = input_node->cast<mindspore::CNodePtr>();
auto input_cnode_primitive = GetValueNode<PrimitivePtr>(input_cnode->input(0));
if (input_cnode_primitive == nullptr) {
MS_LOG(DEBUG) << "input: " << i << " " << input_cnode->fullname_with_scope() << ": "
@ -800,7 +800,7 @@ STATUS FullQuantQuantizer::QuantNode() {
constexpr int tuple_get_item_input_size = 3;
MS_CHECK_TRUE_MSG(cnode->size() == tuple_get_item_input_size, RET_ERROR, "cnode->size() != 3");
auto index_node = cnode->input(THIRD_INPUT);
auto index_value_node = std::dynamic_pointer_cast<mindspore::ValueNode>(index_node);
auto index_value_node = index_node->cast<mindspore::ValueNodePtr>();
if (index_value_node == nullptr) {
MS_LOG(WARNING) << "index value node is null";
continue;
@ -808,7 +808,7 @@ STATUS FullQuantQuantizer::QuantNode() {
size_t index = opt::CastToInt(index_value_node->value()).front();
auto input_node = cnode->input(SECOND_INPUT);
MS_CHECK_TRUE_MSG(input_node != nullptr, RET_ERROR, "input_node == nullptr");
auto input_cnode = std::dynamic_pointer_cast<mindspore::CNode>(input_node);
auto input_cnode = input_node->cast<mindspore::CNodePtr>();
MS_CHECK_TRUE_MSG(input_cnode != nullptr, RET_ERROR, "input_cnode == nullptr");
auto input_cnode_primitive = GetValueNode<PrimitivePtr>(input_cnode->input(0));
if (input_cnode_primitive == nullptr) {
@ -872,7 +872,7 @@ STATUS FullQuantQuantizer::UpdateDivergeInterval() {
STATUS FullQuantQuantizer::PreProcess() {
auto cnodes = funcGraph->GetOrderedCnodes();
for (auto &cnode : cnodes) {
AnfNodePtr anf = std::dynamic_pointer_cast<AnfNode>(cnode);
AnfNodePtr anf = cnode->cast<AnfNodePtr>();
if (anf == nullptr) {
MS_LOG(ERROR) << " cnode is null";
return RET_NULL_PTR;
@ -965,6 +965,7 @@ STATUS FullQuantQuantizer::DoInference() {
const auto *tensor_data = static_cast<const float *>(tensor->MutableData());
MS_CHECK_TRUE_MSG(tensor_data != nullptr, false, "tensor_data is nullptr.");
size_t elem_count = tensor->ElementsNum();
MS_CHECK_GT(elem_count, 0, false);
vector<float> data(tensor_data, tensor_data + elem_count);
auto ret = this->calibrator_->RecordMaxMinValue(data, (*diverg_info_map)[callParam.node_name][i]);
MS_CHECK_TRUE_MSG(ret == RET_OK, false, "Record MaxMinValue failed!");
@ -996,6 +997,7 @@ STATUS FullQuantQuantizer::DoInference() {
const auto *tensor_data = static_cast<const float *>(tensor->MutableData());
CHECK_NULL_RETURN(tensor_data);
size_t elem_count = tensor->ElementsNum();
MS_CHECK_GT(elem_count, 0, false);
vector<float> data(tensor_data, tensor_data + elem_count);
auto ret = this->calibrator_->RecordMaxMinValue(data, (*diverg_info_map)[callParam.node_name][output_i]);
MS_CHECK_TRUE_MSG(ret == RET_OK, false, "Record MaxMinValue failed!");
@ -1103,9 +1105,9 @@ STATUS FullQuantQuantizer::BiasCorrection(const FuncGraphPtr &func_graph, const
// compensate the existed
auto bias_quant_params = input_quant_params.at(THIRD_INPUT);
auto bias = cnode->input(THIRD_INPUT + 1);
auto bias_parameter_ptr = std::dynamic_pointer_cast<Parameter>(bias);
auto bias_parameter_ptr = bias->cast<ParameterPtr>();
auto bias_default_param = bias_parameter_ptr->default_param();
auto bias_param = std::dynamic_pointer_cast<tensor::Tensor>(bias_default_param);
auto bias_param = bias_default_param->cast<tensor::TensorPtr>();
int *bias_datas = static_cast<int *>(bias_param->data_c());
if (static_cast<size_t>(bias_param->DataSize()) != bias_diff.size()) {
@ -1209,6 +1211,7 @@ STATUS FullQuantQuantizer::CollectDataFrequency() {
const auto *tensor_data = static_cast<const float *>(tensor->MutableData());
MS_ASSERT(tensor_data != nullptr);
size_t elem_count = tensor->ElementsNum();
MS_CHECK_GT(elem_count, 0, false);
vector<float> data(tensor_data, tensor_data + elem_count);
auto ret = this->calibrator_->UpdateDataFrequency(data, (*diverg_info_map)[callParam.node_name][input_i++]);
if (ret != RET_OK) {
@ -1234,6 +1237,7 @@ STATUS FullQuantQuantizer::CollectDataFrequency() {
const auto *tensor_data = static_cast<const float *>(tensor->MutableData());
MS_ASSERT(tensor_data != nullptr);
size_t elem_count = tensor->ElementsNum();
MS_CHECK_GT(elem_count, 0, false);
vector<float> data(tensor_data, tensor_data + elem_count);
auto ret = this->calibrator_->UpdateDataFrequency(data, (*diverg_info_map)[call_param.node_name][output_i++]);
if (ret != RET_OK) {
@ -1411,6 +1415,7 @@ KernelCallBack FullQuantQuantizer::GetBeforeCallBack(bool int8_op) {
auto tensor = before_inputs[0];
MS_ASSERT(tensor != nullptr);
size_t elem_count = tensor->ElementsNum();
MS_CHECK_GT(elem_count, 0, false);
std::vector<float> fp32_op_input(elem_count);
auto ret =
memcpy_s(fp32_op_input.data(), fp32_op_input.size() * sizeof(float), tensor->MutableData(), tensor->Size());
@ -1435,18 +1440,13 @@ KernelCallBack FullQuantQuantizer::GetBeforeCallBack(bool int8_op) {
}
auto tensor = before_inputs[0];
MS_ASSERT(tensor != nullptr);
auto lite_tensor = dynamic_cast<mindspore::lite::Tensor *>(tensor);
if (lite_tensor == nullptr) {
MS_LOG(ERROR) << "Before inputs is not a lite::Tensor";
return false;
}
if (tensor->data_type() != kNumberTypeInt8) {
MS_LOG(ERROR) << "unexpected tensor type: " << tensor->data_type();
return false;
}
// do quantization: activation is always per layer quantized
std::vector<int8_t> quant_datas;
auto quant_params = lite_tensor->quant_params();
auto quant_params = tensor->quant_params();
if (quant_params.size() != 1) {
MS_LOG(ERROR) << "unexpected quant_params size: " << quant_params.size();
return false;
@ -1497,17 +1497,13 @@ KernelCallBack FullQuantQuantizer::GetInt8AfterCallBack() {
}
auto tensor = afterOutputs[0];
MS_ASSERT(tensor != nullptr);
auto lite_tensor = dynamic_cast<mindspore::lite::Tensor *>(tensor);
if (lite_tensor == nullptr) {
MS_LOG(ERROR) << "Before inputs is not a lite::Tensor";
return false;
}
if (tensor->data_type() != kNumberTypeInt8) {
MS_LOG(ERROR) << "unexpected tensor type: " << tensor->data_type();
return false;
}
const int8_t *tensor_data = static_cast<int8_t *>(tensor->MutableData());
size_t elem_count = tensor->ElementsNum();
MS_CHECK_GT(elem_count, 0, false);
auto shapes = tensor->shape();
if (shapes.size() != DIMENSION_4D) {
MS_LOG(ERROR) << "unexpected shape size: " << shapes.size();
@ -1519,7 +1515,7 @@ KernelCallBack FullQuantQuantizer::GetInt8AfterCallBack() {
MS_LOG(ERROR) << "unexpected channels: 0";
return false;
}
auto quant_params = lite_tensor->quant_params();
auto quant_params = tensor->quant_params();
if (quant_params.size() != 1) {
MS_LOG(ERROR) << "unexpected activatation quant_params size: " << quant_params.size();
return false;
@ -1575,6 +1571,7 @@ KernelCallBack FullQuantQuantizer::GetFloatAfterCallBack() {
MS_ASSERT(tensor != nullptr);
const auto *tensor_data = static_cast<const float *>(tensor->MutableData());
size_t elem_count = tensor->ElementsNum();
MS_CHECK_GT(elem_count, 0, false);
auto shapes = tensor->shape();
if (shapes.size() != DIMENSION_4D) {
MS_LOG(ERROR) << "unexpected shape size: " << shapes.size();

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
#include "tools/converter/quantizer/parameter_optimizer.h"
#include "tools/converter/quantizer/parameter_tunner.h"
#include <set>
#include <functional>
#include <map>
@ -248,7 +248,7 @@ int ParameterOptimizer::GridSearchForScale(const FuncGraphPtr &func_graph, conve
delete origin_model;
return RET_OK;
}
int babysitting_rounds = 20;
int babysitting_rounds = 25;
step = (min_max.max - min_max.min) / babysitting_rounds;
param.rounds = babysitting_rounds;

View File

@ -14,8 +14,8 @@
* limitations under the License.
*/
#ifndef MINDSPORE_LITE_TOOLS_CONVERTER_QUANTIZER_PARAMETER_OPTIMIZER_H
#define MINDSPORE_LITE_TOOLS_CONVERTER_QUANTIZER_PARAMETER_OPTIMIZER_H
#ifndef MINDSPORE_LITE_TOOLS_CONVERTER_QUANTIZER_PARAMETER_TUNNER_H
#define MINDSPORE_LITE_TOOLS_CONVERTER_QUANTIZER_PARAMETER_TUNNER_H
#include <utility>
#include <map>
#include <vector>
@ -57,4 +57,4 @@ class ParameterOptimizer {
int *origin_model_size);
};
} // namespace mindspore::lite::quant
#endif // MINDSPORE_LITE_TOOLS_CONVERTER_QUANTIZER_PARAMETER_OPTIMIZER_H
#endif // MINDSPORE_LITE_TOOLS_CONVERTER_QUANTIZER_PARAMETER_TUNNER_H

View File

@ -131,9 +131,13 @@ bool QuantStrategy::CanTensorQuantized(const AnfNodePtr &input_node, int preferr
if (weight_shape.size() < kDim2) { // do not quant single dim tensors
return false;
}
size_t shape_size = std::accumulate(weight_shape.begin(), weight_shape.end(), 1, std::multiplies<int>());
if (shape_size < min_quant_weight_size_) {
MS_LOG(INFO) << "shape_size " << shape_size << " less min_quant_weight_size_ " << shape_size;
int64_t total_shape_size = 1;
for (auto shape : weight_shape) {
MS_CHECK_FALSE_MSG(INT_MUL_OVERFLOW(total_shape_size, shape), RET_ERROR, "Int mul overflow");
total_shape_size *= shape;
}
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_;
return false;
}