119 lines
4.7 KiB
ReStructuredText
119 lines
4.7 KiB
ReStructuredText
Stridedslicegrad
|
||
=================
|
||
|
||
计算 StridedSlice(步长切片)操作的梯度。该算子是 StridedSlice 算子的反向传播(backward pass)部分。
|
||
|
||
该算子将上游传来的梯度(对应 StridedSlice 输出的形状)映射回原始输入的位置(对应 StridedSlice 输入的形状)。对于输入梯度中的每个元素,根据原始 StridedSlice 操作的 `begins` 和 `strides` 参数,计算其在原始输入中的位置,并将梯度值写入该位置。
|
||
|
||
.. math::
|
||
|
||
\text{output}[\text{idx}] = \text{inputs}[\text{pos}]
|
||
|
||
其中 `idx` 是根据 `pos` 在 `in_shape` 中的多维索引、`strides` 和 `begins` 计算出的在 `dx_shape` 中的线性索引。
|
||
|
||
|
||
输入:
|
||
- **inputs** - 上游传来的梯度张量数据地址(即 :math:`dy`),形状为 :math:`in\_shape`(原始 StridedSlice 操作的输出形状)。
|
||
- **dx_shape** - 输出梯度张量的形状数组(int*),大小为8,对应原始 StridedSlice 操作的输入形状。对于维度小于8的张量,高位维度形状为1。
|
||
- **strides** - 原始 StridedSlice 操作的步长数组(int*),大小为8。对于维度小于8的张量,高位维度步长为1。
|
||
- **begins** - 原始 StridedSlice 操作的起始索引数组(int*),大小为8。对于维度小于8的张量,高位维度起始索引为0。
|
||
- **in_shape** - 原始 StridedSlice 操作的输出形状数组(int*),大小为8,即输入梯度 `inputs` 的形状。对于维度小于8的张量,高位维度形状为1。
|
||
- **core_mask** - 核掩码(int),仅共享存储版本需要。
|
||
|
||
输出:
|
||
- **output** - 输出梯度张量数据地址(即 :math:`dx`),形状为 :math:`dx\_shape`(原始 StridedSlice 操作的输入形状)。该张量在调用前通常被初始化为全零。
|
||
|
||
支持平台:
|
||
``FT78NE``
|
||
``MT7004``
|
||
|
||
.. note::
|
||
- MT7004 支持fp16, fp32
|
||
- FT78NE 支持fp32
|
||
- 输出张量 `output` 在调用前需要预先初始化为全零
|
||
- 形状数组固定为8维,对于维度小于8的张量,高位维度形状为1
|
||
|
||
**共享存储版本:**
|
||
|
||
.. c:function:: void hp_stridedslicegrad_s(half* inputs, half* output, int* dx_shape, int* strides, int* begins, int* in_shape, int core_mask)
|
||
.. c:function:: void fp_stridedslicegrad_s(float* inputs, float* output, int* dx_shape, int* strides, int* begins, int* in_shape, int core_mask)
|
||
|
||
**C调用示例:**
|
||
|
||
.. code-block:: c
|
||
:linenos:
|
||
:emphasize-lines: 35
|
||
|
||
//MT7004示例
|
||
#include <stdio.h>
|
||
#include <stridedslicegrad.h>
|
||
|
||
int main(int argc, char* argv[]) {
|
||
// 假设在DDR空间
|
||
// 原始 StridedSlice 操作:
|
||
// 输入形状 [2, 3, 4, 5]
|
||
// 输出形状 [1, 2, 2, 3]
|
||
// begins = [0, 1, 1, 2], strides = [1, 1, 2, 1]
|
||
|
||
// 输出梯度形状(原始输入形状)
|
||
int dx_shape[8] = {2, 3, 4, 5, 1, 1, 1, 1};
|
||
|
||
// 输入梯度形状(原始输出形状)
|
||
int in_shape[8] = {1, 2, 2, 3, 1, 1, 1, 1};
|
||
|
||
// 原始 StridedSlice 参数
|
||
int begins[8] = {0, 1, 1, 2, 0, 0, 0, 0};
|
||
int strides[8] = {1, 1, 2, 1, 1, 1, 1, 1};
|
||
|
||
// 输入梯度(上游传来的梯度)
|
||
float *inputs = (float *)0xA0000000; // 形状为 in_shape
|
||
// inputs 包含 1 * 2 * 2 * 3 = 12 个元素
|
||
|
||
// 输出梯度(待计算)
|
||
float *output = (float *)0xB0000000; // 形状为 dx_shape
|
||
// output 包含 2 * 3 * 4 * 5 = 120 个元素
|
||
|
||
// 初始化输出为全零
|
||
memset(output, 0, 120 * sizeof(float));
|
||
|
||
int core_mask = 0xff;
|
||
|
||
fp_stridedslicegrad_s(inputs, output, dx_shape, strides, begins, in_shape, core_mask);
|
||
|
||
return 0;
|
||
}
|
||
|
||
**私有存储版本:**
|
||
|
||
.. c:function:: void hp_stridedslicegrad_p(half* inputs, half* output, int* dx_shape, int* strides, int* begins, int* in_shape)
|
||
.. c:function:: void fp_stridedslicegrad_p(float* inputs, float* output, int* dx_shape, int* strides, int* begins, int* in_shape)
|
||
|
||
**C调用示例:**
|
||
|
||
.. code-block:: c
|
||
:linenos:
|
||
:emphasize-lines: 19
|
||
|
||
//MT7004示例
|
||
#include <stdio.h>
|
||
#include <stridedslicegrad.h>
|
||
|
||
int main(int argc, char* argv[]) {
|
||
// 假设在L2空间
|
||
int dx_shape[8] = {2, 3, 4, 5, 1, 1, 1, 1};
|
||
int in_shape[8] = {1, 2, 2, 3, 1, 1, 1, 1};
|
||
|
||
int begins[8] = {0, 1, 1, 2, 0, 0, 0, 0};
|
||
int strides[8] = {1, 1, 2, 1, 1, 1, 1, 1};
|
||
|
||
float *inputs = (float *)0x10000000;
|
||
float *output = (float *)0x10001000;
|
||
|
||
// 初始化输出为全零
|
||
memset(output, 0, 120 * sizeof(float));
|
||
|
||
fp_stridedslicegrad_p(inputs, output, dx_shape, strides, begins, in_shape);
|
||
|
||
return 0;
|
||
}
|