MCPcopy Create free account
hub / github.com/alibaba/MNN / QuantizeConvPerChannel

Function QuantizeConvPerChannel

tools/quantization/quantizeWeight.cpp:135–192  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

133}
134
135int QuantizeConvPerChannel(const float* weight, const int size, const float* bias, int8_t* quantizedWeight,
136 int32_t* quantizedBias, float* scale, const float inputScale, const float outputScale,
137 const int inputChannel, const int outputChannel, std::string method, float weightClampValue, bool mergeChannel) {
138 const int icXoc = inputChannel * outputChannel;
139 DCHECK(size % icXoc == 0) << "Input Data Size Error!";
140
141 std::vector<float> quantizedWeightScale(outputChannel);
142
143 float inputScalexWeight = 1.0f;
144 if (mergeChannel) {
145 if (method == "MAX_ABS"){
146 SymmetricQuantizeWeight(weight, size, quantizedWeight, quantizedWeightScale.data(), outputChannel, weightClampValue);
147 }
148 else if (method == "ADMM") {
149 QuantizeWeightADMM(weight, size, quantizedWeight, quantizedWeightScale.data(), outputChannel, weightClampValue);
150 }
151 inputScalexWeight = inputScale;
152 } else {
153 const int kernelSize = size / icXoc;
154 const int ocStride = size / outputChannel;
155
156 std::vector<float> weightMultiByInputScale(size);
157 for (int oc = 0; oc < outputChannel; ++oc) {
158 for (int ic = 0; ic < inputChannel; ++ic) {
159 for (int i = 0; i < kernelSize; ++i) {
160 const int index = oc * ocStride + ic * kernelSize + i;
161 weightMultiByInputScale[index] = inputScale * weight[index];
162 }
163 }
164 }
165 if (method == "MAX_ABS"){
166 SymmetricQuantizeWeight(weightMultiByInputScale.data(), size, quantizedWeight, quantizedWeightScale.data(), outputChannel, weightClampValue);
167 }
168 else if (method == "ADMM") {
169 QuantizeWeightADMM(weightMultiByInputScale.data(), size, quantizedWeight, quantizedWeightScale.data(), outputChannel, weightClampValue);
170 }
171 }
172
173 for (int i = 0; i < outputChannel; ++i) {
174 if (fabs(outputScale) <= 1e-6) {
175 scale[i] = 0.0f;
176 } else {
177 scale[i] = inputScalexWeight * quantizedWeightScale[i] / outputScale;
178 }
179 }
180
181 if (bias) {
182 for (int i = 0; i < outputChannel; ++i) {
183 if (fabs(inputScalexWeight) <= 1e-6 || fabs(quantizedWeightScale[i]) <= 1e-6) {
184 quantizedBias[i] = 0;
185 } else {
186 quantizedBias[i] = static_cast<int32_t>(bias[i] / (inputScalexWeight * quantizedWeightScale[i]));
187 }
188 }
189 }
190
191 return 0;
192}

Callers

nothing calls this directly

Calls 4

QuantizeWeightADMMFunction · 0.85
fabsFunction · 0.85
SymmetricQuantizeWeightFunction · 0.70
dataMethod · 0.45

Tested by

no test coverage detected