已合并
doc tools低错内容4.17 #3912
caiwenwen创建于 4月17日
doc tools低错内容4.17 #3912
已合并
共 77 个文件变更+792-151
| @@ -15,7 +15,7 @@ ops-nn 算子首个 Beta 版本 v8.5.0-beta.1 现已发布。 | |||
| 15 | 15 | ||
| 16 | [CANN 8.5.0-beta 1](https://ascend.devcloud.huaweicloud.com/cann/run/software/8.5.0-beta.1/) | 16 | [CANN 8.5.0-beta 1](https://ascend.devcloud.huaweicloud.com/cann/run/software/8.5.0-beta.1/) |
| 17 | 17 | ||
| 18 | -``` | 18 | +```text |
| 19 | 版本目录说明如下: | 19 | 版本目录说明如下: |
| 20 | ├── aarch64 # CPU为ARM类型 | 20 | ├── aarch64 # CPU为ARM类型 |
| 21 | │ ├── ops # ops算子包目录,用于归档算子子包 | 21 | │ ├── ops # ops算子包目录,用于归档算子子包 |
| @@ -37,7 +37,7 @@ Sig组将指派Committer对您提交的Issue进行评审并反馈修改意见。 | |||
| 37 | 37 | ||
| 38 | 生态最简算子交付件如下: | 38 | 生态最简算子交付件如下: |
| 39 | 39 | ||
| 40 | -``` | 40 | +```text |
| 41 | ${op_class} # 算子分类 | 41 | ${op_class} # 算子分类 |
| 42 | ├── ${op_name} # 算子名 | 42 | ├── ${op_name} # 算子名 |
| 43 | │ ├── ${op_name}.cpp # 算子Kernel实现文件 | 43 | │ ├── ${op_name}.cpp # 算子Kernel实现文件 |
| @@ -107,7 +107,7 @@ Committer检视通过后,标注 `/lgtm`标签。Maintainer将在1天内进行 | |||
| 107 | 107 | ||
| 108 | 项目标准算子交付件如下: | 108 | 项目标准算子交付件如下: |
| 109 | 109 | ||
| 110 | -``` | 110 | +```text |
| 111 | ${op_class} # 算子分类 | 111 | ${op_class} # 算子分类 |
| 112 | ├── ${op_name} # 算子名 | 112 | ├── ${op_name} # 算子名 |
| 113 | │ ├── op_host # 算子定义、Tiling相关实现 | 113 | │ ├── op_host # 算子定义、Tiling相关实现 |
| @@ -201,7 +201,7 @@ bash build.sh --run_example add_example eager cust --vendor_name=custom | |||
| 201 | 201 | ||
| 202 | 预期输出:打印算子`AddExample`的加法计算结果,表明算子已成功部署并正确执行。 | 202 | 预期输出:打印算子`AddExample`的加法计算结果,表明算子已成功部署并正确执行。 |
| 203 | 203 | ||
| 204 | -``` | 204 | +```bash |
| 205 | add_example first input[0] is: 1.000000, second input[0] is: 1.000000, result[0] is: 2.000000 | 205 | add_example first input[0] is: 1.000000, second input[0] is: 1.000000, result[0] is: 2.000000 |
| 206 | add_example first input[1] is: 1.000000, second input[1] is: 1.000000, result[1] is: 2.000000 | 206 | add_example first input[1] is: 1.000000, second input[1] is: 1.000000, result[1] is: 2.000000 |
| 207 | add_example first input[2] is: 1.000000, second input[2] is: 1.000000, result[2] is: 2.000000 | 207 | add_example first input[2] is: 1.000000, second input[2] is: 1.000000, result[2] is: 2.000000 |
| @@ -261,7 +261,7 @@ __aicore__ inline void AddExample<T>::Compute(int32_t progress) | |||
| 261 | 261 | ||
| 262 | 4. **成功标志**:输出结果变成乘法结果。 | 262 | 4. **成功标志**:输出结果变成乘法结果。 |
| 263 | 263 | ||
| 264 | - ``` | 264 | + ```bash |
| 265 | add_example first input[0] is: 1.000000, second input[0] is: 1.000000, result[0] is: 1.000000 | 265 | add_example first input[0] is: 1.000000, second input[0] is: 1.000000, result[0] is: 1.000000 |
| 266 | add_example first input[1] is: 1.000000, second input[1] is: 1.000000, result[1] is: 1.000000 | 266 | add_example first input[1] is: 1.000000, second input[1] is: 1.000000, result[1] is: 1.000000 |
| 267 | add_example first input[2] is: 1.000000, second input[2] is: 1.000000, result[2] is: 1.000000 | 267 | add_example first input[2] is: 1.000000, second input[2] is: 1.000000, result[2] is: 1.000000 |
| @@ -45,7 +45,7 @@ ops-nn是[CANN](https://hiascend.com/software/cann) (Compute Architecture for | |||
| 45 | 45 | ||
| 46 | 关键目录如下,详细目录介绍参见[项目目录](./docs/zh/context/dir_structure.md)。 | 46 | 关键目录如下,详细目录介绍参见[项目目录](./docs/zh/context/dir_structure.md)。 |
| 47 | 47 | ||
| 48 | -``` | 48 | +```text |
| 49 | ├── activation # activation类算子 | 49 | ├── activation # activation类算子 |
| 50 | ├── cmake # 项目工程编译目录 | 50 | ├── cmake # 项目工程编译目录 |
| 51 | ├── common # 项目公共头文件和公共源码 | 51 | ├── common # 项目公共头文件和公共源码 |
| @@ -58,7 +58,6 @@ | |||
| 58 | $$ | 58 | $$ |
| 59 | B = x[ : , h : ] | 59 | B = x[ : , h : ] |
| 60 | $$ | 60 | $$ |
| 61 | - | ||
| 62 | 4. 根据输入参数 alpha、limit、bias 进行变体SwiGlu计算,公式如下: | 61 | 4. 根据输入参数 alpha、limit、bias 进行变体SwiGlu计算,公式如下: |
| 63 | 62 | ||
| 64 | $$ | 63 | $$ |
| @@ -76,7 +75,6 @@ | |||
| 76 | $$ | 75 | $$ |
| 77 | y = y\_glu * (B + bias) | 76 | y = y\_glu * (B + bias) |
| 78 | $$ | 77 | $$ |
| 79 | - | ||
| 80 | 5. 重塑输出张量y的维度数量与合轴前的x的维度数量一致,dim轴上的大小为x的一半,其他维度与x相同。 | 78 | 5. 重塑输出张量y的维度数量与合轴前的x的维度数量一致,dim轴上的大小为x的一半,其他维度与x相同。 |
| 81 | 79 | ||
| 82 | ## 参数说明 | 80 | ## 参数说明 |
| @@ -60,7 +60,6 @@ | |||
| 60 | $$ | 60 | $$ |
| 61 | B = x[ : , h : ] | 61 | B = x[ : , h : ] |
| 62 | $$ | 62 | $$ |
| 63 | - | ||
| 64 | 4. 根据输入参数 alpha、limit、bias 进行变体SwiGlu计算,公式如下: | 63 | 4. 根据输入参数 alpha、limit、bias 进行变体SwiGlu计算,公式如下: |
| 65 | 64 | ||
| 66 | $$ | 65 | $$ |
| @@ -78,7 +77,6 @@ | |||
| 78 | $$ | 77 | $$ |
| 79 | y = y\_glu * (B + bias) | 78 | y = y\_glu * (B + bias) |
| 80 | $$ | 79 | $$ |
| 81 | - | ||
| 82 | 5. 重塑输出张量y的维度数量与合轴前的x的维度数量一致,dim轴上的大小为x的一半,其他维度与x相同。 | 80 | 5. 重塑输出张量y的维度数量与合轴前的x的维度数量一致,dim轴上的大小为x的一半,其他维度与x相同。 |
| 83 | 81 | ||
| 84 | ## 函数原型 | 82 | ## 函数原型 |
| @@ -28,7 +28,6 @@ | |||
| 28 | $$ | 28 | $$ |
| 29 | x_1 = \text{input}[..., :d], \quad x_2 = \text{input}[..., d:] | 29 | x_1 = \text{input}[..., :d], \quad x_2 = \text{input}[..., d:] |
| 30 | $$ | 30 | $$ |
| 31 | - | ||
| 32 | 2. 对x1应用Threshold激活函数,定义如下: | 31 | 2. 对x1应用Threshold激活函数,定义如下: |
| 33 | 32 | ||
| 34 | $$ | 33 | $$ |
| @@ -44,7 +43,6 @@ | |||
| 44 | $$ | 43 | $$ |
| 45 | x_1 = \text{Threshold}(x_1, \text{threshold}) | 44 | x_1 = \text{Threshold}(x_1, \text{threshold}) |
| 46 | $$ | 45 | $$ |
| 47 | - | ||
| 48 | 3. 最终输出是x1和x2的逐元素乘积: | 46 | 3. 最终输出是x1和x2的逐元素乘积: |
| 49 | 47 | ||
| 50 | $$ | 48 | $$ |
| @@ -28,7 +28,6 @@ | |||
| 28 | $$ | 28 | $$ |
| 29 | x_1 = \text{input}[..., :d], \quad x_2 = \text{input}[..., d:] | 29 | x_1 = \text{input}[..., :d], \quad x_2 = \text{input}[..., d:] |
| 30 | $$ | 30 | $$ |
| 31 | - | ||
| 32 | 2. 对x1应用Threshold激活函数,定义如下: | 31 | 2. 对x1应用Threshold激活函数,定义如下: |
| 33 | 32 | ||
| 34 | $$ | 33 | $$ |
| @@ -44,7 +43,6 @@ | |||
| 44 | $$ | 43 | $$ |
| 45 | x_1 = \text{Threshold}(x_1, \text{threshold}) | 44 | x_1 = \text{Threshold}(x_1, \text{threshold}) |
| 46 | $$ | 45 | $$ |
| 47 | - | ||
| 48 | 3. 最终输出是x1和x2的逐元素乘积: | 46 | 3. 最终输出是x1和x2的逐元素乘积: |
| 49 | 47 | ||
| 50 | $$ | 48 | $$ |
| @@ -28,7 +28,6 @@ | |||
| 28 | $$ | 28 | $$ |
| 29 | x_1 = \text{input}[..., :d], \quad x_2 = \text{input}[..., d:] | 29 | x_1 = \text{input}[..., :d], \quad x_2 = \text{input}[..., d:] |
| 30 | $$ | 30 | $$ |
| 31 | - | ||
| 32 | 2. 对x1应用GELU激活函数,"tanh"模式公式如下: | 31 | 2. 对x1应用GELU激活函数,"tanh"模式公式如下: |
| 33 | 32 | ||
| 34 | $$ | 33 | $$ |
| @@ -46,7 +45,6 @@ | |||
| 46 | $$ | 45 | $$ |
| 47 | x_1 = \text{GELU}(x_1) | 46 | x_1 = \text{GELU}(x_1) |
| 48 | $$ | 47 | $$ |
| 49 | - | ||
| 50 | 3. 最终输出是x1和x2的逐元素乘积: | 48 | 3. 最终输出是x1和x2的逐元素乘积: |
| 51 | 49 | ||
| 52 | $$ | 50 | $$ |
| @@ -28,7 +28,6 @@ | |||
| 28 | $$ | 28 | $$ |
| 29 | x_1 = \text{input}[..., :d], \quad x_2 = \text{input}[..., d:] | 29 | x_1 = \text{input}[..., :d], \quad x_2 = \text{input}[..., d:] |
| 30 | $$ | 30 | $$ |
| 31 | - | ||
| 32 | 2. 对x1应用GELU激活函数,"tanh"模式公式如下: | 31 | 2. 对x1应用GELU激活函数,"tanh"模式公式如下: |
| 33 | 32 | ||
| 34 | $$ | 33 | $$ |
| @@ -46,7 +45,6 @@ | |||
| 46 | $$ | 45 | $$ |
| 47 | x_1 = \text{GELU}(x_1) | 46 | x_1 = \text{GELU}(x_1) |
| 48 | $$ | 47 | $$ |
| 49 | - | ||
| 50 | 3. 最终输出是x1和x2的逐元素乘积: | 48 | 3. 最终输出是x1和x2的逐元素乘积: |
| 51 | 49 | ||
| 52 | $$ | 50 | $$ |
| @@ -16,7 +16,7 @@ | |||
| 16 | ## 功能说明 | 16 | ## 功能说明 |
| 17 | 17 | ||
| 18 | - 接口功能: | 18 | - 接口功能: |
| 19 | -将输入self执行logits计算,将得到的值与标签值target一起进行[BECLoss](../../sigmoid_cross_entropy_with_logits_v2/docs/aclnnBinaryCrossEntropyWithLogits.md)关于target的反向传播计算。 | 19 | +将输入self执行logits计算,将得到的值与标签值target一起进行[BECLoss](../../../loss/sigmoid_cross_entropy_with_logits_v2/docs/aclnnBinaryCrossEntropyWithLogits.md)关于target的反向传播计算。 |
| 20 | 20 | ||
| 21 | ## 函数原型 | 21 | ## 函数原型 |
| 22 | 22 | ||
| @@ -42,7 +42,7 @@ | |||
| 42 | 42 | ||
| 43 | aclnnStatus: 返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 | 43 | aclnnStatus: 返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 |
| 44 | 44 | ||
| 45 | - ``` | 45 | + ```text |
| 46 | 第一段接口完成入参校验,出现以下场景时报错: | 46 | 第一段接口完成入参校验,出现以下场景时报错: |
| 47 | 161001(ACLNN_ERR_PARAM_NULLPTR):1. 传入的gradOutput、self、target、gradTarget为空指针。 | 47 | 161001(ACLNN_ERR_PARAM_NULLPTR):1. 传入的gradOutput、self、target、gradTarget为空指针。 |
| 48 | 161002(ACLNN_ERR_PARAM_INVALID):1. gradOutput、self、target、gradTarget的数据类型和数据格式不在支持的范围内。 | 48 | 161002(ACLNN_ERR_PARAM_INVALID):1. gradOutput、self、target、gradTarget的数据类型和数据格式不在支持的范围内。 |
| @@ -182,7 +182,7 @@ | |||
| 182 | - Atlas A2 训练系列产品/Atlas A2 推理系列产品、Atlas A3 训练系列产品/Atlas A3 推理系列产品: | 182 | - Atlas A2 训练系列产品/Atlas A2 推理系列产品、Atlas A3 训练系列产品/Atlas A3 推理系列产品: |
| 183 | - `filter` 的 `H`、`W` 维度范围:[1,511]。 | 183 | - `filter` 的 `H`、`W` 维度范围:[1,511]。 |
| 184 | - 不支持空 `tensor`。 | 184 | - 不支持空 `tensor`。 |
| 185 | - - 当 `groups` 为 1, `dilation` 全为 1,`padding` 全为 0,`filter` 没有为 1 的维度, `x` 的 `D` * `H` * `W` 小于 65536,`bias` 为 `FLOAT` 时,会进入 `Pointwise` 分支,可以使用 `NCDHW` 格式。 | 185 | + - 当 `groups` 为 1, `dilation` 全为 1,`padding` 全为 0,`filter` 没有为 1 的维度, `x` 的 `D` *`H`* `W` 小于 65536,`bias` 为 `FLOAT` 时,会进入 `Pointwise` 分支,可以使用 `NCDHW` 格式。 |
| 186 | 186 | ||
| 187 | <table> | 187 | <table> |
| 188 | <tr> | 188 | <tr> |
| @@ -31,7 +31,8 @@ | |||
| 31 | W_{out}=\lfloor \frac{W_{in}+2*padding[2]-dilation[2] * (kernelSize[2] -1) -1}{stride[2]}+1 \rfloor | 31 | W_{out}=\lfloor \frac{W_{in}+2*padding[2]-dilation[2] * (kernelSize[2] -1) -1}{stride[2]}+1 \rfloor |
| 32 | $$ | 32 | $$ |
| 33 | 33 | ||
| 34 | - 卷积反向传播需要计算对卷积正向的输入张量 $x$(对应函数原型中的input)、卷积核权重张量 $w$ (对应函数原型中的weight)和偏置 $b$ 的梯度。 | 34 | + 卷积反向传播需要计算对卷积正向的输入张量 $x$(对应函数原型中的input)、卷积核权重张量 $w$(对应函数原型中的weight)和偏置 $b$ 的梯度。 |
| 35 | + | ||
| 35 | - 对于 $x$ 的梯度 $\frac{\partial L}{\partial x}$(对应函数原型中的gradInput参数): | 36 | - 对于 $x$ 的梯度 $\frac{\partial L}{\partial x}$(对应函数原型中的gradInput参数): |
| 36 | 37 | ||
| 37 | $$ | 38 | $$ |
| @@ -40,7 +40,7 @@ | |||
| 40 | 40 | ||
| 41 | - 撰写清晰的提交信息: | 41 | - 撰写清晰的提交信息: |
| 42 | 42 | ||
| 43 | - ``` | 43 | + ```text |
| 44 | 简短说明(不超过50字符) | 44 | 简短说明(不超过50字符) |
| 45 | 45 | ||
| 46 | 如有必要,在此处进行更详细描述。说明修改的原因和内容,而不是具体改了什么(代码本身会展示)。 | 46 | 如有必要,在此处进行更详细描述。说明修改的原因和内容,而不是具体改了什么(代码本身会展示)。 |
| @@ -4,7 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | 关键目录结构如下: | 5 | 关键目录结构如下: |
| 6 | 6 | ||
| 7 | -``` | 7 | +```text |
| 8 | ├── context # 公共目录,存放包括基本概念、项目目录介绍、build参数说明等文档 | 8 | ├── context # 公共目录,存放包括基本概念、项目目录介绍、build参数说明等文档 |
| 9 | │ ├── dir_structure.md | 9 | │ ├── dir_structure.md |
| 10 | │ ├── build.md | 10 | │ ├── build.md |
| @@ -25,7 +25,7 @@ broadcast(广播)描述了算子在运算期间如何处理不同形状的 | |||
| 25 | 25 | ||
| 26 | 基于上述规则,广播过程一般先按**规则1**进行扩维,再按**规则2**进行形状拉伸,具体例子如下: | 26 | 基于上述规则,广播过程一般先按**规则1**进行扩维,再按**规则2**进行形状拉伸,具体例子如下: |
| 27 | 27 | ||
| 28 | -``` | 28 | +```text |
| 29 | 假设a.shape=(2,2,3),取值形如: | 29 | 假设a.shape=(2,2,3),取值形如: |
| 30 | [[[1 2 3],[4 5 6]], | 30 | [[[1 2 3],[4 5 6]], |
| 31 | [[1 2 3],[4 5 6]]] | 31 | [[1 2 3],[4 5 6]]] |
| @@ -9,7 +9,7 @@ | |||
| 9 | 9 | ||
| 10 | 项目全量目录层级介绍如下: | 10 | 项目全量目录层级介绍如下: |
| 11 | 11 | ||
| 12 | -``` | 12 | +```text |
| 13 | ├── cmake # 项目工程编译目录 | 13 | ├── cmake # 项目工程编译目录 |
| 14 | │ ├── aclnn_ops_nn.h.in # aclnn汇总头文件模板 | 14 | │ ├── aclnn_ops_nn.h.in # aclnn汇总头文件模板 |
| 15 | │ └── ... | 15 | │ └── ... |
| @@ -8,7 +8,7 @@ | |||
| 8 | 8 | ||
| 9 | 框架定义的一种用来管理和存储张量数据的结构(如向量、矩阵等多维度数据),可通过**aclCreateTensor**接口创建该对象。 | 9 | 框架定义的一种用来管理和存储张量数据的结构(如向量、矩阵等多维度数据),可通过**aclCreateTensor**接口创建该对象。 |
| 10 | 10 | ||
| 11 | - ``` | 11 | + ```bash |
| 12 | typedef struct aclTensor aclTensor | 12 | typedef struct aclTensor aclTensor |
| 13 | ``` | 13 | ``` |
| 14 | 14 | ||
| @@ -16,7 +16,7 @@ | |||
| 16 | 16 | ||
| 17 | 框架定义的一种用来管理和存储标量数据的结构(即单一的数值),可通过**aclCreateScalar**接口创建该对象。 | 17 | 框架定义的一种用来管理和存储标量数据的结构(即单一的数值),可通过**aclCreateScalar**接口创建该对象。 |
| 18 | 18 | ||
| 19 | - ``` | 19 | + ```bash |
| 20 | typedef struct aclScalar aclScalar | 20 | typedef struct aclScalar aclScalar |
| 21 | ``` | 21 | ``` |
| 22 | 22 | ||
| @@ -24,7 +24,7 @@ | |||
| 24 | 24 | ||
| 25 | 框架定义的一种用来管理和存储整型数据的数组结构,可通过**aclCreateIntArray**接口创建该对象。 | 25 | 框架定义的一种用来管理和存储整型数据的数组结构,可通过**aclCreateIntArray**接口创建该对象。 |
| 26 | 26 | ||
| 27 | - ``` | 27 | + ```bash |
| 28 | typedef struct aclIntArray aclIntArray | 28 | typedef struct aclIntArray aclIntArray |
| 29 | ``` | 29 | ``` |
| 30 | 30 | ||
| @@ -32,7 +32,7 @@ | |||
| 32 | 32 | ||
| 33 | 框架定义的一种用来管理和存储float32型数据的数组结构,可通过**aclCreateFloatArray**接口创建该对象。 | 33 | 框架定义的一种用来管理和存储float32型数据的数组结构,可通过**aclCreateFloatArray**接口创建该对象。 |
| 34 | 34 | ||
| 35 | - ``` | 35 | + ```bash |
| 36 | typedef struct aclFloatArray aclFloatArray | 36 | typedef struct aclFloatArray aclFloatArray |
| 37 | ``` | 37 | ``` |
| 38 | 38 | ||
| @@ -40,7 +40,7 @@ | |||
| 40 | 40 | ||
| 41 | 框架定义的一种用来管理和存储布尔型数据的数组结构,可通过**aclCreateBoolArray**接口创建该对象。 | 41 | 框架定义的一种用来管理和存储布尔型数据的数组结构,可通过**aclCreateBoolArray**接口创建该对象。 |
| 42 | 42 | ||
| 43 | - ``` | 43 | + ```bash |
| 44 | typedef struct aclBoolArray aclBoolArray | 44 | typedef struct aclBoolArray aclBoolArray |
| 45 | ``` | 45 | ``` |
| 46 | 46 | ||
| @@ -48,7 +48,7 @@ | |||
| 48 | 48 | ||
| 49 | 框架定义的一种用来管理和存储多个张量数据的数组结构,可通过**aclCreateTensorList**接口创建该对象。 | 49 | 框架定义的一种用来管理和存储多个张量数据的数组结构,可通过**aclCreateTensorList**接口创建该对象。 |
| 50 | 50 | ||
| 51 | - ``` | 51 | + ```bash |
| 52 | typedef struct aclTensorList aclTensorList | 52 | typedef struct aclTensorList aclTensorList |
| 53 | ``` | 53 | ``` |
| 54 | 54 | ||
| @@ -56,7 +56,7 @@ | |||
| 56 | 56 | ||
| 57 | 框架定义的一种用来管理和存储标量数据的数组结构,可通过**aclCreateScalarList**接口创建该对象。 | 57 | 框架定义的一种用来管理和存储标量数据的数组结构,可通过**aclCreateScalarList**接口创建该对象。 |
| 58 | 58 | ||
| 59 | - ``` | 59 | + ```bash |
| 60 | typedef struct aclScalarList aclScalarList | 60 | typedef struct aclScalarList aclScalarList |
| 61 | ``` | 61 | ``` |
| 62 | 62 | ||
| @@ -66,7 +66,7 @@ | |||
| 66 | 66 | ||
| 67 | 通常调用算子一阶段接口aclxxXxxGetWorkspaceSize时,框架会自动创建aclOpExecutor;调用二阶段接口aclxxXxx后会自动释放该对象。 | 67 | 通常调用算子一阶段接口aclxxXxxGetWorkspaceSize时,框架会自动创建aclOpExecutor;调用二阶段接口aclxxXxx后会自动释放该对象。 |
| 68 | 68 | ||
| 69 | - ``` | 69 | + ```bash |
| 70 | typedef struct aclOpExecutor aclOpExecutor | 70 | typedef struct aclOpExecutor aclOpExecutor |
| 71 | ``` | 71 | ``` |
| 72 | 72 | ||
| @@ -74,7 +74,7 @@ | |||
| 74 | 74 | ||
| 75 | 框架定义的一种流处理数据结构,用来管理和维护一些异步操作的执行顺序。 | 75 | 框架定义的一种流处理数据结构,用来管理和维护一些异步操作的执行顺序。 |
| 76 | 76 | ||
| 77 | - ``` | 77 | + ```bash |
| 78 | typedef void *aclrtStream | 78 | typedef void *aclrtStream |
| 79 | ``` | 79 | ``` |
| 80 | 80 | ||
| @@ -17,7 +17,7 @@ | |||
| 17 | 17 | ||
| 18 | CMake文件示例如下,请根据实际情况修改: | 18 | CMake文件示例如下,请根据实际情况修改: |
| 19 | 19 | ||
| 20 | - ``` | 20 | + ```bash |
| 21 | # Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. | 21 | # Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. |
| 22 | 22 | ||
| 23 | # CMake lowest version requirement | 23 | # CMake lowest version requirement |
| @@ -63,7 +63,7 @@ | |||
| 63 | 63 | ||
| 64 | 对于集合通信和MatMul计算融合、并行的算子,统称为通算融合算子(简称MC2算子),包括AllGatherMatmul、AlltoAllAllGatherBatchMatMul、BatchMatMulReduceScatterAlltoAll、MatmulAllReduce、MatmulAllReduceAddRmsNorm、MatmulReduceScatter等。调用该类算子API时,一般会涉及多线程和HCCL(Huawei Collective Communication Library,集合通信库),因此CMake文件需要额外导入如下内容,否则无法成功编译。 | 64 | 对于集合通信和MatMul计算融合、并行的算子,统称为通算融合算子(简称MC2算子),包括AllGatherMatmul、AlltoAllAllGatherBatchMatMul、BatchMatMulReduceScatterAlltoAll、MatmulAllReduce、MatmulAllReduceAddRmsNorm、MatmulReduceScatter等。调用该类算子API时,一般会涉及多线程和HCCL(Huawei Collective Communication Library,集合通信库),因此CMake文件需要额外导入如下内容,否则无法成功编译。 |
| 65 | 65 | ||
| 66 | - ``` | 66 | + ```bash |
| 67 | # 设置链接的库文件路径 | 67 | # 设置链接的库文件路径 |
| 68 | find_package(Threads REQUIRED) | 68 | find_package(Threads REQUIRED) |
| 69 | target_link_libraries(opapi_test PRIVATE | 69 | target_link_libraries(opapi_test PRIVATE |
| @@ -84,7 +84,7 @@ | |||
| 84 | 84 | ||
| 85 | 安装CANN软件后,使用CANN运行用户登录环境,执行如下命令生效环境变量。 | 85 | 安装CANN软件后,使用CANN运行用户登录环境,执行如下命令生效环境变量。 |
| 86 | 86 | ||
| 87 | - ``` | 87 | + ```bash |
| 88 | source ${INSTALL_DIR}/set_env.sh | 88 | source ${INSTALL_DIR}/set_env.sh |
| 89 | ``` | 89 | ``` |
| 90 | 90 | ||
| @@ -92,13 +92,13 @@ | |||
| 92 | 3. 编译并运行。 | 92 | 3. 编译并运行。 |
| 93 | - 进入CMakeLists.txt所在目录,执行如下命令,新建build目录存放生成的编译文件。 | 93 | - 进入CMakeLists.txt所在目录,执行如下命令,新建build目录存放生成的编译文件。 |
| 94 | 94 | ||
| 95 | - ``` | 95 | + ```bash |
| 96 | mkdir -p build | 96 | mkdir -p build |
| 97 | ``` | 97 | ``` |
| 98 | 98 | ||
| 99 | - 进入build目录,执行cmake命令编译,再执行make命令生成可执行文件。 | 99 | - 进入build目录,执行cmake命令编译,再执行make命令生成可执行文件。 |
| 100 | 100 | ||
| 101 | - ``` | 101 | + ```bash |
| 102 | cd build | 102 | cd build |
| 103 | cmake ../ -DCMAKE_CXX_COMPILER=g++ -DCMAKE_SKIP_RPATH=TRUE | 103 | cmake ../ -DCMAKE_CXX_COMPILER=g++ -DCMAKE_SKIP_RPATH=TRUE |
| 104 | make | 104 | make |
| @@ -108,14 +108,14 @@ | |||
| 108 | 108 | ||
| 109 | - 进入bin目录,运行可执行文件opapi_test。 | 109 | - 进入bin目录,运行可执行文件opapi_test。 |
| 110 | 110 | ||
| 111 | - ``` | 111 | + ```bash |
| 112 | cd bin | 112 | cd bin |
| 113 | ./opapi_test | 113 | ./opapi_test |
| 114 | ``` | 114 | ``` |
| 115 | 115 | ||
| 116 | 以AddMatMul算子的运行结果为例,运行后的结果示例如下: | 116 | 以AddMatMul算子的运行结果为例,运行后的结果示例如下: |
| 117 | 117 | ||
| 118 | - ``` | 118 | + ```bash |
| 119 | result[0] is: 1.200000 | 119 | result[0] is: 1.200000 |
| 120 | result[1] is: 2.200000 | 120 | result[1] is: 2.200000 |
| 121 | result[2] is: 3.200000 | 121 | result[2] is: 3.200000 |
| @@ -129,7 +129,7 @@ | |||
| 129 | 若执行结果报错,未出现预期结果,可以使用aclGetRecentErrMsg接口获取报错具体信息。 | 129 | 若执行结果报错,未出现预期结果,可以使用aclGetRecentErrMsg接口获取报错具体信息。 |
| 130 | 调用aclnnAddmmGetWorkspaceSize报错获取异常信息示例如下: | 130 | 调用aclnnAddmmGetWorkspaceSize报错获取异常信息示例如下: |
| 131 | 131 | ||
| 132 | - ``` | 132 | + ```bash |
| 133 | // self is nullptr | 133 | // self is nullptr |
| 134 | ret = aclnnAddmmGetWorkspaceSize(self, mat1, mat2, beta, alpha, out, cubeMathType, &workspaceSize, &executor); | 134 | ret = aclnnAddmmGetWorkspaceSize(self, mat1, mat2, beta, alpha, out, cubeMathType, &workspaceSize, &executor); |
| 135 | CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnAddmmGetWorkspaceSize failed. ERROR: %d\n[ERROR msg]%s", ret, aclGetRecentErrMsg()); return ret); | 135 | CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnAddmmGetWorkspaceSize failed. ERROR: %d\n[ERROR msg]%s", ret, aclGetRecentErrMsg()); return ret); |
| @@ -137,7 +137,7 @@ | |||
| 137 | 137 | ||
| 138 | 上述构造空指针问题获取报错信息示例如下: | 138 | 上述构造空指针问题获取报错信息示例如下: |
| 139 | 139 | ||
| 140 | - ``` | 140 | + ```bash |
| 141 | aclnnAddmmGetWorkspaceSize failed. ERROR: 161001 | 141 | aclnnAddmmGetWorkspaceSize failed. ERROR: 161001 |
| 142 | [ERROR msg][PID:xxxx] xxx(timesamp) AclNN_Parameter_Error(EZ1001): Expected a proper Tensor but got null for argument addmmTennsor.self. | 142 | [ERROR msg][PID:xxxx] xxx(timesamp) AclNN_Parameter_Error(EZ1001): Expected a proper Tensor but got null for argument addmmTennsor.self. |
| 143 | ``` | 143 | ``` |
| @@ -35,7 +35,7 @@ CANN Simulator集成在CANN toolkit包里,参考[环境部署](../context/quic | |||
| 35 | 35 | ||
| 36 | * 参考[算子调用](../invocation/quick_op_invocation.md)完成add_example的算子编译和安装。 | 36 | * 参考[算子调用](../invocation/quick_op_invocation.md)完成add_example的算子编译和安装。 |
| 37 | 37 | ||
| 38 | -``` | 38 | +```bash |
| 39 | # 说明:进入项目根目录,执行如下编译命令,命令仅供参考,详细可以查看算子调用的说明。 | 39 | # 说明:进入项目根目录,执行如下编译命令,命令仅供参考,详细可以查看算子调用的说明。 |
| 40 | bash build.sh --pkg --soc=Ascend950 --vendor_name=custom --ops=add_example | 40 | bash build.sh --pkg --soc=Ascend950 --vendor_name=custom --ops=add_example |
| 41 | # 安装自定义算子包 | 41 | # 安装自定义算子包 |
| @@ -46,19 +46,19 @@ bash build.sh --pkg --soc=Ascend950 --vendor_name=custom --ops=add_example | |||
| 46 | 46 | ||
| 47 | ## 执行仿真命令 | 47 | ## 执行仿真命令 |
| 48 | 48 | ||
| 49 | -``` | 49 | +```bash |
| 50 | cannsim record ./test_aclnn_add_example -s Ascend950 --gen-report | 50 | cannsim record ./test_aclnn_add_example -s Ascend950 --gen-report |
| 51 | ``` | 51 | ``` |
| 52 | 52 | ||
| 53 | 仿真工具执行日志文件在examples/add_example/examples/build/bin/cannsim_*目录,执行日志文件为 | 53 | 仿真工具执行日志文件在examples/add_example/examples/build/bin/cannsim_*目录,执行日志文件为 |
| 54 | 54 | ||
| 55 | -``` | 55 | +```bash |
| 56 | cannsim.log | 56 | cannsim.log |
| 57 | ``` | 57 | ``` |
| 58 | 58 | ||
| 59 | 从仿真工具日志文件可以看到示例中的打印信息: | 59 | 从仿真工具日志文件可以看到示例中的打印信息: |
| 60 | 60 | ||
| 61 | -``` | 61 | +```bash |
| 62 | add_example result[2011] is: 2.000000 | 62 | add_example result[2011] is: 2.000000 |
| 63 | add_example result[2012] is: 2.000000 | 63 | add_example result[2012] is: 2.000000 |
| 64 | add_example result[2013] is: 2.000000 | 64 | add_example result[2013] is: 2.000000 |
| @@ -76,7 +76,7 @@ add_example result[2021] is: 2.000000 | |||
| 76 | 76 | ||
| 77 | 仿真性能流水文件在本项目`examples/add_example/examples/build/bin/cannsim_*/report目录,流水相关文件为: | 77 | 仿真性能流水文件在本项目`examples/add_example/examples/build/bin/cannsim_*/report目录,流水相关文件为: |
| 78 | 78 | ||
| 79 | -``` | 79 | +```bash |
| 80 | trace_core0.json | 80 | trace_core0.json |
| 81 | ``` | 81 | ``` |
| 82 | 82 | ||
| @@ -84,19 +84,19 @@ trace_core0.json | |||
| 84 | 84 | ||
| 85 | ## 执行仿真命令 | 85 | ## 执行仿真命令 |
| 86 | 86 | ||
| 87 | -``` | 87 | +```bash |
| 88 | cannsim record ./ascendc_kernels_bbit -s Ascend950 --gen-report | 88 | cannsim record ./ascendc_kernels_bbit -s Ascend950 --gen-report |
| 89 | ``` | 89 | ``` |
| 90 | 90 | ||
| 91 | 仿真工具执行日志文件在add_example/build/cannsim_*目录,执行日志文件为 | 91 | 仿真工具执行日志文件在add_example/build/cannsim_*目录,执行日志文件为 |
| 92 | 92 | ||
| 93 | -``` | 93 | +```bash |
| 94 | cannsim.log | 94 | cannsim.log |
| 95 | ``` | 95 | ``` |
| 96 | 96 | ||
| 97 | 从仿真工具日志文件可以看到示例中的前10结果打印信息: | 97 | 从仿真工具日志文件可以看到示例中的前10结果打印信息: |
| 98 | 98 | ||
| 99 | -``` | 99 | +```bash |
| 100 | First 10 output values: | 100 | First 10 output values: |
| 101 | z[0] = 0.000000 | 101 | z[0] = 0.000000 |
| 102 | z[1] = 3.000000 | 102 | z[1] = 3.000000 |
| @@ -114,7 +114,7 @@ z[9] = 27.000000 | |||
| 114 | 114 | ||
| 115 | 仿真性能流水文件在本项目`examples/add_example/build/cannsim_*/report目录,流水相关文件为: | 115 | 仿真性能流水文件在本项目`examples/add_example/build/cannsim_*/report目录,流水相关文件为: |
| 116 | 116 | ||
| 117 | -``` | 117 | +```bash |
| 118 | trace_core0.json | 118 | trace_core0.json |
| 119 | ``` | 119 | ``` |
| 120 | 120 | ||
| @@ -147,7 +147,7 @@ cannsim record [options] user_app --user_options | |||
| 147 | 1. 完成算子开发和编译。 | 147 | 1. 完成算子开发和编译。 |
| 148 | 2. 执行仿真命令,可参考以下使用示例 | 148 | 2. 执行仿真命令,可参考以下使用示例 |
| 149 | 149 | ||
| 150 | - ``` | 150 | + ```text |
| 151 | 方式一: 启用仿真,并将输出保存至 ./output 目录,/path/to/app 为算子程序 | 151 | 方式一: 启用仿真,并将输出保存至 ./output 目录,/path/to/app 为算子程序 |
| 152 | $ cannsim record /path/to/app -o ./output -s Ascend950 | 152 | $ cannsim record /path/to/app -o ./output -s Ascend950 |
| 153 | 153 | ||
| @@ -157,7 +157,7 @@ cannsim record [options] user_app --user_options | |||
| 157 | 157 | ||
| 158 | 3. 命令完成后,会在默认路径或指定的“output”目录下生成以“cannsim_{timestamp}_${user_app}”命名的文件夹,结构示例如下: | 158 | 3. 命令完成后,会在默认路径或指定的“output”目录下生成以“cannsim_{timestamp}_${user_app}”命名的文件夹,结构示例如下: |
| 159 | 159 | ||
| 160 | - ``` | 160 | + ```text |
| 161 | ├─cannsim_{timestamp}_${user_app} | 161 | ├─cannsim_{timestamp}_${user_app} |
| 162 | ├── cannsim.log | 162 | ├── cannsim.log |
| 163 | ├── log | 163 | ├── log |
| @@ -188,7 +188,7 @@ cannsim record [options] user_app --user_options | |||
| 188 | 188 | ||
| 189 | 以下输出仅为AscendC单算子直调精度比较结果举例,因版本不同略有差异,请以实际输出为准。 | 189 | 以下输出仅为AscendC单算子直调精度比较结果举例,因版本不同略有差异,请以实际输出为准。 |
| 190 | 190 | ||
| 191 | - ``` | 191 | + ```bash |
| 192 | INFO:root:[INFO] compare data case[ case001] | 192 | INFO:root:[INFO] compare data case[ case001] |
| 193 | INFO:root:---------------RESULT--------------- | 193 | INFO:root:---------------RESULT--------------- |
| 194 | INFO:root:['case_name', 'wrong_num', 'total_num', 'result', 'task_duration'] | 194 | INFO:root:['case_name', 'wrong_num', 'total_num', 'result', 'task_duration'] |
| @@ -222,7 +222,7 @@ cannsim report [options] | |||
| 222 | 1. 参考仿真执行执行算子仿真,对比输出示例,确保对应的结果执行正确。 | 222 | 1. 参考仿真执行执行算子仿真,对比输出示例,确保对应的结果执行正确。 |
| 223 | 2. 执行仿真结果解析命令,可参考以下执行用例。 | 223 | 2. 执行仿真结果解析命令,可参考以下执行用例。 |
| 224 | 224 | ||
| 225 | - ``` | 225 | + ```bash |
| 226 | 在当前目录下生成性能分析报告(默认仅分析核0) | 226 | 在当前目录下生成性能分析报告(默认仅分析核0) |
| 227 | cannsim report -e /path/to/cannsim_{timestamp}_${user_app} | 227 | cannsim report -e /path/to/cannsim_{timestamp}_${user_app} |
| 228 | 228 | ||
| @@ -232,7 +232,7 @@ cannsim report [options] | |||
| 232 | 232 | ||
| 233 | 3. 命令执行完后,会在output配置的目录下生成对应的流水文件,文件格式为json格式,输出结果示例如下: | 233 | 3. 命令执行完后,会在output配置的目录下生成对应的流水文件,文件格式为json格式,输出结果示例如下: |
| 234 | 234 | ||
| 235 | - ``` | 235 | + ```bash |
| 236 | trace_core0.json | 236 | trace_core0.json |
| 237 | trace_core1.json | 237 | trace_core1.json |
| 238 | ... | 238 | ... |
| @@ -266,19 +266,19 @@ cannsim report [options] | |||
| 266 | 266 | ||
| 267 | 查询工具帮助信息: | 267 | 查询工具帮助信息: |
| 268 | 268 | ||
| 269 | -``` | 269 | +```bash |
| 270 | cannsim --help | 270 | cannsim --help |
| 271 | ``` | 271 | ``` |
| 272 | 272 | ||
| 273 | 查询工具record 子命令的帮助信息: | 273 | 查询工具record 子命令的帮助信息: |
| 274 | 274 | ||
| 275 | -``` | 275 | +```bash |
| 276 | cannsim record --help | 276 | cannsim record --help |
| 277 | ``` | 277 | ``` |
| 278 | 278 | ||
| 279 | 查询工具report子命令的帮助信息: | 279 | 查询工具report子命令的帮助信息: |
| 280 | 280 | ||
| 281 | -``` | 281 | +```bash |
| 282 | cannsim report --help | 282 | cannsim report --help |
| 283 | ``` | 283 | ``` |
| 284 | 284 | ||
| @@ -291,13 +291,13 @@ cannsim report --help | |||
| 291 | 1. 登录Host侧服务器。 | 291 | 1. 登录Host侧服务器。 |
| 292 | 2. 执行以下命令。 | 292 | 2. 执行以下命令。 |
| 293 | 293 | ||
| 294 | - ``` | 294 | + ```bash |
| 295 | cannsim --help | 295 | cannsim --help |
| 296 | ``` | 296 | ``` |
| 297 | 297 | ||
| 298 | ## 输出说明 | 298 | ## 输出说明 |
| 299 | 299 | ||
| 300 | -``` | 300 | +```bash |
| 301 | Usage: cannsim [OPTIONS] COMMAND [ARGS]... | 301 | Usage: cannsim [OPTIONS] COMMAND [ARGS]... |
| 302 | 302 | ||
| 303 | Command-line tool for performance simulation analysis on Ascend hardware. | 303 | Command-line tool for performance simulation analysis on Ascend hardware. |
| @@ -10,13 +10,13 @@ | |||
| 10 | 10 | ||
| 11 | 程序执行结束后,默认可在"$HOME/ascendc/log"下查看,host日志文件存储路径如下: | 11 | 程序执行结束后,默认可在"$HOME/ascendc/log"下查看,host日志文件存储路径如下: |
| 12 | 12 | ||
| 13 | - ``` | 13 | + ```bash |
| 14 | $HOME/ascend/log/debug/plog/plog-pid_*.log | 14 | $HOME/ascend/log/debug/plog/plog-pid_*.log |
| 15 | ``` | 15 | ``` |
| 16 | 16 | ||
| 17 | 开启环境变量ASCEND_SLOG_PRINT_TO_STDOUT可以将log日志直接打屏显示(1:开启打屏,0:关闭打屏),配置示例如下: | 17 | 开启环境变量ASCEND_SLOG_PRINT_TO_STDOUT可以将log日志直接打屏显示(1:开启打屏,0:关闭打屏),配置示例如下: |
| 18 | 18 | ||
| 19 | - ``` | 19 | + ```bash |
| 20 | export ASCEND_SLOG_PRINT_TO_STDOUT=1 | 20 | export ASCEND_SLOG_PRINT_TO_STDOUT=1 |
| 21 | ``` | 21 | ``` |
| 22 | 22 | ||
| @@ -26,13 +26,13 @@ | |||
| 26 | 26 | ||
| 27 | 通过aclGetRecentErrMsg接口(参见[《acl API(C)》](https://hiascend.com/document/redirect/CannCommunityCppApi))获取aclnn接口调用过程中的异常信息,使用方法如下: | 27 | 通过aclGetRecentErrMsg接口(参见[《acl API(C)》](https://hiascend.com/document/redirect/CannCommunityCppApi))获取aclnn接口调用过程中的异常信息,使用方法如下: |
| 28 | 28 | ||
| 29 | - ``` | 29 | + ```bash |
| 30 | printf(aclGetRecentErrMsg()); | 30 | printf(aclGetRecentErrMsg()); |
| 31 | ``` | 31 | ``` |
| 32 | 32 | ||
| 33 | 打印错误信息样例如下: | 33 | 打印错误信息样例如下: |
| 34 | 34 | ||
| 35 | - ``` | 35 | + ```bash |
| 36 | [PID:646612] 2026-01-24-11:53:44.671.727 AclNN_Parameter_Error(EZ1001): Expected a proper Tensor but got null for argument addmmTennsor.self. | 36 | [PID:646612] 2026-01-24-11:53:44.671.727 AclNN_Parameter_Error(EZ1001): Expected a proper Tensor but got null for argument addmmTennsor.self. |
| 37 | ``` | 37 | ``` |
| 38 | 38 | ||
| @@ -177,13 +177,13 @@ | |||
| 177 | 177 | ||
| 178 | 2. 执行仿真命令,生成仿真数据 | 178 | 2. 执行仿真命令,生成仿真数据 |
| 179 | 179 | ||
| 180 | - ``` | 180 | + ```text |
| 181 | cannsim record ./test_aclnn_add_example -s Ascend950 --gen-report | 181 | cannsim record ./test_aclnn_add_example -s Ascend950 --gen-report |
| 182 | ``` | 182 | ``` |
| 183 | 183 | ||
| 184 | 仿真结果在本项目`examples/add_example/examples/build/bin/cannsim_*`目录,流水相关文件为: | 184 | 仿真结果在本项目`examples/add_example/examples/build/bin/cannsim_*`目录,流水相关文件为: |
| 185 | 185 | ||
| 186 | - ``` | 186 | + ```text |
| 187 | trace_core0.json | 187 | trace_core0.json |
| 188 | ``` | 188 | ``` |
| 189 | 189 | ||
| @@ -15,9 +15,9 @@ | |||
| 15 | 15 | ||
| 16 | 2. [算子定义](#算子定义):确定算子功能与原型定义。 | 16 | 2. [算子定义](#算子定义):确定算子功能与原型定义。 |
| 17 | 17 | ||
| 18 | -3. [Tiling实现](#Tiling实现):实现Host侧算子Tiling函数。 | 18 | +3. [Tiling实现](#tiling实现):实现Host侧算子Tiling函数。 |
| 19 | 19 | ||
| 20 | -4. [Kernel实现](#Kernel实现):实现Device侧算子核函数。 | 20 | +4. [Kernel实现](#kernel实现):实现Device侧算子核函数。 |
| 21 | 21 | ||
| 22 | 5. [aclnn适配](#aclnn适配):自定义算子推荐aclnn接口调用,需提前完成二进制发布。**如采用图模式调用算子**,请参考[图模式适配指南](./graph_develop_guide.md)。 | 22 | 5. [aclnn适配](#aclnn适配):自定义算子推荐aclnn接口调用,需提前完成二进制发布。**如采用图模式调用算子**,请参考[图模式适配指南](./graph_develop_guide.md)。 |
| 23 | 23 | ||
| @@ -52,7 +52,7 @@ Create the initial directory for ${op_name} under ${op_class} success | |||
| 52 | 52 | ||
| 53 | 创建完成后,目录结构如下所示: | 53 | 创建完成后,目录结构如下所示: |
| 54 | 54 | ||
| 55 | -``` | 55 | +```text |
| 56 | ${op_name} # 替换为实际算子名的小写下划线形式 | 56 | ${op_name} # 替换为实际算子名的小写下划线形式 |
| 57 | ├── examples # 算子调用示例 | 57 | ├── examples # 算子调用示例 |
| 58 | │ └── test_aclnn_${op_name}.cpp # 算子aclnn调用示例 | 58 | │ └── test_aclnn_${op_name}.cpp # 算子aclnn调用示例 |
| @@ -49,7 +49,7 @@ Create the AI CPU initial directory for ${op_name} under ${op_class} success | |||
| 49 | 49 | ||
| 50 | 创建完成后,目录结构如下所示: | 50 | 创建完成后,目录结构如下所示: |
| 51 | 51 | ||
| 52 | -``` | 52 | +```text |
| 53 | ${op_name} # 替换为实际算子名的小写下划线形式 | 53 | ${op_name} # 替换为实际算子名的小写下划线形式 |
| 54 | ├── examples # 算子调用示例 | 54 | ├── examples # 算子调用示例 |
| 55 | │ └── test_aclnn_${op_name}.cpp # 算子aclnn调用示例 | 55 | │ └── test_aclnn_${op_name}.cpp # 算子aclnn调用示例 |
| @@ -4,7 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | 自定义算子如需运行图模式,整体流程与算子开发指南([AI Core算子开发指南](aicore_develop_guide.md)/[AI CPU算子开发指南](aicpu_develop_guide.md))一致。值得注意的是,**不需要aclnn适配**,只需做如下交付件适配。 | 5 | 自定义算子如需运行图模式,整体流程与算子开发指南([AI Core算子开发指南](aicore_develop_guide.md)/[AI CPU算子开发指南](aicpu_develop_guide.md))一致。值得注意的是,**不需要aclnn适配**,只需做如下交付件适配。 |
| 6 | 6 | ||
| 7 | -``` | 7 | +```text |
| 8 | ${op_name} # 替换为实际算子名的小写下划线形式 | 8 | ${op_name} # 替换为实际算子名的小写下划线形式 |
| 9 | ├── op_host # Host侧实现 | 9 | ├── op_host # Host侧实现 |
| 10 | │ └── ${op_name}_infershape.cpp # InferShape实现,实现算子形状推导,在运行时推导输出shape | 10 | │ └── ${op_name}_infershape.cpp # InferShape实现,实现算子形状推导,在运行时推导输出shape |
| @@ -217,7 +217,7 @@ int main() | |||
| 217 | 217 | ||
| 218 | 默认在当前执行路径 `/build/bin`下生成可执行文件test\_aclnn\_add\_example,运行结果如下: | 218 | 默认在当前执行路径 `/build/bin`下生成可执行文件test\_aclnn\_add\_example,运行结果如下: |
| 219 | 219 | ||
| 220 | - ``` | 220 | + ```text |
| 221 | mean result[2046] is 2.000000 | 221 | mean result[2046] is 2.000000 |
| 222 | mean result[2047] is 2.000000 | 222 | mean result[2047] is 2.000000 |
| 223 | ``` | 223 | ``` |
| @@ -378,6 +378,6 @@ int main() { | |||
| 378 | 378 | ||
| 379 | 默认在当前执行路径 `/build/bin`下生成可执行文件test\_geir\_add\_example,运行结果如下: | 379 | 默认在当前执行路径 `/build/bin`下生成可执行文件test\_geir\_add\_example,运行结果如下: |
| 380 | 380 | ||
| 381 | - ``` | 381 | + ```text |
| 382 | INFO - [XIR]: Finalize ir graph session success | 382 | INFO - [XIR]: Finalize ir graph session success |
| 383 | ``` | 383 | ``` |
| @@ -158,7 +158,7 @@ | |||
| 158 | 158 | ||
| 159 | \$\{static\_lib\_path\}表示静态库解压路径。解压后目录结构如下: | 159 | \$\{static\_lib\_path\}表示静态库解压路径。解压后目录结构如下: |
| 160 | 160 | ||
| 161 | - ``` | 161 | + ```text |
| 162 | ├── cann-${soc_name}-ops-nn-static_${cann_version}_linux-${arch} | 162 | ├── cann-${soc_name}-ops-nn-static_${cann_version}_linux-${arch} |
| 163 | │ ├── lib64 | 163 | │ ├── lib64 |
| 164 | │ │ ├── libcann_nn_static.a # 静态库文件 | 164 | │ │ ├── libcann_nn_static.a # 静态库文件 |
| @@ -321,7 +321,7 @@ | |||
| 321 | 321 | ||
| 322 | 无论上述哪种方式,算子样例执行后会打印结果,以TransposeBatchMatMul算子执行为例: | 322 | 无论上述哪种方式,算子样例执行后会打印结果,以TransposeBatchMatMul算子执行为例: |
| 323 | 323 | ||
| 324 | -``` | 324 | +```text |
| 325 | result[0] is: 0.000000 | 325 | result[0] is: 0.000000 |
| 326 | result[1] is: 0.000000 | 326 | result[1] is: 0.000000 |
| 327 | result[2] is: 0.000000 | 327 | result[2] is: 0.000000 |
| @@ -2817,7 +2817,7 @@ | |||
| 2817 | </tr> | 2817 | </tr> |
| 2818 | <tr> | 2818 | <tr> |
| 2819 | <td>pooling</td> | 2819 | <td>pooling</td> |
| 2820 | - <td><a href="../../pooling/max_pool3d/README.md">max_pool3d</a></td> | 2820 | + <td><a href="../../pooling/max_pool3_d/README.md">max_pool3d</a></td> |
| 2821 | <td>✓</td> | 2821 | <td>✓</td> |
| 2822 | <td>✓</td> | 2822 | <td>✓</td> |
| 2823 | <td>✗</td> | 2823 | <td>✗</td> |
| @@ -3107,7 +3107,7 @@ | |||
| 3107 | </tr> | 3107 | </tr> |
| 3108 | <tr> | 3108 | <tr> |
| 3109 | <td>rnn</td> | 3109 | <td>rnn</td> |
| 3110 | - <td><a href="../../../../rnn/bidirection_lstm_v2/README.md">bidirection_lstm_v2</a></td> | 3110 | + <td><a href="../../rnn/bidirection_lstmv2/README.md">bidirection_lstm_v2</a></td> |
| 3111 | <td>✓</td> | 3111 | <td>✓</td> |
| 3112 | <td>✓</td> | 3112 | <td>✓</td> |
| 3113 | <td>✓</td> | 3113 | <td>✓</td> |
| @@ -9,7 +9,7 @@ | |||
| 9 | 9 | ||
| 10 | ## 目录说明 | 10 | ## 目录说明 |
| 11 | 11 | ||
| 12 | -``` | 12 | +```text |
| 13 | ├── examples | 13 | ├── examples |
| 14 | │ ├── add_example # AI Core算子名 | 14 | │ ├── add_example # AI Core算子名 |
| 15 | │ │ ├── CMakeLists.txt # 算子编译配置文件,保留原文件即可 | 15 | │ │ ├── CMakeLists.txt # 算子编译配置文件,保留原文件即可 |
| @@ -82,7 +82,7 @@ print("Verification successful!") | |||
| 82 | 82 | ||
| 83 | 2. 在soc目录下新建一个`CMakeLists.txt` | 83 | 2. 在soc目录下新建一个`CMakeLists.txt` |
| 84 | 84 | ||
| 85 | - ``` | 85 | + ```text |
| 86 | add_sources("--npu-arch=dav-2201") | 86 | add_sources("--npu-arch=dav-2201") |
| 87 | ``` | 87 | ``` |
| 88 | 88 | ||
| @@ -12,7 +12,7 @@ | |||
| 12 | 12 | ||
| 13 | ## 目录结构介绍 | 13 | ## 目录结构介绍 |
| 14 | 14 | ||
| 15 | -``` | 15 | +```text |
| 16 | ├── CMakeLists.txt // 编译工程文件 | 16 | ├── CMakeLists.txt // 编译工程文件 |
| 17 | ├── README.md // 算子样例工程介绍文件 | 17 | ├── README.md // 算子样例工程介绍文件 |
| 18 | ├── examples // 样例算子的aclnn接口样例目录 | 18 | ├── examples // 样例算子的aclnn接口样例目录 |
| @@ -1,6 +1,6 @@ | |||
| 1 | # 目录结构介绍 | 1 | # 目录结构介绍 |
| 2 | 2 | ||
| 3 | -``` | 3 | +```text |
| 4 | ├── examples // 通过aclnn调用的方式调用MatmulFp32算子 | 4 | ├── examples // 通过aclnn调用的方式调用MatmulFp32算子 |
| 5 | │ ├── inc // 头文件目录 | 5 | │ ├── inc // 头文件目录 |
| 6 | │ │ ├── common.h // 声明公共方法类,用于读取二进制文件 | 6 | │ │ ├── common.h // 声明公共方法类,用于读取二进制文件 |
| @@ -13,7 +13,7 @@ | |||
| 13 | 13 | ||
| 14 | ## 目录结构介绍 | 14 | ## 目录结构介绍 |
| 15 | 15 | ||
| 16 | -``` | 16 | +```text |
| 17 | ├── weight_quant_batch_matmul_experiment | 17 | ├── weight_quant_batch_matmul_experiment |
| 18 | │ ├── examples // 样例工程 | 18 | │ ├── examples // 样例工程 |
| 19 | │ ├── op_host // tiling && 算子定义 | 19 | │ ├── op_host // tiling && 算子定义 |
| @@ -68,7 +68,6 @@ | |||
| 68 | A_{3} \\ | 68 | A_{3} \\ |
| 69 | \end{bmatrix} | 69 | \end{bmatrix} |
| 70 | $$ | 70 | $$ |
| 71 | - | ||
| 72 | 10. 计算$C_{int}$: | 71 | 10. 计算$C_{int}$: |
| 73 | 72 | ||
| 74 | $$Y_{int} = \begin{bmatrix} | 73 | $$Y_{int} = \begin{bmatrix} |
| @@ -1,6 +1,6 @@ | |||
| 1 | # 目录结构介绍 | 1 | # 目录结构介绍 |
| 2 | 2 | ||
| 3 | -``` | 3 | +```text |
| 4 | ├── examples // 通过aclnn调用的方式调用WeightQuantBatchMatmulExperiment算子 | 4 | ├── examples // 通过aclnn调用的方式调用WeightQuantBatchMatmulExperiment算子 |
| 5 | │ ├── inc // 头文件目录 | 5 | │ ├── inc // 头文件目录 |
| 6 | │ ├── input // 存放脚本生成的输入数据目录 | 6 | │ ├── input // 存放脚本生成的输入数据目录 |
| @@ -20,7 +20,7 @@ | |||
| 20 | 20 | ||
| 21 | - 当mode为sum模式: | 21 | - 当mode为sum模式: |
| 22 | 22 | ||
| 23 | - ``` | 23 | + ```text |
| 24 | output的shape为includeLastOffset ? (bagOffsets - 1, embeddingDim) : (bagOffsets, embeddingDim) | 24 | output的shape为includeLastOffset ? (bagOffsets - 1, embeddingDim) : (bagOffsets, embeddingDim) |
| 25 | offset2bag的shape 为 (bagIndices,) | 25 | offset2bag的shape 为 (bagIndices,) |
| 26 | bagSize的shape为includeLastOffset ? (bagOffsets - 1) : (bagOffsets,) | 26 | bagSize的shape为includeLastOffset ? (bagOffsets - 1) : (bagOffsets,) |
| @@ -29,7 +29,7 @@ | |||
| 29 | 29 | ||
| 30 | - 当mode为mean模式: | 30 | - 当mode为mean模式: |
| 31 | 31 | ||
| 32 | - ``` | 32 | + ```text |
| 33 | output的shape为includeLastOffset? (bagOffsets - 1, embeddingDim) : (bagOffsets, embeddingDim) | 33 | output的shape为includeLastOffset? (bagOffsets - 1, embeddingDim) : (bagOffsets, embeddingDim) |
| 34 | offset2bag的shape为(bagIndices,) | 34 | offset2bag的shape为(bagIndices,) |
| 35 | bagSize的shape为includeLastOffset ? (bagOffsets - 1) : (bagOffsets,) | 35 | bagSize的shape为includeLastOffset ? (bagOffsets - 1) : (bagOffsets,) |
| @@ -38,7 +38,7 @@ | |||
| 38 | 38 | ||
| 39 | - 当mode为max模式: | 39 | - 当mode为max模式: |
| 40 | 40 | ||
| 41 | - ``` | 41 | + ```text |
| 42 | output的shape为includeLastOffset ? (bagOffsets - 1, embeddingDim) : (bagOffsets, embeddingDim) | 42 | output的shape为includeLastOffset ? (bagOffsets - 1, embeddingDim) : (bagOffsets, embeddingDim) |
| 43 | offset2bag的shape为(bagIndices,) | 43 | offset2bag的shape为(bagIndices,) |
| 44 | bagSize的shape为includeLastOffset ? (bagOffsets - 1) : (bagOffsets,) | 44 | bagSize的shape为includeLastOffset ? (bagOffsets - 1) : (bagOffsets,) |
| @@ -48,7 +48,7 @@ | |||
| 48 | - <term>Ascend 950PR/Ascend 950DT</term>: | 48 | - <term>Ascend 950PR/Ascend 950DT</term>: |
| 49 | - 当mode为sum模式: | 49 | - 当mode为sum模式: |
| 50 | 50 | ||
| 51 | - ``` | 51 | + ```text |
| 52 | output的shape为includeLastOffset ? (bagOffsets - 1, embeddingDim) : (bagOffsets, embeddingDim) | 52 | output的shape为includeLastOffset ? (bagOffsets - 1, embeddingDim) : (bagOffsets, embeddingDim) |
| 53 | offset2bag的shape为(bagIndices,) | 53 | offset2bag的shape为(bagIndices,) |
| 54 | bagSize的shape为(bagOffsets,) | 54 | bagSize的shape为(bagOffsets,) |
| @@ -57,7 +57,7 @@ | |||
| 57 | 57 | ||
| 58 | - 当mode为mean模式: | 58 | - 当mode为mean模式: |
| 59 | 59 | ||
| 60 | - ``` | 60 | + ```text |
| 61 | output的shape为includeLastOffset? (bagOffsets - 1, embeddingDim) : (bagOffsets, embeddingDim) | 61 | output的shape为includeLastOffset? (bagOffsets - 1, embeddingDim) : (bagOffsets, embeddingDim) |
| 62 | offset2bag的shape为(bagIndices,) | 62 | offset2bag的shape为(bagIndices,) |
| 63 | bagSize的shape为bagOffsets | 63 | bagSize的shape为bagOffsets |
| @@ -66,7 +66,7 @@ | |||
| 66 | 66 | ||
| 67 | - 当mode为max模式: | 67 | - 当mode为max模式: |
| 68 | 68 | ||
| 69 | - ``` | 69 | + ```text |
| 70 | output的shape为includeLastOffset ? (bagOffsets - 1, embeddingDim) : (bagOffsets, embeddingDim) | 70 | output的shape为includeLastOffset ? (bagOffsets - 1, embeddingDim) : (bagOffsets, embeddingDim) |
| 71 | offset2bag的shape为(bagIndices,) | 71 | offset2bag的shape为(bagIndices,) |
| 72 | bagSize的shape为(bagOffsets,) | 72 | bagSize的shape为(bagOffsets,) |
| @@ -43,7 +43,7 @@ | |||
| 43 | 43 | ||
| 44 | aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 | 44 | aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 |
| 45 | 45 | ||
| 46 | - ``` | 46 | + ```text |
| 47 | 第一段接口完成入参校验,出现如下场景时报错: | 47 | 第一段接口完成入参校验,出现如下场景时报错: |
| 48 | 返回161001(ACLNN_ERR_PARAM_NULLPTR):1. 传入的grad、indices、out是空指针。 | 48 | 返回161001(ACLNN_ERR_PARAM_NULLPTR):1. 传入的grad、indices、out是空指针。 |
| 49 | 返回161002(ACLNN_ERR_PARAM_INVALID):1. grad、indices、out的数据类型和数据格式不在支持的范围之内。 | 49 | 返回161002(ACLNN_ERR_PARAM_INVALID):1. grad、indices、out的数据类型和数据格式不在支持的范围之内。 |
| @@ -26,7 +26,7 @@ | |||
| 26 | $$ | 26 | $$ |
| 27 | out[N][C][i] = gradOutput[N][C][indices[N][C][i]] | 27 | out[N][C][i] = gradOutput[N][C][indices[N][C][i]] |
| 28 | $$ | 28 | $$ |
| 29 | - 其中out、gradOutput、indices是最后两轴合为一轴,经过reshape得到的,i ∈ [0, D * H * W)。 | 29 | + 其中out、gradOutput、indices是最后两轴合为一轴,经过reshape得到的,i ∈ [0, D*H* W)。 |
| 30 | 30 | ||
| 31 | ## 函数原型 | 31 | ## 函数原型 |
| 32 | 32 | ||
| @@ -26,7 +26,7 @@ | |||
| 26 | 26 | ||
| 27 | - 示例: | 27 | - 示例: |
| 28 | 28 | ||
| 29 | - ``` | 29 | + ```text |
| 30 | 例1: | 30 | 例1: |
| 31 | self: [[0, 1],[2, 3]] # self_shape=[2, 2], r=2 | 31 | self: [[0, 1],[2, 3]] # self_shape=[2, 2], r=2 |
| 32 | indices: [[0, 0], [1, 1]] # indices_shape=[2, 2], q=2, indices_shape[-1]=2 | 32 | indices: [[0, 0], [1, 1]] # indices_shape=[2, 2], q=2, indices_shape[-1]=2 |
| @@ -26,7 +26,7 @@ | |||
| 26 | 26 | ||
| 27 | - 示例: | 27 | - 示例: |
| 28 | 28 | ||
| 29 | - ``` | 29 | + ```text |
| 30 | 例1: | 30 | 例1: |
| 31 | self: [[0, 1],[2, 3]] # self_shape=[2, 2], r=2 | 31 | self: [[0, 1],[2, 3]] # self_shape=[2, 2], r=2 |
| 32 | indices: [[0, 0], [1, 1]] # indices_shape=[2, 2], q=2, indices_shape[-1]=2 | 32 | indices: [[0, 0], [1, 1]] # indices_shape=[2, 2], q=2, indices_shape[-1]=2 |
| @@ -20,14 +20,15 @@ | |||
| 20 | - 示例: | 20 | - 示例: |
| 21 | - 示例1: | 21 | - 示例1: |
| 22 | 22 | ||
| 23 | - ``` | 23 | + ```text |
| 24 | 当keepDim为True时,则将对应维度的size置为1,若为False,则删除对应维度。 | 24 | 当keepDim为True时,则将对应维度的size置为1,若为False,则删除对应维度。 |
| 25 | 假设self的shape为[2, 3, 4],dim = 1,keepDim为true,则输出shape为[2, 1, 4]。 | 25 | 假设self的shape为[2, 3, 4],dim = 1,keepDim为true,则输出shape为[2, 1, 4]。 |
| 26 | 假设self的shape为[2, 3, 4],dim = 1,keepDim为false,则输出shape为[2, 4]。 | 26 | 假设self的shape为[2, 3, 4],dim = 1,keepDim为false,则输出shape为[2, 4]。 |
| 27 | ``` | 27 | ``` |
| 28 | 28 | ||
| 29 | - 示例2: | 29 | - 示例2: |
| 30 | - ``` | 30 | + |
| 31 | + ```text | ||
| 31 | 关于输出shape的示例 | 32 | 关于输出shape的示例 |
| 32 | 若输入 | 33 | 若输入 |
| 33 | self = tensor([[1, float('nan'), 3, 2],[-1, float('nan'), 3, 2]]) shape为[2, 4] | 34 | self = tensor([[1, float('nan'), 3, 2],[-1, float('nan'), 3, 2]]) shape为[2, 4] |
| @@ -40,7 +41,7 @@ | |||
| 40 | 41 | ||
| 41 | - 示例3: | 42 | - 示例3: |
| 42 | 43 | ||
| 43 | - ``` | 44 | + ```text |
| 44 | 若输入 | 45 | 若输入 |
| 45 | self = tensor([[1, float('nan'), 3, 2],[-1, float('nan'), 3, 2]]) shape为[2, 4] | 46 | self = tensor([[1, float('nan'), 3, 2],[-1, float('nan'), 3, 2]]) shape为[2, 4] |
| 46 | dim = 0 | 47 | dim = 0 |
| @@ -52,7 +53,7 @@ | |||
| 52 | 53 | ||
| 53 | - 示例4: | 54 | - 示例4: |
| 54 | 55 | ||
| 55 | - ``` | 56 | + ```text |
| 56 | 若输入 | 57 | 若输入 |
| 57 | self = tensor([[1, float('nan'), 3, 2],[-1, float('nan'), 3, 2]]) shape为[2, 4] | 58 | self = tensor([[1, float('nan'), 3, 2],[-1, float('nan'), 3, 2]]) shape为[2, 4] |
| 58 | dim = 1 | 59 | dim = 1 |
| @@ -49,7 +49,7 @@ $$ | |||
| 49 | 49 | ||
| 50 | aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 | 50 | aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 |
| 51 | 51 | ||
| 52 | - ``` | 52 | + ```text |
| 53 | 第一段接口完成入参校验,出现以下场景时报错: | 53 | 第一段接口完成入参校验,出现以下场景时报错: |
| 54 | 161001 (ACLNN_ERR_PARAM_NULLPTR):1. 参数self、index、out是空指针。 | 54 | 161001 (ACLNN_ERR_PARAM_NULLPTR):1. 参数self、index、out是空指针。 |
| 55 | 161002 (ACLNN_ERR_PARAM_INVALID):1. 参数self、index、out的数据类型不在支持范围内。 | 55 | 161002 (ACLNN_ERR_PARAM_INVALID):1. 参数self、index、out的数据类型不在支持范围内。 |
| @@ -22,7 +22,7 @@ | |||
| 22 | 22 | ||
| 23 | **场景一:** indices为1维,axis指定更新的维度shape为1,indices指定的是每个batch维度(最高维)在axis维度的偏移。 | 23 | **场景一:** indices为1维,axis指定更新的维度shape为1,indices指定的是每个batch维度(最高维)在axis维度的偏移。 |
| 24 | 24 | ||
| 25 | - ``` | 25 | + ```text |
| 26 | 样例输入: | 26 | 样例输入: |
| 27 | data:(a, b, c, d) | 27 | data:(a, b, c, d) |
| 28 | updates:(a, b, 1, d) | 28 | updates:(a, b, 1, d) |
| @@ -35,7 +35,7 @@ | |||
| 35 | 35 | ||
| 36 | **场景二:** indices为1维,axis指定更新的维度shape大于1,indices指定的是每个batch维度(最高维)在axis维度的偏移。 | 36 | **场景二:** indices为1维,axis指定更新的维度shape大于1,indices指定的是每个batch维度(最高维)在axis维度的偏移。 |
| 37 | 37 | ||
| 38 | - ``` | 38 | + ```text |
| 39 | 样例输入: | 39 | 样例输入: |
| 40 | data:(a, b, c, d) | 40 | data:(a, b, c, d) |
| 41 | updates:(a, b, e, d), indices[i] + e <= c | 41 | updates:(a, b, e, d), indices[i] + e <= c |
| @@ -22,7 +22,7 @@ | |||
| 22 | 22 | ||
| 23 | **场景一:** indices为1维,axis指定更新的维度shape为1,indices指定的是每个batch维度(最高维)在axis维度的偏移。 | 23 | **场景一:** indices为1维,axis指定更新的维度shape为1,indices指定的是每个batch维度(最高维)在axis维度的偏移。 |
| 24 | 24 | ||
| 25 | - ``` | 25 | + ```text |
| 26 | 样例输入: | 26 | 样例输入: |
| 27 | data:(a, b, c, d) | 27 | data:(a, b, c, d) |
| 28 | updates:(a, b, 1, d) | 28 | updates:(a, b, 1, d) |
| @@ -35,7 +35,7 @@ | |||
| 35 | 35 | ||
| 36 | **场景二:** indices为1维,axis指定更新的维度shape大于1,indices指定的是每个batch维度(最高维)在axis维度的偏移。 | 36 | **场景二:** indices为1维,axis指定更新的维度shape大于1,indices指定的是每个batch维度(最高维)在axis维度的偏移。 |
| 37 | 37 | ||
| 38 | - ``` | 38 | + ```text |
| 39 | 样例输入: | 39 | 样例输入: |
| 40 | data:(a, b, c, d) | 40 | data:(a, b, c, d) |
| 41 | updates:(a, b, e, d), indices[i] + e <= c | 41 | updates:(a, b, e, d), indices[i] + e <= c |
| @@ -16,7 +16,7 @@ | |||
| 16 | - 算子功能:将src tensor中的值按指定的轴方向和index tensor中的位置关系逐个填入self tensor中,若有多于一个src值被填入到self的同一位置,那么这些值将会在这一位置上进行累加。 | 16 | - 算子功能:将src tensor中的值按指定的轴方向和index tensor中的位置关系逐个填入self tensor中,若有多于一个src值被填入到self的同一位置,那么这些值将会在这一位置上进行累加。 |
| 17 | 对于一个3D tensor, self会按照如下的规则进行更新: | 17 | 对于一个3D tensor, self会按照如下的规则进行更新: |
| 18 | 18 | ||
| 19 | - ``` | 19 | + ```text |
| 20 | self[index[i][j][k]][j][k] += src[i][j][k] # 如果 dim == 0 | 20 | self[index[i][j][k]][j][k] += src[i][j][k] # 如果 dim == 0 |
| 21 | self[i][index[i][j][k]][k] += src[i][j][k] # 如果 dim == 1 | 21 | self[i][index[i][j][k]][k] += src[i][j][k] # 如果 dim == 1 |
| 22 | self[i][j][index[i][j][k]] += src[i][j][k] # 如果 dim == 2 | 22 | self[i][j][index[i][j][k]] += src[i][j][k] # 如果 dim == 2 |
| @@ -20,7 +20,7 @@ | |||
| 20 | 用例: | 20 | 用例: |
| 21 | 对于一个3D tensor,self会按照如下的规则进行更新: | 21 | 对于一个3D tensor,self会按照如下的规则进行更新: |
| 22 | 22 | ||
| 23 | - ``` | 23 | + ```text |
| 24 | self[index[i][j][k]][j][k] += src[i][j][k] # 如果 dim == 0 | 24 | self[index[i][j][k]][j][k] += src[i][j][k] # 如果 dim == 0 |
| 25 | self[i][index[i][j][k]][k] += src[i][j][k] # 如果 dim == 1 | 25 | self[i][index[i][j][k]][k] += src[i][j][k] # 如果 dim == 1 |
| 26 | self[i][j][index[i][j][k]] += src[i][j][k] # 如果 dim == 2 | 26 | self[i][j][index[i][j][k]] += src[i][j][k] # 如果 dim == 2 |
| @@ -186,6 +186,7 @@ aclnnStatus aclnnScatterAdd( | |||
| 186 | 186 | ||
| 187 | aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 | 187 | aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 |
| 188 | 188 | ||
| 189 | + ```text | ||
| 189 | 第一段接口完成入参校验,出现以下场景时报错: | 190 | 第一段接口完成入参校验,出现以下场景时报错: |
| 190 | 191 | ||
| 191 | <table style="undefined;table-layout: fixed; width: 1150px"><colgroup> | 192 | <table style="undefined;table-layout: fixed; width: 1150px"><colgroup> |
| @@ -18,9 +18,9 @@ | |||
| 18 | - 算子功能: 将tensor src中的值按指定的轴和方向和对应的位置关系逐个替换/累加/累乘至tensor self中。 | 18 | - 算子功能: 将tensor src中的值按指定的轴和方向和对应的位置关系逐个替换/累加/累乘至tensor self中。 |
| 19 | 19 | ||
| 20 | - 示例: | 20 | - 示例: |
| 21 | - 对于一个3D tensor, self会按照如下的规则进行更新: | 21 | + 对于一个3D tensor,self会按照如下的规则进行更新: |
| 22 | 22 | ||
| 23 | - ``` | 23 | + ```text |
| 24 | self[index[i][j][k]][j][k] += src[i][j][k] # 如果 dim == 0 && reduction == 1 | 24 | self[index[i][j][k]][j][k] += src[i][j][k] # 如果 dim == 0 && reduction == 1 |
| 25 | self[i][index[i][j][k]][k] *= src[i][j][k] # 如果 dim == 1 && reduction == 2 | 25 | self[i][index[i][j][k]][k] *= src[i][j][k] # 如果 dim == 1 && reduction == 2 |
| 26 | self[i][j][index[i][j][k]] = src[i][j][k] # 如果 dim == 2 && reduction == 0 | 26 | self[i][j][index[i][j][k]] = src[i][j][k] # 如果 dim == 2 && reduction == 0 |
| @@ -40,7 +40,7 @@ | |||
| 40 | 40 | ||
| 41 | aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 | 41 | aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 |
| 42 | 42 | ||
| 43 | - ``` | 43 | + ```text |
| 44 | 第一段接口完成入参校验,出现以下场景时报错: | 44 | 第一段接口完成入参校验,出现以下场景时报错: |
| 45 | 返回161001(ACLNN_ERR_PARAM_NULLPTR):1. 传入的 self或valueOut或inverseOut是空指针时。 | 45 | 返回161001(ACLNN_ERR_PARAM_NULLPTR):1. 传入的 self或valueOut或inverseOut是空指针时。 |
| 46 | 返回161002(ACLNN_ERR_PARAM_INVALID):1. self 或valueOut 的数据类型不在支持的范围之内。 | 46 | 返回161002(ACLNN_ERR_PARAM_INVALID):1. self 或valueOut 的数据类型不在支持的范围之内。 |
| @@ -51,7 +51,7 @@ | |||
| 51 | 51 | ||
| 52 | ## aclnnUnique | 52 | ## aclnnUnique |
| 53 | 53 | ||
| 54 | -* **参数说明**: | 54 | +* **参数说明** |
| 55 | * workspace(void\*, 入参):在Device侧申请的workspace内存地址。 | 55 | * workspace(void\*, 入参):在Device侧申请的workspace内存地址。 |
| 56 | * workspaceSize(uint64\_t, 入参):在Device侧申请的workspace大小,由第一段接口aclnnUniqueGetWorkspaceSize获取。 | 56 | * workspaceSize(uint64\_t, 入参):在Device侧申请的workspace大小,由第一段接口aclnnUniqueGetWorkspaceSize获取。 |
| 57 | * executor(aclOpExecutor\*, 入参):op执行器,包含了算子计算流程。 | 57 | * executor(aclOpExecutor\*, 入参):op执行器,包含了算子计算流程。 |
| @@ -41,7 +41,7 @@ | |||
| 41 | 41 | ||
| 42 | aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 | 42 | aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 |
| 43 | 43 | ||
| 44 | - ``` | 44 | + ```text |
| 45 | 第一段接口完成入参校验,出现以下场景时报错: | 45 | 第一段接口完成入参校验,出现以下场景时报错: |
| 46 | 返回161001(ACLNN_ERR_PARAM_NULLPTR):1. 传入的 self或valueOut或inverseOut或countsOut 是空指针时。 | 46 | 返回161001(ACLNN_ERR_PARAM_NULLPTR):1. 传入的 self或valueOut或inverseOut或countsOut 是空指针时。 |
| 47 | 返回161002(ACLNN_ERR_PARAM_INVALID):1. self 或valueOut 的数据类型不在支持的范围之内。 | 47 | 返回161002(ACLNN_ERR_PARAM_INVALID):1. self 或valueOut 的数据类型不在支持的范围之内。 |
| @@ -18,7 +18,7 @@ | |||
| 18 | - 示例: | 18 | - 示例: |
| 19 | 对于一个3D tensor, self会按照如下的规则进行更新: | 19 | 对于一个3D tensor, self会按照如下的规则进行更新: |
| 20 | 20 | ||
| 21 | - ``` | 21 | + ```text |
| 22 | self[index[i][j][k]][j][k] += src[i][j][k] # 如果 dim == 0 && reduction == 1 | 22 | self[index[i][j][k]][j][k] += src[i][j][k] # 如果 dim == 0 && reduction == 1 |
| 23 | self[i][index[i][j][k]][k] *= src[i][j][k] # 如果 dim == 1 && reduction == 2 | 23 | self[i][index[i][j][k]][k] *= src[i][j][k] # 如果 dim == 1 && reduction == 2 |
| 24 | self[i][j][index[i][j][k]] = src[i][j][k] # 如果 dim == 2 && reduction == 0 | 24 | self[i][j][index[i][j][k]] = src[i][j][k] # 如果 dim == 2 && reduction == 0 |
| @@ -20,7 +20,7 @@ | |||
| 20 | - 示例: | 20 | - 示例: |
| 21 | 对于一个3D tensor,self会按照如下的规则进行更新: | 21 | 对于一个3D tensor,self会按照如下的规则进行更新: |
| 22 | 22 | ||
| 23 | - ``` | 23 | + ```text |
| 24 | self[index[i][j][k]][j][k] += src[i][j][k] # 如果 dim == 0 && reduction == 1 | 24 | self[index[i][j][k]][j][k] += src[i][j][k] # 如果 dim == 0 && reduction == 1 |
| 25 | self[i][index[i][j][k]][k] *= src[i][j][k] # 如果 dim == 1 && reduction == 2 | 25 | self[i][index[i][j][k]][k] *= src[i][j][k] # 如果 dim == 1 && reduction == 2 |
| 26 | self[i][j][index[i][j][k]] = src[i][j][k] # 如果 dim == 2 && reduction == 0 | 26 | self[i][j][index[i][j][k]] = src[i][j][k] # 如果 dim == 2 && reduction == 0 |
| @@ -0,0 +1,419 @@ | |||
| 1 | +# aclnnScatterAdd | ||
| 2 | + | ||
| 3 | +📄 [查看源码](https://gitcode.com/cann/ops-nn/tree/master/index/scatter_elements_v2) | ||
| 4 | + | ||
| 5 | +## 产品支持情况 | ||
| 6 | + | ||
| 7 | +| 产品 | 是否支持 | | ||
| 8 | +| :--- | :---: | | ||
| 9 | +| <term>Ascend 950PR/Ascend 950DT</term> | √ | | ||
| 10 | +| <term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term> | √ | | ||
| 11 | +| <term>Atlas A2 训练系列产品/Atlas A2 推理系列产品</term> | √ | | ||
| 12 | +| <term>Atlas 200I/500 A2 推理产品</term> | × | | ||
| 13 | +| <term>Atlas 推理系列产品</term> | × | | ||
| 14 | +| <term>Atlas 训练系列产品</term> | × | | ||
| 15 | + | ||
| 16 | +## 功能说明 | ||
| 17 | + | ||
| 18 | +- 接口功能:将src tensor中的值按指定的轴方向和index tensor中的位置关系逐个填入self tensor中,若有多于一个src值被填入到self的同一位置,那么这些值将会在这一位置上进行累加。 | ||
| 19 | + | ||
| 20 | + 用例: | ||
| 21 | + 对于一个3D tensor,self会按照如下的规则进行更新: | ||
| 22 | + | ||
| 23 | + ```text | ||
| 24 | + self[index[i][j][k]][j][k] += src[i][j][k] # 如果 dim == 0 | ||
| 25 | + self[i][index[i][j][k]][k] += src[i][j][k] # 如果 dim == 1 | ||
| 26 | + self[i][j][index[i][j][k]] += src[i][j][k] # 如果 dim == 2 | ||
| 27 | + ``` | ||
| 28 | + | ||
| 29 | + 在计算时需要满足以下要求: | ||
| 30 | + - self、index和src的维度数量必须相同。 | ||
| 31 | + - 对于每一个维度d,有index.size(d) <= src.size(d)。 | ||
| 32 | + - 对于每一个维度d,如果有d != dim,有index.size(d) <= self.size(d)。 | ||
| 33 | + - dim取值范围为[-self.dim(), self.dim() - 1]。 | ||
| 34 | + | ||
| 35 | +- 示例: | ||
| 36 | + | ||
| 37 | + 输入tensor $self = \begin{bmatrix} [1&2&3] \\ [4&5&6] \\ [7&8&9] \end{bmatrix}$, | ||
| 38 | + 索引tensor $index = \begin{bmatrix} [0&2&1] \\ [0&0&1] \end{bmatrix}$, dim = 1, | ||
| 39 | + 源tensor $src = \begin{bmatrix} [10&11&12] \\ [13&14&15] \end{bmatrix}$, | ||
| 40 | + 输出tensor $output = \begin{bmatrix} [11&14&14] \\ [31&20&6] \\ [7&8&9] \end{bmatrix}$ | ||
| 41 | + | ||
| 42 | + dim = 1 表示scatter_add根据$index$在tensor的列上进行累加。 | ||
| 43 | + | ||
| 44 | + $output[0][0] = self[0][0] + src[0][0]$ = 1 + 10, | ||
| 45 | + | ||
| 46 | + $output[0][1] = self[0][1] + src[0][2]$ = 2 + 12, | ||
| 47 | + | ||
| 48 | + $output[0][2] = self[0][2] + src[0][1]$ = 3 + 11, | ||
| 49 | + | ||
| 50 | + $output[1][0] = self[1][0] + src[1][0] + src[1][1]$ = 4 + 13 + 14, | ||
| 51 | + | ||
| 52 | + $output[1][1] = self[1][1] + src[1][2]$ = 5 + 15, | ||
| 53 | + | ||
| 54 | + $output[1][2] = self[1][2]$ = 6, | ||
| 55 | + | ||
| 56 | + $output[2][0] = self[2][0]$ = 7, | ||
| 57 | + | ||
| 58 | + $output[2][1] = self[2][1]$ = 8, | ||
| 59 | + | ||
| 60 | + $output[2][2] = self[2][2]$ = 9。 | ||
| 61 | + | ||
| 62 | + 其中,$self$、$index$、$src$的维度数量均为2,$index$每个维度大小{2,3}都不大于$src$的对应维度大小{2,3},在dim != 1的维度上(dim = 0),$index$的维度大小{2}不大于$self$的对应维度大小{3},$index$中的最大值{2},小于$self$在dim = 1维度的大小{3}。 | ||
| 63 | + | ||
| 64 | +## 函数原型 | ||
| 65 | + | ||
| 66 | +每个算子分为[两段式接口](../../../docs/zh/context/两段式接口.md),必须先调用“aclnnScatterAddGetWorkspaceSize”接口获取计算所需workspace大小以及包含了算子计算流程的执行器,再调用“aclnnScatterAdd”接口执行计算。 | ||
| 67 | + | ||
| 68 | +```Cpp | ||
| 69 | +aclnnStatus aclnnScatterAddGetWorkspaceSize( | ||
| 70 | + const aclTensor* self, | ||
| 71 | + int64_t dim, | ||
| 72 | + const aclTensor* index, | ||
| 73 | + const aclTensor* src, | ||
| 74 | + aclTensor* out, | ||
| 75 | + uint64_t* workspaceSize, | ||
| 76 | + aclOpExecutor** executor) | ||
| 77 | +``` | ||
| 78 | + | ||
| 79 | +```Cpp | ||
| 80 | +aclnnStatus aclnnScatterAdd( | ||
| 81 | + void* workspace, | ||
| 82 | + uint64_t workspaceSize, | ||
| 83 | + aclOpExecutor* executor, | ||
| 84 | + const aclrtStream stream) | ||
| 85 | +``` | ||
| 86 | + | ||
| 87 | +## aclnnScatterAddGetWorkspaceSize | ||
| 88 | + | ||
| 89 | +- **参数说明:** | ||
| 90 | + | ||
| 91 | + <table style="undefined;table-layout: fixed; width: 1550px"><colgroup> | ||
| 92 | + <col style="width: 180px"> | ||
| 93 | + <col style="width: 120px"> | ||
| 94 | + <col style="width: 280px"> | ||
| 95 | + <col style="width: 320px"> | ||
| 96 | + <col style="width: 250px"> | ||
| 97 | + <col style="width: 120px"> | ||
| 98 | + <col style="width: 140px"> | ||
| 99 | + <col style="width: 140px"> | ||
| 100 | + </colgroup> | ||
| 101 | + <thead> | ||
| 102 | + <tr> | ||
| 103 | + <th>参数名</th> | ||
| 104 | + <th>输入/输出</th> | ||
| 105 | + <th>描述</th> | ||
| 106 | + <th>使用说明</th> | ||
| 107 | + <th>数据类型</th> | ||
| 108 | + <th>数据格式</th> | ||
| 109 | + <th>维度(shape)</th> | ||
| 110 | + <th>非连续Tensor</th> | ||
| 111 | + </tr></thead> | ||
| 112 | + <tbody> | ||
| 113 | + <tr> | ||
| 114 | + <td>self(aclTensor*)</td> | ||
| 115 | + <td>输入</td> | ||
| 116 | + <td>公式中的输入`self`,scatter的目标张量。</td> | ||
| 117 | + <td>维度数量需要与index和src相同。<br>数据类型与src的数据类型一致。</td> | ||
| 118 | + <td>BFLOAT16、FLOAT16、FLOAT32、DOUBLE、INT64、INT32、INT16、INT8、UINT8、BOOL、COMPLEX64、COMPLEX128</td> | ||
| 119 | + <td>ND</td> | ||
| 120 | + <td>0-8</td> | ||
| 121 | + <td>√</td> | ||
| 122 | + </tr> | ||
| 123 | + <tr> | ||
| 124 | + <td>dim(int64_t)</td> | ||
| 125 | + <td>输入</td> | ||
| 126 | + <td>计算公式中的输入`dim`。</td> | ||
| 127 | + <td>-</td> | ||
| 128 | + <td>-</td> | ||
| 129 | + <td>-</td> | ||
| 130 | + <td>-</td> | ||
| 131 | + <td>-</td> | ||
| 132 | + </tr> | ||
| 133 | + <tr> | ||
| 134 | + <td>index(aclTensor*)</td> | ||
| 135 | + <td>输入</td> | ||
| 136 | + <td>公式中的输入`index`。</td> | ||
| 137 | + <td>维度数量需要与src相同。</td> | ||
| 138 | + <td>INT32、INT64</td> | ||
| 139 | + <td>ND</td> | ||
| 140 | + <td>-</td> | ||
| 141 | + <td>√</td> | ||
| 142 | + </tr> | ||
| 143 | + <tr> | ||
| 144 | + <td>src(aclTensor*)</td> | ||
| 145 | + <td>输入</td> | ||
| 146 | + <td>公式中的输入`src`,源张量。</td> | ||
| 147 | + <td>维度数量需要与index相同。<br>数据类型与self的数据类型一致。</td> | ||
| 148 | + <td>BFLOAT16、FLOAT16、FLOAT32、DOUBLE、INT64、INT32、INT16、INT8、UINT8、BOOL、COMPLEX64、COMPLEX128</td> | ||
| 149 | + <td>ND</td> | ||
| 150 | + <td>-</td> | ||
| 151 | + <td>×</td> | ||
| 152 | + </tr> | ||
| 153 | + <tr> | ||
| 154 | + <td>out(aclTensor*)</td> | ||
| 155 | + <td>输出</td> | ||
| 156 | + <td>公式中的`output`。</td> | ||
| 157 | + <td>shape需要与self一致。<br>数据类型与self的数据类型一致。</td> | ||
| 158 | + <td>BFLOAT16、FLOAT16、FLOAT32、DOUBLE、INT64、INT32、INT16、INT8、UINT8、BOOL、COMPLEX64、COMPLEX128</td> | ||
| 159 | + <td>ND</td> | ||
| 160 | + <td>-</td> | ||
| 161 | + <td>×</td> | ||
| 162 | + </tr> | ||
| 163 | + <tr> | ||
| 164 | + <td>workspaceSize(uint64_t*)</td> | ||
| 165 | + <td>输出</td> | ||
| 166 | + <td>返回需要在Device侧申请的workspace大小。</td> | ||
| 167 | + <td>-</td> | ||
| 168 | + <td>-</td> | ||
| 169 | + <td>-</td> | ||
| 170 | + <td>-</td> | ||
| 171 | + <td>-</td> | ||
| 172 | + </tr> | ||
| 173 | + <tr> | ||
| 174 | + <td>executor(aclOpExecutor**)</td> | ||
| 175 | + <td>输出</td> | ||
| 176 | + <td>返回op执行器,包含了算子计算流程。</td> | ||
| 177 | + <td>-</td> | ||
| 178 | + <td>-</td> | ||
| 179 | + <td>-</td> | ||
| 180 | + <td>-</td> | ||
| 181 | + <td>-</td> | ||
| 182 | + </tr> | ||
| 183 | + </tbody></table> | ||
| 184 | + | ||
| 185 | +- **返回值:** | ||
| 186 | + | ||
| 187 | + aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 | ||
| 188 | + | ||
| 189 | + 第一段接口完成入参校验,出现以下场景时报错: | ||
| 190 | + | ||
| 191 | + <table style="undefined;table-layout: fixed; width: 1150px"><colgroup> | ||
| 192 | + <col style="width: 300px"> | ||
| 193 | + <col style="width: 134px"> | ||
| 194 | + <col style="width: 716px"> | ||
| 195 | + </colgroup> | ||
| 196 | + <thead> | ||
| 197 | + <tr> | ||
| 198 | + <th>返回值</th> | ||
| 199 | + <th>错误码</th> | ||
| 200 | + <th>描述</th> | ||
| 201 | + </tr></thead> | ||
| 202 | + <tbody> | ||
| 203 | + <tr> | ||
| 204 | + <td>ACLNN_ERR_PARAM_NULLPTR</td> | ||
| 205 | + <td>161001</td> | ||
| 206 | + <td>传入的self、index、src或out是空指针。</td> | ||
| 207 | + </tr> | ||
| 208 | + <tr> | ||
| 209 | + <td rowspan="3">ACLNN_ERR_PARAM_INVALID</td> | ||
| 210 | + <td rowspan="3">161002</td> | ||
| 211 | + <td>self、index、src或out的数据类型不在支持的范围之内。</td> | ||
| 212 | + </tr> | ||
| 213 | + <tr> | ||
| 214 | + <td>self和out的shape不一致。</td> | ||
| 215 | + </tr> | ||
| 216 | + <tr> | ||
| 217 | + <td>src或index的shape不合法。</td> | ||
| 218 | + </tr> | ||
| 219 | + </tbody></table> | ||
| 220 | + | ||
| 221 | +## aclnnScatterAdd | ||
| 222 | + | ||
| 223 | +- **参数说明:** | ||
| 224 | + | ||
| 225 | + <table style="undefined;table-layout: fixed; width: 1100px"><colgroup> | ||
| 226 | + <col style="width: 200px"> | ||
| 227 | + <col style="width: 130px"> | ||
| 228 | + <col style="width: 770px"> | ||
| 229 | + </colgroup> | ||
| 230 | + <thead> | ||
| 231 | + <tr> | ||
| 232 | + <th>参数名</th> | ||
| 233 | + <th>输入/输出</th> | ||
| 234 | + <th>描述</th> | ||
| 235 | + </tr></thead> | ||
| 236 | + <tbody> | ||
| 237 | + <tr> | ||
| 238 | + <td>workspace</td> | ||
| 239 | + <td>输入</td> | ||
| 240 | + <td>在Device侧申请的workspace内存地址。</td> | ||
| 241 | + </tr> | ||
| 242 | + <tr> | ||
| 243 | + <td>workspaceSize</td> | ||
| 244 | + <td>输入</td> | ||
| 245 | + <td>在Device侧申请的workspace大小,由第一段接口aclnnScatterAddGetWorkspaceSize获取。</td> | ||
| 246 | + </tr> | ||
| 247 | + <tr> | ||
| 248 | + <td>executor</td> | ||
| 249 | + <td>输入</td> | ||
| 250 | + <td>op执行器,包含了算子计算流程。</td> | ||
| 251 | + </tr> | ||
| 252 | + <tr> | ||
| 253 | + <td>stream</td> | ||
| 254 | + <td>输入</td> | ||
| 255 | + <td>指定执行任务的Stream。</td> | ||
| 256 | + </tr> | ||
| 257 | + </tbody></table> | ||
| 258 | + | ||
| 259 | +- **返回值:** | ||
| 260 | + | ||
| 261 | + aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 | ||
| 262 | + | ||
| 263 | +## 约束说明 | ||
| 264 | + | ||
| 265 | +- 确定性计算: | ||
| 266 | + - aclnnScatterAdd默认确定性实现。 | ||
| 267 | + | ||
| 268 | +## 调用示例 | ||
| 269 | + | ||
| 270 | +示例代码如下,仅供参考,具体编译和执行过程请参考[编译与运行样例](../../../docs/zh/context/编译与运行样例.md)。 | ||
| 271 | + | ||
| 272 | +```Cpp | ||
| 273 | +#include <iostream> | ||
| 274 | +#include <vector> | ||
| 275 | +#include "acl/acl.h" | ||
| 276 | +#include "aclnnop/aclnn_scatter_add.h" | ||
| 277 | + | ||
| 278 | +#define CHECK_RET(cond, return_expr) \ | ||
| 279 | + do { \ | ||
| 280 | + if (!(cond)) { \ | ||
| 281 | + return_expr; \ | ||
| 282 | + } \ | ||
| 283 | + } while (0) | ||
| 284 | + | ||
| 285 | +#define LOG_PRINT(message, ...) \ | ||
| 286 | + do { \ | ||
| 287 | + printf(message, ##__VA_ARGS__); \ | ||
| 288 | + } while (0) | ||
| 289 | + | ||
| 290 | +int64_t GetShapeSize(const std::vector<int64_t>& shape) { | ||
| 291 | + int64_t shapeSize = 1; | ||
| 292 | + for (auto i : shape) { | ||
| 293 | + shapeSize *= i; | ||
| 294 | + } | ||
| 295 | + return shapeSize; | ||
| 296 | +} | ||
| 297 | + | ||
| 298 | +int Init(int32_t deviceId, aclrtStream* stream) { | ||
| 299 | + // 固定写法,资源初始化 | ||
| 300 | + auto ret = aclInit(nullptr); | ||
| 301 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclInit failed. ERROR: %d\n", ret); return ret); | ||
| 302 | + ret = aclrtSetDevice(deviceId); | ||
| 303 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSetDevice failed. ERROR: %d\n", ret); return ret); | ||
| 304 | + ret = aclrtCreateStream(stream); | ||
| 305 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtCreateStream failed. ERROR: %d\n", ret); return ret); | ||
| 306 | + return 0; | ||
| 307 | +} | ||
| 308 | + | ||
| 309 | +template <typename T> | ||
| 310 | +int CreateAclTensor(const std::vector<T>& hostData, const std::vector<int64_t>& shape, void** deviceAddr, | ||
| 311 | + aclDataType dataType, aclTensor** tensor) { | ||
| 312 | + auto size = GetShapeSize(shape) * sizeof(T); | ||
| 313 | + // 调用aclrtMalloc申请device侧内存 | ||
| 314 | + auto ret = aclrtMalloc(deviceAddr, size, ACL_MEM_MALLOC_HUGE_FIRST); | ||
| 315 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMalloc failed. ERROR: %d\n", ret); return ret); | ||
| 316 | + // 调用aclrtMemcpy将host侧数据拷贝到device侧内存上 | ||
| 317 | + ret = aclrtMemcpy(*deviceAddr, size, hostData.data(), size, ACL_MEMCPY_HOST_TO_DEVICE); | ||
| 318 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMemcpy failed. ERROR: %d\n", ret); return ret); | ||
| 319 | + | ||
| 320 | + // 计算连续tensor的strides | ||
| 321 | + std::vector<int64_t> strides(shape.size(), 1); | ||
| 322 | + for (int64_t i = shape.size() - 2; i >= 0; i--) { | ||
| 323 | + strides[i] = shape[i + 1] * strides[i + 1]; | ||
| 324 | + } | ||
| 325 | + | ||
| 326 | + // 调用aclCreateTensor接口创建aclTensor | ||
| 327 | + *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, | ||
| 328 | + shape.data(), shape.size(), *deviceAddr); | ||
| 329 | + return 0; | ||
| 330 | +} | ||
| 331 | + | ||
| 332 | +int main() { | ||
| 333 | + // 1. (固定写法)device/stream初始化,参考acl API手册 | ||
| 334 | + // 根据自己的实际device填写deviceId | ||
| 335 | + int32_t deviceId = 0; | ||
| 336 | + aclrtStream stream; | ||
| 337 | + auto ret = Init(deviceId, &stream); | ||
| 338 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); | ||
| 339 | + | ||
| 340 | + // 2. 构造输入与输出,需要根据API的接口自定义构造 | ||
| 341 | + std::vector<int64_t> selfShape = {4, 4}; | ||
| 342 | + std::vector<int64_t> indexShape = {3, 4}; | ||
| 343 | + std::vector<int64_t> srcShape = {4, 4}; | ||
| 344 | + std::vector<int64_t> outShape = {4, 4}; | ||
| 345 | + int64_t dim = 0; | ||
| 346 | + void* selfDeviceAddr = nullptr; | ||
| 347 | + void* indexDeviceAddr = nullptr; | ||
| 348 | + void* srcDeviceAddr = nullptr; | ||
| 349 | + void* outDeviceAddr = nullptr; | ||
| 350 | + aclTensor* self = nullptr; | ||
| 351 | + aclTensor* index = nullptr; | ||
| 352 | + aclTensor* src = nullptr; | ||
| 353 | + aclTensor* out = nullptr; | ||
| 354 | + std::vector<float> selfHostData(16, 0); | ||
| 355 | + std::vector<int64_t> indexHostData = {0, 1, 2, 1, 0, 1, 2, 0, 2, 2, 1, 0}; | ||
| 356 | + std::vector<float> srcHostData = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; | ||
| 357 | + std::vector<float> outHostData(16, 0); | ||
| 358 | + // 创建self aclTensor | ||
| 359 | + ret = CreateAclTensor(selfHostData, selfShape, &selfDeviceAddr, aclDataType::ACL_FLOAT, &self); | ||
| 360 | + CHECK_RET(ret == ACL_SUCCESS, return ret); | ||
| 361 | + // 创建index aclTensor | ||
| 362 | + ret = CreateAclTensor(indexHostData, indexShape, &indexDeviceAddr, aclDataType::ACL_INT64, &index); | ||
| 363 | + CHECK_RET(ret == ACL_SUCCESS, return ret); | ||
| 364 | + // 创建src aclTensor | ||
| 365 | + ret = CreateAclTensor(srcHostData, srcShape, &srcDeviceAddr, aclDataType::ACL_FLOAT, &src); | ||
| 366 | + CHECK_RET(ret == ACL_SUCCESS, return ret); | ||
| 367 | + // 创建out aclTensor | ||
| 368 | + ret = CreateAclTensor(outHostData, outShape, &outDeviceAddr, aclDataType::ACL_FLOAT, &out); | ||
| 369 | + CHECK_RET(ret == ACL_SUCCESS, return ret); | ||
| 370 | + | ||
| 371 | + // 3. 调用CANN算子库API,需要修改为具体的Api名称 | ||
| 372 | + uint64_t workspaceSize = 0; | ||
| 373 | + aclOpExecutor* executor; | ||
| 374 | + // 调用aclnnScatterAdd第一段接口 | ||
| 375 | + ret = aclnnScatterAddGetWorkspaceSize(self, dim, index, src, out, &workspaceSize, &executor); | ||
| 376 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnScatterAddGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); | ||
| 377 | + // 根据第一段接口计算出的workspaceSize申请device内存 | ||
| 378 | + void* workspaceAddr = nullptr; | ||
| 379 | + if (workspaceSize > 0) { | ||
| 380 | + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); | ||
| 381 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); | ||
| 382 | + } | ||
| 383 | + // 调用aclnnScatterAdd第二段接口 | ||
| 384 | + ret = aclnnScatterAdd(workspaceAddr, workspaceSize, executor, stream); | ||
| 385 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnScatterAdd failed. ERROR: %d\n", ret); return ret); | ||
| 386 | + | ||
| 387 | + // 4. (固定写法)同步等待任务执行结束 | ||
| 388 | + ret = aclrtSynchronizeStream(stream); | ||
| 389 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); | ||
| 390 | + | ||
| 391 | + // 5. 获取输出的值,将device侧内存上的结果拷贝至host侧,需要根据具体API的接口定义修改 | ||
| 392 | + auto size = GetShapeSize(outShape); | ||
| 393 | + std::vector<float> resultData(size, 0); | ||
| 394 | + ret = aclrtMemcpy(resultData.data(), resultData.size() * sizeof(resultData[0]), outDeviceAddr, | ||
| 395 | + size * sizeof(resultData[0]), ACL_MEMCPY_DEVICE_TO_HOST); | ||
| 396 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("copy result from device to host failed. ERROR: %d\n", ret); return ret); | ||
| 397 | + for (int64_t i = 0; i < size; i++) { | ||
| 398 | + LOG_PRINT("result[%ld] is: %f\n", i, resultData[i]); | ||
| 399 | + } | ||
| 400 | + | ||
| 401 | + // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 | ||
| 402 | + aclDestroyTensor(self); | ||
| 403 | + aclDestroyTensor(index); | ||
| 404 | + aclDestroyTensor(src); | ||
| 405 | + aclDestroyTensor(out); | ||
| 406 | + // 7. 释放device资源,需要根据具体API的接口定义参数 | ||
| 407 | + aclrtFree(selfDeviceAddr); | ||
| 408 | + aclrtFree(indexDeviceAddr); | ||
| 409 | + aclrtFree(srcDeviceAddr); | ||
| 410 | + aclrtFree(outDeviceAddr); | ||
| 411 | + if (workspaceSize > 0) { | ||
| 412 | + aclrtFree(workspaceAddr); | ||
| 413 | + } | ||
| 414 | + aclrtDestroyStream(stream); | ||
| 415 | + aclrtResetDevice(deviceId); | ||
| 416 | + aclFinalize(); | ||
| 417 | + return 0; | ||
| 418 | +} | ||
| 419 | +``` | ||
| @@ -18,7 +18,7 @@ | |||
| 18 | - **示例:** | 18 | - **示例:** |
| 19 | 对于一个3D tensor, self会按照如下的规则进行更新: | 19 | 对于一个3D tensor, self会按照如下的规则进行更新: |
| 20 | 20 | ||
| 21 | - ``` | 21 | + ```text |
| 22 | self[index[i][j][k]][j][k] = value # 如果 dim == 0 | 22 | self[index[i][j][k]][j][k] = value # 如果 dim == 0 |
| 23 | self[i][index[i][j][k]][k] = value # 如果 dim == 1 | 23 | self[i][index[i][j][k]][k] = value # 如果 dim == 1 |
| 24 | self[i][j][index[i][j][k]] = value # 如果 dim == 2 | 24 | self[i][j][index[i][j][k]] = value # 如果 dim == 2 |
| @@ -73,7 +73,7 @@ | |||
| 73 | 73 | ||
| 74 | aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 | 74 | aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 |
| 75 | 75 | ||
| 76 | - ``` | 76 | + ```text |
| 77 | 第一段接口完成入参校验,出现以下场景时报错: | 77 | 第一段接口完成入参校验,出现以下场景时报错: |
| 78 | 返回161001 (ACLNN_ERR_PARAM_NULLPTR): 1. 传入的self、index、value或out是空指针。 | 78 | 返回161001 (ACLNN_ERR_PARAM_NULLPTR): 1. 传入的self、index、value或out是空指针。 |
| 79 | 返回161002 (ACLNN_ERR_PARAM_INVALID): 1. self、index、value或out的数据类型不在支持范围内。 | 79 | 返回161002 (ACLNN_ERR_PARAM_INVALID): 1. self、index、value或out的数据类型不在支持范围内。 |
| @@ -122,7 +122,7 @@ | |||
| 122 | - **返回值:** | 122 | - **返回值:** |
| 123 | aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 | 123 | aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 |
| 124 | 124 | ||
| 125 | - ``` | 125 | + ```text |
| 126 | 第一段接口完成入参校验,出现以下场景时报错: | 126 | 第一段接口完成入参校验,出现以下场景时报错: |
| 127 | 返回161001 (ACLNN_ERR_PARAM_NULLPTR): 1. 传入的selfRef、index、value是空指针。 | 127 | 返回161001 (ACLNN_ERR_PARAM_NULLPTR): 1. 传入的selfRef、index、value是空指针。 |
| 128 | 返回161002 (ACLNN_ERR_PARAM_INVALID): 1. selfRef、index、value的数据类型不在支持范围内 | 128 | 返回161002 (ACLNN_ERR_PARAM_INVALID): 1. selfRef、index、value的数据类型不在支持范围内 |
| @@ -0,0 +1,231 @@ | |||
| 1 | +# aclnnScatterNd | ||
| 2 | + | ||
| 3 | +## 产品支持情况 | ||
| 4 | + | ||
| 5 | +| 产品 | 是否支持 | | ||
| 6 | +| :----------------------------------------------------------- | :------: | | ||
| 7 | +| <term>Ascend 950PR/Ascend 950DT</term> | × | | ||
| 8 | +| <term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term> | √ | | ||
| 9 | +| <term>Atlas A2 训练系列产品/Atlas A2 推理系列产品</term> | √ | | ||
| 10 | +| <term>Atlas 200I/500 A2 推理产品</term> | × | | ||
| 11 | +| <term>Atlas 推理系列产品</term> | × | | ||
| 12 | +| <term>Atlas 训练系列产品</term> | × | | ||
| 13 | + | ||
| 14 | +## 功能说明 | ||
| 15 | + | ||
| 16 | +算子功能:拷贝data的数据至out,同时在指定indices处根据updates更新out中的数据。 | ||
| 17 | + | ||
| 18 | +## 函数原型 | ||
| 19 | + | ||
| 20 | +每个算子分为[两段式接口](../../../docs/zh/context/两段式接口.md),必须先调用“aclnnScatterNdGetWorkspaceSize”接口获取计算所需workspace大小以及包含了算子计算流程的执行器,再调用“aclnnScatterNd”接口执行计算。 | ||
| 21 | + | ||
| 22 | +* `aclnnStatus aclnnScatterNdGetWorkspaceSize(const aclTensor *data,const aclTensor *indices,const aclTensor *updates, aclTensor *out, uint64_t *workspaceSize, aclOpExecutor **executor)` | ||
| 23 | +* `aclnnStatus aclnnScatterNd(void *workspace, uint64_t workspaceSize, aclOpExecutor *executor, aclrtStream stream)` | ||
| 24 | + | ||
| 25 | +## aclnnScatterNdGetWorkspaceSize | ||
| 26 | + | ||
| 27 | +- **参数说明:** | ||
| 28 | + * data(aclTensor*,计算输入):Device侧的aclTensor, 数据类型与updates、out一致,shape满足1<=rank(data)<=8。支持[非连续的Tensor](../../../docs/zh/context/非连续的Tensor.md),[数据格式](../../../docs/zh/context/数据格式.md)支持ND。 | ||
| 29 | + - <term>Atlas A2 训练系列产品/Atlas A2 推理系列产品</term>、<term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term>:数据类型支持FLOAT16、FLOAT、BOOL、BFLOAT16 | ||
| 30 | + * indices(aclTensor*,计算输入):Device侧的aclTensor,数据类型支持INT32、INT64。indices.shape[-1] <= rank(data),且1<=rank(indices)<=8。支持[非连续的Tensor](../../../docs/zh/context/非连续的Tensor.md),[数据格式](../../../docs/zh/context/数据格式.md)支持ND。仅支持非负索引。indices中的索引数据不支持越界。 | ||
| 31 | + | ||
| 32 | + * updates(aclTensor*,计算输入):Device侧的aclTensor, 数据类型与data、out一致。shape要求rank(updates)=rank(data)+rank(indices)-indices.shape[-1] -1, 且满足1<=rank(updates)<=8。支持[非连续的Tensor](../../../docs/zh/context/非连续的Tensor.md),[数据格式](../../../docs/zh/context/数据格式.md)支持ND。 | ||
| 33 | + - <term>Atlas A2 训练系列产品/Atlas A2 推理系列产品</term>、<term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term>:数据类型支持FLOAT16、FLOAT、BOOL、BFLOAT16 | ||
| 34 | + * out(aclTensor*,计算输出):Device侧的aclTensor,数据类型与data、out一致,shape与data一致。支持[非连续的Tensor](../../../docs/zh/context/非连续的Tensor.md),[数据格式](../../../docs/zh/context/数据格式.md)支持ND。 | ||
| 35 | + - <term>Atlas A2 训练系列产品/Atlas A2 推理系列产品</term>、<term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term>:数据类型支持FLOAT16、FLOAT、BOOL、BFLOAT16 | ||
| 36 | + * workspaceSize(uint64_t*,出参):返回需要在Device侧申请的workspace大小。 | ||
| 37 | + | ||
| 38 | + * executor(aclOpExecutor**,出参):返回op执行器,包含了算子计算流程。 | ||
| 39 | + | ||
| 40 | +- **返回值:** | ||
| 41 | + | ||
| 42 | + aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 | ||
| 43 | + | ||
| 44 | + ```text | ||
| 45 | + 第一段接口完成入参校验,出现以下场景时报错: | ||
| 46 | + 返回161001(ACLNN_ERR_PARAM_NULLPTR):1.传入的data、indices、updates、out中有空指针 | ||
| 47 | + 返回161002(ACLNN_ERR_PARAM_INVALID):1. 数据类型不在支持的范围之内; | ||
| 48 | + 2. shape不满足要求:1<=rank(data)<=8, 1<=rank(indices)<=8,rank(updates)=rank(data)+rank(indices)- indices.shape[-1] -1 | ||
| 49 | + 3. shape不满足要求:1<=rank(indices)<=8, indices.shape[-1] <= rank(data) | ||
| 50 | + 4. shape不满足要求:1<=rank(updates)<=8, updates.shape == indices.shape[:-1] + data.shape[indices.shape[-1] :] | ||
| 51 | + 5. shape不满足要求:data.shape == out.shape | ||
| 52 | + ``` | ||
| 53 | + | ||
| 54 | +## aclnnScatterNd | ||
| 55 | + | ||
| 56 | +- **参数说明:** | ||
| 57 | + * workspace(void *, 入参):在Device侧申请的workspace内存地址。 | ||
| 58 | + * workspaceSize(uint64_t, 入参):在Device侧申请的workspace大小,由第一段接口aclnnScatterNdGetWorkspaceSize获取。 | ||
| 59 | + * executor(aclOpExecutor *, 入参):op执行器,包含了算子计算流程。 | ||
| 60 | + * stream(aclrtStream, 入参):指定执行任务的Stream。 | ||
| 61 | +- **返回值:** | ||
| 62 | + | ||
| 63 | + aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 | ||
| 64 | + | ||
| 65 | +## 约束说明 | ||
| 66 | + | ||
| 67 | +- 确定性计算: | ||
| 68 | + - aclnnScatterNd默认确定性实现。 | ||
| 69 | + | ||
| 70 | +## 调用示例 | ||
| 71 | + | ||
| 72 | +示例代码如下,仅供参考,具体编译和执行过程请参考[编译与运行样例](../../../docs/zh/context/编译与运行样例.md)。 | ||
| 73 | + | ||
| 74 | +```Cpp | ||
| 75 | +#include <iostream> | ||
| 76 | +#include <vector> | ||
| 77 | +#include "acl/acl.h" | ||
| 78 | +#include "aclnnop/aclnn_scatter_nd.h" | ||
| 79 | +#include "aclnn/aclnn_base.h" | ||
| 80 | + | ||
| 81 | +#define CHECK_RET(cond, return_expr) \ | ||
| 82 | + do { \ | ||
| 83 | + if (!(cond)) { \ | ||
| 84 | + return_expr; \ | ||
| 85 | + } \ | ||
| 86 | + } while (0) | ||
| 87 | + | ||
| 88 | +#define LOG_PRINT(message, ...) \ | ||
| 89 | + do { \ | ||
| 90 | + printf(message, ##__VA_ARGS__); \ | ||
| 91 | + } while (0) | ||
| 92 | + | ||
| 93 | +int64_t GetShapeSize(const std::vector<int64_t>& shape) { | ||
| 94 | + int64_t shapeSize = 1; | ||
| 95 | + for (auto i : shape) { | ||
| 96 | + shapeSize *= i; | ||
| 97 | + } | ||
| 98 | + return shapeSize; | ||
| 99 | +} | ||
| 100 | + | ||
| 101 | +int Init(int32_t deviceId, aclrtStream* stream) { | ||
| 102 | + // 固定写法,资源初始化 | ||
| 103 | + | ||
| 104 | + auto ret = aclInit(nullptr); | ||
| 105 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclInit failed. ERROR: %d\n", ret); return ret); | ||
| 106 | + ret = aclrtSetDevice(deviceId); | ||
| 107 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSetDevice failed. ERROR: %d\n", ret); return ret); | ||
| 108 | + ret = aclrtCreateStream(stream); | ||
| 109 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtCreateStream failed. ERROR: %d\n", ret); return ret); | ||
| 110 | + return 0; | ||
| 111 | +} | ||
| 112 | + | ||
| 113 | +template <typename T> | ||
| 114 | +int CreateAclTensor(const std::vector<T>& hostData, const std::vector<int64_t>& shape, void** deviceAddr, | ||
| 115 | + aclDataType dataType, aclTensor** tensor) { | ||
| 116 | + auto size = GetShapeSize(shape) * sizeof(T); | ||
| 117 | + // 调用aclrtMalloc申请device侧内存 | ||
| 118 | + auto ret = aclrtMalloc(deviceAddr, size, ACL_MEM_MALLOC_HUGE_FIRST); | ||
| 119 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMalloc failed. ERROR: %d\n", ret); return ret); | ||
| 120 | + | ||
| 121 | + // 调用aclrtMemcpy将host侧数据拷贝到device侧内存上 | ||
| 122 | + ret = aclrtMemcpy(*deviceAddr, size, hostData.data(), size, ACL_MEMCPY_HOST_TO_DEVICE); | ||
| 123 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMemcpy failed. ERROR: %d\n", ret); return ret); | ||
| 124 | + | ||
| 125 | + // 计算连续tensor的strides | ||
| 126 | + std::vector<int64_t> strides(shape.size(), 1); | ||
| 127 | + for (int64_t i = shape.size() - 2; i >= 0; i--) { | ||
| 128 | + strides[i] = shape[i + 1] * strides[i + 1]; | ||
| 129 | + } | ||
| 130 | + | ||
| 131 | + // 调用aclCreateTensor接口创建aclTensor | ||
| 132 | + *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, | ||
| 133 | + shape.data(), shape.size(), *deviceAddr); | ||
| 134 | + return 0; | ||
| 135 | +} | ||
| 136 | + | ||
| 137 | +int main() { | ||
| 138 | + // 1. (固定写法)device/stream初始化, 参考acl对外接口列表 | ||
| 139 | + // 根据自己的实际device填写deviceId | ||
| 140 | + int32_t deviceId = 0; | ||
| 141 | + aclrtStream stream; | ||
| 142 | + auto ret = Init(deviceId, &stream); | ||
| 143 | + // check根据自己的需要处理 | ||
| 144 | + CHECK_RET(ret == 0, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); | ||
| 145 | + // 2. 构造输入与输出,需要根据API的接口自定义构造 | ||
| 146 | + std::vector<int64_t> dataShape = {8}; | ||
| 147 | + std::vector<int64_t> indicesShape = {4, 1}; | ||
| 148 | + std::vector<int64_t> updatesShape = {4}; | ||
| 149 | + std::vector<int64_t> outShape = {8}; | ||
| 150 | + | ||
| 151 | + void* dataDeviceAddr = nullptr; | ||
| 152 | + void* indicesDeviceAddr = nullptr; | ||
| 153 | + void* updatesDeviceAddr = nullptr; | ||
| 154 | + void* outDeviceAddr = nullptr; | ||
| 155 | + aclTensor* data = nullptr; | ||
| 156 | + aclTensor* indices = nullptr; | ||
| 157 | + aclTensor* updates = nullptr; | ||
| 158 | + aclTensor* out = nullptr; | ||
| 159 | + | ||
| 160 | + std::vector<float> selfHostData = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0}; | ||
| 161 | + std::vector<int32_t> indicesData = {4,3,1,7}; | ||
| 162 | + std::vector<float> updatesData = {9.0, 10.0, 11.0, 12.0}; | ||
| 163 | + std::vector<float> outData = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; | ||
| 164 | + | ||
| 165 | + ret = CreateAclTensor(selfHostData, dataShape, &dataDeviceAddr, aclDataType::ACL_FLOAT, &data); | ||
| 166 | + CHECK_RET(ret == ACL_SUCCESS, return ret); | ||
| 167 | + | ||
| 168 | + ret = CreateAclTensor(indicesData, indicesShape, &indicesDeviceAddr, aclDataType::ACL_INT32, &indices); | ||
| 169 | + CHECK_RET(ret == ACL_SUCCESS, return ret); | ||
| 170 | + | ||
| 171 | + ret = CreateAclTensor(updatesData, updatesShape, &updatesDeviceAddr, aclDataType::ACL_FLOAT, &updates); | ||
| 172 | + CHECK_RET(ret == ACL_SUCCESS, return ret); | ||
| 173 | + | ||
| 174 | + ret = CreateAclTensor(outData, outShape, &outDeviceAddr, aclDataType::ACL_FLOAT, &out); | ||
| 175 | + CHECK_RET(ret == ACL_SUCCESS, return ret); | ||
| 176 | + | ||
| 177 | + // 创建out aclTensor | ||
| 178 | + // ret = CreateAclTensor(outData, outShape, &outDeviceAddr, aclDataType::ACL_INT32, &out); | ||
| 179 | + // CHECK_RET(ret == ACL_SUCCESS, return ret); | ||
| 180 | + | ||
| 181 | + // 3. 调用CANN算子库API,需要修改为具体的API | ||
| 182 | + uint64_t workspaceSize = 0; | ||
| 183 | + aclOpExecutor* executor; | ||
| 184 | + // 调用aclnnAdd第一段接口 | ||
| 185 | + ret = aclnnScatterNdGetWorkspaceSize(data, indices, updates, out, &workspaceSize, &executor); | ||
| 186 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnScatterNdGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); | ||
| 187 | + // 根据第一段接口计算出的workspaceSize申请device内存 | ||
| 188 | + void* workspaceAddr = nullptr; | ||
| 189 | + if (workspaceSize > 0) { | ||
| 190 | + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); | ||
| 191 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret;); | ||
| 192 | + } | ||
| 193 | + | ||
| 194 | + ret = aclnnScatterNd(workspaceAddr, workspaceSize, executor, stream); | ||
| 195 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnScatterNd failed. ERROR: %d\n", ret); return ret); | ||
| 196 | + // 4. (固定写法)同步等待任务执行结束 | ||
| 197 | + ret = aclrtSynchronizeStream(stream); | ||
| 198 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); | ||
| 199 | + // 5. 获取输出的值,将device侧内存上的结果拷贝至host侧,需要根据具体API的接口定义修改 | ||
| 200 | + auto size = GetShapeSize(outShape); | ||
| 201 | + std::vector<float> resultData(size, 0); | ||
| 202 | + ret = aclrtMemcpy(resultData.data(), resultData.size() * sizeof(resultData[0]), outDeviceAddr, size * sizeof(float), | ||
| 203 | + ACL_MEMCPY_DEVICE_TO_HOST); | ||
| 204 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("copy result from device to host failed. ERROR: %d\n", ret); return ret); | ||
| 205 | + | ||
| 206 | + for (int64_t i = 0; i < size; i++) { | ||
| 207 | + LOG_PRINT("result[%ld] is: %f\n", i, resultData[i]); | ||
| 208 | + } | ||
| 209 | + | ||
| 210 | + // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 | ||
| 211 | + aclDestroyTensor(data); | ||
| 212 | + aclDestroyTensor(indices); | ||
| 213 | + aclDestroyTensor(updates); | ||
| 214 | + aclDestroyTensor(out); | ||
| 215 | + | ||
| 216 | + // 7. 释放device资源,需要根据具体API的接口定义修改 | ||
| 217 | + | ||
| 218 | + aclrtFree(dataDeviceAddr); | ||
| 219 | + aclrtFree(indicesDeviceAddr); | ||
| 220 | + aclrtFree(updatesDeviceAddr); | ||
| 221 | + aclrtFree(outDeviceAddr); | ||
| 222 | + if (workspaceSize > 0) { | ||
| 223 | + aclrtFree(workspaceAddr); | ||
| 224 | + } | ||
| 225 | + aclrtDestroyStream(stream); | ||
| 226 | + aclrtResetDevice(deviceId); | ||
| 227 | + aclFinalize(); | ||
| 228 | + | ||
| 229 | + return 0; | ||
| 230 | +} | ||
| 231 | +``` | ||
| @@ -17,7 +17,7 @@ | |||
| 17 | 17 | ||
| 18 | - 示例: | 18 | - 示例: |
| 19 | 19 | ||
| 20 | - ``` | 20 | + ```text |
| 21 | # If sparse_values is scalar | 21 | # If sparse_values is scalar |
| 22 | dense[i] = (i == sparse_indices ? sparse_values : default_value) | 22 | dense[i] = (i == sparse_indices ? sparse_values : default_value) |
| 23 | 23 | ||
| @@ -46,7 +46,7 @@ $$ | |||
| 46 | 46 | ||
| 47 | 返回aclnnStatus状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 | 47 | 返回aclnnStatus状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 |
| 48 | 48 | ||
| 49 | - ``` | 49 | + ```text |
| 50 | 第一段接口完成入参校验,若出现以下错误码,则对应原因为: | 50 | 第一段接口完成入参校验,若出现以下错误码,则对应原因为: |
| 51 | - 161001(ACLNN_ERR_PARAM_NULLPTR): 1. 传入的varRef、indices、updates是空指针。 | 51 | - 161001(ACLNN_ERR_PARAM_NULLPTR): 1. 传入的varRef、indices、updates是空指针。 |
| 52 | - 161002(ACLNN_ERR_PARAM_INVALID): 1. varRef、indices、updates的数据类型不在支持的范围之内。 | 52 | - 161002(ACLNN_ERR_PARAM_INVALID): 1. varRef、indices、updates的数据类型不在支持的范围之内。 |
| @@ -62,6 +62,7 @@ logits中的每一行logits[batch][:]根据相应的topK[batch]、topP[batch]、 | |||
| 62 | v = 8 * \text{ks\_max} | 62 | v = 8 * \text{ks\_max} |
| 63 | $$ | 63 | $$ |
| 64 | ks_max有效取值范围[1,1024],默认为1024,并且需要向上对齐到8的整数倍。 | 64 | ks_max有效取值范围[1,1024],默认为1024,并且需要向上对齐到8的整数倍。 |
| 65 | + | ||
| 65 | * 生成需要过滤的mask | 66 | * 生成需要过滤的mask |
| 66 | 67 | ||
| 67 | $$ | 68 | $$ |
| @@ -92,6 +93,7 @@ logits中的每一行logits[batch][:]根据相应的topK[batch]、topP[batch]、 | |||
| 92 | $$ | 93 | $$ |
| 93 | 94 | ||
| 94 | TopP采样 | 95 | TopP采样 |
| 96 | + | ||
| 95 | * 根据入参约束属性inputIsLogits,如果该属性为True,则对排序后结果进行归一化: | 97 | * 根据入参约束属性inputIsLogits,如果该属性为True,则对排序后结果进行归一化: |
| 96 | $$ | 98 | $$ |
| 97 | \text{logit\_sortProb} = | 99 | \text{logit\_sortProb} = |
| @@ -172,6 +174,7 @@ logits中的每一行logits[batch][:]根据相应的topK[batch]、topP[batch]、 | |||
| 172 | min_ps[b]≥1时,每个batch仅取1个最大token,其余位置填充defLogit。 | 174 | min_ps[b]≥1时,每个batch仅取1个最大token,其余位置填充defLogit。 |
| 173 | 175 | ||
| 174 | 可选输出 | 176 | 可选输出 |
| 177 | + | ||
| 175 | * 如果入参属性IsNeedLogits=True,则使用topK-topP-minP联合采样后的logitsIndexMasked,进行`logits_top_kp_select`输出。 | 178 | * 如果入参属性IsNeedLogits=True,则使用topK-topP-minP联合采样后的logitsIndexMasked,进行`logits_top_kp_select`输出。 |
| 176 | $$ | 179 | $$ |
| 177 | \text{logitsIndex}[b][v] = \text{Index}(\text{logitsSortMasked}[b][v] \in \text{Logits}) | 180 | \text{logitsIndex}[b][v] = \text{Index}(\text{logitsSortMasked}[b][v] \in \text{Logits}) |
| @@ -190,6 +193,7 @@ logits中的每一行logits[batch][:]根据相应的topK[batch]、topP[batch]、 | |||
| 190 | $$ | 193 | $$ |
| 191 | 194 | ||
| 192 | 后继处理 | 195 | 后继处理 |
| 196 | + | ||
| 193 | * 此阶段输入为前序对前序topK-topP-minP采样的联合结果logitsSortMasked。 | 197 | * 此阶段输入为前序对前序topK-topP-minP采样的联合结果logitsSortMasked。 |
| 194 | * 此处输入须要确保logitsSortMasked∈(0,1),根据输入Logits的实际情况,配置入参约束属性inputIsLogits,即: | 198 | * 此处输入须要确保logitsSortMasked∈(0,1),根据输入Logits的实际情况,配置入参约束属性inputIsLogits,即: |
| 195 | $$ | 199 | $$ |
| @@ -64,6 +64,7 @@ logits中的每一行logits[batch][:]根据相应的topK[batch]、topP[batch]、 | |||
| 64 | v = 8 * \text{ks\_max} | 64 | v = 8 * \text{ks\_max} |
| 65 | $$ | 65 | $$ |
| 66 | ks_max有效取值范围[1,1024],默认为1024,并且需要向上对齐到8的整数倍。 | 66 | ks_max有效取值范围[1,1024],默认为1024,并且需要向上对齐到8的整数倍。 |
| 67 | + | ||
| 67 | * 生成需要过滤的mask | 68 | * 生成需要过滤的mask |
| 68 | 69 | ||
| 69 | $$ | 70 | $$ |
| @@ -94,6 +95,7 @@ logits中的每一行logits[batch][:]根据相应的topK[batch]、topP[batch]、 | |||
| 94 | $$ | 95 | $$ |
| 95 | 96 | ||
| 96 | TopP采样 | 97 | TopP采样 |
| 98 | + | ||
| 97 | * 根据入参约束属性inputIsLogits,如果该属性为True,则对排序后结果进行归一化: | 99 | * 根据入参约束属性inputIsLogits,如果该属性为True,则对排序后结果进行归一化: |
| 98 | $$ | 100 | $$ |
| 99 | \text{logit\_sortProb} = | 101 | \text{logit\_sortProb} = |
| @@ -174,6 +176,7 @@ logits中的每一行logits[batch][:]根据相应的topK[batch]、topP[batch]、 | |||
| 174 | min_ps[b]≥1时,每个batch仅取1个最大token,其余位置填充defLogit。 | 176 | min_ps[b]≥1时,每个batch仅取1个最大token,其余位置填充defLogit。 |
| 175 | 177 | ||
| 176 | 可选输出 | 178 | 可选输出 |
| 179 | + | ||
| 177 | * 如果入参属性IsNeedLogits=True,则使用topK-topP-minP联合采样后的logitsIndexMasked,进行`logits_top_kp_select`输出。 | 180 | * 如果入参属性IsNeedLogits=True,则使用topK-topP-minP联合采样后的logitsIndexMasked,进行`logits_top_kp_select`输出。 |
| 178 | $$ | 181 | $$ |
| 179 | \text{logitsIndex}[b][v] = \text{Index}(\text{logitsSortMasked}[b][v] \in \text{Logits}) | 182 | \text{logitsIndex}[b][v] = \text{Index}(\text{logitsSortMasked}[b][v] \in \text{Logits}) |
| @@ -192,6 +195,7 @@ logits中的每一行logits[batch][:]根据相应的topK[batch]、topP[batch]、 | |||
| 192 | $$ | 195 | $$ |
| 193 | 196 | ||
| 194 | 后继处理 | 197 | 后继处理 |
| 198 | + | ||
| 195 | * 此阶段输入为前序对前序topK-topP-minP采样的联合结果logitsSortMasked。 | 199 | * 此阶段输入为前序对前序topK-topP-minP采样的联合结果logitsSortMasked。 |
| 196 | * 此处输入需要确保logitsSortMasked∈(0,1),根据输入Logits的实际情况,配置入参约束属性inputIsLogits,即: | 200 | * 此处输入需要确保logitsSortMasked∈(0,1),根据输入Logits的实际情况,配置入参约束属性inputIsLogits,即: |
| 197 | $$ | 201 | $$ |
| @@ -205,6 +205,8 @@ aclnnStatus aclnnUniqueDim( | |||
| 205 | - **返回值** | 205 | - **返回值** |
| 206 | 206 | ||
| 207 | aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 | 207 | aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 |
| 208 | + | ||
| 209 | + ```text | ||
| 208 | 第一段接口完成入参校验,出现以下场景时报错: | 210 | 第一段接口完成入参校验,出现以下场景时报错: |
| 209 | 211 | ||
| 210 | <table style="undefined;table-layout: fixed; width: 1035px"><colgroup> | 212 | <table style="undefined;table-layout: fixed; width: 1035px"><colgroup> |
| @@ -125,7 +125,7 @@ | |||
| 125 | * input_lengths的元素数量必须为N,值为[0, T]。 | 125 | * input_lengths的元素数量必须为N,值为[0, T]。 |
| 126 | * target_lengths的元素数量必须为N,值为[1, S]。 | 126 | * target_lengths的元素数量必须为N,值为[1, S]。 |
| 127 | * neg_log_likelihood的shape必须为1维(N)。 | 127 | * neg_log_likelihood的shape必须为1维(N)。 |
| 128 | -* log_alpha的shape必须为3维(N, T, X),其中X=((2 * S + 1) + 7) / 8 * 8。 | 128 | +* log_alpha的shape必须为3维(N, T, X),其中X=((2*S + 1) + 7) / 8*8。 |
| 129 | * blank的值域为[0, C - 1]。 | 129 | * blank的值域为[0, C - 1]。 |
| 130 | * reduction的取值范围为{'none', 'mean', 'sum'}。 | 130 | * reduction的取值范围为{'none', 'mean', 'sum'}。 |
| 131 | 131 | ||
| @@ -39,6 +39,7 @@ | |||
| 39 | sum(L), & \text{if reduction} = \text{sum} | 39 | sum(L), & \text{if reduction} = \text{sum} |
| 40 | \end{cases} | 40 | \end{cases} |
| 41 | $$ | 41 | $$ |
| 42 | + | ||
| 42 | - 其中: | 43 | - 其中: |
| 43 | - Xn: predictions | 44 | - Xn: predictions |
| 44 | - Yn: labels/truth | 45 | - Yn: labels/truth |
| @@ -107,7 +107,7 @@ aclnnStatus aclnnBatchMatmulQuant( | |||
| 107 | <td>quantParam</td> | 107 | <td>quantParam</td> |
| 108 | <td>输入</td> | 108 | <td>输入</td> |
| 109 | <td>硬件完成量化计算的量化参数。</td> | 109 | <td>硬件完成量化计算的量化参数。</td> |
| 110 | - <td>可以通过 <a href="../../quant/trans_quant_param/docs/aclnnTransQuantParam.md">aclnnTransQuantParam</a> 接口获取。shape的大小(即元素个数)需要满足以下场景中任意一种:<ul><li>shape的大小为1。</li> | 110 | + <td>可以通过 <a href="../../../quant/trans_quant_param/docs/aclnnTransQuantParam.md">aclnnTransQuantParam</a> 接口获取。shape的大小(即元素个数)需要满足以下场景中任意一种:<ul><li>shape的大小为1。</li> |
| 111 | <li>shape的大小等于输出tensor(out)最后一个维度的大小向上对齐到16的倍数。</li></ul></td> | 111 | <li>shape的大小等于输出tensor(out)最后一个维度的大小向上对齐到16的倍数。</li></ul></td> |
| 112 | <td>UINT64</td> | 112 | <td>UINT64</td> |
| 113 | <td>NC1HWC0</td> | 113 | <td>NC1HWC0</td> |
| @@ -20,31 +20,26 @@ | |||
| 20 | $$ | 20 | $$ |
| 21 | vocab\_parallel\_logits\_out = input @ weight^T | 21 | vocab\_parallel\_logits\_out = input @ weight^T |
| 22 | $$ | 22 | $$ |
| 23 | - | 23 | + 2. 计算$vocab\_parallel\_logits\_out$每行的最大值: |
| 24 | - 2. 计算$vocab\_parallel\_logits\_out$每行的最大值: | ||
| 25 | 24 | ||
| 26 | $$ | 25 | $$ |
| 27 | logits\_max\_local = max(vocab\_parallel\_logits\_out, dim=-1) | 26 | logits\_max\_local = max(vocab\_parallel\_logits\_out, dim=-1) |
| 28 | $$ | 27 | $$ |
| 29 | - | 28 | + 3. 计算$vocab\_parallel\_logits\_out$与$logits\_max\_local$的差值: |
| 30 | - 3. 计算$vocab\_parallel\_logits\_out$与$logits\_max\_local$的差值: | ||
| 31 | 29 | ||
| 32 | $$ | 30 | $$ |
| 33 | sub\_res[b][n] = vocab\_parallel\_logits\_out[b][n] - logits\_max\_local[b] | 31 | sub\_res[b][n] = vocab\_parallel\_logits\_out[b][n] - logits\_max\_local[b] |
| 34 | $$ | 32 | $$ |
| 35 | - | 33 | + 4. 计算$sub\_res$经过指数运算后每行的和 |
| 36 | - 4. 计算$sub\_res$经过指数运算后每行的和 | ||
| 37 | 34 | ||
| 38 | $$ | 35 | $$ |
| 39 | sum\_exp\_logits\_local = sum(exp(sub\_res), dim=-1) | 36 | sum\_exp\_logits\_local = sum(exp(sub\_res), dim=-1) |
| 40 | $$ | 37 | $$ |
| 41 | - | ||
| 42 | 5. 计算$target$小于$vocab\_start\_index$或$target$大于$vocab\_end\_index$的mask | 38 | 5. 计算$target$小于$vocab\_start\_index$或$target$大于$vocab\_end\_index$的mask |
| 43 | 39 | ||
| 44 | $$ | 40 | $$ |
| 45 | target\_mask = (target < vocab\_start\_index) | (target > vocab\_end\_index) | 41 | target\_mask = (target < vocab\_start\_index) | (target > vocab\_end\_index) |
| 46 | $$ | 42 | $$ |
| 47 | - | ||
| 48 | 6. 计算$masked\_target$ | 43 | 6. 计算$masked\_target$ |
| 49 | 44 | ||
| 50 | $$ | 45 | $$ |
| @@ -54,7 +49,6 @@ | |||
| 54 | target[b] - vocab\_start\_index & \text{target\_mask[b]=false} | 49 | target[b] - vocab\_start\_index & \text{target\_mask[b]=false} |
| 55 | \end{cases} | 50 | \end{cases} |
| 56 | $$ | 51 | $$ |
| 57 | - | ||
| 58 | 7. 计算$predicted\_logits\_local$ | 52 | 7. 计算$predicted\_logits\_local$ |
| 59 | 53 | ||
| 60 | $$ | 54 | $$ |
| @@ -64,7 +58,6 @@ | |||
| 64 | sub\_res[b][masked\_target[b]] & \text{target\_mask[b]=false} | 58 | sub\_res[b][masked\_target[b]] & \text{target\_mask[b]=false} |
| 65 | \end{cases} | 59 | \end{cases} |
| 66 | $$ | 60 | $$ |
| 67 | - | ||
| 68 | 8. 计算$target\_mask$ | 61 | 8. 计算$target\_mask$ |
| 69 | 62 | ||
| 70 | $$ | 63 | $$ |
| @@ -24,31 +24,26 @@ | |||
| 24 | $$ | 24 | $$ |
| 25 | vocabParallelLogitsOutOptional = input @ weight^T | 25 | vocabParallelLogitsOutOptional = input @ weight^T |
| 26 | $$ | 26 | $$ |
| 27 | - | ||
| 28 | 2. 计算$vocabParallelLogitsOutOptional$每行的最大值: | 27 | 2. 计算$vocabParallelLogitsOutOptional$每行的最大值: |
| 29 | 28 | ||
| 30 | $$ | 29 | $$ |
| 31 | logitsMaxLocalOut = max(vocabParallelLogitsOutOptional, dim=-1) | 30 | logitsMaxLocalOut = max(vocabParallelLogitsOutOptional, dim=-1) |
| 32 | $$ | 31 | $$ |
| 33 | - | ||
| 34 | 3. 计算$vocabParallelLogitsOutOptional$与$logitsMaxLocalOut$的差值: | 32 | 3. 计算$vocabParallelLogitsOutOptional$与$logitsMaxLocalOut$的差值: |
| 35 | 33 | ||
| 36 | $$ | 34 | $$ |
| 37 | subRes[b][n] = vocabParallelLogitsOutOptional[b][n] - logitsMaxLocalOut[b] | 35 | subRes[b][n] = vocabParallelLogitsOutOptional[b][n] - logitsMaxLocalOut[b] |
| 38 | $$ | 36 | $$ |
| 39 | - | ||
| 40 | 4. 计算$subRes$经过指数运算后每行的和 | 37 | 4. 计算$subRes$经过指数运算后每行的和 |
| 41 | 38 | ||
| 42 | $$ | 39 | $$ |
| 43 | sumExpLogitsLocalOut = sum(exp(subRes), dim=-1) | 40 | sumExpLogitsLocalOut = sum(exp(subRes), dim=-1) |
| 44 | $$ | 41 | $$ |
| 45 | - | ||
| 46 | 5. 计算$target$小于$vocabStartIndex$或$target$大于$vocabEndIndex$的mask | 42 | 5. 计算$target$小于$vocabStartIndex$或$target$大于$vocabEndIndex$的mask |
| 47 | 43 | ||
| 48 | $$ | 44 | $$ |
| 49 | targetMask = (target < vocabStartIndex) | (target > vocabEndIndex) | 45 | targetMask = (target < vocabStartIndex) | (target > vocabEndIndex) |
| 50 | $$ | 46 | $$ |
| 51 | - | ||
| 52 | 6. 计算$maskedTargetOut$ | 47 | 6. 计算$maskedTargetOut$ |
| 53 | 48 | ||
| 54 | $$ | 49 | $$ |
| @@ -58,7 +53,6 @@ | |||
| 58 | target[b] - vocabStartIndex & \text{targetMask[b]=false} | 53 | target[b] - vocabStartIndex & \text{targetMask[b]=false} |
| 59 | \end{cases} | 54 | \end{cases} |
| 60 | $$ | 55 | $$ |
| 61 | - | ||
| 62 | 7. 计算$predictedLogitsLocalOut$ | 56 | 7. 计算$predictedLogitsLocalOut$ |
| 63 | 57 | ||
| 64 | $$ | 58 | $$ |
| @@ -68,7 +62,6 @@ | |||
| 68 | subRes[b][maskedTargetOut[b]] & \text{targetMask[b]=false} | 62 | subRes[b][maskedTargetOut[b]] & \text{targetMask[b]=false} |
| 69 | \end{cases} | 63 | \end{cases} |
| 70 | $$ | 64 | $$ |
| 71 | - | ||
| 72 | 8. 计算$targetMaskOut$ | 65 | 8. 计算$targetMaskOut$ |
| 73 | 66 | ||
| 74 | $$ | 67 | $$ |
| @@ -24,7 +24,7 @@ | |||
| 24 | 24 | ||
| 25 | - 示例: | 25 | - 示例: |
| 26 | 26 | ||
| 27 | - ``` | 27 | + ```text |
| 28 | a = tensor([[1, 2, 3], | 28 | a = tensor([[1, 2, 3], |
| 29 | [4, 5, 6]],dtype=float) | 29 | [4, 5, 6]],dtype=float) |
| 30 | b = tensor([1, 1, 1], dtype=float) | 30 | b = tensor([1, 1, 1], dtype=float) |
| @@ -491,7 +491,7 @@ aclnnStatus aclnnQuantMatmulWeightNz( | |||
| 491 | | INT8 | INT32 | UINT64 | FLOAT32 | null | FLOAT32 | null | FLOAT16/BFLOAT16 | | 491 | | INT8 | INT32 | UINT64 | FLOAT32 | null | FLOAT32 | null | FLOAT16/BFLOAT16 | |
| 492 | 492 | ||
| 493 | - x1的约束:当数据类型为INT8时,且x2的数据类型为INT32时,transposeX1为false。维度为:(m,k),要求k为偶数,并小于29576。 | 493 | - x1的约束:当数据类型为INT8时,且x2的数据类型为INT32时,transposeX1为false。维度为:(m,k),要求k为偶数,并小于29576。 |
| 494 | - - yOffset的约束:shape支持1维(n)。为计算过程中离线计算的辅助结果,值要求为8 * x2 * x2Scale,并在第1维累加。 | 494 | + - yOffset的约束:shape支持1维(n)。为计算过程中离线计算的辅助结果,值要求为8 *x2* x2Scale,并在第1维累加。 |
| 495 | 495 | ||
| 496 | </details> | 496 | </details> |
| 497 | 497 | ||
| @@ -692,7 +692,7 @@ aclnnStatus aclnnQuantMatmulV5( | |||
| 692 | - 数据格式支持ND。shape支持1维(n,)或3维(batch,1,n),n与x2的n一致。 | 692 | - 数据格式支持ND。shape支持1维(n,)或3维(batch,1,n),n与x2的n一致。 |
| 693 | - 当x1和x2为INT32、INT4时,bias的shape只支持1维(n,)。 | 693 | - 当x1和x2为INT32、INT4时,bias的shape只支持1维(n,)。 |
| 694 | - 当out的shape为2、4、5、6维时,bias的shape只支持1维(n,)。 | 694 | - 当out的shape为2、4、5、6维时,bias的shape只支持1维(n,)。 |
| 695 | - - yOffset的约束:shape支持1维(n)。为计算过程中离线计算的辅助结果,值要求为8 * x2 * x2Scale,并在第1维累加。 | 695 | + - yOffset的约束:shape支持1维(n)。为计算过程中离线计算的辅助结果,值要求为8 *x2* x2Scale,并在第1维累加。 |
| 696 | 696 | ||
| 697 | </details> | 697 | </details> |
| 698 | 698 | ||
| @@ -34,6 +34,7 @@ | |||
| 34 | $$ | 34 | $$ |
| 35 | 35 | ||
| 36 | 4.矩阵乘+反量化 | 36 | 4.矩阵乘+反量化 |
| 37 | + | ||
| 37 | - 4.1 若输入的$scale_{weight}$数据类型为FLOAT32, 则: | 38 | - 4.1 若输入的$scale_{weight}$数据类型为FLOAT32, 则: |
| 38 | 39 | ||
| 39 | $$ | 40 | $$ |
| @@ -39,6 +39,7 @@ | |||
| 39 | $$ | 39 | $$ |
| 40 | 40 | ||
| 41 | D为x中参加均值计算的数量。 | 41 | D为x中参加均值计算的数量。 |
| 42 | + | ||
| 42 | - $Var(x)$: | 43 | - $Var(x)$: |
| 43 | $$ | 44 | $$ |
| 44 | Var(x) = E(x-{\bar{x}})^2 | 45 | Var(x) = E(x-{\bar{x}})^2 |
| @@ -40,6 +40,7 @@ | |||
| 40 | $$ | 40 | $$ |
| 41 | y2Out=round((y/scales2)+zeroPoints2Optional) | 41 | y2Out=round((y/scales2)+zeroPoints2Optional) |
| 42 | $$ | 42 | $$ |
| 43 | + | ||
| 43 | - divMode为False时: | 44 | - divMode为False时: |
| 44 | 45 | ||
| 45 | $$ | 46 | $$ |
| @@ -30,6 +30,7 @@ | |||
| 30 | $$ | 30 | $$ |
| 31 | y2=round((y/scales2)+zero\_points2) | 31 | y2=round((y/scales2)+zero\_points2) |
| 32 | $$ | 32 | $$ |
| 33 | + | ||
| 33 | - divMode为False时: | 34 | - divMode为False时: |
| 34 | 35 | ||
| 35 | $$ | 36 | $$ |
| @@ -181,7 +181,7 @@ aclnnStatus aclnnMaxPool3dWithArgmaxBackward( | |||
| 181 | </tr> | 181 | </tr> |
| 182 | </tbody></table> | 182 | </tbody></table> |
| 183 | 183 | ||
| 184 | - - <term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term>、<term>Atlas A2 训练系列产品/Atlas A2 推理系列产品</term>:`indices` 数据类型不支持INT64。depth * height * width 不支持大于 max int32。 | 184 | + - <term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term>、<term>Atlas A2 训练系列产品/Atlas A2 推理系列产品</term>:`indices` 数据类型不支持INT64。depth *height* width 不支持大于 max int32。 |
| 185 | 185 | ||
| 186 | - **返回值:** | 186 | - **返回值:** |
| 187 | 187 | ||
| @@ -23,11 +23,13 @@ | |||
| 23 | $$ | 23 | $$ |
| 24 | out(N_i, C_j, d, h, w) = \max\limits_{{k\in[0,k_{D}-1],m\in[0,k_{H}-1],n\in[0,k_{W}-1]}}input(N_i,C_j,stride[0]\times d + k, stride[1]\times h + m, stride[2]\times w + n) | 24 | out(N_i, C_j, d, h, w) = \max\limits_{{k\in[0,k_{D}-1],m\in[0,k_{H}-1],n\in[0,k_{W}-1]}}input(N_i,C_j,stride[0]\times d + k, stride[1]\times h + m, stride[2]\times w + n) |
| 25 | $$ | 25 | $$ |
| 26 | + | ||
| 26 | * out tensor的shape推导公式 (默认ceilMode=false,即向下取整): | 27 | * out tensor的shape推导公式 (默认ceilMode=false,即向下取整): |
| 27 | 28 | ||
| 28 | $$ | 29 | $$ |
| 29 | [N, C, D_{out}, H_{out}, W_{out}]=[N,C,\lfloor{\frac{D_{in}+2 \times {padding[0] - dilation[0] \times(kernelSize[0] - 1) - 1}}{stride[0]}}\rfloor + 1,\lfloor{\frac{H_{in}+2 \times {padding[1] - dilation[1] \times(kernelSize[1] - 1) - 1}}{stride[1]}}\rfloor + 1, \lfloor{\frac{W_{in}+2 \times {padding[2] - dilation[2] \times(kernelSize[2] - 1) - 1}}{stride[2]}}\rfloor + 1] | 30 | [N, C, D_{out}, H_{out}, W_{out}]=[N,C,\lfloor{\frac{D_{in}+2 \times {padding[0] - dilation[0] \times(kernelSize[0] - 1) - 1}}{stride[0]}}\rfloor + 1,\lfloor{\frac{H_{in}+2 \times {padding[1] - dilation[1] \times(kernelSize[1] - 1) - 1}}{stride[1]}}\rfloor + 1, \lfloor{\frac{W_{in}+2 \times {padding[2] - dilation[2] \times(kernelSize[2] - 1) - 1}}{stride[2]}}\rfloor + 1] |
| 30 | $$ | 31 | $$ |
| 32 | + | ||
| 31 | * out tensor的shape推导公式 (默认ceilMode=true,即向上取整): | 33 | * out tensor的shape推导公式 (默认ceilMode=true,即向上取整): |
| 32 | 34 | ||
| 33 | $$ | 35 | $$ |
| @@ -18,7 +18,8 @@ | |||
| 18 | * 算子功能: | 18 | * 算子功能: |
| 19 | * 对于输入信号的输入通道,提供3维最大池化(Max pooling)操作,输出池化后的值out和索引indices。 | 19 | * 对于输入信号的输入通道,提供3维最大池化(Max pooling)操作,输出池化后的值out和索引indices。 |
| 20 | * 输入dims的描述:N - 批次,C - 通道,D - 深度,W - 宽度,H - 高度。 | 20 | * 输入dims的描述:N - 批次,C - 通道,D - 深度,W - 宽度,H - 高度。 |
| 21 | - * 当D * H * W超过int32时,建议在模型尺寸上分割D轴。 | 21 | + * 当D *H* W超过int32时,建议在模型尺寸上分割D轴。 |
| 22 | + | ||
| 22 | * 计算公式: | 23 | * 计算公式: |
| 23 | 24 | ||
| 24 | * output tensor中每个元素的计算公式: | 25 | * output tensor中每个元素的计算公式: |
| @@ -196,7 +197,7 @@ aclnnStatus aclnnMaxPool3dWithArgmax( | |||
| 196 | </tr> | 197 | </tr> |
| 197 | </tbody></table> | 198 | </tbody></table> |
| 198 | 199 | ||
| 199 | - - <term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term>、<term>Atlas A2 训练系列产品/Atlas A2 推理系列产品</term>:`dilation` 元素值仅支持为1;`indices` 数据类型不支持INT64。输入数据排布不支持NDHWC。depth * height * width 不支持大于 max int32。 | 200 | + - <term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term>、<term>Atlas A2 训练系列产品/Atlas A2 推理系列产品</term>:`dilation` 元素值仅支持为1;`indices` 数据类型不支持INT64。输入数据排布不支持NDHWC。depth*height*width 不支持大于 max int32。 |
| 200 | 201 | ||
| 201 | * **返回值**: | 202 | * **返回值**: |
| 202 | 203 | ||
| @@ -77,6 +77,7 @@ | |||
| 77 | $$ | 77 | $$ |
| 78 | 78 | ||
| 79 | 其中: | 79 | 其中: |
| 80 | + | ||
| 80 | - row_max代表每行求最大值。 | 81 | - row_max代表每行求最大值。 |
| 81 | - row_min代表每行求最小值。 | 82 | - row_min代表每行求最小值。 |
| 82 | - 当输出y类型为INT8时,scale_opt为255.0,offset_opt为127.0。 | 83 | - 当输出y类型为INT8时,scale_opt为255.0,offset_opt为127.0。 |
| @@ -24,7 +24,6 @@ | |||
| 24 | $$ | 24 | $$ |
| 25 | out = out\ |\ (scale\ \&\ 0xFFFFE000)\ |\ (1\ll46) | 25 | out = out\ |\ (scale\ \&\ 0xFFFFE000)\ |\ (1\ll46) |
| 26 | $$ | 26 | $$ |
| 27 | - | ||
| 28 | 3. 根据`offset`取值进行后续计算: | 27 | 3. 根据`offset`取值进行后续计算: |
| 29 | - 若`offset`不存在,不再进行后续计算。 | 28 | - 若`offset`不存在,不再进行后续计算。 |
| 30 | - 若`offset`存在: | 29 | - 若`offset`存在: |
| @@ -26,14 +26,13 @@ | |||
| 26 | $$ | 26 | $$ |
| 27 | scale = Round(scale) | 27 | scale = Round(scale) |
| 28 | $$ | 28 | $$ |
| 29 | - | ||
| 30 | 3. `scale`按bit位取高19位截断,存储于`out`的bit位32位处,并将46位修改为1。 | 29 | 3. `scale`按bit位取高19位截断,存储于`out`的bit位32位处,并将46位修改为1。 |
| 31 | 30 | ||
| 32 | $$ | 31 | $$ |
| 33 | out = out\ |\ (scale\ \&\ 0xFFFFE000)\ |\ (1\ll46) | 32 | out = out\ |\ (scale\ \&\ 0xFFFFE000)\ |\ (1\ll46) |
| 34 | $$ | 33 | $$ |
| 35 | - | ||
| 36 | 4. 根据`offset`取值进行后续计算: | 34 | 4. 根据`offset`取值进行后续计算: |
| 35 | + | ||
| 37 | - 若`offset`不存在,不再进行后续计算。 | 36 | - 若`offset`不存在,不再进行后续计算。 |
| 38 | - 若`offset`存在: | 37 | - 若`offset`存在: |
| 39 | 1. 将`offset`值处理为int,范围为[-256, 255]。 | 38 | 1. 将`offset`值处理为int,范围为[-256, 255]。 |
| @@ -24,8 +24,8 @@ | |||
| 24 | $$ | 24 | $$ |
| 25 | out = out\ |\ (scale\ \&\ 0xFFFFE000)\ |\ (1\ll46) | 25 | out = out\ |\ (scale\ \&\ 0xFFFFE000)\ |\ (1\ll46) |
| 26 | $$ | 26 | $$ |
| 27 | - | ||
| 28 | 3. 根据`offset`取值进行后续计算: | 27 | 3. 根据`offset`取值进行后续计算: |
| 28 | + | ||
| 29 | - 若`offset`不存在,不再进行后续计算。 | 29 | - 若`offset`不存在,不再进行后续计算。 |
| 30 | - 若`offset`存在: | 30 | - 若`offset`存在: |
| 31 | 1. 将`offset`值处理为int,范围为[-256, 255]。 | 31 | 1. 将`offset`值处理为int,范围为[-256, 255]。 |
| @@ -25,13 +25,11 @@ | |||
| 25 | $$ | 25 | $$ |
| 26 | scale = Round(scale) | 26 | scale = Round(scale) |
| 27 | $$ | 27 | $$ |
| 28 | - | ||
| 29 | 3. `scale`按bit位取高19位截断,存储于`out`的bit位32位处,并将46位修改为1。 | 28 | 3. `scale`按bit位取高19位截断,存储于`out`的bit位32位处,并将46位修改为1。 |
| 30 | 29 | ||
| 31 | $$ | 30 | $$ |
| 32 | out = out\ |\ (scale\ \&\ 0xFFFFE000)\ |\ (1\ll46) | 31 | out = out\ |\ (scale\ \&\ 0xFFFFE000)\ |\ (1\ll46) |
| 33 | $$ | 32 | $$ |
| 34 | - | ||
| 35 | 4. 根据`offset`取值进行后续计算: | 33 | 4. 根据`offset`取值进行后续计算: |
| 36 | - 若`offset`不存在,不再进行后续计算。 | 34 | - 若`offset`不存在,不再进行后续计算。 |
| 37 | - 若`offset`存在: | 35 | - 若`offset`存在: |