| 
									
										
										
										
											2019-04-17 10:49:11 +08:00
										 |  |  | //
 | 
					
						
							|  |  |  | //  ConvolutionIntFactory.cpp
 | 
					
						
							|  |  |  | //  MNN
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //  Created by MNN on 2018/08/06.
 | 
					
						
							|  |  |  | //  Copyright © 2018, Alibaba Group Holding Limited
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-27 22:16:57 +08:00
										 |  |  | #include "backend/cpu/compute/ConvolutionIntFactory.hpp"
 | 
					
						
							|  |  |  | #include "backend/cpu/compute/ConvolutionGroup.hpp"
 | 
					
						
							| 
									
										
										
										
											2023-06-16 09:42:45 +08:00
										 |  |  | #include "backend/cpu/compute/IdstConvolutionInt8.hpp"
 | 
					
						
							| 
									
										
										
										
											2019-04-17 10:49:11 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace MNN { | 
					
						
							|  |  |  | Execution *ConvolutionIntFactory::createUnit(const Tensor *input, const Tensor *output, const MNN::Op *op, | 
					
						
							| 
									
										
										
										
											2020-03-02 22:13:38 +08:00
										 |  |  |                                              Backend *backend, const ConvolutionCommon::Int8Common *common, const float *bias, | 
					
						
							| 
									
										
										
										
											2019-04-17 10:49:11 +08:00
										 |  |  |                                              size_t biasSize) { | 
					
						
							| 
									
										
										
										
											2019-11-15 14:22:45 +08:00
										 |  |  |     auto conv2d = op->main_as_Convolution2D(); | 
					
						
							| 
									
										
										
										
											2023-06-16 09:42:45 +08:00
										 |  |  |     return new IdstConvolutionInt8(conv2d->common(), backend, common, bias, biasSize); | 
					
						
							| 
									
										
										
										
											2019-04-17 10:49:11 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Execution *ConvolutionIntFactory::create(const Tensor *input, const Tensor *output, const MNN::Op *op, Backend *backend, | 
					
						
							| 
									
										
										
										
											2020-03-02 22:13:38 +08:00
										 |  |  |                                          const ConvolutionCommon::Int8Common *common) { | 
					
						
							| 
									
										
										
										
											2019-04-17 10:49:11 +08:00
										 |  |  |     auto conv2d = op->main_as_Convolution2D(); | 
					
						
							| 
									
										
										
										
											2021-01-06 19:12:36 +08:00
										 |  |  |     int group            = conv2d->common()->group(); | 
					
						
							|  |  |  |     if (conv2d->common()->inputCount() != input->channel() && conv2d->common()->inputCount() > 0) { | 
					
						
							|  |  |  |         group = input->channel()/ conv2d->common()->inputCount(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 10:49:11 +08:00
										 |  |  |     if (1 == group) { | 
					
						
							|  |  |  |         return createUnit(input, output, op, backend, common, conv2d->bias()->data(), conv2d->bias()->size()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     MNN_ASSERT(common->weight.get() != nullptr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Split
 | 
					
						
							|  |  |  |     std::vector<std::shared_ptr<Execution>> subConvolution; | 
					
						
							|  |  |  |     auto groupOutputCount = conv2d->common()->outputCount() / group; | 
					
						
							|  |  |  |     auto groupWeightSize  = common->weight.size() / group; | 
					
						
							|  |  |  |     for (int i = 0; i < group; ++i) { | 
					
						
							| 
									
										
										
										
											2020-03-02 22:13:38 +08:00
										 |  |  |         auto subCommon = std::make_shared<ConvolutionCommon::Int8Common>(); | 
					
						
							| 
									
										
										
										
											2019-04-17 10:49:11 +08:00
										 |  |  |         subCommon->alpha.reset(groupOutputCount); | 
					
						
							|  |  |  |         ::memcpy(subCommon->alpha.get(), common->alpha.get() + groupOutputCount * i, groupOutputCount * sizeof(float)); | 
					
						
							|  |  |  |         subCommon->quan = common->quan; | 
					
						
							|  |  |  |         subCommon->weight.reset(groupWeightSize); | 
					
						
							|  |  |  |         ::memcpy(subCommon->weight.get(), common->weight.get() + groupWeightSize * i, groupWeightSize * sizeof(int8_t)); | 
					
						
							|  |  |  |         subConvolution.push_back( | 
					
						
							|  |  |  |             std::shared_ptr<Execution>(createUnit(input, output, op, backend, subCommon.get(), | 
					
						
							|  |  |  |                                                   conv2d->bias()->data() + groupOutputCount * i, groupOutputCount))); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return new ConvolutionGroup(backend, subConvolution); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } // namespace MNN
 |