已合并
aclnnGlobalMaxPool 新资料模板修改 #2163
sunchun创建于 4月10日
aclnnGlobalMaxPool 新资料模板修改 #2163
已合并
从已删除 :aclnnglobalmaxpool合入到cann/ops-mathmaster
共 1 个文件变更+199-141
| @@ -15,37 +15,106 @@ | |||
| 15 | 15 | ||
| 16 | ## 功能说明 | 16 | ## 功能说明 |
| 17 | 17 | ||
| 18 | -输入一个张量,并对同一通道中的值取最大值 | 18 | +输入一个张量,并对同一通道中的值取最大值。 |
| 19 | 19 | ||
| 20 | ## 函数原型 | 20 | ## 函数原型 |
| 21 | 21 | ||
| 22 | -每个算子分为[两段式接口](../../../docs/zh/context/两段式接口.md),必须先调用“aclnnGlobalMaxPoolGetWorkspaceSize”接口获取计算所需workspace大小以及包含了算子计算流程的执行器,再调用“aclnnGlobalMaxPool”接口执行计算。 | 22 | +每个算子分为[两段式接口](../../../docs/zh/context/两段式接口.md),必须先调用"aclnnGlobalMaxPoolGetWorkspaceSize"接口获取计算所需workspace大小以及包含了算子计算流程的执行器,再调用"aclnnGlobalMaxPool"接口执行计算。 |
| 23 | 23 | ||
| 24 | -- `aclnnStatus aclnnGlobalMaxPoolGetWorkspaceSize(const aclTensor* self, aclTensor* out, uint64_t* workspaceSize, aclOpExecutor** executor)` | 24 | +```Cpp |
| 25 | -- `aclnnStatus aclnnGlobalMaxPool(void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, const aclrtStream stream)` | 25 | +aclnnStatus aclnnGlobalMaxPoolGetWorkspaceSize( |
| 26 | + const aclTensor* self, | ||
| 27 | + aclTensor* out, | ||
| 28 | + uint64_t* workspaceSize, | ||
| 29 | + aclOpExecutor** executor) | ||
| 30 | +``` | ||
| 31 | + | ||
| 32 | +```Cpp | ||
| 33 | +aclnnStatus aclnnGlobalMaxPool( | ||
| 34 | + void* workspace, | ||
| 35 | + uint64_t workspaceSize, | ||
| 36 | + aclOpExecutor* executor, | ||
| 37 | + const aclrtStream stream) | ||
| 38 | +``` | ||
| 26 | 39 | ||
| 27 | ## aclnnGlobalMaxPoolGetWorkspaceSize | 40 | ## aclnnGlobalMaxPoolGetWorkspaceSize |
| 28 | 41 | ||
| 29 | - **参数说明:** | 42 | - **参数说明:** |
| 30 | 43 | ||
| 31 | - - self(aclTensor*, 计算输入):Device侧的aclTensor,数据类型支持FLOAT、FLOAT16、DOUBLE。支持[非连续的Tensor](../../../docs/zh/context/非连续的Tensor.md),[数据格式](../../../docs/zh/context/数据格式.md)支持ND、NCHW、NCDHW。 | 44 | + <table style="undefined;table-layout: fixed; width: 1555px"><colgroup> |
| 45 | + <col style="width: 217px"> | ||
| 46 | + <col style="width: 125px"> | ||
| 47 | + <col style="width: 247px"> | ||
| 48 | + <col style="width: 317px"> | ||
| 49 | + <col style="width: 233px"> | ||
| 50 | + <col style="width: 126px"> | ||
| 51 | + <col style="width: 144px"> | ||
| 52 | + <col style="width: 146px"> | ||
| 53 | + </colgroup> | ||
| 54 | + <thead> | ||
| 55 | + <tr> | ||
| 56 | + <th>参数名</th> | ||
| 57 | + <th>输入/输出</th> | ||
| 58 | + <th>描述</th> | ||
| 59 | + <th>使用说明</th> | ||
| 60 | + <th>数据类型</th> | ||
| 61 | + <th>数据格式</th> | ||
| 62 | + <th>维度(shape)</th> | ||
| 63 | + <th>非连续Tensor</th> | ||
| 64 | + </tr></thead> | ||
| 65 | + <tbody> | ||
| 66 | + <tr> | ||
| 67 | + <td>self(aclTensor*)</td> | ||
| 68 | + <td>输入</td> | ||
| 69 | + <td>输入tensor。</td> | ||
| 70 | + <td>-</td> | ||
| 71 | + <td>FLOAT、FLOAT16、DOUBLE</td> | ||
| 72 | + <td>ND、NCHW、NCDHW</td> | ||
| 73 | + <td>4-8维</td> | ||
| 74 | + <td>√</td> | ||
| 75 | + </tr> | ||
| 76 | + <tr> | ||
| 77 | + <td>out(aclTensor*)</td> | ||
| 78 | + <td>输出</td> | ||
| 79 | + <td>输出tensor。</td> | ||
| 80 | + <td>需要与self数据类型相同。out前两维与self相同,其他维度均为1。</td> | ||
| 81 | + <td>FLOAT、FLOAT16、DOUBLE</td> | ||
| 82 | + <td>ND、NCHW、NCDHW</td> | ||
| 83 | + <td>4-8维</td> | ||
| 84 | + <td>√</td> | ||
| 85 | + </tr> | ||
| 86 | + <tr> | ||
| 87 | + <td>workspaceSize(uint64_t*)</td> | ||
| 88 | + <td>输出</td> | ||
| 89 | + <td>返回需要在Device侧申请的workspace大小。</td> | ||
| 90 | + <td>-</td> | ||
| 91 | + <td>-</td> | ||
| 92 | + <td>-</td> | ||
| 93 | + <td>-</td> | ||
| 94 | + <td>-</td> | ||
| 95 | + </tr> | ||
| 96 | + <tr> | ||
| 97 | + <td>executor(aclOpExecutor**)</td> | ||
| 98 | + <td>输出</td> | ||
| 99 | + <td>返回op执行器,包含了算子计算流程。</td> | ||
| 100 | + <td>-</td> | ||
| 101 | + <td>-</td> | ||
| 102 | + <td>-</td> | ||
| 103 | + <td>-</td> | ||
| 104 | + <td>-</td> | ||
| 105 | + </tr> | ||
| 106 | + </tbody></table> | ||
| 32 | 107 | ||
| 33 | - - out(aclTensor*, 计算输出):Device侧的aclTensor,数据类型支持FLOAT、FLOAT16、DOUBLE。支持[非连续的Tensor](../../../docs/zh/context/非连续的Tensor.md),[数据格式](../../../docs/zh/context/数据格式.md)支持ND、NCHW、NCDHW。 | 108 | +- **返回值:** |
| 34 | - | ||
| 35 | - - workspaceSize(uint64_t*, 出参):返回需要在Device侧申请的workspace大小。 | ||
| 36 | - | ||
| 37 | - - executor(aclOpExecutor**, 出参):返回op执行器,包含了算子计算流程。 | ||
| 38 | - | ||
| 39 | -- **返回码:** | ||
| 40 | 109 | ||
| 41 | aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 | 110 | aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 |
| 42 | 111 | ||
| 43 | - 第一段接口完成入参校验,出现以下场景时报错: | 112 | + 第一段接口完成入参校验,出现如下场景时报错: |
| 44 | 113 | ||
| 45 | <table style="undefined;table-layout: fixed; width: 1150px"><colgroup> | 114 | <table style="undefined;table-layout: fixed; width: 1150px"><colgroup> |
| 46 | - <col style="width: 287px"> | 115 | + <col style="width: 300px"> |
| 47 | - <col style="width: 124px"> | 116 | + <col style="width: 134px"> |
| 48 | - <col style="width: 739px"> | 117 | + <col style="width: 716px"> |
| 49 | </colgroup> | 118 | </colgroup> |
| 50 | <thead> | 119 | <thead> |
| 51 | <tr> | 120 | <tr> |
| @@ -57,7 +126,7 @@ | |||
| 57 | <tr> | 126 | <tr> |
| 58 | <td>ACLNN_ERR_PARAM_NULLPTR</td> | 127 | <td>ACLNN_ERR_PARAM_NULLPTR</td> |
| 59 | <td>161001</td> | 128 | <td>161001</td> |
| 60 | - <td>传入的self和out是空指针。</td> | 129 | + <td>传入的self或out是空指针。</td> |
| 61 | </tr> | 130 | </tr> |
| 62 | <tr> | 131 | <tr> |
| 63 | <td rowspan="3">ACLNN_ERR_PARAM_INVALID</td> | 132 | <td rowspan="3">ACLNN_ERR_PARAM_INVALID</td> |
| @@ -77,10 +146,10 @@ | |||
| 77 | 146 | ||
| 78 | - **参数说明:** | 147 | - **参数说明:** |
| 79 | 148 | ||
| 80 | - <table style="undefined;table-layout: fixed; width: 1149px"><colgroup> | 149 | + <table style="undefined;table-layout: fixed; width: 1151px"><colgroup> |
| 81 | - <col style="width: 167px"> | 150 | + <col style="width: 184px"> |
| 82 | <col style="width: 134px"> | 151 | <col style="width: 134px"> |
| 83 | - <col style="width: 848px"> | 152 | + <col style="width: 833px"> |
| 84 | </colgroup> | 153 | </colgroup> |
| 85 | <thead> | 154 | <thead> |
| 86 | <tr> | 155 | <tr> |
| @@ -112,7 +181,7 @@ | |||
| 112 | </tbody> | 181 | </tbody> |
| 113 | </table> | 182 | </table> |
| 114 | 183 | ||
| 115 | -- **返回码:** | 184 | +- **返回值:** |
| 116 | 185 | ||
| 117 | aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 | 186 | aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 |
| 118 | 187 | ||
| @@ -132,146 +201,135 @@ | |||
| 132 | #include "aclnnop/aclnn_global_max_pool.h" | 201 | #include "aclnnop/aclnn_global_max_pool.h" |
| 133 | 202 | ||
| 134 | #define CHECK_RET(cond, return_expr) \ | 203 | #define CHECK_RET(cond, return_expr) \ |
| 135 | - do { \ | 204 | + do { \ |
| 136 | - if (!(cond)) { \ | 205 | + if (!(cond)) { \ |
| 137 | - return_expr; \ | 206 | + return_expr; \ |
| 138 | - } \ | 207 | + } \ |
| 139 | - } while (0) | 208 | + } while (0) |
| 140 | 209 | ||
| 141 | -#define LOG_PRINT(message, ...) \ | 210 | +#define LOG_PRINT(message, ...) \ |
| 142 | - do { \ | 211 | + do { \ |
| 143 | - printf(message, ##__VA_ARGS__); \ | 212 | + printf(message, ##__VA_ARGS__); \ |
| 144 | - } while (0) | 213 | + } while (0) |
| 145 | 214 | ||
| 146 | -int64_t GetShapeSize(const std::vector<int64_t>& shape) { | 215 | +int64_t GetShapeSize(const std::vector<int64_t>& shape) |
| 147 | - int64_t shape_size = 1; | 216 | +{ |
| 148 | - for (auto i : shape) { | 217 | + int64_t shapeSize = 1; |
| 149 | - shape_size *= i; | 218 | + for (auto i : shape) { |
| 150 | - } | 219 | + shapeSize *= i; |
| 151 | - return shape_size; | 220 | + } |
| 221 | + return shapeSize; | ||
| 152 | } | 222 | } |
| 153 | 223 | ||
| 154 | -int Init(int32_t deviceId, aclrtStream* stream) { | 224 | +int Init(int32_t deviceId, aclrtStream* stream) |
| 155 | - // 固定写法,资源初始化 | 225 | +{ |
| 156 | - auto ret = aclInit(nullptr); | 226 | + // 固定写法,资源初始化 |
| 157 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclInit failed. ERROR: %d\n", ret); return ret); | 227 | + auto ret = aclInit(nullptr); |
| 158 | - ret = aclrtSetDevice(deviceId); | 228 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclInit failed. ERROR: %d\n", ret); return ret); |
| 159 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSetDevice failed. ERROR: %d\n", ret); return ret); | 229 | + ret = aclrtSetDevice(deviceId); |
| 160 | - ret = aclrtCreateStream(stream); | 230 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSetDevice failed. ERROR: %d\n", ret); return ret); |
| 161 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtCreateStream failed. ERROR: %d\n", ret); return ret); | 231 | + ret = aclrtCreateStream(stream); |
| 162 | - return 0; | 232 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtCreateStream failed. ERROR: %d\n", ret); return ret); |
| 233 | + return 0; | ||
| 163 | } | 234 | } |
| 164 | 235 | ||
| 165 | template <typename T> | 236 | template <typename T> |
| 166 | -int CreateAclTensor(const std::vector<T>& hostData, const std::vector<int64_t>& shape, void** deviceAddr, | 237 | +int CreateAclTensor( |
| 167 | - aclDataType dataType, aclTensor** tensor) { | 238 | + const std::vector<T>& hostData, const std::vector<int64_t>& shape, void** deviceAddr, aclDataType dataType, |
| 168 | - auto size = GetShapeSize(shape) * sizeof(T); | 239 | + aclTensor** tensor) |
| 169 | - // 调用aclrtMalloc申请device侧内存 | 240 | +{ |
| 170 | - auto ret = aclrtMalloc(deviceAddr, size, ACL_MEM_MALLOC_HUGE_FIRST); | 241 | + auto size = GetShapeSize(shape) * sizeof(T); |
| 171 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMalloc failed. ERROR: %d\n", ret); return ret); | 242 | + // 调用aclrtMalloc申请device侧内存 |
| 243 | + auto ret = aclrtMalloc(deviceAddr, size, ACL_MEM_MALLOC_HUGE_FIRST); | ||
| 244 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMalloc failed. ERROR: %d\n", ret); return ret); | ||
| 245 | + // 调用aclrtMemcpy将host侧数据拷贝到device侧内存上 | ||
| 246 | + ret = aclrtMemcpy(*deviceAddr, size, hostData.data(), size, ACL_MEMCPY_HOST_TO_DEVICE); | ||
| 247 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMemcpy failed. ERROR: %d\n", ret); return ret); | ||
| 172 | 248 | ||
| 173 | - // 调用aclrtMemcpy将host侧数据拷贝到device侧内存上 | 249 | + // 计算连续tensor的strides |
| 174 | - ret = aclrtMemcpy(*deviceAddr, size, hostData.data(), size, ACL_MEMCPY_HOST_TO_DEVICE); | 250 | + std::vector<int64_t> strides(shape.size(), 1); |
| 175 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMemcpy failed. ERROR: %d\n", ret); return ret); | 251 | + for (int64_t i = shape.size() - 2; i >= 0; i--) { |
| 252 | + strides[i] = shape[i + 1] * strides[i + 1]; | ||
| 253 | + } | ||
| 176 | 254 | ||
| 177 | - // 计算连续tensor的strides | 255 | + // 调用aclCreateTensor接口创建aclTensor |
| 178 | - std::vector<int64_t> strides(shape.size(), 1); | 256 | + *tensor = aclCreateTensor( |
| 179 | - for (int64_t i = shape.size() - 2; i >= 0; i--) { | 257 | + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), |
| 180 | - strides[i] = shape[i + 1] * strides[i + 1]; | 258 | + *deviceAddr); |
| 181 | - } | 259 | + return 0; |
| 182 | - | ||
| 183 | - // 调用aclCreateTensor接口创建aclTensor | ||
| 184 | - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, | ||
| 185 | - shape.data(), shape.size(), *deviceAddr); | ||
| 186 | - return 0; | ||
| 187 | } | 260 | } |
| 188 | 261 | ||
| 189 | -template <typename T> | 262 | +int main() |
| 190 | -int CreateAclIntArray(const std::vector<T>& hostData, void** deviceAddr, aclIntArray** intArray) { | 263 | +{ |
| 191 | - auto size = GetShapeSize(hostData) * sizeof(T); | 264 | + // device/stream初始化,参考acl API手册 |
| 192 | - // 调用aclrtMalloc申请device侧内存 | 265 | + int32_t deviceId = 0; |
| 193 | - auto ret = aclrtMalloc(deviceAddr, size, ACL_MEM_MALLOC_HUGE_FIRST); | 266 | + aclrtStream stream; |
| 194 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMalloc failed. ERROR: %d\n", ret); return ret); | 267 | + auto ret = Init(deviceId, &stream); |
| 268 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); | ||
| 195 | 269 | ||
| 196 | - // 调用aclrtMemcpy将host侧数据拷贝到device侧内存上 | 270 | + std::vector<int64_t> selfShape = {1, 3, 2, 2}; |
| 197 | - ret = aclrtMemcpy(*deviceAddr, size, hostData.data(), size, ACL_MEMCPY_HOST_TO_DEVICE); | 271 | + std::vector<int64_t> outShape = {1, 3, 1, 1}; |
| 198 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMemcpy failed. ERROR: %d\n", ret); return ret); | ||
| 199 | 272 | ||
| 200 | - // 调用aclCreateIntArray接口创建aclIntArray | 273 | + void* selfDeviceAddr = nullptr; |
| 201 | - *intArray = aclCreateIntArray(hostData.data(), hostData.size()); | 274 | + void* outDeviceAddr = nullptr; |
| 202 | - return 0; | 275 | + aclTensor* self = nullptr; |
| 203 | -} | 276 | + aclTensor* out = nullptr; |
| 204 | 277 | ||
| 205 | -int main() { | 278 | + std::vector<float> selfHostData = {2, 3, 5, 8, 4, 12, 6, 7, 5, 3, 7, 6}; |
| 206 | - // 1. (固定写法)device/stream初始化,参考acl API手册 | 279 | + std::vector<float> outHostData = {4.5, 7.25, 5.25}; |
| 207 | - // 根据自己的实际device填写deviceId | ||
| 208 | - int32_t deviceId = 0; | ||
| 209 | - aclrtStream stream; | ||
| 210 | - auto ret = Init(deviceId, &stream); | ||
| 211 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); | ||
| 212 | 280 | ||
| 213 | - // 2. 构造输入与输出,需要根据API的接口自定义构造 | 281 | + // 创建self aclTensor |
| 214 | - std::vector<int64_t> selfShape = {1, 3, 2, 2}; | 282 | + ret = CreateAclTensor(selfHostData, selfShape, &selfDeviceAddr, aclDataType::ACL_FLOAT, &self); |
| 215 | - std::vector<int64_t> outShape = {1, 3, 1, 1}; | 283 | + CHECK_RET(ret == ACL_SUCCESS, return ret); |
| 284 | + // 创建out aclTensor | ||
| 285 | + ret = CreateAclTensor(outHostData, outShape, &outDeviceAddr, aclDataType::ACL_FLOAT, &out); | ||
| 286 | + CHECK_RET(ret == ACL_SUCCESS, return ret); | ||
| 216 | 287 | ||
| 217 | - void* selfDeviceAddr = nullptr; | 288 | + // 调用CANN算子库API |
| 218 | - void* outDeviceAddr = nullptr; | 289 | + uint64_t workspaceSize = 0; |
| 219 | - aclTensor* self = nullptr; | 290 | + aclOpExecutor* executor; |
| 220 | - aclTensor* out = nullptr; | 291 | + // 调用aclnnGlobalMaxPool第一段接口 |
| 292 | + ret = aclnnGlobalMaxPoolGetWorkspaceSize(self, out, &workspaceSize, &executor); | ||
| 293 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnGlobalMaxPoolGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); | ||
| 294 | + // 根据第一段接口计算出的workspaceSize申请device内存 | ||
| 295 | + void* workspaceAddr = nullptr; | ||
| 296 | + if (workspaceSize > 0) { | ||
| 297 | + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); | ||
| 298 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); | ||
| 299 | + } | ||
| 300 | + // 调用aclnnGlobalMaxPool第二段接口 | ||
| 301 | + ret = aclnnGlobalMaxPool(workspaceAddr, workspaceSize, executor, stream); | ||
| 302 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnGlobalMaxPool failed. ERROR: %d\n", ret); return ret); | ||
| 221 | 303 | ||
| 222 | - std::vector<float> selfHostData = {2, 3, 5, 8, 4, 12, 6, 7, 5, 3, 7, 6}; | 304 | + // 同步等待任务执行结束 |
| 223 | - std::vector<float> outHostData = {4.5, 7.25, 5.25}; | 305 | + ret = aclrtSynchronizeStream(stream); |
| 306 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); | ||
| 224 | 307 | ||
| 225 | - // 创建self aclTensor | 308 | + // 获取输出的值,将device侧内存上的结果拷贝至host侧 |
| 226 | - ret = CreateAclTensor(selfHostData, selfShape, &selfDeviceAddr, aclDataType::ACL_FLOAT, &self); | 309 | + auto size = GetShapeSize(outShape); |
| 227 | - CHECK_RET(ret == ACL_SUCCESS, return ret); | 310 | + std::vector<float> resultData(size, 0); |
| 228 | - // 创建out aclTensor | 311 | + ret = aclrtMemcpy( |
| 229 | - ret = CreateAclTensor(outHostData, outShape, &outDeviceAddr, aclDataType::ACL_FLOAT, &out); | 312 | + resultData.data(), resultData.size() * sizeof(resultData[0]), outDeviceAddr, |
| 230 | - CHECK_RET(ret == ACL_SUCCESS, return ret); | 313 | + size * sizeof(resultData[0]), ACL_MEMCPY_DEVICE_TO_HOST); |
| 314 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("copy result from device to host failed. ERROR: %d\n", ret); return ret); | ||
| 315 | + for (int64_t i = 0; i < size; i++) { | ||
| 316 | + LOG_PRINT("result[%ld] is: %f\n", i, resultData[i]); | ||
| 317 | + } | ||
| 231 | 318 | ||
| 232 | - // 3. 调用CANN算子库API | 319 | + // 释放aclTensor |
| 233 | - uint64_t workspaceSize = 0; | 320 | + aclDestroyTensor(self); |
| 234 | - aclOpExecutor* executor; | 321 | + aclDestroyTensor(out); |
| 235 | - // 调用aclnnGlobalMaxPool第一段接口 | ||
| 236 | - ret = aclnnGlobalMaxPoolGetWorkspaceSize(self, out, &workspaceSize, &executor); | ||
| 237 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnGlobalMaxPoolGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); | ||
| 238 | - // 根据第一段接口计算出的workspaceSize申请device内存 | ||
| 239 | - void* workspaceAddr = nullptr; | ||
| 240 | - if (workspaceSize > 0) { | ||
| 241 | - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); | ||
| 242 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret;); | ||
| 243 | - } | ||
| 244 | - // 调用aclnnGlobalMaxPool第二段接口 | ||
| 245 | - ret = aclnnGlobalMaxPool(workspaceAddr, workspaceSize, executor, stream); | ||
| 246 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnGlobalMaxPool failed. ERROR: %d\n", ret); return ret); | ||
| 247 | 322 | ||
| 248 | - // 4. (固定写法)同步等待任务执行结束 | 323 | + // 释放资源 |
| 249 | - ret = aclrtSynchronizeStream(stream); | 324 | + aclrtFree(selfDeviceAddr); |
| 250 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); | 325 | + aclrtFree(outDeviceAddr); |
| 326 | + if (workspaceSize > 0) { | ||
| 327 | + aclrtFree(workspaceAddr); | ||
| 328 | + } | ||
| 329 | + aclrtDestroyStream(stream); | ||
| 330 | + aclrtResetDevice(deviceId); | ||
| 331 | + aclFinalize(); | ||
| 251 | 332 | ||
| 252 | - // 5. 获取输出的值,将device侧内存上的结果拷贝至host侧,需要根据具体API的接口定义修改 | 333 | + return 0; |
| 253 | - auto size = GetShapeSize(outShape); | ||
| 254 | - std::vector<float> resultData(size, 0); | ||
| 255 | - ret = aclrtMemcpy(resultData.data(), resultData.size() * sizeof(resultData[0]), | ||
| 256 | - outDeviceAddr, size * sizeof(resultData[0]), ACL_MEMCPY_DEVICE_TO_HOST); | ||
| 257 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("copy resultData from device to host failed. ERROR: %d\n", ret); return ret); | ||
| 258 | - for (int64_t i = 0; i < size; i++) { | ||
| 259 | - LOG_PRINT("result[%ld] is: %f\n", i, resultData[i]); | ||
| 260 | - } | ||
| 261 | - | ||
| 262 | - // 6. 释放aclTensor,需要根据具体API的接口定义修改 | ||
| 263 | - aclDestroyTensor(self); | ||
| 264 | - aclDestroyTensor(out); | ||
| 265 | - | ||
| 266 | - // 7. 释放device资源,需要根据具体API的接口定义修改 | ||
| 267 | - aclrtFree(selfDeviceAddr); | ||
| 268 | - aclrtFree(outDeviceAddr); | ||
| 269 | - if (workspaceSize > 0) { | ||
| 270 | - aclrtFree(workspaceAddr); | ||
| 271 | - } | ||
| 272 | - aclrtDestroyStream(stream); | ||
| 273 | - aclrtResetDevice(deviceId); | ||
| 274 | - aclFinalize(); | ||
| 275 | - return 0; | ||
| 276 | } | 334 | } |
| 277 | ``` | 335 | ``` |