Avgpooling
=================


对NHWC格式的输入张量执行2D平均池化，并随后进行范围裁剪（Clip）激活。

该算子融合了两个步骤：

1. **平均池化 (Average Pooling)**:

.. math::

    \text{Pool}_{i,j} = \frac{1}{k_h \times k_w} \sum_{m=0}^{k_h-1} \sum_{n=0}^{k_w-1} \text{Input}_{i \cdot s_h + m, j \cdot s_w + n}

2. **裁剪激活 (Clipping Activation)**:

.. math::

    \text{Output} = \max(\min\_val, \min(\text{Pool}, \max\_val))

输入：
    - **input** - 输入张量的数据地址。格式: NHWC。
    - **batch** (N) - 批处理大小。
    - **in_h** (H) - 输入特征图的高度。
    - **in_w** (W) - 输入特征图的宽度。
    - **channel** (C) - 输入特征图的通道数。
    - **win_h** - 池化核的高度。
    - **win_w** - 池化核的宽度。
    - **stride_h** - 垂直方向的步长。
    - **stride_w** - 水平方向的步长。
    - **pad_top** - 上边距填充。
    - **pad_bottom** - 下边距填充。
    - **pad_left** - 左边距填充。
    - **pad_right** - 右边距填充。
    - **min_val** - 裁剪范围的最小值。
    - **max_val** - 裁剪范围的最大值。
    - **core_mask** - 核掩码。

输出：
    - **output** - 输出张量的数据地址。

支持平台：
    ``FT78NE``
    ``MT7004``

.. note::
    - FT78NE 支持fp32, int8
    - MT7004 支持fp16, fp32


**共享存储版本:**

.. c:function:: void i8_avgpool_fusion_s(int8_t* input, int8_t* output, int batch, int in_h, int in_w, int channel, int win_h, int win_w, int stride_h, int stride_w, int pad_top, int pad_bottom, int pad_left, int pad_right, int8_t min_val, int8_t max_val, int core_mask)
.. c:function:: void fp_avgpool_fusion_s(float* input, float* output, int batch, int in_h, int in_w, int channel, int win_h, int win_w, int stride_h, int stride_w, int pad_top, int pad_bottom, int pad_left, int pad_right, float min_val, float max_val, int core_mask)
.. c:function:: void hp_avgpool_fusion_s(half* input, half* output, int batch, int in_h, int in_w, int channel, int win_h, int win_w, int stride_h, int stride_w, int pad_top, int pad_bottom, int pad_left, int pad_right, half min_val, half max_val, int core_mask)
    
**C调用示例：**

.. code-block:: c
   :linenos:
   :emphasize-lines: 25-28

   //FT78NE示例
   #include <stdio.h>
   #include <avgpooling.h>
   int main(int argc, char* argv[]) {
       float *input = (float *)0xA0000000;      // input在DDR空间
       float *output = (float *)0xB0000000;     // output

       // Shape parameters
       int batch = 2;
       int in_h = 224;
       int in_w = 224;
       int channel = 3;

       // Pooling parameters
       int win_h = 3, win_w = 3;
       int stride_h = 2, stride_w = 2;
       int pad_top = 1, pad_bottom = 1, pad_left = 1, pad_right = 1;

       // Fusion parameters (e.g., for ReLU6 activation)
       float min_val = 0.0f;
       float max_val = 6.0f;
       
       int core_mask = 0xff;
       
       fp_avgpool_fusion_s(input, output, batch, in_h, in_w, channel, 
                           win_h, win_w, stride_h, stride_w, 
                           pad_top, pad_bottom, pad_left, pad_right, 
                           min_val, max_val, core_mask);
       return 0;
   }



**私有存储版本:**

.. c:function:: void i8_avgpool_fusion_p(int8_t* input, int8_t* output, int batch, int in_h, int in_w, int channel, int win_h, int win_w, int stride_h, int stride_w, int pad_top, int pad_bottom, int pad_left, int pad_right, int8_t min_val, int8_t max_val)
.. c:function:: void fp_avgpool_fusion_p(float* input, float* output, int batch, int in_h, int in_w, int channel, int win_h, int win_w, int stride_h, int stride_w, int pad_top, int pad_bottom, int pad_left, int pad_right, float min_val, float max_val)
.. c:function:: void hp_avgpool_fusion_p(half* input, half* output, int batch, int in_h, int in_w, int channel, int win_h, int win_w, int stride_h, int stride_w, int pad_top, int pad_bottom, int pad_left, int pad_right, half min_val, half max_val)
    

**C调用示例：**

.. code-block:: c
   :linenos:
   :emphasize-lines: 23-26

   //FT78NE示例
   #include <stdio.h>
   #include <avgpooling.h>
   int main(int argc, char* argv[]) {
       float *input = (float *)0x10000000;      // input在L2空间
       float *output = (float *)0x10100000;     // output

       // Shape parameters
       int batch = 2;
       int in_h = 32;
       int in_w = 32;
       int channel = 16;

       // Pooling parameters
       int win_h = 2, win_w = 2;
       int stride_h = 2, stride_w = 2;
       int pad_top = 0, pad_bottom = 0, pad_left = 0, pad_right = 0;

       // Fusion parameters
       float min_val = -127.0f;
       float max_val = 127.0f;
       
       fp_avgpool_fusion_p(input, output, batch, in_h, in_w, channel, 
                           win_h, win_w, stride_h, stride_w, 
                           pad_top, pad_bottom, pad_left, pad_right, 
                           min_val, max_val);
       return 0;
   }
