LstmGradData
=================

计算 LSTM 网络中每个时间步的输入梯度和隐藏状态梯度，支持单向和双向 LSTM。

.. math::

    dH_t &= dY_t + dH_{t+1} \\
    dC_t &= dC_{t+1} \odot f_{t+1} + dH_t \odot o_t \odot (1 - \tanh^2(C_t)) \\
    dX_t &= dA_t \cdot W^T \\
    dW &= \sum_t dA_t \cdot X_t^T \\
    dU &= \sum_t dA_t \cdot H_{t-1}^T \\
    dA_t &= dH_t \odot o_t \odot (1 - \tanh^2(C_t)) \odot g'_t
     
其中：

- \(dH_t\) 表示隐藏状态的梯度。
- \(dC_t\) 表示细胞状态的梯度。
- \(dX_t\) 表示输入梯度。
- \(dW, dU\) 分别表示输入权重和隐藏状态权重的梯度。
- \(dA_t\) 表示门控单元梯度。
- \(f_t, o_t, C_t, g_t\) 分别为遗忘门、输出门、细胞状态、输入门的前向值。
- \(\odot\) 表示元素逐乘。

输入：
    - **params** - 静态参数数组，包含 LSTM 网络配置、权重、状态指针等。
    - **dynamic_params** - 动态参数数组，用于存储运行时指针及中间梯度。

输出：
    - **dX_** - 输入梯度。
    - **dH_** - 隐藏状态梯度。
    - **dC_** - 细胞状态梯度。
    - **dA_tmp_** - 门控梯度中间缓存。

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

.. note::
    - FT78NE 支持 fp
    - MT7004 支持 hp, fp

**共享存储版本:**

.. c:function:: void fp_lstmgraddata_s(long long *params, long long *dynamic_params, int core_mask)
.. c:function:: void hp_lstmgraddata_s(long long *params, long long *dynamic_params, int core_mask)

**C调用示例：**

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

    #include <stdio.h>
    #include <lstmgraddata.h>

    int main() {
        long long params[32];
        long long dynamic_params[32];
        int core_mask = 0xff;

        // 初始化 params 和 dynamic_params
        fp_lstmgraddata_s(params, dynamic_params, core_mask);
        return 0;
    }

**私有存储版本:**

.. c:function:: void fp_lstmgraddata_p(long long *params, long long *dynamic_params)
.. c:function:: void hp_lstmgraddata_p(long long *params, long long *dynamic_params)

**C调用示例：**

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

    #include <stdio.h>
    #include <lstmgraddata.h>

    int main() {
        long long params[32];
        long long dynamic_params[32];

        // 初始化 params 和 dynamic_params
        fp_lstmgraddata_p(params, dynamic_params);
        return 0;
    }
