FakeQuantWithMinMaxVarsPerChannel
=====================================

对输入数据执行按通道（Per-Channel）的逐元素伪量化运算。该算子将输入数据划分为 ``channel_num`` 个等长的通道，每个通道根据其对应的最小/最大值（min_val[c] / max_val[c]）独立计算缩放因子和零点，进行模拟量化与反量化。

.. math::

   channel\_size = \frac{length}{channel\_num}

.. math::

   \text{对于通道 } c: \quad scale_c = \frac{max\_val_c - min\_val_c}{quant\_max - quant\_min}

.. math::

   zp\_from\_min_c = quant\_min - \frac{min\_val_c}{scale_c}

.. math::

   nudge\_zp_c = \text{round} \left( \min \left( quant\_max, \max \left( quant\_min, zp\_from\_min_c \right) \right) \right)

.. math::

   nudge\_min_c = (quant\_min - nudge\_zp_c) \times scale_c

.. math::

   nudge\_max_c = (quant\_max - nudge\_zp_c) \times scale_c

.. math::

   output_{c,i} = \left( \text{round} \left( \frac{\text{clamp}(input_{c,i}, nudge\_min_c, nudge\_max_c) - nudge\_min_c}{scale_c} \right) \right) \times scale_c + nudge\_min_c

对称量化（symmetric 为 true 时）：

.. math::

   max\_val_c = \max(-min\_val_c, max\_val_c), \quad min\_val_c = -max\_val_c

输入：
    - **input** - 输入数据地址。
    - **min_val** - 每个通道最小值组成的数组地址。
    - **max_val** - 每个通道最大值组成的数组地址。
    - **params** - 参数数组，包含以下元素：

        - ``params[0]`` - length，输入数据总长度（需能被通道数整除）。
        - ``params[1]`` - quant_min，量化后的整数最小值（例如 0 或 -128）。
        - ``params[2]`` - quant_max，量化后的整数最大值（例如 255 或 127）。
        - ``params[3]`` - symmetric，是否使用对称量化（bool 类型）。若为 true，则范围调整为关于 0 对称。
        - ``params[4]`` - channel_num，通道数量。

    - **core_mask(int, 可选)** - 核掩码（仅适用于共享存储版本）。

输出：
    - **output** - 伪量化后的计算结果地址。

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

.. note::
    - FT78NE 支持：fp32 (fp)
    - MT7004 支持：fp16 (hp), fp32 (fp)
    - 输入数据的总长度 ``length`` 必须可以被 ``channel_num`` 整除。
    - 每个通道的逻辑（包括 Nudge 零点调整）与单变量版本的伪量化一致。

**共享存储版本:**

.. c:function:: void fp_fake_quant_with_min_max_vars_per_channel_s(float* input, float* min_val, float* max_val, float* output, long long* params, int core_mask)
.. c:function:: void hp_fake_quant_with_min_max_vars_per_channel_s(float16* input, float16* min_val, float16* max_val, float16* output, long long* params, int core_mask)

    **C调用示例：**

    .. code-block:: c
        :linenos:
        :emphasize-lines: 19

        // MT7004 示例：fp32 类型共享存储多核计算
        #include <stdio.h>
        #include <stdbool.h>

        int main(int argc, char* argv[]) {
            float *input = (float *)0x83002000;
            float *min_arr = (float *)0x81000000;
            float *max_arr = (float *)0x82000000;
            float *output = (float *)0x84000000;
            int length = 1000;
            int channel_num = 10;
            int core_mask = 0b1011;
            long long params[10];
            params[0] = length;
            params[1] = 0;           // quant_min
            params[2] = 255;         // quant_max
            params[3] = false;       // symmetric
            params[4] = channel_num;
            fp_fake_quant_with_min_max_vars_per_channel_s(input, min_arr, max_arr, output, params, core_mask);
            return 0;
        }

**私有存储版本:**

.. c:function:: void fp_fake_quant_with_min_max_vars_per_channel_p(float* input, float* min_val, float* max_val, float* output, long long* params)
.. c:function:: void hp_fake_quant_with_min_max_vars_per_channel_p(float16* input, float16* min_val, float16* max_val, float16* output, long long* params)

    **C调用示例：**

    .. code-block:: c
        :linenos:
        :emphasize-lines: 18

        // MT7004 示例：fp16 (float16) 类型私有存储单核计算
        #include <stdio.h>
        #include <stdbool.h>

        int main(int argc, char* argv[]) {
            float16 *input = (float16 *)0x10030000;
            float16 *min_arr = (float16 *)0x10010000;
            float16 *max_arr = (float16 *)0x10020000;
            float16 *output = (float16 *)0x10040000;
            int length = 1000;
            int channel_num = 10;
            long long params[10];
            params[0] = length;
            params[1] = 0;           // quant_min
            params[2] = 255;         // quant_max
            params[3] = true;        // symmetric
            params[4] = channel_num;
            hp_fake_quant_with_min_max_vars_per_channel_p(input, min_arr, max_arr, output, params);
            return 0;
        }