| 141 | } |
| 142 | |
| 143 | void CPUConvolution::MutableResourceInt8::updateInputOutputScale(std::vector<float> inputQuantInfo, std::vector<float> outputQuantInfo) { |
| 144 | if (mResource->mUseConvQuan) { |
| 145 | return; |
| 146 | } |
| 147 | // new scales and zero points |
| 148 | float inputScale = inputQuantInfo[0]; |
| 149 | float outputScale = outputQuantInfo[0]; |
| 150 | float inputZeroPoint = inputQuantInfo[1]; |
| 151 | float outputZeroPoint = outputQuantInfo[1]; |
| 152 | mClampMin = int8_t(outputQuantInfo[2]); |
| 153 | mClampMax = int8_t(outputQuantInfo[3]); |
| 154 | |
| 155 | mInputScale = mResource->mInputScale; |
| 156 | mOutputScale = mResource->mOutputScale; |
| 157 | mInputZeroPoint = mResource->mInputZeroPoint; |
| 158 | mOutputZeroPoint = mResource->mOutputZeroPoint; |
| 159 | if (inputScale != 0 && outputScale != 0) { |
| 160 | mInputScale = inputScale; |
| 161 | mOutputScale = outputScale; |
| 162 | mInputZeroPoint = inputZeroPoint; |
| 163 | mOutputZeroPoint = outputZeroPoint; |
| 164 | } |
| 165 | if (mInputScale == 0 || mOutputScale == 0) { |
| 166 | return; |
| 167 | } |
| 168 | |
| 169 | const int ocUp4 = mResource->mOriginBias->length(0); |
| 170 | auto biasData = mResource->mOriginBias->host<float>(); |
| 171 | auto scaleDiv = mInputScale / mOutputScale; |
| 172 | auto scale = mScaleFloat->host<float>(); |
| 173 | auto bias = mBiasInt32->host<int32_t>(); |
| 174 | auto biasfloat = mBiasFloat->host<float>(); |
| 175 | #ifdef MNN_USE_SSE |
| 176 | float offset = 128.f; |
| 177 | #else |
| 178 | float offset = 0.f; |
| 179 | #endif |
| 180 | if (mResource->mOriginScale) { // Only depthwiseInt8 has mOriginScale |
| 181 | auto weightScalePtr = mResource->mOriginScale->host<float>(); |
| 182 | for (int i = 0; i < ocUp4; i++) { |
| 183 | auto weightScale = weightScalePtr[i]; |
| 184 | if (fabs(weightScale) < 1e-6) { |
| 185 | weightScale = 1e-6; |
| 186 | } |
| 187 | scale[i] = weightScale * scaleDiv; // input_scale*weight_scale/output_scale |
| 188 | // compute outputZeroPointFused in asymmetric quant |
| 189 | int outputZeroPointFused = static_cast<int32_t>(mOutputZeroPoint / scale[i]); |
| 190 | bias[i] = static_cast<int32_t>(biasData[i] / (mInputScale * weightScale)) - mResource->mInt8WeightKernelSum[i] * (mInputZeroPoint + offset) + outputZeroPointFused; |
| 191 | } |
| 192 | } else { |
| 193 | auto outputScale = mResource->mWeightBits == 4 ? 1.f : mOutputScale; |
| 194 | int32_t outputZero = mResource->mWeightBits == 4 ? 0 : mOutputZeroPoint; |
| 195 | for (int i = 0; i < ocUp4; ++i) { |
| 196 | biasfloat[i] = (biasData[i] - mResource->mWeightKernelSum->host<float>()[i] * (mInputZeroPoint + offset) * mInputScale) / outputScale + outputZero; |
| 197 | |
| 198 | } |
| 199 | } |
| 200 | } |