78 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			78 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | #ifndef CNN_AVG_POOLING
 | ||
|  | #define CNN_AVG_POOLING
 | ||
|  | /* os shim includes */ | ||
|  | #include "os_types_api.h"
 | ||
|  | 
 | ||
|  | #ifdef __cplusplus
 | ||
|  | extern "C" { | ||
|  | #endif
 | ||
|  | 
 | ||
|  | /** \defgroup cnn pool API
 | ||
|  |   * @brief cnn pool APIs | ||
|  |   * These functions could be used for calculating pooling | ||
|  |   * For any features, every column will occupy a size which is a multiple of 32 bytes. Here column means the last dimension of a tensor | ||
|  |   * For example, if a tensor of type int8_t named A is of size 4 * 30 * 300, it will be saved in the memory of this form so that every column occupies 320 bytes: | ||
|  |   * A[0][0][0], A[0][0][1], ..., A[0][0][299], 0, 0, 0, ..., 0, A[0][1][0], A[0][1][1], ..., A[0][1][299], 0, 0, 0, 0, ..., 0, ..., A[0][29][0], ..., A[0][29][299], 0, ..., 0, A[1][0][0], ... | ||
|  |   * Set out_sep_mode to 1 can accelerate the calculate process, however, in this mode, cpu cannot access the output, and these conditions below must be satisfied: | ||
|  |   *     (1) this layer should be either depthwise or pointwise, innerproduct (or fc) could be regarded as pointwise, pooling could be regarded as depthwise | ||
|  |   *     (2) if this layer is pointwise, next layer should be depthwise; if this layer is depthwise, next layer should be pointwise | ||
|  |   *     (3) width of output plus left padding of next layer should be no larger than 16 bytes | ||
|  |   *     (4) stride of next layer should be 1 | ||
|  |   *     (5) (height + next_pad_up) * channel of output should be no larger than 8192 | ||
|  |   * If out_sep_mode of previous layer is set to 1, in_sep_mode of this layer should be 1 | ||
|  |   * | ||
|  |   * | ||
|  |   */ | ||
|  | 
 | ||
|  | /** @addtogroup cnn_pool_APIs
 | ||
|  |   * @{ | ||
|  |   */ | ||
|  | 
 | ||
|  | 
 | ||
|  | struct cnn_pooling_config_bean | ||
|  | { | ||
|  |     uint16_t in_channel; // how many channels of input
 | ||
|  |     uint16_t in_height; // height of input
 | ||
|  |     uint16_t in_width; // output of input
 | ||
|  |     uint16_t out_height; // don't need to be setted, this is used to save the height of output when the calculation finishes
 | ||
|  |     uint16_t out_width; // don't need to be setted, this is used to save the height of output when the calculation finishes
 | ||
|  |     uint8_t kernel_size_h; // height of the convolving kernel
 | ||
|  |     uint8_t kernel_size_w; // width of the convolving kernel
 | ||
|  |     uint8_t stride; | ||
|  |     int8_t padding_to_same; // non-zero: output size will be ceil((input size + 2 * padding)/stride) by padding input. zero : output size will be calculated by config
 | ||
|  |     uint8_t padding; // zero-padding added to both sides of the input
 | ||
|  |     uint8_t input_signed; // whether input is signed
 | ||
|  |     uint8_t mac_8bit; // non_zero: 8bit mode; zero: 16bit mode
 | ||
|  |     uint8_t count_include_pad; // when non-0, include the zero-padding in the averaging calculation
 | ||
|  |     uint8_t ceil_mode; // when non-0, use ceil instead of floor to compute the output shape. only valid when padding_to_same is zero
 | ||
|  | 	uint8_t avg; // non-zero: avg pooling, zero: max pooling
 | ||
|  |     uint8_t out_shift; // the fraction of output minus the fraction of input, you can set this to a positive number for a higher precision, only valid in avgpooling
 | ||
|  |     uint8_t input_iram; // nonzero - read input from iram, 0 - read input from ddr
 | ||
|  |     uint8_t output_iram; // nonzero - put output into iram, 0 - put output into ddr
 | ||
|  |     uint8_t in_sep_mode; // whether read input from iram as separable conv mode
 | ||
|  |     uint8_t out_sep_mode; // whether put output into iram as separable conv mode
 | ||
|  | }; | ||
|  | 
 | ||
|  | /* @brief cnn_pool_2d() - do a pooling process using cnn engine, it is necessary that input_addr, output_addr are multiple of 256
 | ||
|  |  * @parem input_addr: where the input is put | ||
|  |  * @parem output_addr: where the output will be put | ||
|  |  * @parem config: config info of the pooling process | ||
|  |  * @return 0 -- succeed | ||
|  |  * @return 1 -- input channel is 0 | ||
|  |  * @return 2 -- input height is 0 | ||
|  |  * @return 3 -- input width is 0 | ||
|  |  * @return 4 -- input height is so small that output height will be 0 | ||
|  |  * @return 5 -- input width is so small that output width will be 0 | ||
|  |  * @return 7 -- kernel is 0 | ||
|  |  * @return 8 -- kernel is too large | ||
|  |  * @return 9 -- stride is 0 | ||
|  |  * @return 10 -- stride is too large | ||
|  |  */ | ||
|  | uint8_t cnn_pool_2d(uint32_t input_addr, uint32_t output_addr,  | ||
|  |     struct cnn_pooling_config_bean *config); | ||
|  | 
 | ||
|  | #ifdef __cplusplus
 | ||
|  | } | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #endif
 |