已合并
[CANNBOT]atanh 算子修改tiling #3184
wangweidong创建于 6月8日
[CANNBOT]atanh 算子修改tiling #3184
已合并
wangweidong创建于 6月8日
4 个文件变更+256-193
@@ -16,114 +16,140 @@
16#include "aclnnop/aclnn_atanh.h"16#include "aclnnop/aclnn_atanh.h"
17 17 
18#define CHECK_RET(cond, return_expr) \18#define CHECK_RET(cond, return_expr) \
19- do { \19+ do { \
20- if (!(cond)) { \20+ if (!(cond)) { \
21- return_expr; \21+ return_expr; \
22- } \22+ } \
23- } while (0)23+ } while (0)
24 24 
25#define LOG_PRINT(message, ...) \25#define LOG_PRINT(message, ...) \
26- do { \26+ do { \
27- printf(message, ##__VA_ARGS__); \27+ printf(message, ##__VA_ARGS__); \
28- } while (0)28+ } while (0)
29 29 
30-int64_t GetShapeSize(const std::vector<int64_t>& shape)30+int64_t GetShapeSize(const std::vector<int64_t>& shape) {
31-{31+ int64_t shapeSize = 1;
32- int64_t shapeSize = 1;32+ for (auto i : shape) {
33- for (auto i : shape) {33+ shapeSize *= i;
34- shapeSize *= i;34+ }
35- }35+ return shapeSize;
36- return shapeSize;
37}36}
38 37 
39-int Init(int32_t deviceId, aclrtStream* stream)38+int Init(int32_t deviceId, aclrtStream* stream) {
40-{39+ // 固定写法,资源初始化
41- auto ret = aclInit(nullptr);40+ auto ret = aclInit(nullptr);
42- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclInit failed. ERROR: %d\n", ret); return ret);41+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclInit failed. ERROR: %d\n", ret); return ret);
43- ret = aclrtSetDevice(deviceId);42+ ret = aclrtSetDevice(deviceId);
44- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSetDevice failed. ERROR: %d\n", ret); return ret);43+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSetDevice failed. ERROR: %d\n", ret); return ret);
45- ret = aclrtCreateStream(stream);44+ ret = aclrtCreateStream(stream);
46- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtCreateStream failed. ERROR: %d\n", ret); return ret);45+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtCreateStream failed. ERROR: %d\n", ret); return ret);
47- return 0;46+ return 0;
48}47}
49 48 
50template <typename T>49template <typename T>
51int CreateAclTensor(const std::vector<T>& hostData, const std::vector<int64_t>& shape, void** deviceAddr,50int CreateAclTensor(const std::vector<T>& hostData, const std::vector<int64_t>& shape, void** deviceAddr,
52- aclDataType dataType, aclTensor** tensor)51+ aclDataType dataType, aclTensor** tensor) {
53-{52+ auto size = GetShapeSize(shape) * sizeof(T);
M

确认缩进是否合理

likedislike
54- auto size = GetShapeSize(shape) * sizeof(T);53+ // 调用aclrtMalloc申请device侧内存
55- auto ret = aclrtMalloc(deviceAddr, size, ACL_MEM_MALLOC_HUGE_FIRST);54+ auto ret = aclrtMalloc(deviceAddr, size, ACL_MEM_MALLOC_HUGE_FIRST);
56- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMalloc failed. ERROR: %d\n", ret); return ret);55+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMalloc failed. ERROR: %d\n", ret); return ret);
57- ret = aclrtMemcpy(*deviceAddr, size, hostData.data(), size, ACL_MEMCPY_HOST_TO_DEVICE);56+ // 调用aclrtMemcpy将host侧数据拷贝到device侧内存上
58- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMemcpy failed. ERROR: %d\n", ret); return ret);57+ ret = aclrtMemcpy(*deviceAddr, size, hostData.data(), size, ACL_MEMCPY_HOST_TO_DEVICE);
58+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMemcpy failed. ERROR: %d\n", ret); return ret);
59 59 
60- std::vector<int64_t> strides(shape.size(), 1);60+ // 计算连续tensor的strides
61- for (int64_t i = shape.size() - 2; i >= 0; i--) {61+ std::vector<int64_t> strides(shape.size(), 1);
62- strides[i] = shape[i + 1] * strides[i + 1];62+ for (int64_t i = shape.size() - 2; i >= 0; i--) {
63- }63+ strides[i] = shape[i + 1] * strides[i + 1];
64+ }
64 65 
65- *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0,66+ // 调用aclCreateTensor接口创建aclTensor
66- aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), *deviceAddr);67+ *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), *deviceAddr);
67- return 0;68+ return 0;
68}69}
69 70 
70-int main()71+int main() {
71-{72+ // 1. (固定写法)device/stream初始化,参考acl API手册
72- int32_t deviceId = 0;73+ // 根据自己的实际device填写deviceId
73- aclrtStream stream;74+ int32_t deviceId = 0;
74- auto ret = Init(deviceId, &stream);75+ aclrtStream stream;
75- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret);76+ auto ret = Init(deviceId, &stream);
77+ // check根据自己的需要处理
78+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret);
79+ // 2. 构造输入与输出,需要根据API的接口自定义构造
80+ std::vector<int64_t> selfShape = {4, 2};
81+ std::vector<int64_t> outShape = {4, 2};
82+ void* selfDeviceAddr = nullptr;
83+ void* outDeviceAddr = nullptr;
84+ aclTensor* self = nullptr;
85+ aclTensor* out = nullptr;
86+ std::vector<float> selfHostData = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8};
87+ std::vector<float> outHostData = {0, 0, 0, 0, 0, 0, 0, 0};
88+ // 创建self aclTensor
89+ ret = CreateAclTensor(selfHostData, selfShape, &selfDeviceAddr, aclDataType::ACL_FLOAT, &self);
90+ CHECK_RET(ret == ACL_SUCCESS, return ret);
91+ // 创建out aclTensor
92+ ret = CreateAclTensor(outHostData, outShape, &outDeviceAddr, aclDataType::ACL_FLOAT, &out);
93+ CHECK_RET(ret == ACL_SUCCESS, return ret);
76 94 
77- std::vector<int64_t> selfShape = {4, 2};95+ // aclnnAtanh接口调用示例
78- std::vector<int64_t> outShape = {4, 2};96+ // 3. 调用CANN算子库API
79- void* selfDeviceAddr = nullptr;97+ // 调用aclnnAtanh第一段接口
80- void* outDeviceAddr = nullptr;98+ uint64_t workspaceSize = 0;
81- aclTensor* self = nullptr;99+ aclOpExecutor* executor;
82- aclTensor* out = nullptr;100+ ret = aclnnAtanhGetWorkspaceSize(self, out, &workspaceSize, &executor);
83- std::vector<float> selfHostData = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8};101+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnAtanhGetWorkspaceSize failed. ERROR: %d\n", ret); return ret);
84- std::vector<float> outHostData = {0, 0, 0, 0, 0, 0, 0, 0};102+ // 根据第一段接口计算出的workspaceSize申请device内存
103+ void* workspaceAddr = nullptr;
104+ if (workspaceSize > 0) {
105+ ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST);
106+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret);
107+ }
108+ // 调用aclnnAtanh第二段接口
109+ ret = aclnnAtanh(workspaceAddr, workspaceSize, executor, stream);
110+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnAtanh failed. ERROR: %d\n", ret); return ret);
111+
112+ // aclnnInplaceAtanh接口调用示例
113+ uint64_t inplaceWorkspaceSize = 0;
114+ aclOpExecutor* inplaceExecutor;
115+ ret = aclnnInplaceAtanhGetWorkspaceSize(self, &inplaceWorkspaceSize, &inplaceExecutor);
116+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnInplaceAtanhGetWorkspaceSize failed. ERROR: %d\n", ret); return ret);
117+ // 根据第一段接口计算出的workspaceSize申请device内存
118+ void* inplaceWorkspaceAddr = nullptr;
119+ if (inplaceWorkspaceSize > 0) {
120+ ret = aclrtMalloc(&inplaceWorkspaceAddr, inplaceWorkspaceSize, ACL_MEM_MALLOC_HUGE_FIRST);
121+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret);
122+ }
123+ // 调用aclnnInplaceAtanh第二段接口
124+ ret = aclnnInplaceAtanh(inplaceWorkspaceAddr, inplaceWorkspaceSize, inplaceExecutor, stream);
125+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnInplaceAtanh failed. ERROR: %d\n", ret); return ret);
126+
127+ // 4. (固定写法)同步等待任务执行结束
128+ ret = aclrtSynchronizeStream(stream);
129+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret);
85 130 
86- ret = CreateAclTensor(selfHostData, selfShape, &selfDeviceAddr, aclDataType::ACL_FLOAT, &self);131+ // 5. 获取输出的值,将device侧内存上的结果拷贝至host侧,需要根据具体API的接口定义修改
87- CHECK_RET(ret == ACL_SUCCESS, return ret);132+ auto size = GetShapeSize(outShape);
88- ret = CreateAclTensor(outHostData, outShape, &outDeviceAddr, aclDataType::ACL_FLOAT, &out);133+ std::vector<float> resultData(size, 0);
89- CHECK_RET(ret == ACL_SUCCESS, return ret);134+ ret = aclrtMemcpy(resultData.data(), resultData.size() * sizeof(resultData[0]), outDeviceAddr,
135+ size * sizeof(resultData[0]), ACL_MEMCPY_DEVICE_TO_HOST);
136+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("copy result from device to host failed. ERROR: %d\n", ret); return ret);
137+ for (int64_t i = 0; i < size; i++) {
138+ LOG_PRINT("result[%ld] is: %f\n", i, resultData[i]);
139+ }
90 140 
91- uint64_t workspaceSize = 0;141+ // 6. 释放aclTensor,需要根据具体API的接口定义修改
92- aclOpExecutor* executor;142+ aclDestroyTensor(self);
93- ret = aclnnAtanhGetWorkspaceSize(self, out, &workspaceSize, &executor);143+ aclDestroyTensor(out);
94- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnAtanhGetWorkspaceSize failed. ERROR: %d\n", ret); return ret);144+
95- 145+ // 7. 释放device资源,需要根据具体API的接口定义修改
96- void* workspaceAddr = nullptr;146+ aclrtFree(selfDeviceAddr);
97- if (workspaceSize > 0) {147+ aclrtFree(outDeviceAddr);
98- ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST);148+ if (workspaceSize > 0) {
99- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret);149+ aclrtFree(workspaceAddr);
100- }150+ }
101- 151+ aclrtDestroyStream(stream);
102- ret = aclnnAtanh(workspaceAddr, workspaceSize, executor, stream);152+ aclrtResetDevice(deviceId);
103- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnAtanh failed. ERROR: %d\n", ret); return ret);153+ aclFinalize();
104- 154+ return 0;
105- ret = aclrtSynchronizeStream(stream);155+}
106- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret);
107- 
108- auto size = GetShapeSize(outShape);
109- std::vector<float> resultData(size, 0);
110- ret = aclrtMemcpy(resultData.data(), resultData.size() * sizeof(resultData[0]), outDeviceAddr,
111- size * sizeof(resultData[0]), ACL_MEMCPY_DEVICE_TO_HOST);
112- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("copy result from device to host failed. ERROR: %d\n", ret); return ret);
113- for (int64_t i = 0; i < size; i++) {
114- LOG_PRINT("result[%ld] is: %f\n", i, resultData[i]);
115- }
116- 
117- aclDestroyTensor(self);
118- aclDestroyTensor(out);
119- 
120- aclrtFree(selfDeviceAddr);
121- aclrtFree(outDeviceAddr);
122- if (workspaceSize > 0) {
123- aclrtFree(workspaceAddr);
124- }
125- aclrtDestroyStream(stream);
126- aclrtResetDevice(deviceId);
127- aclFinalize();
128- return 0;
129-}
@@ -16,114 +16,140 @@
16#include "aclnnop/aclnn_atanh.h"16#include "aclnnop/aclnn_atanh.h"
17 17 
18#define CHECK_RET(cond, return_expr) \18#define CHECK_RET(cond, return_expr) \
19- do { \19+ do { \
20- if (!(cond)) { \20+ if (!(cond)) { \
21- return_expr; \21+ return_expr; \
22- } \22+ } \
23- } while (0)23+ } while (0)
24 24 
25#define LOG_PRINT(message, ...) \25#define LOG_PRINT(message, ...) \
26- do { \26+ do { \
27- printf(message, ##__VA_ARGS__); \27+ printf(message, ##__VA_ARGS__); \
28- } while (0)28+ } while (0)
29 29 
30-int64_t GetShapeSize(const std::vector<int64_t>& shape)30+int64_t GetShapeSize(const std::vector<int64_t>& shape) {
31-{31+ int64_t shapeSize = 1;
32- int64_t shapeSize = 1;32+ for (auto i : shape) {
33- for (auto i : shape) {33+ shapeSize *= i;
34- shapeSize *= i;34+ }
35- }35+ return shapeSize;
36- return shapeSize;
37}36}
38 37 
39-int Init(int32_t deviceId, aclrtStream* stream)38+int Init(int32_t deviceId, aclrtStream* stream) {
40-{39+ // 固定写法,资源初始化
41- auto ret = aclInit(nullptr);40+ auto ret = aclInit(nullptr);
42- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclInit failed. ERROR: %d\n", ret); return ret);41+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclInit failed. ERROR: %d\n", ret); return ret);
43- ret = aclrtSetDevice(deviceId);42+ ret = aclrtSetDevice(deviceId);
44- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSetDevice failed. ERROR: %d\n", ret); return ret);43+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSetDevice failed. ERROR: %d\n", ret); return ret);
45- ret = aclrtCreateStream(stream);44+ ret = aclrtCreateStream(stream);
46- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtCreateStream failed. ERROR: %d\n", ret); return ret);45+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtCreateStream failed. ERROR: %d\n", ret); return ret);
47- return 0;46+ return 0;
48}47}
49 48 
50template <typename T>49template <typename T>
51int CreateAclTensor(const std::vector<T>& hostData, const std::vector<int64_t>& shape, void** deviceAddr,50int CreateAclTensor(const std::vector<T>& hostData, const std::vector<int64_t>& shape, void** deviceAddr,
52- aclDataType dataType, aclTensor** tensor)51+ aclDataType dataType, aclTensor** tensor) {
53-{52+ auto size = GetShapeSize(shape) * sizeof(T);
54- auto size = GetShapeSize(shape) * sizeof(T);53+ // 调用aclrtMalloc申请device侧内存
55- auto ret = aclrtMalloc(deviceAddr, size, ACL_MEM_MALLOC_HUGE_FIRST);54+ auto ret = aclrtMalloc(deviceAddr, size, ACL_MEM_MALLOC_HUGE_FIRST);
56- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMalloc failed. ERROR: %d\n", ret); return ret);55+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMalloc failed. ERROR: %d\n", ret); return ret);
57- ret = aclrtMemcpy(*deviceAddr, size, hostData.data(), size, ACL_MEMCPY_HOST_TO_DEVICE);56+ // 调用aclrtMemcpy将host侧数据拷贝到device侧内存上
58- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMemcpy failed. ERROR: %d\n", ret); return ret);57+ ret = aclrtMemcpy(*deviceAddr, size, hostData.data(), size, ACL_MEMCPY_HOST_TO_DEVICE);
58+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMemcpy failed. ERROR: %d\n", ret); return ret);
59 59 
60- std::vector<int64_t> strides(shape.size(), 1);60+ // 计算连续tensor的strides
61- for (int64_t i = shape.size() - 2; i >= 0; i--) {61+ std::vector<int64_t> strides(shape.size(), 1);
62- strides[i] = shape[i + 1] * strides[i + 1];62+ for (int64_t i = shape.size() - 2; i >= 0; i--) {
63- }63+ strides[i] = shape[i + 1] * strides[i + 1];
64+ }
64 65 
65- *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0,66+ // 调用aclCreateTensor接口创建aclTensor
66- aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), *deviceAddr);67+ *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), *deviceAddr);
67- return 0;68+ return 0;
68}69}
69 70 
70-int main()71+int main() {
71-{72+ // 1. (固定写法)device/stream初始化,参考acl API手册
72- int32_t deviceId = 0;73+ // 根据自己的实际device填写deviceId
73- aclrtStream stream;74+ int32_t deviceId = 0;
74- auto ret = Init(deviceId, &stream);75+ aclrtStream stream;
75- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret);76+ auto ret = Init(deviceId, &stream);
77+ // check根据自己的需要处理
78+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret);
79+ // 2. 构造输入与输出,需要根据API的接口自定义构造
80+ std::vector<int64_t> selfShape = {4, 2};
81+ std::vector<int64_t> outShape = {4, 2};
82+ void* selfDeviceAddr = nullptr;
83+ void* outDeviceAddr = nullptr;
84+ aclTensor* self = nullptr;
85+ aclTensor* out = nullptr;
86+ std::vector<float> selfHostData = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8};
87+ std::vector<float> outHostData = {0, 0, 0, 0, 0, 0, 0, 0};
88+ // 创建self aclTensor
89+ ret = CreateAclTensor(selfHostData, selfShape, &selfDeviceAddr, aclDataType::ACL_FLOAT, &self);
90+ CHECK_RET(ret == ACL_SUCCESS, return ret);
91+ // 创建out aclTensor
92+ ret = CreateAclTensor(outHostData, outShape, &outDeviceAddr, aclDataType::ACL_FLOAT, &out);
93+ CHECK_RET(ret == ACL_SUCCESS, return ret);
76 94 
77- std::vector<int64_t> selfShape = {4, 2};95+ // aclnnAtanh接口调用示例
78- std::vector<int64_t> outShape = {4, 2};96+ // 3. 调用CANN算子库API
79- void* selfDeviceAddr = nullptr;97+ // 调用aclnnAtanh第一段接口
80- void* outDeviceAddr = nullptr;98+ uint64_t workspaceSize = 0;
81- aclTensor* self = nullptr;99+ aclOpExecutor* executor;
82- aclTensor* out = nullptr;100+ ret = aclnnAtanhGetWorkspaceSize(self, out, &workspaceSize, &executor);
83- std::vector<float> selfHostData = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8};101+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnAtanhGetWorkspaceSize failed. ERROR: %d\n", ret); return ret);
84- std::vector<float> outHostData = {0, 0, 0, 0, 0, 0, 0, 0};102+ // 根据第一段接口计算出的workspaceSize申请device内存
103+ void* workspaceAddr = nullptr;
104+ if (workspaceSize > 0) {
105+ ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST);
106+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret);
107+ }
108+ // 调用aclnnAtanh第二段接口
109+ ret = aclnnAtanh(workspaceAddr, workspaceSize, executor, stream);
110+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnAtanh failed. ERROR: %d\n", ret); return ret);
111+
112+ // aclnnInplaceAtanh接口调用示例
113+ uint64_t inplaceWorkspaceSize = 0;
114+ aclOpExecutor* inplaceExecutor;
115+ ret = aclnnInplaceAtanhGetWorkspaceSize(self, &inplaceWorkspaceSize, &inplaceExecutor);
116+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnInplaceAtanhGetWorkspaceSize failed. ERROR: %d\n", ret); return ret);
117+ // 根据第一段接口计算出的workspaceSize申请device内存
118+ void* inplaceWorkspaceAddr = nullptr;
119+ if (inplaceWorkspaceSize > 0) {
120+ ret = aclrtMalloc(&inplaceWorkspaceAddr, inplaceWorkspaceSize, ACL_MEM_MALLOC_HUGE_FIRST);
W

SEC-5.2 FAIL — 两个示例文件中,新增的 aclnnInplaceAtanh 路径申请了 inplaceWorkspaceAddr(aclrtMalloc,行 120),但清理阶段(行 146-151)未释放。原有 aclnnAtanh 的 workspaceAddr 有 aclrtFree,新增路径遗漏了对称释放。 修复:在 aclrtFree(workspaceAddr) 之后补充: if (inplaceWorkspaceSize > 0) { aclrtFree(inplaceWorkspaceAddr); }

likedislike
121+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret);
122+ }
123+ // 调用aclnnInplaceAtanh第二段接口
124+ ret = aclnnInplaceAtanh(inplaceWorkspaceAddr, inplaceWorkspaceSize, inplaceExecutor, stream);
125+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnInplaceAtanh failed. ERROR: %d\n", ret); return ret);
126+
127+ // 4. (固定写法)同步等待任务执行结束
128+ ret = aclrtSynchronizeStream(stream);
129+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret);
85 130 
86- ret = CreateAclTensor(selfHostData, selfShape, &selfDeviceAddr, aclDataType::ACL_FLOAT, &self);131+ // 5. 获取输出的值,将device侧内存上的结果拷贝至host侧,需要根据具体API的接口定义修改
87- CHECK_RET(ret == ACL_SUCCESS, return ret);132+ auto size = GetShapeSize(outShape);
88- ret = CreateAclTensor(outHostData, outShape, &outDeviceAddr, aclDataType::ACL_FLOAT, &out);133+ std::vector<float> resultData(size, 0);
89- CHECK_RET(ret == ACL_SUCCESS, return ret);134+ ret = aclrtMemcpy(resultData.data(), resultData.size() * sizeof(resultData[0]), outDeviceAddr,
135+ size * sizeof(resultData[0]), ACL_MEMCPY_DEVICE_TO_HOST);
136+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("copy result from device to host failed. ERROR: %d\n", ret); return ret);
137+ for (int64_t i = 0; i < size; i++) {
138+ LOG_PRINT("result[%ld] is: %f\n", i, resultData[i]);
139+ }
90 140 
91- uint64_t workspaceSize = 0;141+ // 6. 释放aclTensor,需要根据具体API的接口定义修改
92- aclOpExecutor* executor;142+ aclDestroyTensor(self);
93- ret = aclnnAtanhGetWorkspaceSize(self, out, &workspaceSize, &executor);143+ aclDestroyTensor(out);
94- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnAtanhGetWorkspaceSize failed. ERROR: %d\n", ret); return ret);144+
95- 145+ // 7. 释放device资源,需要根据具体API的接口定义修改
96- void* workspaceAddr = nullptr;146+ aclrtFree(selfDeviceAddr);
97- if (workspaceSize > 0) {147+ aclrtFree(outDeviceAddr);
98- ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST);148+ if (workspaceSize > 0) {
99- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret);149+ aclrtFree(workspaceAddr);
100- }150+ }
101- 151+ aclrtDestroyStream(stream);
102- ret = aclnnAtanh(workspaceAddr, workspaceSize, executor, stream);152+ aclrtResetDevice(deviceId);
103- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnAtanh failed. ERROR: %d\n", ret); return ret);153+ aclFinalize();
104- 154+ return 0;
105- ret = aclrtSynchronizeStream(stream);155+}
106- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret);
107- 
108- auto size = GetShapeSize(outShape);
109- std::vector<float> resultData(size, 0);
110- ret = aclrtMemcpy(resultData.data(), resultData.size() * sizeof(resultData[0]), outDeviceAddr,
111- size * sizeof(resultData[0]), ACL_MEMCPY_DEVICE_TO_HOST);
112- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("copy result from device to host failed. ERROR: %d\n", ret); return ret);
113- for (int64_t i = 0; i < size; i++) {
114- LOG_PRINT("result[%ld] is: %f\n", i, resultData[i]);
115- }
116- 
117- aclDestroyTensor(self);
118- aclDestroyTensor(out);
119- 
120- aclrtFree(selfDeviceAddr);
121- aclrtFree(outDeviceAddr);
122- if (workspaceSize > 0) {
123- aclrtFree(workspaceAddr);
124- }
125- aclrtDestroyStream(stream);
126- aclrtResetDevice(deviceId);
127- aclFinalize();
128- return 0;
129-}
@@ -75,7 +75,13 @@ static ge::graphStatus AtanhTilingFunc(gert::TilingContext* context)
75 OP_LOGE(context, "set tiling data error"), return ge::GRAPH_FAILED);75 OP_LOGE(context, "set tiling data error"), return ge::GRAPH_FAILED);
76 76 
77 tiling->totalNum = totalNum;77 tiling->totalNum = totalNum;
78+ // blockDim 必须封顶在物理 AIV 核数;SIMT 核内用 grid-stride 覆盖全部元素。
79+ // 原实现 SetBlockDim(CeilDiv(totalNum, coreNum)) 会让 blockDim 随元素数线性膨胀,
80+ // 大 shape 下远超可用核数,触发 507035 vector core exception。
78 int64_t usedCoreNum = Ops::Base::CeilDiv(totalNum, coreNum);81 int64_t usedCoreNum = Ops::Base::CeilDiv(totalNum, coreNum);
82+ if (usedCoreNum > coreNum) {
83+ usedCoreNum = coreNum;
84+ }
79 if (usedCoreNum == 0) {85 if (usedCoreNum == 0) {
80 usedCoreNum = 1;86 usedCoreNum = 1;
81 }87 }
@@ -37,9 +37,14 @@ template <typename T>
37__simt_vf__ __aicore__ LAUNCH_BOUND(THREAD_NUM)37__simt_vf__ __aicore__ LAUNCH_BOUND(THREAD_NUM)
38inline void OpAtanhSimtKernel(int64_t totalElements, __gm__ T* x, __gm__ T* y)38inline void OpAtanhSimtKernel(int64_t totalElements, __gm__ T* x, __gm__ T* y)
39{39{
40- for (uint64_t index = static_cast<uint64_t>(Simt::GetBlockIdx() * Simt::GetThreadNum() + Simt::GetThreadIdx());40+ // 全程使用 uint64 计算 index/stride,避免 blockIdx*threadNum 32-bit 下溢出(大元素数下越界)。
41- index < totalElements;41+ uint64_t threadNum = static_cast<uint64_t>(Simt::GetThreadNum());
42- index += static_cast<uint32_t>(Simt::GetThreadNum() * Simt::GetBlockNum())) {42+ uint64_t blockNum = static_cast<uint64_t>(Simt::GetBlockNum());
43+ uint64_t total = static_cast<uint64_t>(totalElements);
44+ uint64_t stride = threadNum * blockNum;
45+ for (uint64_t index = static_cast<uint64_t>(Simt::GetBlockIdx()) * threadNum + static_cast<uint64_t>(Simt::GetThreadIdx());
46+ index < total;
47+ index += stride) {
43 if constexpr (std::is_same_v<T, float>) {48 if constexpr (std::is_same_v<T, float>) {
44 y[index] = atanhf(x[index]);49 y[index] = atanhf(x[index]);
45 } else if constexpr (std::is_same_v<T, half>) {50 } else if constexpr (std::is_same_v<T, half>) {