CANN Runtime 内建任务实战指南:Reduce 归约与随机数生成的异步下发(aclrtReduceAsync / aclrtRandomNumAsync)
2026/9/18 14:50:06 网站建设 项目流程

CANN Runtime 内建任务实战指南:Reduce 归约与随机数生成的异步下发(aclrtReduceAsync / aclrtRandomNumAsync)

【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime

CANN Runtime 将归约(Reduce)、随机数生成等高频计算能力封装为内建任务(built-in task),应用可以直接通过aclrtReduceAsyncaclrtRandomNumAsync等 API 在 Stream 上异步下发,无需自行编写并编译算子内核,即可在 Device 侧完成数据归约与多分布随机数生成。本文基于本仓库example/2_advanced_features/built_in_task目录下的两个可运行样例,完整讲解这两类内建任务的使用流程、核心 API 结构体与参数语义、随机数算法与内存要求,并结合include/external/acl/acl_rt.h等源码级定义验证其底层接口契约。读完本文,你可以直接复现 Reduce 求和样例与五类随机数生成样例,并掌握在自有程序中正确组装aclrtRandomNumTaskInfo下发随机数任务的完整方法。

一、内建任务是什么

在 CANN 的编程模型中,绝大多数 Device 侧计算以**算子内核(Kernel)**形式下发:应用侧编译或加载内核二进制,再通过 Stream 提交执行。而内建任务是 Runtime 预先内置在 Device 侧的一类特殊任务,无需用户提供内核代码,只需通过几个专用 API 描述任务参数,即可完成一类标准化的数据操作。

example/2_advanced_features/built_in_task目录正是围绕这一能力组织样例的,包含两个子样例:

样例目录演示能力核心 API
0_reduce_taskReduce 任务的下发与结果读取(数组求和)aclrtReduceAsync
1_random_num_task随机数任务的下发与多分布生成aclrtRandomNumAsync

两者共用同一套"初始化 → 设置 Device → 创建 Stream → 申请/拷贝内存 → 异步下发 → 同步 → 拷回结果 → 释放资源"的标准 Runtime 流程,差异只在于任务本身的参数组装方式。

二、产品支持情况

两个内建任务样例在产品上的支持情况略有差异,下表可直接作为选型参考:

产品Reduce 任务(0_reduce_task)随机数任务(1_random_num_task)
Ascend 950PR / Ascend 950DT×
Atlas A3 训练系列产品 / Atlas A3 推理系列产品
Atlas A2 训练系列产品 / Atlas A2 推理系列产品

可以看到,随机数任务目前在 Ascend 950PR / Ascend 950DT 上暂不支持,在 Atlas A2 / A3 系列上两类任务均可运行。开发前请先核对目标硬件型号。

三、Reduce 归约任务

3.1 功能概述

归约(Reduce)是并行计算中的常见操作,对数组元素执行求和、求最大值、求最小值等聚合运算。在深度学习中,归约被广泛用于 loss 计算、梯度聚合、attention 内部的归一化统计等场景。通过aclrtReduceAsync,应用可以在不编写内核的情况下,把这段计算直接交给 Device 侧完成。

3.2 核心 API:aclrtReduceAsync

该 API 的原型在 include/external/acl/acl_rt.h 中声明:

ACL_FUNC_VISIBILITY aclError aclrtReduceAsync( void* dst, const void* src, uint64_t count, aclrtReduceKind kind, aclDataType type, aclrtStream stream, void* reserve);

各参数说明:

参数说明
dst输出地址,指向 Device 内存中存放归约结果的位置
src输入地址,指向 Device 内存中的源数据
count数据大小,单位为字节(注意不是元素个数,样例中传入count * sizeof(float)
kind归约类型,取值为aclrtReduceKind枚举
type输入/输出的数据类型,取值为aclDataType(如ACL_FLOAT
stream任务下发所在的 Stream
reserve预留参数,当前传NULL

返回ACL_SUCCESS表示调用成功,其他值表示失败;该调用本身是异步的,任务真正执行完成需要配合aclrtSynchronizeStream等待。

3.3 归约类型:aclrtReduceKind

aclrtReduceKind枚举定义在 include/external/acl/acl_rt.h:

typedef enum { ACL_RT_MEMCPY_SDMA_AUTOMATIC_SUM = 10, // 自动求和(前缀和) ACL_RT_MEMCPY_SDMA_AUTOMATIC_MAX = 11, // 求最大值 ACL_RT_MEMCPY_SDMA_AUTOMATIC_MIN = 12, // 求最小值 ACL_RT_MEMCPY_SDMA_AUTOMATIC_EQUAL = 13, // 相等比较 } aclrtReduceKind;

从源码结构看,归约能力与 Runtime 的 SDMA(数据搬运引擎)自动模式绑定,因此这组枚举沿用了ACL_RT_MEMCPY_SDMA_AUTOMATIC_*的命名风格。Reduce 样例使用的ACL_RT_MEMCPY_SDMA_AUTOMATIC_SUM执行的是前缀和(扫描求和):输出数组的第 i 个元素等于输入数组前 i+1 个元素之和,而不是简单的单值归约——这正是样例输出中结果呈现递增累加的原因。

3.4 完整代码流程解析

样例主体见 0_reduce_task/main.cpp,完整流程如下:

#include <acl/acl.h> #include "utils.h" int main() { aclError ret; // 1. 初始化 ACL CHECK_ERROR(aclInit(NULL)); // 2. 指定用于运算的 Device CHECK_ERROR(aclrtSetDevice(0)); // 3. 创建 Stream aclrtStream stream; CHECK_ERROR(aclrtCreateStream(&stream)); // 4. 准备 Host 数据(4 个 float 元素) const int count = 4; float hostInput[4] = {1.0, 2.0, 3.0, 4.0}; float hostOutput[4] = {0, 0, 0, 0}; size_t size = count * sizeof(float); // 5. 申请 Device 内存 void* devInput = NULL; void* devOutput = NULL; CHECK_ERROR(aclrtMalloc(&devInput, size, ACL_MEM_MALLOC_HUGE_FIRST)); CHECK_ERROR(aclrtMalloc(&devOutput, size, ACL_MEM_MALLOC_HUGE_FIRST)); // 6. 拷贝数据到 Device CHECK_ERROR(aclrtMemcpy(devInput, size, hostInput, size, ACL_MEMCPY_HOST_TO_DEVICE)); CHECK_ERROR(aclrtMemcpy(devOutput, size, hostInput, size, ACL_MEMCPY_HOST_TO_DEVICE)); // 7. 异步下发 Reduce 任务(前缀和) ret = aclrtReduceAsync( devOutput, devInput, size, ACL_RT_MEMCPY_SDMA_AUTOMATIC_SUM, // 归约类型 ACL_FLOAT, // 数据类型 stream, NULL); CHECK_ERROR(ret); // 8. 同步等待 Stream 上的任务执行完成 CHECK_ERROR(aclrtSynchronizeStream(stream)); // 9. 将结果拷回 Host CHECK_ERROR(aclrtMemcpy(hostOutput, size, devOutput, size, ACL_MEMCPY_DEVICE_TO_HOST)); // 10. 打印结果 for (int i = 0; i < count; i++) { printf("Reduce SUM result[%d] = %f\n", i, hostOutput[i]); } // 11. 释放资源 aclrtFree(devInput); aclrtFree(devOutput); aclrtDestroyStream(stream); aclrtResetDeviceForce(0); aclFinalize(); return 0; }

代码中的CHECK_ERROR宏来自 example/utils.h,它检查aclError返回值,非ACL_SUCCESS时打印错误信息并退出,是样例统一的错误处理方式。

几个值得注意的工程细节:

  • aclrtResetDeviceForce用于强制复位当前运算的 Device 并回收其上的资源,与普通释放相比更彻底,适合样例这种一次性运行的场景。
  • dstsrc指向同一块内存(或内容相同)是允许的:样例先把devOutput也填成输入值,再把归约结果写回devOutput,读者可以观察这种原地覆盖式用法。
  • count的单位是字节,若元素是 float(4 字节),4 个元素即 16 字节。

3.5 示例输出

运行0_reduce_task后,预期输出如下(对应{1, 2, 3, 4}的前缀和序列):

Reduce SUM result[0] = 2.000000 Reduce SUM result[1] = 4.000000 Reduce SUM result[2] = 6.000000 Reduce SUM result[3] = 8.000000 [INFO] Sample run successfully.

注意result[0]的值为 2.0 而不是 1.0,这是因为样例在dst中预先放置了与输入相同的内容,前缀和从输入首元素开始累加,因此result[0] = 1.0(原值) + 1.0(输入首元素)= 2.0,其余元素依此类推。若希望得到{1, 3, 6, 10}的纯前缀和结果,可将devOutput初始化为全 0(参考随机数样例中aclrtMemset清零的做法)。

四、随机数生成任务

4.1 功能概述

aclrtRandomNumAsync是 Runtime 提供的另一类内建任务:在 Device 侧直接生成指定分布、指定类型的随机数,并支持生成 Dropout 所需的 bitmask。它支持均匀分布、正态分布、截断正态分布与 Dropout bitmask 四种函数类型,且无需用户编写内核代码,非常适合初始化阶段的大规模随机数填充(如权重初始化、mask 生成)。

4.2 核心 API:aclrtRandomNumAsync

该 API 原型声明于 include/external/acl/acl_rt.h:

ACL_FUNC_VISIBILITY aclError aclrtRandomNumAsync( const aclrtRandomNumTaskInfo* taskInfo, const aclrtStream stream, void* reserve);
参数说明
taskInfo随机数任务信息,见下文aclrtRandomNumTaskInfo结构体
stream任务下发所在的 Stream
reserve预留字段,当前传NULL

aclrtReduceAsync的"位置参数"风格不同,随机数任务的所有信息通过一个结构体聚合传递,因此参数组装是关键。

4.3 任务信息结构体:aclrtRandomNumTaskInfo

aclrtRandomNumTaskInfo定义在 include/external/acl/acl_rt.h:

typedef struct { aclDataType dataType; aclrtRandomNumFuncParaInfo randomNumFuncParaInfo; void *randomParaAddr; void *randomResultAddr; void *randomCounterAddr; aclrtRandomParaInfo randomSeed; aclrtRandomParaInfo randomNum; uint8_t rsv[10]; } aclrtRandomNumTaskInfo;

字段语义如下:

字段说明
dataType随机数的数据类型(ACL_FLOATACL_FLOAT16ACL_BF16及整数类型等)
randomNumFuncParaInfo函数类型标识与分布参数(见 4.4)
randomParaAddr分布参数所在设备地址;样例中参数直接内嵌在结构体中,此处传NULL
randomResultAddr输出缓冲区(Device 地址),存放生成的随机数
randomCounterAddr随机数状态计数器(Counter)的 Device 地址,固定 16 字节
randomSeed随机种子,aclrtRandomParaInfo封装(见 4.5)
randomNum生成的随机数个数,aclrtRandomParaInfo封装
rsv[10]预留字节,置 0 即可

4.4 函数类型与分布参数:aclrtRandomNumFuncParaInfo

函数类型枚举与参数联合体定义在 include/external/acl/acl_rt.h:

typedef enum { ACL_RT_RANDOM_NUM_FUNC_TYPE_DROPOUT_BITMASK = 0, // dropout bitmask ACL_RT_RANDOM_NUM_FUNC_TYPE_UNIFORM_DIS, // uniform distribution ACL_RT_RANDOM_NUM_FUNC_TYPE_NORMAL_DIS, // normal distribution ACL_RT_RANDOM_NUM_FUNC_TYPE_TRUNCATED_NORMAL_DIS, // truncated normal distribution } aclrtRandomNumFuncType; typedef struct { aclrtRandomNumFuncType funcType; union { aclrtDropoutBitmaskInfo dropoutBitmaskInfo; aclrtUniformDisInfo uniformDisInfo; aclrtNormalDisInfo normalDisInfo; } paramInfo; } aclrtRandomNumFuncParaInfo;

其中分布参数结构体(acl_rt.h):

// dropout bitmask typedef struct { aclrtRandomParaInfo dropoutRation; } aclrtDropoutBitmaskInfo; // uniform distribution typedef struct { aclrtRandomParaInfo min; aclrtRandomParaInfo max; } aclrtUniformDisInfo; // normal distribution typedef struct { aclrtRandomParaInfo mean; aclrtRandomParaInfo stddev; } aclrtNormalDisInfo;

4.5 参数封装:aclrtRandomParaInfo

分布参数、种子、数量统一用aclrtRandomParaInfo封装,定义在 include/external/acl/acl_rt.h:

typedef struct { uint8_t isAddr; uint8_t valueOrAddr[8]; uint8_t size; uint8_t rsv[6]; } aclrtRandomParaInfo;
  • isAddr:0 表示valueOrAddr中直接存放立即值,非 0 表示valueOrAddr中存放设备内存地址(参数在 Device 内存中);
  • valueOrAddr[8]:8 字节缓冲区,既可作为立即值的存储区,也可作为地址使用;
  • size:参数字节数;
  • rsv[6]:预留。

样例中所有参数均采用立即值方式(isAddr = 0),例如 1_random_num_task/main.cpp 中组装均匀分布参数:

*((float*)taskInfo.randomNumFuncParaInfo.paramInfo.uniformDisInfo.min.valueOrAddr) = min; taskInfo.randomNumFuncParaInfo.paramInfo.uniformDisInfo.min.size = sizeof(float); taskInfo.randomNumFuncParaInfo.paramInfo.uniformDisInfo.min.isAddr = 0;

4.6 支持的分布类型与数据类型

(1)均匀分布(Uniform Distribution)

  • 函数类型标识:ACL_RT_RANDOM_NUM_FUNC_TYPE_UNIFORM_DIS
  • 支持数据类型:浮点ACL_FLOATACL_FLOAT16ACL_BF16;整数ACL_INT32ACL_INT64ACL_UINT32ACL_UINT64
  • 参数:min(最小值)、max(最大值)

(2)正态分布(Normal Distribution)

  • 函数类型标识:ACL_RT_RANDOM_NUM_FUNC_TYPE_NORMAL_DIS
  • 支持数据类型:ACL_FLOATACL_FLOAT16ACL_BF16
  • 参数:mean(均值)、stddev(标准差)

(3)截断正态分布(Truncated Normal Distribution)

  • 函数类型标识:ACL_RT_RANDOM_NUM_FUNC_TYPE_TRUNCATED_NORMAL_DIS
  • 支持数据类型:ACL_FLOATACL_FLOAT16ACL_BF16
  • 参数:mean(均值)、stddev(标准差)

(4)Dropout Bitmask 生成

  • 用于生成随机失活(Dropout)的 bit mask,按比例生成
  • 函数类型标识:ACL_RT_RANDOM_NUM_FUNC_TYPE_DROPOUT_BITMASK
  • 参数:ratio(dropout 比例,支持数据类型ACL_FLOATACL_FLOAT16ACL_BF16

4.7 随机数算法

算法特性
Philox4_32_10支持所有分布类型;Counter 为 128bit,需要 16Byte 存储

Philox4_32_10是一种基于计数器(counter-based)的伪随机数生成算法:给定 seed 与 counter 即可确定性地产出随机序列。由于是 counter-based 算法,同一个 seed 下改变 counter 可以并行生成互不重叠的随机序列,这对大规模并行初始化非常重要;同时它也要求用户为每个任务维护独立的 counter 状态(见 4.8)。

4.8 内存要求

根据文档与样例实现,随机数任务需要三类 Device 内存:

  1. Counter 内存:固定 16 字节,任意字节对齐地址即可。样例中先申请再清零:
    constexpr size_t kCounterSize = 16U; void* counterAddr = nullptr; CHECK_ERROR(aclrtMalloc(&counterAddr, kCounterSize, ACL_MEM_MALLOC_HUGE_FIRST)); CHECK_ERROR(aclrtMemset(counterAddr, kCounterSize, 0, kCounterSize));
  2. 输出内存:根据数据类型和随机数数量动态分配。样例申请num * sizeof(uint64_t)作为"足够大"的输出缓冲,以容纳不同位宽的结果:
    uint64_t num = 128; size_t size = num * sizeof(uint64_t); CHECK_ERROR(aclrtMalloc(&devOutput, size, ACL_MEM_MALLOC_HUGE_FIRST));
  3. 参数内存:均值、标准差、范围等参数既可使用立即值(内嵌在结构体的valueOrAddr中),也可使用设备内存(isAddr = 1valueOrAddr存地址)。样例统一使用立即值方式。

4.9 完整代码流程解析

随机数样例的完整骨架见 1_random_num_task/main.cpp,其任务下发模式如下(以正态分布 float 为例):

aclError NormalFloatAsync( float mean, float stddev, bool isTruncated, uint64_t seed, uint64_t num, void* counterDevAddr, void* devOutput, aclrtStream stream) { aclrtRandomNumTaskInfo taskInfo = {}; taskInfo.dataType = ACL_FLOAT; taskInfo.randomNumFuncParaInfo.funcType = isTruncated ? ACL_RT_RANDOM_NUM_FUNC_TYPE_TRUNCATED_NORMAL_DIS : ACL_RT_RANDOM_NUM_FUNC_TYPE_NORMAL_DIS; taskInfo.randomParaAddr = NULL; taskInfo.randomCounterAddr = counterDevAddr; taskInfo.randomResultAddr = devOutput; *((float*)taskInfo.randomNumFuncParaInfo.paramInfo.normalDisInfo.mean.valueOrAddr) = mean; taskInfo.randomNumFuncParaInfo.paramInfo.normalDisInfo.mean.size = sizeof(float); taskInfo.randomNumFuncParaInfo.paramInfo.normalDisInfo.mean.isAddr = 0; *((float*)taskInfo.randomNumFuncParaInfo.paramInfo.normalDisInfo.stddev.valueOrAddr) = stddev; taskInfo.randomNumFuncParaInfo.paramInfo.normalDisInfo.stddev.size = sizeof(float); taskInfo.randomNumFuncParaInfo.paramInfo.normalDisInfo.stddev.isAddr = 0; *((uint64_t*)taskInfo.randomSeed.valueOrAddr) = seed; taskInfo.randomSeed.size = sizeof(uint64_t); taskInfo.randomSeed.isAddr = 0; *((uint64_t*)taskInfo.randomNum.valueOrAddr) = num; taskInfo.randomNum.size = sizeof(uint64_t); taskInfo.randomNum.isAddr = 0; return aclrtRandomNumAsync(&taskInfo, stream, NULL); }

主程序依次生成五组随机数并打印前 5 个结果,每组之间均执行"同步 Stream → 拷回 Host → 打印":

INFO_LOG("Generate normal distribution random numbers, data type: float"); float mean = 3.0; float stddev = 2.0; CHECK_ERROR(NormalFloatAsync(mean, stddev, false, seed, num, counterAddr, devOutput, stream)); CHECK_ERROR(aclrtSynchronizeStream(stream)); CHECK_ERROR(aclrtMemcpy(hostOutput.get(), size, devOutput, size, ACL_MEMCPY_DEVICE_TO_HOST));

半精度类型(FP16 / BF16)在样例中直接以uint16_t表示并采用十六进制字面量构造数值,例如0x3F80即 BF16 的 1.0、0x4000即 2.0,打印时使用%#x

BF16 meanBF16 = 0x3F80; // bf16(1.0) BF16 stddevBF16 = 0x4000; // bf16(2.0) CHECK_ERROR(NormalBF16Async(meanBF16, stddevBF16, true, seed, num, counterAddr, devOutput, stream));

Dropout bitmask 生成与分布生成共用同一套接口,区别仅在于funcType改为ACL_RT_RANDOM_NUM_FUNC_TYPE_DROPOUT_BITMASK,并填充dropoutBitmaskInfo.dropoutRation

float ration = 0.4; CHECK_ERROR(DropoutBitmask(ration, seed, num, counterAddr, devOutput, stream));

4.10 示例输出

运行1_random_num_task后,预期输出结构如下(随机数值随种子不同而变化):

[INFO] Generate normal distribution random numbers, data type: float Random result[0] = ... ... [INFO] Generate truncated normal distribution random numbers, data type: BF16 Random result[0] = ... ... [INFO] Generate uniform distribution random numbers, data type: FP16 Random result[0] = ... ... [INFO] Generate uniform distribution random numbers, data type: INT32 Random result[0] = ... ... [INFO] Generate dropout bitmask, output data type: UINT8 Random result[0] = ... [INFO] Sample run successfully.

五、编译与运行

5.1 前置环境

  • 已安装 CANN 软件包(默认安装根目录为/usr/local/Ascend);
  • 目标 Device 符合上文的"产品支持情况";
  • 样例代码位于仓库 example/2_advanced_features/built_in_task 目录下,编译依赖头文件与acl_rt库(CANN 安装包自带)。

5.2 编译运行步骤

在任意一个样例目录下执行:

# ${install_root} 替换为 CANN 安装根目录,默认安装在 /usr/local/Ascend source ${install_root}/cann/set_env.sh export ASCEND_INSTALL_PATH=${install_root}/cann # 编译并运行 bash run.sh

环境安装详情与运行详情也可参见 example/README.md。

5.3 run.sh 脚本解析

两个样例的 run.sh 完全一致,核心流程为:

set -e # 获取 CANN 安装路径 _ASCEND_INSTALL_PATH=$ASCEND_INSTALL_PATH source $_ASCEND_INSTALL_PATH/bin/setenv.bash # 在脚本所在目录创建 build 目录并进入 BUILD_DIR="${SCRIPT_DIR}/build" mkdir -p "${BUILD_DIR}" cd "${BUILD_DIR}" # 执行 cmake 配置 cmake .. -DASCEND_CANN_PACKAGE_PATH=${_ASCEND_INSTALL_PATH} # 编译 make -j$(nproc) # 运行生成的可执行文件 ./build/main

注意:脚本依赖ASCEND_INSTALL_PATH环境变量,这正是 5.2 中先export ASCEND_INSTALL_PATH=${install_root}/cann的原因。

5.4 CMake 配置要点

样例的 CMakeLists.txt 结构简洁,可供自有工程参考:

cmake_minimum_required(VERSION 3.16.0) project(Reduce_Sample) # 随机数样例为 Random_Num_Sample include_directories(${ASCEND_CANN_PACKAGE_PATH}/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../..) # 引入 example/utils.h link_directories(${ASCEND_CANN_PACKAGE_PATH}/lib64) add_executable(main main.cpp) target_compile_options(main PRIVATE -O2 -std=c++17 -D_GLIBCXX_USE_CXX11_ABI=0 -Wall -Werror ) target_link_libraries(main PRIVATE acl_rt )

要点解读:

  • 头文件搜索路径指向 CANN 安装包的include目录,运行时库搜索路径指向lib64,链接库为acl_rt
  • -D_GLIBCXX_USE_CXX11_ABI=0与 CANN 发行库的 ABI 保持一致,避免链接期符号不匹配;
  • -Wall -Werror将警告升级为错误,保证样例代码的严格性;
  • 额外 include 到example顶层目录,是为了使用 example/utils.h 中定义的CHECK_ERRORINFO_LOG宏。

六、接口契约的源码级印证

上文涉及的核心类型与函数均可在公开头文件中找到权威定义,可作为编写自有程序时的接口契约依据:

  • aclrtReduceAsync原型:include/external/acl/acl_rt.h
  • aclrtReduceKind枚举(SUM/MAX/MIN/EQUAL):include/external/acl/acl_rt.h
  • aclrtRandomNumAsync原型:include/external/acl/acl_rt.h
  • aclrtRandomNumTaskInfo结构体:include/external/acl/acl_rt.h
  • aclrtRandomNumFuncType枚举与分布参数联合体:include/external/acl/acl_rt.h
  • aclrtRandomParaInfo参数封装:include/external/acl/acl_rt.h
  • aclrtReduceAsync的 Host 侧实现位于 src/acl/aclrt_impl/memory.cpp,可据此进一步追踪其任务封装与下发的底层调用链。

七、注意事项与已知问题

  • 字节单位aclrtReduceAsynccount参数是字节数而非元素个数,组装参数时务必乘以sizeof(type)
  • Counter 唯一性:随机数任务要求 Counter 为固定 16 字节、任意字节对齐的 Device 内存,多次下发需保证 Counter 状态连续正确(样例在首次使用前通过aclrtMemset清零);从源码结构看,不同任务/不同线程若复用同一 Counter,需自行保证串行化或管理好状态;
  • 半精度字面量:FP16/BF16 参数需要以二进制位模式(十六进制)构造,切勿直接赋浮点常量;
  • 产品差异:随机数任务在 Ascend 950PR/Ascend 950DT 上不支持,Reduce 任务在三个产品系列上均支持;
  • 异步语义:两个 API 均为异步下发,读取结果前必须调用aclrtSynchronizeStream等待任务完成,否则可能读到未就绪的数据;
  • 已知 issue:截至当前仓库版本,两个样例均标注"暂无"已知 issue。

总体而言,Reduce 与随机数生成是 Runtime 内建任务中最具代表性的两类能力:前者展示了"一个枚举+一次调用"即完成标准聚合计算,后者展示了"结构体聚合描述任务"的复杂参数传递模式。掌握这两类任务的组装方式后,迁移到其他内建任务时只需替换对应的 API 与参数结构,流程骨架完全一致。

【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询