Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions source/backend/qnn/backend/QNNBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2432,9 +2432,19 @@ class QnnRuntimeCreator : public RuntimeCreator {
}
if (op->main_as_Convolution2D() && op->main_as_Convolution2D()->weight() != nullptr) {
return false;
} else {
return true;
}
// Guard against promoting a Conv that carries no quantized weight
// data (e.g. a Conv listed in skip_quant_op_names but still
// surrounded by int8 tensors): the QNN Conv execution would later
// dereference a missing weight and crash.
{
auto conv2d = op->main_as_Convolution2D();
if (conv2d->quanParameter() == nullptr &&
(conv2d->symmetricQuan() == nullptr || conv2d->symmetricQuan()->weight() == nullptr)) {
return false;
}
}
return true;
case OpType_ReLU:
if ((op->main_as_Relu() == nullptr) || op->main_as_Relu()->slope() == 0.f) {
return true;
Expand Down
16 changes: 14 additions & 2 deletions source/backend/qnn/execution/QNNConvDepthwise.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ void QNNConvDepthwise::isWeightQuantSupported(const Tensor *input, const int oc)
}

std::shared_ptr<ConvolutionCommon::Int8Common> quanCommon = ConvolutionCommon::load(mOp, this->backend(), false, true);
if(quanCommon->asymmetric || dataType == QNN_DATATYPE_FLOAT_16 || dataType == QNN_DATATYPE_FLOAT_32){
if (nullptr == quanCommon || quanCommon->asymmetric || dataType == QNN_DATATYPE_FLOAT_16 || dataType == QNN_DATATYPE_FLOAT_32) {
// not support asymmetric and mBlockSize > 1 results incorrect now
mWeightQuant = false;
return;
Expand Down Expand Up @@ -194,7 +194,9 @@ ErrorCode QNNConvDepthwise::onEncode(const std::vector<Tensor *> &inputs, const
this->createParamTensor("pad_amount", QNN_DATATYPE_UINT_32, {2, 2}, (void *)padAmountData.data());
this->createParamTensor("dilation", QNN_DATATYPE_UINT_32, {2}, (void *)dilationData.data());

this->createWeightAndBias(dataType, inputs[0], oc, kernelH, kernelW);
if (!this->createWeightAndBias(dataType, inputs[0], oc, kernelH, kernelW)) {
return NOT_SUPPORT;
}
// dequant input and quant output
if(mWeightQuant == false && dataType != QNN_DATATYPE_FLOAT_16 && dataType != QNN_DATATYPE_FLOAT_32){
return this->onEncodeQuantDequantDepthConv(inputs[0], outputs[0], n, ic, oc);
Expand Down Expand Up @@ -261,6 +263,11 @@ void QNNConvDepthwise::createWeightAndBias(Qnn_DataType_t dataType, const Tensor
if(mWeightQuant){
Qnn_QuantizeParams_t weightQuantize{};
std::shared_ptr<ConvolutionCommon::Int8Common> quanCommon = ConvolutionCommon::load(mOp, this->backend(), false, true);
if (nullptr == quanCommon) {
MNN_ERROR("QNNConvDepthwise: op '%s' has no quantized weight data\n",
mOp->name() ? mOp->name()->c_str() : "unknown");
return;
}

// [TODO] Support asymmetric and other quantBits.
MNN_ASSERT(!quanCommon->asymmetric);
Expand Down Expand Up @@ -376,6 +383,11 @@ void QNNConvDepthwise::createWeightAndBias(Qnn_DataType_t dataType, const Tensor
int weightElementNum = 0;
std::shared_ptr<ConvolutionCommon::Int8Common> quanWeight;
ConvolutionCommon::getConvParameters(&quanWeight, mBackend, mOp, &source, &weightElementNum);
if (nullptr == source || weightElementNum <= 0) {
MNN_ERROR("QNNConvDepthwise: op '%s' has no weight data\n",
mOp->name() ? mOp->name()->c_str() : "unknown");
return;
}
// oc ic h w ---> h w ic oc
weightData.resize(weightElementNum);
convertWeight(source, (float *) weightData.data(), oc, kernelH, kernelW);
Expand Down
18 changes: 17 additions & 1 deletion source/backend/qnn/execution/QNNConvolution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ void QNNConvolution::isWeightQuantSupported(const Tensor *input, const int ic, c
}

std::shared_ptr<ConvolutionCommon::Int8Common> quanCommon = ConvolutionCommon::load(mOp, this->backend(), false, true);
if (nullptr == quanCommon) {
mWeightQuant = false;
return;
}
int totalCount = quanCommon->alpha.size();
mBlockSize = totalCount / oc;
if(quanCommon->asymmetric){
Expand Down Expand Up @@ -118,7 +122,9 @@ ErrorCode QNNConvolution::onEncode(const std::vector<Tensor *> &inputs, const st
this->createParamScalar("group", (uint32_t)group);
}

this->createWeightAndBias(dataType, inputs[0], oc, ic, kernelH, kernelW, group);
if (!this->createWeightAndBias(dataType, inputs[0], oc, ic, kernelH, kernelW, group)) {
return NOT_SUPPORT;
}
// dequant input and quant output
if(mWeightQuant == false && dataType != QNN_DATATYPE_FLOAT_16 && dataType != QNN_DATATYPE_FLOAT_32){
return this->onEncodeQuantDequantConv(inputs[0], outputs[0], n, ic, oc);
Expand Down Expand Up @@ -562,6 +568,11 @@ bool QNNConvolution::createWeightAndBias(Qnn_DataType_t dataType, const Tensor *
if(mWeightQuant){
Qnn_QuantizeParams_t weightQuantize{};
std::shared_ptr<ConvolutionCommon::Int8Common> quanCommon = ConvolutionCommon::load(mOp, this->backend(), false, true);
if (nullptr == quanCommon) {
MNN_ERROR("QNNConvolution: op '%s' has no quantized weight data\n",
mOp->name() ? mOp->name()->c_str() : "unknown");
return false;
}
if(quanCommon->asymmetric) {
MNN_ERROR("[Error]: Qnn weight quant only support symmetric currently\n");
return false;
Expand Down Expand Up @@ -676,6 +687,11 @@ bool QNNConvolution::createWeightAndBias(Qnn_DataType_t dataType, const Tensor *
int weightElementNum = 0;
std::shared_ptr<ConvolutionCommon::Int8Common> quanWeight;
ConvolutionCommon::getConvParameters(&quanWeight, mBackend, mOp, &source, &weightElementNum);
if (nullptr == source || weightElementNum <= 0) {
MNN_ERROR("QNNConvolution: op '%s' has no weight data\n",
mOp->name() ? mOp->name()->c_str() : "unknown");
return false;
}
// oc ic h w ---> h w ic oc
weightData.resize(weightElementNum);
convertWeight(source, (float *) weightData.data(), oc, ic/group, kernelH, kernelW);
Expand Down
Loading