124 lines
4.9 KiB
ReStructuredText
124 lines
4.9 KiB
ReStructuredText
Sparsereshape
|
||
=================
|
||
|
||
对稀疏张量进行形状重塑(Reshape)。该算子将稀疏张量的索引从输入形状转换到输出形状,不改变稀疏值本身,只更新索引。该算子不区分数据类型,只处理索引信息。
|
||
|
||
|
||
对于每个稀疏元素:
|
||
- 计算其在输入形状中的线性索引:
|
||
|
||
:math:`\text{ori\_index} = \sum_{j=0}^{\text{input\_rank}-1} \text{in\_indices}[j] \times \text{in\_stride}[j]`
|
||
|
||
- 将线性索引转换为输出形状的多维索引:
|
||
|
||
:math:`\text{out\_indices}[j] = \text{ori\_index} / \text{out\_stride}[j]`,然后 :math:`\text{ori\_index} = \text{ori\_index} \% \text{out\_stride}[j]`
|
||
|
||
输入:
|
||
- **in_indices_ptr** - 输入稀疏张量的索引数组,大小为 `N * input\_rank`,每 `input\_rank` 个元素表示一个非零元素的索引。
|
||
- **in_inshape_ptr** - 输入稀疏张量的形状数组,大小为 `input\_rank`,例如 `[2, 3]` 表示 2×3 的矩阵。
|
||
- **in_outshape_ptr** - 目标输出形状数组,大小为 `output_rank`,例如 `[3, 2]` 表示要将形状转换为 3×2。
|
||
- **out_outshape_ptr** - 输出形状数组,应该与 `in_outshape_ptr` 一致,大小为 `output_rank`。
|
||
- **input_rank** - 输入稀疏张量的维度数。
|
||
- **output_rank** - 输出稀疏张量的维度数。
|
||
- **N** - 稀疏张量中非零元素的数量。
|
||
- **in_stride** - 输入形状的步长数组(临时空间),大小为 `input_rank`,用于中间计算。
|
||
- **out_stride** - 输出形状的步长数组(临时空间),大小为 `output_rank`,用于中间计算。
|
||
- **core_mask** - 核掩码(仅共享存储版本需要)。
|
||
|
||
输出:
|
||
- **out_indices_ptr** - 转换后的索引数组,大小为 `N * output_rank`,每 `output_rank` 个元素表示一个非零元素在输出形状中的索引。
|
||
|
||
支持平台:
|
||
``FT78NE``
|
||
``MT7004``
|
||
|
||
.. note::
|
||
- FT78NE 支持fp32
|
||
- MT7004 支持fp32
|
||
|
||
**共享存储版本:**
|
||
|
||
.. c:function:: void sparsereshape_s(int* in_indices_ptr, int* in_inshape_ptr, int* in_outshape_ptr, int* out_indices_ptr, int* out_outshape_ptr, int input_rank, int output_rank, int N, int* in_stride, int* out_stride, int core_mask)
|
||
|
||
**C调用示例:**
|
||
|
||
.. code-block:: c
|
||
:linenos:
|
||
:emphasize-lines: 31-33
|
||
|
||
//FT78NE示例
|
||
#include <stdio.h>
|
||
#include <sparsereshape.h>
|
||
|
||
int main(int argc, char* argv[]) {
|
||
// 假设在DDR空间
|
||
int N = 3; // 有3个非零元素
|
||
int input_rank = 2; // 输入是2维
|
||
int output_rank = 2; // 输出也是2维
|
||
|
||
// 输入形状 [2, 3],输出形状 [3, 2]
|
||
int in_inshape[] = {2, 3};
|
||
int in_outshape[] = {3, 2};
|
||
int out_outshape[] = {3, 2}; // 应该和 in_outshape 一致
|
||
|
||
// 输入索引:[[0,0], [0,1], [1,2]]
|
||
int *in_indices_ptr = (int *)0xA0000000;
|
||
in_indices_ptr[0] = 0; in_indices_ptr[1] = 0; // 第一个元素在位置(0,0)
|
||
in_indices_ptr[2] = 0; in_indices_ptr[3] = 1; // 第二个元素在位置(0,1)
|
||
in_indices_ptr[4] = 1; in_indices_ptr[5] = 2; // 第三个元素在位置(1,2)
|
||
|
||
// 输出索引(待填充)
|
||
int *out_indices_ptr = (int *)0xB0000000;
|
||
|
||
// 临时空间:步长数组
|
||
int *in_stride = (int *)0xC0000000; // 大小为 input_rank
|
||
int *out_stride = (int *)0xC0100000; // 大小为 output_rank
|
||
|
||
int core_mask = 0xff;
|
||
|
||
sparsereshape_s(in_indices_ptr, in_inshape, in_outshape, out_indices_ptr,
|
||
out_outshape, input_rank, output_rank, N, in_stride,
|
||
out_stride, core_mask);
|
||
|
||
return 0;
|
||
}
|
||
|
||
**私有存储版本:**
|
||
|
||
.. c:function:: void sparsereshape_p(int* in_indices_ptr, int* in_inshape_ptr, int* in_outshape_ptr, int* out_indices_ptr, int* out_outshape_ptr, int input_rank, int output_rank, int N, int* in_stride, int* out_stride)
|
||
|
||
**C调用示例:**
|
||
|
||
.. code-block:: c
|
||
:linenos:
|
||
:emphasize-lines: 24-26
|
||
|
||
//FT78NE示例
|
||
#include <stdio.h>
|
||
#include <sparsereshape.h>
|
||
|
||
int main(int argc, char* argv[]) {
|
||
// 假设在L2空间
|
||
int N = 3;
|
||
int input_rank = 2;
|
||
int output_rank = 2;
|
||
|
||
int in_inshape[] = {2, 3};
|
||
int in_outshape[] = {3, 2};
|
||
int out_outshape[] = {3, 2};
|
||
|
||
int *in_indices_ptr = (int *)0x10000000;
|
||
in_indices_ptr[0] = 0; in_indices_ptr[1] = 0;
|
||
in_indices_ptr[2] = 0; in_indices_ptr[3] = 1;
|
||
in_indices_ptr[4] = 1; in_indices_ptr[5] = 2;
|
||
|
||
int *out_indices_ptr = (int *)0x10001000;
|
||
int *in_stride = (int *)0x10002000;
|
||
int *out_stride = (int *)0x10003000;
|
||
|
||
sparsereshape_p(in_indices_ptr, in_inshape, in_outshape, out_indices_ptr,
|
||
out_outshape, input_rank, output_rank, N, in_stride,
|
||
out_stride);
|
||
|
||
return 0;
|
||
} |