DeconvGradFilter
=================



计算反卷积（Deconvolution / Transposed Convolution）算子的权重梯度，用于反向传播阶段。
该算子根据输出梯度 ``dy`` 与输入特征 ``x``，通过 ``im2row + GEMM`` 的方式累加得到卷积核梯度 ``dw``，并支持分组（group）计算。

.. math::

    \frac{\partial W}{\partial L}
    =
    \sum_{b=0}^{B-1}
    \text{Im2Row}(dY_b) \cdot X_b

其中每个 Group 独立计算，最终在 Group 维度上拼接。

输入：
    - **dy_data** - 输出特征梯度地址，形状为 ``[batch, out_h, out_w, out_c]``。
    - **x_data** - 输入特征地址，形状为 ``[batch, in_h, in_w, in_c]``。
    - **param** - 参数数组地址，用于描述反卷积计算相关参数与工作空间。
        - ``param[0]``  : input_batch
        - ``param[1]``  : in_h
        - ``param[2]``  : in_w
        - ``param[3]``  : in_c
        - ``param[4]``  : batch
        - ``param[5]``  : out_h
        - ``param[6]``  : out_w
        - ``param[7]``  : out_c
        - ``param[8]``  : kernel_h
        - ``param[9]``  : kernel_w
        - ``param[16]`` : group
        - ``param[17]`` : im2row 工作缓冲区地址
    - **core_mask** - 核掩码（仅适用于共享存储版本）。

输出：
    - **dw_data** - 权重梯度输出地址，布局为 ``[group, out_c/group * k_h * k_w, in_c/group]``。

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

.. note::
    - FT78NE 仅支持 fp 类型
    - MT7004 支持 hp, fp 类型
    - 输入与输出数据格式为 NHWC


**共享存储版本:**

.. c:function:: void hp_deconv_grad_filter_s(half* dy_data, half* x_data, half* dw_data, long long* param, int core_mask)
.. c:function:: void fp_deconv_grad_filter_s(float* dy_data, float* x_data, float* dw_data, long long* param, int core_mask)

**C调用示例：**

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

    //FT78NE示例
    #include <stdio.h>
    #include <deconvgradfilter.h>

    int main(int argc, char* argv[]) {
        float *x = (float *)0x10010000;
        float *dy = (float *)0x10020000;
        float *dw = (float *)0x10030000;
        float *temp_space = (float *)0x10050000;

        //参数
        int input_batch = 16;
        int output_batch = input_batch;
        
        // Input: 2x2, 1 Channel
        int input_h = 4;
        int input_w = 4;
        int input_channel = 4;
        
        // Output Grad (dy): 2x2, 1 Channel
        int output_h = input_h;
        int output_w = input_w;
        int output_channel = input_channel;
        
        // Kernel: 2x2
        int kernel_h = 4;
        int kernel_w = 4;
        
        int stride_h = 1;
        int stride_w = 1;
        int pad_u = 0;
        int pad_l = 0;
        int dilation_h = 1;
        int dilation_w = 1;
        int group = 1;
        
        srand(seed++);
        int i;
        for(i = 0; i < input_batch * input_h * input_w * input_channel; ++i) {
            x[i] = (float)(rand()%10)/50.0f + 0.1f;
        }
        for(i = 0; i < output_batch *output_h * output_w * output_channel; ++i) {
            dy[i] = (float)(rand()%10)/50.0f + 0.1f;
        }
        for(i = 0; i < kernel_h * kernel_w * output_channel * input_channel/group; ++i) {
            dw[i] = 0.0f;
        }

        // 1. 设置参数
        long long params[20];
        params[0] = input_batch;
        params[1] = input_h;
        params[2] = input_w;
        params[3] = input_channel;
        params[4] = output_batch;
        params[5] = output_h;
        params[6] = output_w;
        params[7] = output_channel;
        params[8] = kernel_h;
        params[9] = kernel_w;
        params[10] = stride_h;
        params[11] = stride_w;
        params[12] = pad_u;
        params[13] = pad_l;
        params[14] = dilation_h;
        params[15] = dilation_w;
        params[16] = group;
        params[17] = (long long)temp_space;

        int core_mask = 0b1111;
        /*性能统计*/
        fp_deconv_grad_filter_s(dy, x, dw, params, core_mask);
        return 0;
    }


**私有存储版本:**

.. c:function:: void hp_deconv_grad_filter_p(half* dy_data, half* x_data, half* dw_data, long long* param)
.. c:function:: void fp_deconv_grad_filter_p(float* dy_data, float* x_data, float* dw_data, long long* param)

**C调用示例：**

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

    //FT78NE示例
    #include <stdio.h>
    #include <deconvgradfilter.h>

    int main(int argc, char* argv[]) {
        float *x = (float *)0x10010000;
        float *dy = (float *)0x10020000;
        float *dw = (float *)0x10030000;
        float *temp_space = (float *)0x10050000;

        //参数
        int input_batch = 16;
        int output_batch = input_batch;
        
        // Input: 2x2, 1 Channel
        int input_h = 4;
        int input_w = 4;
        int input_channel = 4;
        
        // Output Grad (dy): 2x2, 1 Channel
        int output_h = input_h;
        int output_w = input_w;
        int output_channel = input_channel;
        
        // Kernel: 2x2
        int kernel_h = 4;
        int kernel_w = 4;
        
        int stride_h = 1;
        int stride_w = 1;
        int pad_u = 0;
        int pad_l = 0;
        int dilation_h = 1;
        int dilation_w = 1;
        int group = 1;
        
        srand(seed++);
        int i;
        for(i = 0; i < input_batch * input_h * input_w * input_channel; ++i) {
            x[i] = (float)(rand()%10)/50.0f + 0.1f;
        }
        for(i = 0; i < output_batch *output_h * output_w * output_channel; ++i) {
            dy[i] = (float)(rand()%10)/50.0f + 0.1f;
        }
        for(i = 0; i < kernel_h * kernel_w * output_channel * input_channel/group; ++i) {
            dw[i] = 0.0f;
        }

        // 1. 设置参数
        long long params[20];
        params[0] = input_batch;
        params[1] = input_h;
        params[2] = input_w;
        params[3] = input_channel;
        params[4] = output_batch;
        params[5] = output_h;
        params[6] = output_w;
        params[7] = output_channel;
        params[8] = kernel_h;
        params[9] = kernel_w;
        params[10] = stride_h;
        params[11] = stride_w;
        params[12] = pad_u;
        params[13] = pad_l;
        params[14] = dilation_h;
        params[15] = dilation_w;
        params[16] = group;
        params[17] = (long long)temp_space;

        fp_deconv_grad_filter_p(dy, x, dw, params);
        return 0;
    }
