FT_DSP.gitlink.net/master/html/_sources/functionlib/dsplib/scatter_elements.rst.txt

178 lines
8.7 KiB
ReStructuredText
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

ScatterElements
=================
返回一个新tensor根据指定索引和更新值对input中的元素进行指定操作替换或相加。不支持隐式类型转换。举例一个三维输入tensor的返回为:
.. code-block:: python
output[indices[i][j][k]][j][k] = updates[i][j][k] #if axis == 0, reduction == "none"
output[i][indices[i][j][k]][k] += updates[i][j][k] #if axis == 1, reduction == "add"
output[i][j][indices[i][j][k]] = updates[i][j][k] #if axis == 2, reduction == "none"
输入:
- **input** - 输入数据的地址
- **indices** - 指定索引。
- **updates** - 更新值。
- **param** - 算子计算所需参数的结构体。其各成员见下述。
- **core_mask** - 核掩码。
**ScatterElementsParameter定义**
.. code-block:: c
:linenos:
typedef struct ScatterElementsParameter {
int* indices_stride_; // 对应于indices数组每一维度的步长
int* output_stride_; // 对应于output数组每一维度的步长
int input_dims_; // 输入张量的维度数
int axis_; // 指定索引所在的轴
int input_axis_size_; // 索引所在轴的元素数
int indices_total_num_; // indices数组的总元素数
int input_total_num_; // input数组的总元素数
int reduction_type_; // 规约类型0代表none1代表add
} ScatterElementsParameter;
输出:
- **output** - 输出地址。
支持平台:
``FT78NE``
``MT7004``
.. note::
- FT78NE 支持int8, int16, int32, fp32, fp64, cplx64, cplx128
- MT7004 支持fp16, fp32, int16, int32, cplx64
- 如果 indices 中有多个索引向量对应于同一位置,则输出中该位置值是不确定的。
- 如果 indices 的值超出 input 索引上下界,则相应的 updates 不会更新到 input也不会抛出索引错误。
**共享存储版本:**
.. c:function:: void i8_scatter_elements_s(int8_t* input, int8_t* output, int* indices, int8_t* updates, ScatterElementsParameter* param, int core_mask)
.. c:function:: void i16_scatter_elements_s(int16_t* input, int16_t* output, int* indices, int16_t* updates, ScatterElementsParameter* param, int core_mask)
.. c:function:: void i32_scatter_elements_s(int* input, int* output, int* indices, int* updates, ScatterElementsParameter* param, int core_mask)
.. c:function:: void hp_scatter_elements_s(half* input, half* output, int* indices, half* updates, ScatterElementsParameter* param, int core_mask)
.. c:function:: void fp_scatter_elements_s(float* input, float* output, int* indices, float* updates, ScatterElementsParameter* param, int core_mask)
.. c:function:: void dp_scatter_elements_s(double* input, double* output, int* indices, double* updates, ScatterElementsParameter* param, int core_mask)
.. c:function:: void c64_scatter_elements_s(float* input, float* output, int* indices, float* updates, ScatterElementsParameter* param, int core_mask)
.. c:function:: void c128_scatter_elements_s(double* input, double* output, int* indices, double* updates, ScatterElementsParameter* param, int core_mask)
**C调用示例**
.. code-block:: c
:linenos:
:emphasize-lines: 40
void PackParam(ScatterElementsParameter* param, int* indices_shape, int* input_shape) {
param->indices_stride_[param->input_dims_ - 1] = 1;
int i;
for (i = param->input_dims_ - 1; i > 0; --i) {
param->indices_stride_[i - 1] = param->indices_stride_[i] * indices_shape[i];
}
param->output_stride_[param->input_dims_ - 1] = 1;
for (i = param->input_dims_ - 1; i > 0; --i) {
param->output_stride_[i - 1] = param->output_stride_[i] * input_shape[i];
}
param->indices_total_num_ = 1;
for (i = 0; i < param->input_dims_; i++) {
param->indices_total_num_ *= indices_shape[i];
}
param->input_total_num_ = 1;
for (i = 0; i < param->input_dims_; i++) {
param->input_total_num_ *= input_shape[i];
}
param->input_axis_size_ = input_shape[param->axis_];
}
void TestScatterElementsSMC(int* input_shape, int* indices_shape, int ndim, int axis, int reduction_type, int core_mask) {
int core_num = GetCoreNum(core_mask);
int core_id = get_core_id();
int logic_core_id = GetLogicCoreId(core_mask, core_id);
void* input_data = (void*)0x88000000;
void* output_data = (void*)0x98000000;
int* indices_data = (int*)0xA8000000;
void* updates_data = (void*)0xB8000000;
ScatterElementsParameter* param = (ScatterElementsParameter*)0xC8000000;
if (logic_core_id == 0) {
param->axis_ = axis;
param->input_dims_ = ndim;
param->indices_stride_ = (int*)0xC8020000;
param->output_stride_ = (int*)0xC8040000;
param->reduction_type_ = reduction_type;
PackParam(param, indices_shape, input_shape);
}
sys_bar(0, core_num); // 初始化参数完成后进行同步
fp_scatter_elements_s(input_data, output_data, indices_data, updates_data, param, core_mask);
}
void main() {
int input_shape[2] = {8, 30};
int indices_shape[2] = {3, 3};
int ndim = 2;
int axis = 0;
int reduction_type = 0;
int core_mask = 0b1111;
TestScatterElementsSMC(input_shape, indices_shape, ndim, axis, reduction_type, core_mask);
}
**私有存储版本:**
.. c:function:: void i8_scatter_elements_p(int8_t* input, int8_t* output, int* indices, int8_t* updates, ScatterElementsParameter* param, int core_mask)
.. c:function:: void i16_scatter_elements_p(int16_t* input, int16_t* output, int* indices, int16_t* updates, ScatterElementsParameter* param, int core_mask)
.. c:function:: void i32_scatter_elements_p(int* input, int* output, int* indices, int* updates, ScatterElementsParameter* param, int core_mask)
.. c:function:: void hp_scatter_elements_p(half* input, half* output, int* indices, half* updates, ScatterElementsParameter* param, int core_mask)
.. c:function:: void fp_scatter_elements_p(float* input, float* output, int* indices, float* updates, ScatterElementsParameter* param, int core_mask)
.. c:function:: void dp_scatter_elements_p(double* input, double* output, int* indices, double* updates, ScatterElementsParameter* param, int core_mask)
.. c:function:: void c64_scatter_elements_p(float* input, float* output, int* indices, float* updates, ScatterElementsParameter* param, int core_mask)
.. c:function:: void c128_scatter_elements_p(double* input, double* output, int* indices, double* updates, ScatterElementsParameter* param, int core_mask)
**C调用示例**
.. code-block:: c
:linenos:
:emphasize-lines: 34
void PackParam(ScatterElementsParameter* param, int* indices_shape, int* input_shape) {
param->indices_stride_[param->input_dims_ - 1] = 1;
int i;
for (i = param->input_dims_ - 1; i > 0; --i) {
param->indices_stride_[i - 1] = param->indices_stride_[i] * indices_shape[i];
}
param->output_stride_[param->input_dims_ - 1] = 1;
for (i = param->input_dims_ - 1; i > 0; --i) {
param->output_stride_[i - 1] = param->output_stride_[i] * input_shape[i];
}
param->indices_total_num_ = 1;
for (i = 0; i < param->input_dims_; i++) {
param->indices_total_num_ *= indices_shape[i];
}
param->input_total_num_ = 1;
for (i = 0; i < param->input_dims_; i++) {
param->input_total_num_ *= input_shape[i];
}
param->input_axis_size_ = input_shape[param->axis_];
}
void TestScatterElementsL2(int* input_shape, int* indices_shape, int ndim, int axis, int reduction_type, int core_mask) {
void* input_data = (void*)0x10000000; // 私有存储版本地址设置在AM内
void* output_data = (void*)0x10001000;
int* indices_data = (int*)0x10002000;
void* updates_data = (void*)0x10003000;
ScatterElementsParameter* param = (ScatterElementsParameter*)0x10004000;
param->axis_ = axis;
param->input_dims_ = ndim;
param->indices_stride_ = (int*)0x10005000;
param->output_stride_ = (int*)0x10006000;
param->reduction_type_ = reduction_type;
PackParam(param, indices_shape, input_shape);
fp_scatter_elements_p(input_data, output_data, indices_data, updates_data, param, core_mask);
}
void main() {
int input_shape[2] = {8, 30};
int indices_shape[2] = {3, 3};
int ndim = 2;
int axis = 0;
int reduction_type = 0;
int core_mask = 0b0001; // 私有存储版本只能设置为一个核心启动
TestScatterElementsL2(input_shape, indices_shape, ndim, axis, reduction_type, core_mask);
}