SparseSoftmaxCrossEntropyWithLogits
=======================================

    计算稀疏标签下的 Softmax 交叉熵损失及梯度。

    与 SoftmaxCrossEntropyWithLogits 不同，该算子的标签（Labels）是类别的索引（整数），而不是 One-hot 向量。这通常能节省内存并加速计算。

    算法逻辑如下：

    1. **Softmax**:

    .. math::

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

    2. **Cross Entropy Loss**:
       假设 :math:`y_i` 为第 :math:`i` 个样本的标签索引：

    .. math::

        loss_i = - \log(p_{i, y_i})

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

    .. math::

        \frac{\partial loss}{\partial x_{i,j}} = p_{i,j} - \mathbb{1}(j == y_i)

    输入：
        - **input** - 输入 Logits 地址。形状为 :math:`[N, C]`。
        - **losses** - 输出损失地址。
        - **sum_data** - 中间计算缓冲区（Workspace）。
        - **inner_size** - 内部维度大小。对于二维输入 :math:`[N, C]`，通常为 1。
        - **outter_size** - 外部维度大小。对于二维输入 :math:`[N, C]`，通常为 :math:`N` (Batch Size)。
        - **axis_size** - 轴维度大小。对于二维输入 :math:`[N, C]`，通常为 :math:`C` (Num Classes)。
        - **labels** - 标签索引地址。类型为 int，形状为 :math:`[N]`。
        - **is_grad** - 是否计算梯度 (0: 否, 1: 是)。
        - **output** - 输出梯度地址。如果 ``is_grad`` 为 1，则存储计算出的梯度，形状同输入。
        - **batch_size** - 批大小 (N)。
        - **number_of_classes** - 类别数量 (C)。
        - **partial_losses** - 中间计算缓冲区（Workspace），用于归约计算。
        - **core_mask** - 核掩码（仅适用于共享存储版本）。

    输出：
        - **losses** - 计算得到的交叉熵损失。
        - **output** - 计算得到的梯度（若启用）。

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

    .. note::
        - **FT78NE** 仅支持 Fp32 数据类型。
        - **MT7004** 支持 Fp32 和 FP16 数据类型。
        - 输入数据必须是二维矩阵。
        - FP16 模式下，labels 依然保持为 int 类型，其余浮点指针变为 float16*。

**共享存储版本:**

.. c:function:: void fp_sparse_softmax_cross_entropy_with_logits_s(float* input, float* losses, float* sum_data, uint64_t inner_size, uint64_t outter_size, uint64_t axis_size, int* labels, uint64_t is_grad, float* output, uint64_t batch_size, uint64_t number_of_classes, float* partial_losses, int core_mask)
.. c:function:: void hp_sparse_softmax_cross_entropy_with_logits_s(float16* input, float16* losses, float16* sum_data, uint64_t inner_size, uint64_t outter_size, uint64_t axis_size, int* labels, uint64_t is_grad, float16* output, uint64_t batch_size, uint64_t number_of_classes, float16* partial_losses, int core_mask)

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

    .. code-block:: c
        :linenos:
        :emphasize-lines: 24-29

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

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

            uint64_t batch_size = 64;
            uint64_t number_of_classes = 1000;
            
            // 针对二维输入 [N, C] 的常用配置
            uint64_t outter_size = batch_size;
            uint64_t axis_size = number_of_classes;
            uint64_t inner_size = 1;
            
            uint64_t is_grad = 1; // 计算梯度
            int core_mask = 0xff;

            fp_sparse_softmax_cross_entropy_with_logits_s(input, losses, sum_data, 
                                                          inner_size, outter_size, axis_size, 
                                                          labels, is_grad, output, 
                                                          batch_size, number_of_classes, 
                                                          partial_losses, core_mask);
            
            return 0;
        }

**私有存储版本:**

.. c:function:: void fp_sparse_softmax_cross_entropy_with_logits_p(float* input, float* losses, float* sum_data, uint64_t inner_size, uint64_t outter_size, uint64_t axis_size, int* labels, uint64_t is_grad, float* output, uint64_t batch_size, uint64_t number_of_classes, float* partial_losses)
.. c:function:: void hp_sparse_softmax_cross_entropy_with_logits_p(float16* input, float16* losses, float16* sum_data, uint64_t inner_size, uint64_t outter_size, uint64_t axis_size, int* labels, uint64_t is_grad, float16* output, uint64_t batch_size, uint64_t number_of_classes, float16* partial_losses)

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

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

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

        int main(int argc, char* argv[]) {
            // 假设数据位于 AM 空间
            float16* input = (float16*)0x10010000;
            float16* losses = (float16*)0x10020000;
            float16* sum_data = (float16*)0x10030000;
            int* labels = (int*)0x10040000;       // 标签仍为 int
            float16* output = (float16*)0x10050000;
            float16* partial_losses = (float16*)0x10060000;

            uint64_t batch_size = 32;
            uint64_t number_of_classes = 100;
            
            uint64_t outter_size = batch_size;
            uint64_t axis_size = number_of_classes;
            uint64_t inner_size = 1;

            uint64_t is_grad = 0; // 仅计算 Loss，不计算梯度

            hp_sparse_softmax_cross_entropy_with_logits_p(input, losses, sum_data,
                                                           inner_size, outter_size, axis_size,
                                                           labels, is_grad, output,
                                                           batch_size, number_of_classes,
                                                           partial_losses);
            
            return 0;
        }