QuantDTypeCast
=================


逐元素执行量化与反量化的数据类型转换操作，用于在浮点数与整型量化表示之间进行转换。

- **Quantize**：将 fp32/fp16 数据量化为 int8
- **Dequantize**：将 int8 数据反量化为 fp32/fp16


.. math::

    \text{Quantize:}\quad
    q_i = \operatorname{clip}\Bigl(\operatorname{round}\bigl(\frac{x_i}{\text{scale}} + \text{zp}\bigr),\ q_{\min},\ q_{\max}\Bigr)

.. math::

    \text{Dequantize:}\quad
    x_i = (q_i - \text{zp}) \times \text{scale}

其中：

- :math:`x_i` 为输入浮点值
- :math:`q_i` 为量化后的整型值
- :math:`\text{scale}` 为量化比例因子
- :math:`\text{zp}` 为零点（zero point）
- :math:`q_{\min}, q_{\max}` 为量化数据类型的取值范围（int8 对应 -128 到 127）


输入：
    - **input** - 输入数据地址。
    - **scale** - 量化或反量化所使用的比例因子。
    - **zp** - 零点（zero point）。
    - **length** - 输入数据的元素个数。
    - **core_mask** - 核掩码。

输出：
    - **output** - 输出数据地址，其大小与 ``input`` 相同。

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

.. note::
    - FT78NE 支持的数据类型：
        - Quantize：fp32 → int8
        - Dequantize：int8 → fp32
    - MT7004 支持的数据类型：
        - Quantize：fp32/fp16 → int8
        - Dequantize：int8 → fp32/fp16
    - 当输入值为 ``+∞`` 或 ``-∞`` 时，Quantize 结果分别饱和到 ``q_max`` 或 ``q_min``


**共享存储版本：**

.. c:function:: void fp_to_i8_quant_s(float* input, int8_t* output, float scale, int zp, int length, int core_mask)
.. c:function:: void i8_to_fp_dequant_s(int8_t* input, float* output, float scale, int zp, int length, int core_mask)
.. c:function:: void hp_to_i8_quant_s(half* input, int8_t* output, half scale, int zp, int length, int core_mask)
.. c:function:: void i8_to_hp_dequant_s(int8_t* input, half* output, half scale, int zp, int length, int core_mask)

**C调用示例：**

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

    // FT78NE 多核示例（Quantize）
    #include <stdio.h>
    #include <quant_dtype_cast.h>

    int main(int argc, char* argv[]) {
        float  *input  = (float *)0xA0000000;   // input 在 DDR 空间
        int8_t *output = (int8_t *)0xB0000000;  // output 在 DDR 空间

        float scale = 0.05f;
        int zp = 0;
        int length = 4096;
        int core_mask = 0xff;

        fp_to_i8_quant_s(input, output, scale, zp, length, core_mask);
        return 0;
    }


**私有存储版本：**

.. c:function:: void fp_to_i8_quant_p(float* input, int8_t* output, float scale, int zp, int length)
.. c:function:: void i8_to_fp_dequant_p(int8_t* input, float* output, float scale, int zp, int length)
.. c:function:: void hp_to_i8_quant_p(half* input, int8_t* output, half scale, int zp, int length)
.. c:function:: void i8_to_hp_dequant_p(int8_t* input, half* output, half scale, int zp, int length)


**C调用示例：**

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

    // MT7004 单核示例（Dequantize）
    #include <stdio.h>
    #include <quant_dtype_cast.h>

    int main(int argc, char* argv[]) {
        int8_t *input  = (int8_t *)0x10000000;   // input 在 L2 空间
        float  *output = (float *)0x11000000;   // output 在 L2 空间

        float scale = 0.05f;
        int zp = 0;
        int length = 1024;

        i8_to_fp_dequant_p(input, output, scale, zp, length);
        return 0;
    }
