SoftmaxCrossEntropyWithLogits
=================================

    计算 Softmax 交叉熵损失及梯度。

    该算子首先对输入 ``logits`` 进行 Softmax 归一化得到概率，然后计算其与 ``labels`` 的交叉熵损失。如果启用了 ``need_grads``，则会计算损失相对于 ``logits`` 的梯度。

    算法逻辑如下：

    1. **Softmax**:

    .. math::

        p_{i,j} = \frac{e^{x_{i,j}}}{\sum_{k} e^{x_{i,k}}}

    2. **Cross Entropy Loss**:

    .. math::

        loss_i = - \sum_{j} y_{i,j} \log(p_{i,j})

    3. **Gradients** (当 need_grads=1 时):

    .. math::

        \frac{\partial loss}{\partial x_{i,j}} = p_{i,j} - y_{i,j}

    输入：
        - **logits** - 输入数据地址（未归一化的对数概率）。形状为 :math:`[batch\_size, num\_of\_classes]`。
        - **labels** - 标签数据地址。形状为 :math:`[batch\_size, num\_of\_classes]`。
        - **probs** - 输出概率地址（Softmax 结果）。
        - **grads** - 输出梯度地址。如果 ``need_grads`` 为 0，可忽略。
        - **output** - 输出损失值地址（通常为标量或每个样本的损失）。
        - **sum_data** - 中间计算缓冲区（Workspace），用于存储行和等临时数据。
        - **batch_size** - 批大小。
        - **num_of_classes** - 类别数量。
        - **need_grads** - 是否需要计算梯度 (0: 不计算, 1: 计算)。
        - **core_mask** - 核掩码（仅适用于共享存储版本）。

    输出：
        - **probs** - 更新后的概率分布。
        - **grads** - 计算得到的梯度（如启用）。
        - **output** - 计算得到的交叉熵损失。

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

    .. note::
        - **FT78NE** 支持 Fp32 和 Int8 数据类型。
        - **MT7004** 支持 Fp32 和 FP16 数据类型。
        - 输入数据必须是二维矩阵，行优先存储。
        - Int8 版本通常采用混合精度计算：输入/标签为 ``int8_t``，但输出（概率、梯度、损失）为 ``float`` 以保证精度。

**共享存储版本:**

.. c:function:: void fp_softmax_cross_entropy_with_logits_s(float* logits, float* labels, float* probs, float* grads, float* output, float* sum_data, int batch_size, int num_of_classes, int need_grads, int core_mask)
.. c:function:: void hp_softmax_cross_entropy_with_logits_s(float16* logits, float16* labels, float16* probs, float16* grads, float16* output, float16* sum_data, int batch_size, int num_of_classes, int need_grads, int core_mask)
.. c:function:: void i8_softmax_cross_entropy_with_logits_s(int8_t* logits, int8_t* labels, float* probs, float* grads, float* output, float* sum_data, int batch_size, int num_of_classes, int need_grads, int core_mask)

    **C调用示例（FT78NE - Int8）：**

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

        #include <stdio.h>
        #include <stdint.h>

        int main(int argc, char* argv[]) {
            // 假设所有数据均位于DDR空间
            int8_t* logits = (int8_t*)0xC0000000;
            int8_t* labels = (int8_t*)0xC1000000;
            float* probs   = (float*)0xC2000000;
            float* grads   = (float*)0xC3000000;
            float* output  = (float*)0xC4000000;
            float* sum_data= (float*)0xC5000000; // Workspace

            int batch_size = 128;
            int num_of_classes = 1000;
            int need_grads = 1;
            int core_mask = 0xff; // 使用所有核心

            // i8版本：输入为int8，输出及中间计算为float
            i8_softmax_cross_entropy_with_logits_s(logits, labels, probs, grads, output,
                                                   sum_data, batch_size, num_of_classes, 
                                                   need_grads, core_mask);
            
            return 0;
        }


**私有存储版本:**

.. c:function:: void fp_softmax_cross_entropy_with_logits_p(float* logits, float* labels, float* probs, float* grads, float* output, float* sum_data, int batch_size, int num_of_classes, int need_grads)
.. c:function:: void hp_softmax_cross_entropy_with_logits_p(float16* logits, float16* labels, float16* probs, float16* grads, float16* output, float16* sum_data, int batch_size, int num_of_classes, int need_grads)
.. c:function:: void i8_softmax_cross_entropy_with_logits_p(int8_t* logits, int8_t* labels, float* probs, float* grads, float* output, float* sum_data, int batch_size, int num_of_classes, int need_grads)

    **C调用示例（MT7004 - FP16）：**

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

        #include <stdio.h>

        int main(int argc, char* argv[]) {
            // 假设所有数据均位于AM空间
            float16* logits = (float16*)0x10010000;
            float16* labels = (float16*)0x10020000;
            float16* probs  = (float16*)0x10030000;
            float16* grads  = (float16*)0x10040000;
            float16* output = (float16*)0x10050000;
            float16* sum_data=(float16*)0x10060000;

            int batch_size = 32;
            int num_of_classes = 512;
            int need_grads = 1;

            hp_softmax_cross_entropy_with_logits_p(logits, labels, probs, grads, output,
                                                    sum_data, batch_size, num_of_classes,
                                                    need_grads);
            
            return 0;
        }