news 2026/5/11 7:48:33

CANN/ops-nn三维平均池化算子API文档

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CANN/ops-nn三维平均池化算子API文档

aclnnAvgPool3d

【免费下载链接】ops-nn本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。项目地址: https://gitcode.com/cann/ops-nn

产品支持情况

产品是否支持
Ascend 950PR/Ascend 950DT
Atlas A3 训练系列产品/Atlas A3 推理系列产品
Atlas A2 训练系列产品/Atlas A2 推理系列产品
Atlas 200I/500 A2 推理产品×
Atlas 推理系列产品
Atlas 训练系列产品×

功能说明

  • 接口功能:对输入Tensor进行窗口为$kD * kH * kW$、步长为$sD * sH * sW$的三维平均池化操作,其中$k$为kernelSize,表示池化窗口的大小,$s$为stride,表示池化操作的步长。

  • 计算公式: 输入input($N,C,D_{in},H_{in},W_{in}$)、输出out($N,C,D_{out},H_{out},W_{out}$)和池化步长($stride$)、池化窗口大小kernelSize($kD,kH,kW$)的关系是

    $$ D_{out}=\lfloor \frac{D_{in}+2*padding[0]-kernelSize[0]}{stride[0]}+1 \rfloor $$

    $$ H_{out}=\lfloor \frac{H_{in}+2*padding[1]-kernelSize[1]}{stride[1]}+1 \rfloor $$

    $$ W_{out}=\lfloor \frac{W_{in}+2*padding[2]-kernelSize[2]}{stride[2]}+1 \rfloor $$

    若ceilMode为true,且满足

    $$ (D_{out} - 1) * stride[0] >= D_{in} + padding[0] $$

    则D_{out}的shape需减1。H_{out},W_{out}同理。

    $$ out(N_i,C_i,d,h,w)=\frac{1}{kDkHkW}\sum_{k=0}^{kD-1}\sum_{m=0}^{kH-1}\sum_{n=0}^{kW-1}input(N_i,C_i,stride[0]*d+k,stride[1]*h+m,stride[2]*w+n) $$

函数原型

每个算子分为两段式接口,必须先调用“aclnnAvgPool3dGetWorkspaceSize”接口获取计算所需workspace大小以及包含了算子计算流程的执行器,再调用“aclnnAvgPool3d”接口执行计算。

aclnnStatus aclnnAvgPool3dGetWorkspaceSize( const aclTensor *self, const aclIntArray *kernelSize, const aclIntArray *strides, const aclIntArray *padding, bool ceilMode, bool countIncludePad, int64_t divisorOverride, aclTensor *out, uint64_t *workspaceSize, aclOpExecutor **executor)
aclnnStatus aclnnAvgPool3d( void *workspace, uint64_t workspaceSize, aclOpExecutor *executor, aclrtStream stream)

aclnnAvgPool3dGetWorkspaceSize

  • 参数说明

    参数名输入/输出描述使用说明数据类型数据格式维度(shape)非连续Tensor
    self输入正向过程中的输入,对应公式中的input。-FLOAT32、FLOAT16、BFLOAT16ND4-5
    kernelSize输入池化窗口大小,公式中的k。长度为1(KD = KH = KW)或3(KD, KH, KW),数值必须大于0且在对应的DHW维度上小于等于self的大小。INT64---
    strides输入池化操作的步长,公式中的strides。长度为0(数值与kernelSize数值保持一致)或者1(SD = SH = SW)或者3(SD, SH, SW),长度为1或3时数值必须大于0。INT64---
    padding输入在输入的D、H、W方向上padding补0的层数,公式中的paddings。长度为1(PD = PH = PW)或3(PD, PH, PW),数值在[0, kernelSize/2]的范围内。INT64---
    ceilMode输入推导的输出out的shape是否向上取整。-BOOL---
    countIncludePad输入计算平均池化时是否包括padding填充的0。-BOOL---
    divisorOverride输入取平均的除数。当值为0时,该属性不生效。INT64---
    out输出输出的tensor。-FLOAT32、FLOAT16、BFLOAT16ND4-5
    workspaceSize输出返回需要在Device侧申请的workspace大小。-----
    executor输出返回op执行器,包含了算子计算流程。-----
    • Atlas 推理系列产品 :参数self、out的数据类型不支持BFLOAT16。
  • 返回值

    aclnnStatus:返回状态码,具体参见aclnn返回码。

    第一段接口完成入参校验,出现以下场景时报错:

    返回码错误码描述
    ACLNN_ERR_PARAM_NULLPTR161001传入的self、kernelSize、stride、padding或out是空指针。
    ACLNN_ERR_PARAM_INVALID161002传入的self或out的数据类型/数据格式不在支持的范围之内。
    传入的self和out的数据类型/数据格式不一致。
    传入的stride存在某维度的值小于等于0,padding的值不在[0, kernelSize/2]的范围内。
    传入的kernelSize存在某维度的值小于等于0或大于self对应维度上的值。
    传入的kernelSize、padding的长度既不等于1也不等于3,stride的长度既不等于0、1,也不等于3。
    根据平均池化语义计算得到的输出shape与接口传入的输出shape不一致。

aclnnAvgPool3d

  • 参数说明:

    参数名输入/输出描述
    workspace输入在Device侧申请的workspace内存地址。
    workspaceSize输入在Device侧申请的workspace大小,由第一段接口aclnnAvgPool3dGetWorkspaceSize获取。
    executor输入op执行器,包含了算子计算流程。
    stream输入指定执行任务的Stream。
  • 返回值:

    aclnnStatus:返回状态码,具体参见aclnn返回码。

约束说明

  • 确定性计算:
    • aclnnAvgPool3d默认确定性实现。

调用示例

示例代码如下,仅供参考,具体编译和执行过程请参考编译与运行样例。

#include <cstdio> #include <iostream> #include <memory> #include <vector> #include "acl/acl.h" #include "aclnnop/aclnn_avgpool3d.h" #define CHECK_RET(cond, return_expr) \ do { \ if (!(cond)) { \ return_expr; \ } \ } while (0) #define CHECK_FREE_RET(cond, return_expr) \ do { \ if (!(cond)) { \ Finalize(deviceId, stream); \ return_expr; \ } \ } while (0) #define LOG_PRINT(message, ...) \ do { \ printf(message, ##__VA_ARGS__); \ } while (0) int64_t GetShapeSize(const std::vector<int64_t>& shape) { int64_t shapeSize = 1; for (auto i : shape) { shapeSize *= i; } return shapeSize; } int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclInit failed. ERROR: %d\n", ret); return ret); ret = aclrtSetDevice(deviceId); CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSetDevice failed. ERROR: %d\n", ret); return ret); ret = aclrtCreateStream(stream); CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtCreateStream failed. ERROR: %d\n", ret); return ret); return 0; } template <typename T> int CreateAclTensor(const std::vector<T>& hostData, const std::vector<int64_t>& shape, void** deviceAddr, aclDataType dataType, aclTensor** tensor) { auto size = GetShapeSize(shape) * sizeof(T); // 调用aclrtMalloc申请device侧内存 auto ret = aclrtMalloc(deviceAddr, size, ACL_MEM_MALLOC_HUGE_FIRST); CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMalloc failed. ERROR: %d\n", ret); return ret); // 调用aclrtMemcpy将host侧数据拷贝到device侧内存上 ret = aclrtMemcpy(*deviceAddr, size, hostData.data(), size, ACL_MEMCPY_HOST_TO_DEVICE); CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMemcpy failed. ERROR: %d\n", ret); return ret); // 计算连续tensor的stride std::vector<int64_t> stride(shape.size(), 1); for (int64_t i = shape.size() - 2; i >= 0; i--) { stride[i] = shape[i + 1] * stride[i + 1]; } // 调用aclCreateTensor接口创建aclTensor *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, stride.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), *deviceAddr); return 0; } void Finalize(int32_t deviceId, aclrtStream stream) { aclrtDestroyStream(stream); aclrtResetDevice(deviceId); aclFinalize(); } int aclnnAvgPool3dTest(int32_t deviceId, aclrtStream& stream) { auto ret = Init(deviceId, &stream); CHECK_FREE_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); // 2. 构造输入与输出,需要根据API的接口自定义构造 int64_t divisorOverride = 0; bool countIncludePad = true; bool ceilMode = false; std::vector<int64_t> selfShape = {1, 16, 4, 4, 4}; std::vector<int64_t> outShape = {1, 16, 1, 1, 1}; std::vector<int64_t> kernelDims = {4, 4, 4}; std::vector<int64_t> strideDims = {1, 1, 1}; std::vector<int64_t> paddingDims = {0, 0, 0}; void* selfDeviceAddr = nullptr; void* outDeviceAddr = nullptr; aclTensor* self = nullptr; aclTensor* out = nullptr; std::vector<float> selfHostData(1024, 2); std::vector<float> outHostData(16, 0); // 创建self aclTensor ret = CreateAclTensor(selfHostData, selfShape, &selfDeviceAddr, aclDataType::ACL_FLOAT, &self); std::unique_ptr<aclTensor, aclnnStatus (*)(const aclTensor *)> selfTensorPtr(self, aclDestroyTensor); std::unique_ptr<void, aclError (*)(void *)> selfDeviceAddrPtr(selfDeviceAddr, aclrtFree); CHECK_FREE_RET(ret == ACL_SUCCESS, return ret); // 创建kernel aclIntArray aclIntArray *kernelSize = aclCreateIntArray(kernelDims.data(), 3); CHECK_FREE_RET(kernelSize != nullptr, return ACL_ERROR_INTERNAL_ERROR); // 创建stride aclIntArray aclIntArray *stride = aclCreateIntArray(strideDims.data(), 3); CHECK_FREE_RET(stride != nullptr, return ACL_ERROR_INTERNAL_ERROR); // 创建padding aclIntArray aclIntArray *padding = aclCreateIntArray(paddingDims.data(), 3); CHECK_FREE_RET(padding != nullptr, return ACL_ERROR_INTERNAL_ERROR); // 创建out aclTensor ret = CreateAclTensor(outHostData, outShape, &outDeviceAddr, aclDataType::ACL_FLOAT, &out); std::unique_ptr<aclTensor, aclnnStatus (*)(const aclTensor *)> outTensorPtr(out, aclDestroyTensor); std::unique_ptr<void, aclError (*)(void *)> outDeviceAddrPtr(outDeviceAddr, aclrtFree); CHECK_FREE_RET(ret == ACL_SUCCESS, return ret); // 3. 调用CANN算子库API,需要修改为具体的Api名称 uint64_t workspaceSize = 0; aclOpExecutor* executor; // 调用aclnnAvgPool3d第一段接口 ret = aclnnAvgPool3dGetWorkspaceSize(self, kernelSize, stride, padding, ceilMode, countIncludePad, divisorOverride, out, &workspaceSize, &executor); CHECK_FREE_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnAvgPool3dGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); // 根据第一段接口计算出的workspaceSize申请device内存 void* workspaceAddr = nullptr; std::unique_ptr<void, aclError (*)(void *)> workspaceAddrPtr(nullptr, aclrtFree); if (workspaceSize > 0) { ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); CHECK_FREE_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); workspaceAddrPtr.reset(workspaceAddr); } // 调用aclnnAvgPool3d第二段接口 ret = aclnnAvgPool3d(workspaceAddr, workspaceSize, executor, stream); CHECK_FREE_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnAvgPool3d failed. ERROR: %d\n", ret); return ret); // 4. (固定写法)同步等待任务执行结束 ret = aclrtSynchronizeStream(stream); CHECK_FREE_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); // 5. 获取输出的值,将device侧内存上的结果拷贝至host侧,需要根据具体API的接口定义修改 auto size = GetShapeSize(outShape); std::vector<float> outData(size, 0); ret = aclrtMemcpy(outData.data(), outData.size() * sizeof(outData[0]), outDeviceAddr, size * sizeof(outData[0]), ACL_MEMCPY_DEVICE_TO_HOST); CHECK_FREE_RET(ret == ACL_SUCCESS, LOG_PRINT("copy result from device to host failed. ERROR: %d\n", ret); return ret); for (int64_t i = 0; i < size; i++) { LOG_PRINT("out result[%ld] is: %f\n", i, outData[i]); } return ACL_SUCCESS; } int main() { // 1. (固定写法)device/stream初始化,参考acl API手册 // 根据自己的实际device填写deviceId int32_t deviceId = 0; aclrtStream stream; auto ret = aclnnAvgPool3dTest(deviceId, stream); CHECK_FREE_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnAvgPool3dTest failed. ERROR: %d\n", ret); return ret); Finalize(deviceId, stream); return 0; }

【免费下载链接】ops-nn本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。项目地址: https://gitcode.com/cann/ops-nn

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/11 7:47:03

CANN/asc-devkit自然对数API文档

Ln 【免费下载链接】asc-devkit 本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言&#xff0c;原生支持C和C标准规范&#xff0c;主要由类库和语言扩展层构成&#xff0c;提供多层级API&#xff0c;满足多维场景算子开发诉求。 项目地址: https://gitcode.com/cann/as…

作者头像 李华
网站建设 2026/5/11 7:44:49

昇腾C倒数函数API文档

Reciprocal 【免费下载链接】asc-devkit 本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言&#xff0c;原生支持C和C标准规范&#xff0c;主要由类库和语言扩展层构成&#xff0c;提供多层级API&#xff0c;满足多维场景算子开发诉求。 项目地址: https://gitcode.com…

作者头像 李华
网站建设 2026/5/11 7:37:32

sdrtrunk完全配置教程:10个关键设置优化你的SDR性能

sdrtrunk完全配置教程&#xff1a;10个关键设置优化你的SDR性能 【免费下载链接】sdrtrunk A cross-platform java application for decoding, monitoring, recording and streaming trunked mobile and related radio protocols using Software Defined Radios (SDR). Website…

作者头像 李华
网站建设 2026/5/11 7:31:57

3步快速部署GitHub中文化插件:告别英文界面的烦恼

3步快速部署GitHub中文化插件&#xff1a;告别英文界面的烦恼 【免费下载链接】github-chinese GitHub 汉化插件&#xff0c;GitHub 中文化界面。 (GitHub Translation To Chinese) 项目地址: https://gitcode.com/gh_mirrors/gi/github-chinese 你是否曾经因为GitHub的…

作者头像 李华