已合并
Log示例改用C++ RAII资源管理,与IsFinite/IsInf示例风格对齐 #4704
sunday创建于 8月14日
Log示例改用C++ RAII资源管理,与IsFinite/IsInf示例风格对齐 #4704
已合并
共 3 个文件变更+296-249
| @@ -9,130 +9,147 @@ | |||
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | 11 | ||
| 12 | + | ||
| 13 | + | ||
| 12 | 14 | ||
| 13 | 15 | ||
| 14 | 16 | ||
| 15 | 17 | ||
| 16 | 18 | ||
| 17 | - do { \ | 19 | + do { \ |
| 18 | - if (!(cond)) { \ | 20 | + if (!(cond)) { \ |
| 19 | - return_expr; \ | 21 | + return_expr; \ |
| 20 | - } \ | 22 | + } \ |
| 21 | - } while (0) | 23 | + } while (0) |
| 22 | 24 | ||
| 23 | -#define LOG_PRINT(message, ...) \ | 25 | +#define LOG_PRINT(message, ...) \ |
| 24 | - do { \ | 26 | + do { \ |
| 25 | - printf(message, ##__VA_ARGS__); \ | 27 | + printf(message, ##__VA_ARGS__); \ |
| 26 | - } while (0) | 28 | + } while (0) |
| 27 | 29 | ||
| 28 | -int64_t GetShapeSize(const std::vector<int64_t>& shape) { | 30 | +int64_t GetShapeSize(const std::vector<int64_t>& shape) |
| 29 | - int64_t shapeSize = 1; | 31 | +{ |
| 30 | - for (auto i : shape) { | 32 | + int64_t shapeSize = 1; |
| 31 | - shapeSize *= i; | 33 | + for (auto i : shape) { |
| 32 | - } | 34 | + shapeSize *= i; |
| 33 | - return shapeSize; | 35 | + } |
| 36 | + return shapeSize; | ||
| 34 | } | 37 | } |
| 35 | 38 | ||
| 36 | -int Init(int32_t deviceId, aclrtStream* stream) { | 39 | +using StreamPtr = std::unique_ptr<std::remove_pointer<aclrtStream>::type, decltype(&aclrtDestroyStream)>; |
| 37 | - // 固定写法,资源初始化 | 40 | +using DeviceMemPtr = std::unique_ptr<void, decltype(&aclrtFree)>; |
| 38 | - auto ret = aclInit(nullptr); | 41 | +using TensorPtr = std::unique_ptr<aclTensor, decltype(&aclDestroyTensor)>; |
| 39 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclInit failed. ERROR: %d\n", ret); return ret); | 42 | + |
| 40 | - ret = aclrtSetDevice(deviceId); | 43 | +int Init(int32_t deviceId, StreamPtr& stream, bool& initialized, bool& deviceSet) |
| 41 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSetDevice failed. ERROR: %d\n", ret); return ret); | 44 | +{ |
| 42 | - ret = aclrtCreateStream(stream); | 45 | + // 固定写法,资源初始化 |
| 43 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtCreateStream failed. ERROR: %d\n", ret); return ret); | 46 | + auto ret = aclInit(nullptr); |
| 44 | - return 0; | 47 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclInit failed. ERROR: %d\n", ret); return ret); |
| 48 | + initialized = true; | ||
| 49 | + ret = aclrtSetDevice(deviceId); | ||
| 50 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSetDevice failed. ERROR: %d\n", ret); return ret); | ||
| 51 | + deviceSet = true; | ||
| 52 | + aclrtStream rawStream = nullptr; | ||
| 53 | + ret = aclrtCreateStream(&rawStream); | ||
| 54 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtCreateStream failed. ERROR: %d\n", ret); return ret); | ||
| 55 | + stream.reset(rawStream); | ||
| 56 | + return 0; | ||
| 45 | } | 57 | } |
| 46 | 58 | ||
| 47 | template <typename T> | 59 | template <typename T> |
| 48 | -int CreateAclTensor(const std::vector<T>& hostData, const std::vector<int64_t>& shape, void** deviceAddr, | 60 | +int CreateAclTensor(const std::vector<T>& hostData, const std::vector<int64_t>& shape, aclDataType dataType, |
| 49 | - aclDataType dataType, aclTensor** tensor) { | 61 | + DeviceMemPtr& deviceAddr, TensorPtr& tensor) |
| 50 | - auto size = GetShapeSize(shape) * sizeof(T); | 62 | +{ |
| 51 | - // 调用aclrtMalloc申请device侧内存 | 63 | + auto size = GetShapeSize(shape) * sizeof(T); |
| 52 | - auto ret = aclrtMalloc(deviceAddr, size, ACL_MEM_MALLOC_HUGE_FIRST); | 64 | + // 调用aclrtMalloc申请device侧内存 |
| 53 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMalloc failed. ERROR: %d\n", ret); return ret); | 65 | + void* rawDeviceAddr = nullptr; |
| 54 | - // 调用aclrtMemcpy将host侧数据拷贝到device侧内存上 | 66 | + auto ret = aclrtMalloc(&rawDeviceAddr, size, ACL_MEM_MALLOC_HUGE_FIRST); |
| 55 | - ret = aclrtMemcpy(*deviceAddr, size, hostData.data(), size, ACL_MEMCPY_HOST_TO_DEVICE); | 67 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMalloc failed. ERROR: %d\n", ret); return ret); |
| 56 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMemcpy failed. ERROR: %d\n", ret); return ret); | 68 | + deviceAddr.reset(rawDeviceAddr); |
| 69 | + // 调用aclrtMemcpy将host侧数据拷贝到device侧内存上 | ||
| 70 | + ret = aclrtMemcpy(deviceAddr.get(), size, hostData.data(), size, ACL_MEMCPY_HOST_TO_DEVICE); | ||
| 71 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMemcpy failed. ERROR: %d\n", ret); return ret); | ||
| 57 | 72 | ||
| 58 | - // 计算连续tensor的strides | 73 | + // 计算连续tensor的strides |
| 59 | - std::vector<int64_t> strides(shape.size(), 1); | 74 | + std::vector<int64_t> strides(shape.size(), 1); |
| 60 | - for (int64_t i = shape.size() - 2; i >= 0; i--) { | 75 | + for (int64_t i = shape.size() - 2; i >= 0; i--) { |
| 61 | - strides[i] = shape[i + 1] * strides[i + 1]; | 76 | + strides[i] = shape[i + 1] * strides[i + 1]; |
| 62 | - } | 77 | + } |
| 63 | 78 | ||
| 64 | - // 调用aclCreateTensor接口创建aclTensor | 79 | + // 调用aclCreateTensor接口创建aclTensor |
| 65 | - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, | 80 | + aclTensor* rawTensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, |
| 66 | - shape.data(), shape.size(), *deviceAddr); | 81 | + aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), deviceAddr.get()); |
| 67 | - return 0; | 82 | + CHECK_RET(rawTensor != nullptr, LOG_PRINT("aclCreateTensor failed.\n"); return ACL_ERROR_FAILURE); |
| 83 | + tensor.reset(rawTensor); | ||
| 84 | + return 0; | ||
| 68 | } | 85 | } |
| 69 | 86 | ||
| 70 | -int main() { | 87 | +int main() |
| 71 | - // 1. (固定写法)device/stream初始化,参考acl API手册 | 88 | +{ |
| 72 | - // 根据自己的实际device填写deviceId | 89 | + // 1. (固定写法)device/stream初始化,参考acl API手册 |
| 73 | - int32_t deviceId = 0; | 90 | + // 根据自己的实际device填写deviceId |
| 74 | - aclrtStream stream; | 91 | + int32_t deviceId = 0; |
| 75 | - auto ret = Init(deviceId, &stream); | 92 | + bool initialized = false; |
| 76 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); | 93 | + bool deviceSet = false; |
| 94 | + std::shared_ptr<void> aclGuard(nullptr, [&](void*) { | ||
| 95 | + if (deviceSet) { | ||
| 96 | + aclrtResetDevice(deviceId); | ||
| 97 | + } | ||
| 98 | + if (initialized) { | ||
| 99 | + aclFinalize(); | ||
| 100 | + } | ||
| 101 | + }); | ||
| 102 | + StreamPtr stream(nullptr, &aclrtDestroyStream); | ||
| 103 | + auto ret = Init(deviceId, stream, initialized, deviceSet); | ||
| 104 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); | ||
| 77 | 105 | ||
| 78 | - // 2. 构造输入与输出,需要根据API的接口自定义构造 | 106 | + // 2. 构造输入与输出,需要根据API的接口自定义构造 |
| 79 | - std::vector<int64_t> selfShape = {4, 2}; | 107 | + std::vector<int64_t> selfShape = {4, 2}; |
| 80 | - std::vector<int64_t> outShape = {4, 2}; | 108 | + std::vector<int64_t> outShape = {4, 2}; |
| 81 | - void* selfDeviceAddr = nullptr; | 109 | + DeviceMemPtr selfDeviceAddr(nullptr, &aclrtFree); |
| 82 | - void* outDeviceAddr = nullptr; | 110 | + DeviceMemPtr outDeviceAddr(nullptr, &aclrtFree); |
| 83 | - aclTensor* self = nullptr; | 111 | + TensorPtr self(nullptr, &aclDestroyTensor); |
| 84 | - aclTensor* out = nullptr; | 112 | + TensorPtr out(nullptr, &aclDestroyTensor); |
| 85 | - std::vector<float> selfHostData = {0, 1, 2, 3, 4, 5, 6, 7}; | 113 | + std::vector<float> selfHostData = {0, 1, 2, 3, 4, 5, 6, 7}; |
| 86 | - std::vector<float> outHostData(8, 0); | 114 | + std::vector<float> outHostData(8, 0); |
| 87 | - // 创建self aclTensor | 115 | + // 创建self aclTensor |
| 88 | - ret = CreateAclTensor(selfHostData, selfShape, &selfDeviceAddr, aclDataType::ACL_FLOAT, &self); | 116 | + ret = CreateAclTensor(selfHostData, selfShape, aclDataType::ACL_FLOAT, selfDeviceAddr, self); |
| 89 | - CHECK_RET(ret == ACL_SUCCESS, return ret); | 117 | + CHECK_RET(ret == ACL_SUCCESS, return ret); |
| 90 | - // 创建out aclTensor | 118 | + // 创建out aclTensor |
| 91 | - ret = CreateAclTensor(outHostData, outShape, &outDeviceAddr, aclDataType::ACL_FLOAT, &out); | 119 | + ret = CreateAclTensor(outHostData, outShape, aclDataType::ACL_FLOAT, outDeviceAddr, out); |
| 92 | - CHECK_RET(ret == ACL_SUCCESS, return ret); | 120 | + CHECK_RET(ret == ACL_SUCCESS, return ret); |
| 93 | 121 | ||
| 94 | - // 3. 调用CANN算子库API,需要修改为具体的Api名称 | 122 | + // 3. 调用CANN算子库API,需要修改为具体的Api名称 |
| 95 | - uint64_t workspaceSize = 0; | 123 | + uint64_t workspaceSize = 0; |
| 96 | - aclOpExecutor* executor; | 124 | + aclOpExecutor* executor; |
| 97 | - // 调用aclnnLog第一段接口 | 125 | + // 调用aclnnLog第一段接口 |
| 98 | - ret = aclnnLogGetWorkspaceSize(self, out, &workspaceSize, &executor); | 126 | + ret = aclnnLogGetWorkspaceSize(self.get(), out.get(), &workspaceSize, &executor); |
| 99 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnLogGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); | 127 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnLogGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); |
| 100 | - // 根据第一段接口计算出的workspaceSize申请device内存 | 128 | + // 根据第一段接口计算出的workspaceSize申请device内存 |
| 101 | - void* workspaceAddr = nullptr; | 129 | + DeviceMemPtr workspaceAddr(nullptr, &aclrtFree); |
| 102 | - if (workspaceSize > 0) { | 130 | + if (workspaceSize > static_cast<uint64_t>(0)) { |
| 103 | - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); | 131 | + void* rawWorkspaceAddr = nullptr; |
| 104 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); | 132 | + ret = aclrtMalloc(&rawWorkspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); |
| 105 | - } | 133 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); |
| 106 | - // 调用aclnnLog第二段接口 | 134 | + workspaceAddr.reset(rawWorkspaceAddr); |
| 107 | - ret = aclnnLog(workspaceAddr, workspaceSize, executor, stream); | 135 | + } |
| 108 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnLog failed. ERROR: %d\n", ret); return ret); | 136 | + // 调用aclnnLog第二段接口 |
| 137 | + ret = aclnnLog(workspaceAddr.get(), workspaceSize, executor, stream.get()); | ||
| 138 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnLog failed. ERROR: %d\n", ret); return ret); | ||
| 109 | 139 | ||
| 110 | - // 4. (固定写法)同步等待任务执行结束 | 140 | + // 4. (固定写法)同步等待任务执行结束 |
| 111 | - ret = aclrtSynchronizeStream(stream); | 141 | + ret = aclrtSynchronizeStream(stream.get()); |
| 112 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); | 142 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); |
| 113 | 143 | ||
| 114 | - // 5. 获取输出的值,将device侧内存上的结果拷贝至host侧,需要根据具体API的接口定义修改 | 144 | + // 5. 获取输出的值,将device侧内存上的结果拷贝至host侧,需要根据具体API的接口定义修改 |
| 115 | - auto size = GetShapeSize(outShape); | 145 | + auto size = GetShapeSize(outShape); |
| 116 | - std::vector<float> resultData(size, 0); | 146 | + std::vector<float> resultData(size, 0); |
| 117 | - ret = aclrtMemcpy(resultData.data(), resultData.size() * sizeof(resultData[0]), outDeviceAddr, | 147 | + ret = aclrtMemcpy(resultData.data(), resultData.size() * sizeof(resultData[0]), outDeviceAddr.get(), |
| 118 | - size * sizeof(resultData[0]), ACL_MEMCPY_DEVICE_TO_HOST); | 148 | + size * sizeof(resultData[0]), ACL_MEMCPY_DEVICE_TO_HOST); |
| 119 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("copy result from device to host failed. ERROR: %d\n", ret); return ret); | 149 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("copy result from device to host failed. ERROR: %d\n", ret); return ret); |
| 120 | - for (int64_t i = 0; i < size; i++) { | 150 | + for (int64_t i = 0; i < size; i++) { |
| 121 | - LOG_PRINT("result[%ld] is: %f\n", i, resultData[i]); | 151 | + LOG_PRINT("result[%ld] is: %f\n", i, resultData[i]); |
| 122 | - } | 152 | + } |
| 123 | 153 | ||
| 124 | - // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 | 154 | + return 0; |
| 125 | - aclDestroyTensor(self); | 155 | +} |
| 126 | - aclDestroyTensor(out); | ||
| 127 | - | ||
| 128 | - // 7. 释放device资源,需要根据具体API的接口定义修改 | ||
| 129 | - aclrtFree(selfDeviceAddr); | ||
| 130 | - aclrtFree(outDeviceAddr); | ||
| 131 | - if (workspaceSize > 0) { | ||
| 132 | - aclrtFree(workspaceAddr); | ||
| 133 | - } | ||
| 134 | - aclrtDestroyStream(stream); | ||
| 135 | - aclrtResetDevice(deviceId); | ||
| 136 | - aclFinalize(); | ||
| 137 | - return 0; | ||
| 138 | -} | ||
| @@ -9,6 +9,8 @@ | |||
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | 11 | ||
| 12 | + | ||
| 13 | + | ||
| 12 | 14 | ||
| 13 | 15 | ||
| 14 | 16 | ||
| @@ -34,29 +36,39 @@ int64_t GetShapeSize(const std::vector<int64_t>& shape) | |||
| 34 | return shape_size; | 36 | return shape_size; |
| 35 | } | 37 | } |
| 36 | 38 | ||
| 37 | -int Init(int32_t deviceId, aclrtStream* stream) | 39 | +using StreamPtr = std::unique_ptr<std::remove_pointer<aclrtStream>::type, decltype(&aclrtDestroyStream)>; |
| 40 | +using DeviceMemPtr = std::unique_ptr<void, decltype(&aclrtFree)>; | ||
| 41 | +using TensorPtr = std::unique_ptr<aclTensor, decltype(&aclDestroyTensor)>; | ||
| 42 | + | ||
| 43 | +int Init(int32_t deviceId, StreamPtr& stream, bool& initialized, bool& deviceSet) | ||
| 38 | { | 44 | { |
| 39 | // 固定写法,资源初始化 | 45 | // 固定写法,资源初始化 |
| 40 | auto ret = aclInit(nullptr); | 46 | auto ret = aclInit(nullptr); |
| 41 | CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclInit failed. ERROR: %d\n", ret); return ret); | 47 | CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclInit failed. ERROR: %d\n", ret); return ret); |
| 48 | + initialized = true; | ||
| 42 | ret = aclrtSetDevice(deviceId); | 49 | ret = aclrtSetDevice(deviceId); |
| 43 | CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSetDevice failed. ERROR: %d\n", ret); return ret); | 50 | CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSetDevice failed. ERROR: %d\n", ret); return ret); |
| 44 | - ret = aclrtCreateStream(stream); | 51 | + deviceSet = true; |
| 52 | + aclrtStream rawStream = nullptr; | ||
| 53 | + ret = aclrtCreateStream(&rawStream); | ||
| 45 | CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtCreateStream failed. ERROR: %d\n", ret); return ret); | 54 | CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtCreateStream failed. ERROR: %d\n", ret); return ret); |
| 55 | + stream.reset(rawStream); | ||
| 46 | return 0; | 56 | return 0; |
| 47 | } | 57 | } |
| 48 | 58 | ||
| 49 | template <typename T> | 59 | template <typename T> |
| 50 | -int CreateAclTensor(const std::vector<T>& hostData, const std::vector<int64_t>& shape, void** deviceAddr, | 60 | +int CreateAclTensor(const std::vector<T>& hostData, const std::vector<int64_t>& shape, aclDataType dataType, |
| 51 | - aclDataType dataType, aclTensor** tensor) | 61 | + DeviceMemPtr& deviceAddr, TensorPtr& tensor) |
| 52 | { | 62 | { |
| 53 | auto size = GetShapeSize(shape) * sizeof(T); | 63 | auto size = GetShapeSize(shape) * sizeof(T); |
| 54 | // 调用aclrtMalloc申请device侧内存 | 64 | // 调用aclrtMalloc申请device侧内存 |
| 55 | - auto ret = aclrtMalloc(deviceAddr, size, ACL_MEM_MALLOC_HUGE_FIRST); | 65 | + void* rawDeviceAddr = nullptr; |
| 66 | + auto ret = aclrtMalloc(&rawDeviceAddr, size, ACL_MEM_MALLOC_HUGE_FIRST); | ||
| 56 | CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMalloc failed. ERROR: %d\n", ret); return ret); | 67 | CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMalloc failed. ERROR: %d\n", ret); return ret); |
| 68 | + deviceAddr.reset(rawDeviceAddr); | ||
| 57 | 69 | ||
| 58 | // 调用aclrtMemcpy将host侧数据拷贝到device侧内存上 | 70 | // 调用aclrtMemcpy将host侧数据拷贝到device侧内存上 |
| 59 | - ret = aclrtMemcpy(*deviceAddr, size, hostData.data(), size, ACL_MEMCPY_HOST_TO_DEVICE); | 71 | + ret = aclrtMemcpy(deviceAddr.get(), size, hostData.data(), size, ACL_MEMCPY_HOST_TO_DEVICE); |
| 60 | CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMemcpy failed. ERROR: %d\n", ret); return ret); | 72 | CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMemcpy failed. ERROR: %d\n", ret); return ret); |
| 61 | 73 | ||
| 62 | // 计算连续tensor的strides | 74 | // 计算连续tensor的strides |
| @@ -66,8 +78,10 @@ int CreateAclTensor(const std::vector<T>& hostData, const std::vector<int64_t>& | |||
| 66 | } | 78 | } |
| 67 | 79 | ||
| 68 | // 调用aclCreateTensor接口创建aclTensor | 80 | // 调用aclCreateTensor接口创建aclTensor |
| 69 | - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, | 81 | + aclTensor* rawTensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, |
| 70 | - shape.data(), shape.size(), *deviceAddr); | 82 | + aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), deviceAddr.get()); |
| 83 | + CHECK_RET(rawTensor != nullptr, LOG_PRINT("aclCreateTensor failed.\n"); return ACL_ERROR_FAILURE); | ||
| 84 | + tensor.reset(rawTensor); | ||
| 71 | return 0; | 85 | return 0; |
| 72 | } | 86 | } |
| 73 | 87 | ||
| @@ -76,25 +90,35 @@ int main() | |||
| 76 | // 1. (固定写法)device/stream初始化, 参考acl API手册 | 90 | // 1. (固定写法)device/stream初始化, 参考acl API手册 |
| 77 | // 根据自己的实际device填写deviceId | 91 | // 根据自己的实际device填写deviceId |
| 78 | int32_t deviceId = 0; | 92 | int32_t deviceId = 0; |
| 79 | - aclrtStream stream; | 93 | + bool initialized = false; |
| 80 | - auto ret = Init(deviceId, &stream); | 94 | + bool deviceSet = false; |
| 95 | + std::shared_ptr<void> aclGuard(nullptr, [&](void*) { | ||
| 96 | + if (deviceSet) { | ||
| 97 | + aclrtResetDevice(deviceId); | ||
| 98 | + } | ||
| 99 | + if (initialized) { | ||
| 100 | + aclFinalize(); | ||
| 101 | + } | ||
| 102 | + }); | ||
| 103 | + StreamPtr stream(nullptr, &aclrtDestroyStream); | ||
| 104 | + auto ret = Init(deviceId, stream, initialized, deviceSet); | ||
| 81 | // check根据自己的需要处理 | 105 | // check根据自己的需要处理 |
| 82 | - CHECK_RET(ret == 0, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); | 106 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); |
| 83 | // 2. 构造输入与输出,需要根据API的接口自定义构造 | 107 | // 2. 构造输入与输出,需要根据API的接口自定义构造 |
| 84 | std::vector<int64_t> selfShape = {4, 2}; | 108 | std::vector<int64_t> selfShape = {4, 2}; |
| 85 | std::vector<int64_t> outShape = {4, 2}; | 109 | std::vector<int64_t> outShape = {4, 2}; |
| 86 | - void* selfDeviceAddr = nullptr; | 110 | + DeviceMemPtr selfDeviceAddr(nullptr, &aclrtFree); |
| 87 | - void* outDeviceAddr = nullptr; | 111 | + DeviceMemPtr outDeviceAddr(nullptr, &aclrtFree); |
| 88 | - aclTensor* self = nullptr; | 112 | + TensorPtr self(nullptr, &aclDestroyTensor); |
| 89 | - aclTensor* out = nullptr; | 113 | + TensorPtr out(nullptr, &aclDestroyTensor); |
| 90 | std::vector<float> selfHostData = {0, 1, 2, 3, 4, 5, 6, 7}; | 114 | std::vector<float> selfHostData = {0, 1, 2, 3, 4, 5, 6, 7}; |
| 91 | std::vector<float> outHostData = {0, 0, 0, 0, 0, 0, 0, 0}; | 115 | std::vector<float> outHostData = {0, 0, 0, 0, 0, 0, 0, 0}; |
| 92 | 116 | ||
| 93 | // 创建self aclTensor | 117 | // 创建self aclTensor |
| 94 | - ret = CreateAclTensor(selfHostData, selfShape, &selfDeviceAddr, aclDataType::ACL_FLOAT, &self); | 118 | + ret = CreateAclTensor(selfHostData, selfShape, aclDataType::ACL_FLOAT, selfDeviceAddr, self); |
| 95 | CHECK_RET(ret == ACL_SUCCESS, return ret); | 119 | CHECK_RET(ret == ACL_SUCCESS, return ret); |
| 96 | // 创建out aclTensor | 120 | // 创建out aclTensor |
| 97 | - ret = CreateAclTensor(outHostData, outShape, &outDeviceAddr, aclDataType::ACL_FLOAT, &out); | 121 | + ret = CreateAclTensor(outHostData, outShape, aclDataType::ACL_FLOAT, outDeviceAddr, out); |
| 98 | CHECK_RET(ret == ACL_SUCCESS, return ret); | 122 | CHECK_RET(ret == ACL_SUCCESS, return ret); |
| 99 | 123 | ||
| 100 | // aclnnLog10接口调用示例 | 124 | // aclnnLog10接口调用示例 |
| @@ -102,42 +126,31 @@ int main() | |||
| 102 | uint64_t workspaceSize = 0; | 126 | uint64_t workspaceSize = 0; |
| 103 | aclOpExecutor* executor; | 127 | aclOpExecutor* executor; |
| 104 | // 调用aclnnLog10第一段接口 | 128 | // 调用aclnnLog10第一段接口 |
| 105 | - ret = aclnnLog10GetWorkspaceSize(self, out, &workspaceSize, &executor); | 129 | + ret = aclnnLog10GetWorkspaceSize(self.get(), out.get(), &workspaceSize, &executor); |
| 106 | CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnLog10GetWorkspaceSize failed. ERROR: %d\n", ret); return ret); | 130 | CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnLog10GetWorkspaceSize failed. ERROR: %d\n", ret); return ret); |
| 107 | // 根据第一段接口计算出的workspaceSize申请device内存 | 131 | // 根据第一段接口计算出的workspaceSize申请device内存 |
| 108 | - void* workspaceAddr = nullptr; | 132 | + DeviceMemPtr workspaceAddr(nullptr, &aclrtFree); |
| 109 | - if (workspaceSize > 0) { | 133 | + if (workspaceSize > static_cast<uint64_t>(0)) { |
| 110 | - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); | 134 | + void* rawWorkspaceAddr = nullptr; |
| 135 | + ret = aclrtMalloc(&rawWorkspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); | ||
| 111 | CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); | 136 | CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); |
| 137 | + workspaceAddr.reset(rawWorkspaceAddr); | ||
| 112 | } | 138 | } |
| 113 | // 调用aclnnLog10第二段接口 | 139 | // 调用aclnnLog10第二段接口 |
| 114 | - ret = aclnnLog10(workspaceAddr, workspaceSize, executor, stream); | 140 | + ret = aclnnLog10(workspaceAddr.get(), workspaceSize, executor, stream.get()); |
| 115 | CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnLog10 failed. ERROR: %d\n", ret); return ret); | 141 | CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnLog10 failed. ERROR: %d\n", ret); return ret); |
| 116 | // 4. (固定写法)同步等待任务执行结束 | 142 | // 4. (固定写法)同步等待任务执行结束 |
| 117 | - ret = aclrtSynchronizeStream(stream); | 143 | + ret = aclrtSynchronizeStream(stream.get()); |
| 118 | CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); | 144 | CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); |
| 119 | // 5. 获取输出的值,将device侧内存上的结果拷贝至host侧,需要根据具体API的接口定义修改 | 145 | // 5. 获取输出的值,将device侧内存上的结果拷贝至host侧,需要根据具体API的接口定义修改 |
| 120 | auto size = GetShapeSize(outShape); | 146 | auto size = GetShapeSize(outShape); |
| 121 | std::vector<float> resultData(size, 0); | 147 | std::vector<float> resultData(size, 0); |
| 122 | - ret = aclrtMemcpy(resultData.data(), resultData.size() * sizeof(resultData[0]), outDeviceAddr, | 148 | + ret = aclrtMemcpy(resultData.data(), resultData.size() * sizeof(resultData[0]), outDeviceAddr.get(), |
| 123 | size * sizeof(resultData[0]), ACL_MEMCPY_DEVICE_TO_HOST); | 149 | size * sizeof(resultData[0]), ACL_MEMCPY_DEVICE_TO_HOST); |
| 124 | CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("copy result from device to host failed. ERROR: %d\n", ret); return ret); | 150 | CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("copy result from device to host failed. ERROR: %d\n", ret); return ret); |
| 125 | for (int64_t i = 0; i < size; i++) { | 151 | for (int64_t i = 0; i < size; i++) { |
| 126 | LOG_PRINT("result[%ld] is: %f\n", i, resultData[i]); | 152 | LOG_PRINT("result[%ld] is: %f\n", i, resultData[i]); |
| 127 | } | 153 | } |
| 128 | 154 | ||
| 129 | - // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 | ||
| 130 | - aclDestroyTensor(self); | ||
| 131 | - aclDestroyTensor(out); | ||
| 132 | - | ||
| 133 | - // 7. 释放device资源,需要根据具体API的接口定义修改 | ||
| 134 | - aclrtFree(selfDeviceAddr); | ||
| 135 | - aclrtFree(outDeviceAddr); | ||
| 136 | - if (workspaceSize > 0) { | ||
| 137 | - aclrtFree(workspaceAddr); | ||
| 138 | - } | ||
| 139 | - aclrtDestroyStream(stream); | ||
| 140 | - aclrtResetDevice(deviceId); | ||
| 141 | - aclFinalize(); | ||
| 142 | return 0; | 155 | return 0; |
| 143 | } | 156 | } |
| @@ -9,130 +9,147 @@ | |||
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | 11 | ||
| 12 | + | ||
| 13 | + | ||
| 12 | 14 | ||
| 13 | 15 | ||
| 14 | 16 | ||
| 15 | 17 | ||
| 16 | 18 | ||
| 17 | - do { \ | 19 | + do { \ |
| 18 | - if (!(cond)) { \ | 20 | + if (!(cond)) { \ |
| 19 | - return_expr; \ | 21 | + return_expr; \ |
| 20 | - } \ | 22 | + } \ |
| 21 | - } while (0) | 23 | + } while (0) |
| 22 | 24 | ||
| 23 | -#define LOG_PRINT(message, ...) \ | 25 | +#define LOG_PRINT(message, ...) \ |
| 24 | - do { \ | 26 | + do { \ |
| 25 | - printf(message, ##__VA_ARGS__); \ | 27 | + printf(message, ##__VA_ARGS__); \ |
| 26 | - } while (0) | 28 | + } while (0) |
| 27 | 29 | ||
| 28 | -int64_t GetShapeSize(const std::vector<int64_t>& shape) { | 30 | +int64_t GetShapeSize(const std::vector<int64_t>& shape) |
| 29 | - int64_t shapeSize = 1; | 31 | +{ |
| 30 | - for (auto i : shape) { | 32 | + int64_t shapeSize = 1; |
| 31 | - shapeSize *= i; | 33 | + for (auto i : shape) { |
| 32 | - } | 34 | + shapeSize *= i; |
| 33 | - return shapeSize; | 35 | + } |
| 36 | + return shapeSize; | ||
| 34 | } | 37 | } |
| 35 | 38 | ||
| 36 | -int Init(int32_t deviceId, aclrtStream* stream) { | 39 | +using StreamPtr = std::unique_ptr<std::remove_pointer<aclrtStream>::type, decltype(&aclrtDestroyStream)>; |
| 37 | - // 固定写法,资源初始化 | 40 | +using DeviceMemPtr = std::unique_ptr<void, decltype(&aclrtFree)>; |
| 38 | - auto ret = aclInit(nullptr); | 41 | +using TensorPtr = std::unique_ptr<aclTensor, decltype(&aclDestroyTensor)>; |
| 39 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclInit failed. ERROR: %d\n", ret); return ret); | 42 | + |
| 40 | - ret = aclrtSetDevice(deviceId); | 43 | +int Init(int32_t deviceId, StreamPtr& stream, bool& initialized, bool& deviceSet) |
| 41 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSetDevice failed. ERROR: %d\n", ret); return ret); | 44 | +{ |
| 42 | - ret = aclrtCreateStream(stream); | 45 | + // 固定写法,资源初始化 |
| 43 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtCreateStream failed. ERROR: %d\n", ret); return ret); | 46 | + auto ret = aclInit(nullptr); |
| 44 | - return 0; | 47 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclInit failed. ERROR: %d\n", ret); return ret); |
| 48 | + initialized = true; | ||
| 49 | + ret = aclrtSetDevice(deviceId); | ||
| 50 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSetDevice failed. ERROR: %d\n", ret); return ret); | ||
| 51 | + deviceSet = true; | ||
| 52 | + aclrtStream rawStream = nullptr; | ||
| 53 | + ret = aclrtCreateStream(&rawStream); | ||
| 54 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtCreateStream failed. ERROR: %d\n", ret); return ret); | ||
| 55 | + stream.reset(rawStream); | ||
| 56 | + return 0; | ||
| 45 | } | 57 | } |
| 46 | 58 | ||
| 47 | template <typename T> | 59 | template <typename T> |
| 48 | -int CreateAclTensor(const std::vector<T>& hostData, const std::vector<int64_t>& shape, void** deviceAddr, | 60 | +int CreateAclTensor(const std::vector<T>& hostData, const std::vector<int64_t>& shape, aclDataType dataType, |
| 49 | - aclDataType dataType, aclTensor** tensor) { | 61 | + DeviceMemPtr& deviceAddr, TensorPtr& tensor) |
| 50 | - auto size = GetShapeSize(shape) * sizeof(T); | 62 | +{ |
| 51 | - // 调用aclrtMalloc申请device侧内存 | 63 | + auto size = GetShapeSize(shape) * sizeof(T); |
| 52 | - auto ret = aclrtMalloc(deviceAddr, size, ACL_MEM_MALLOC_HUGE_FIRST); | 64 | + // 调用aclrtMalloc申请device侧内存 |
| 53 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMalloc failed. ERROR: %d\n", ret); return ret); | 65 | + void* rawDeviceAddr = nullptr; |
| 54 | - // 调用aclrtMemcpy将host侧数据拷贝到device侧内存上 | 66 | + auto ret = aclrtMalloc(&rawDeviceAddr, size, ACL_MEM_MALLOC_HUGE_FIRST); |
| 55 | - ret = aclrtMemcpy(*deviceAddr, size, hostData.data(), size, ACL_MEMCPY_HOST_TO_DEVICE); | 67 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMalloc failed. ERROR: %d\n", ret); return ret); |
| 56 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMemcpy failed. ERROR: %d\n", ret); return ret); | 68 | + deviceAddr.reset(rawDeviceAddr); |
| 69 | + // 调用aclrtMemcpy将host侧数据拷贝到device侧内存上 | ||
| 70 | + ret = aclrtMemcpy(deviceAddr.get(), size, hostData.data(), size, ACL_MEMCPY_HOST_TO_DEVICE); | ||
| 71 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMemcpy failed. ERROR: %d\n", ret); return ret); | ||
| 57 | 72 | ||
| 58 | - // 计算连续tensor的strides | 73 | + // 计算连续tensor的strides |
| 59 | - std::vector<int64_t> strides(shape.size(), 1); | 74 | + std::vector<int64_t> strides(shape.size(), 1); |
| 60 | - for (int64_t i = shape.size() - 2; i >= 0; i--) { | 75 | + for (int64_t i = shape.size() - 2; i >= 0; i--) { |
| 61 | - strides[i] = shape[i + 1] * strides[i + 1]; | 76 | + strides[i] = shape[i + 1] * strides[i + 1]; |
| 62 | - } | 77 | + } |
| 63 | 78 | ||
| 64 | - // 调用aclCreateTensor接口创建aclTensor | 79 | + // 调用aclCreateTensor接口创建aclTensor |
| 65 | - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, | 80 | + aclTensor* rawTensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, |
| 66 | - shape.data(), shape.size(), *deviceAddr); | 81 | + aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), deviceAddr.get()); |
| 67 | - return 0; | 82 | + CHECK_RET(rawTensor != nullptr, LOG_PRINT("aclCreateTensor failed.\n"); return ACL_ERROR_FAILURE); |
| 83 | + tensor.reset(rawTensor); | ||
| 84 | + return 0; | ||
| 68 | } | 85 | } |
| 69 | 86 | ||
| 70 | -int main() { | 87 | +int main() |
| 71 | - // 1. (固定写法)device/stream初始化,参考acl API手册 | 88 | +{ |
| 72 | - // 根据自己的实际device填写deviceId | 89 | + // 1. (固定写法)device/stream初始化,参考acl API手册 |
| 73 | - int32_t deviceId = 0; | 90 | + // 根据自己的实际device填写deviceId |
| 74 | - aclrtStream stream; | 91 | + int32_t deviceId = 0; |
| 75 | - auto ret = Init(deviceId, &stream); | 92 | + bool initialized = false; |
| 76 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); | 93 | + bool deviceSet = false; |
| 94 | + std::shared_ptr<void> aclGuard(nullptr, [&](void*) { | ||
| 95 | + if (deviceSet) { | ||
| 96 | + aclrtResetDevice(deviceId); | ||
| 97 | + } | ||
| 98 | + if (initialized) { | ||
| 99 | + aclFinalize(); | ||
| 100 | + } | ||
| 101 | + }); | ||
| 102 | + StreamPtr stream(nullptr, &aclrtDestroyStream); | ||
| 103 | + auto ret = Init(deviceId, stream, initialized, deviceSet); | ||
| 104 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); | ||
| 77 | 105 | ||
| 78 | - // 2. 构造输入与输出,需要根据API的接口自定义构造 | 106 | + // 2. 构造输入与输出,需要根据API的接口自定义构造 |
| 79 | - std::vector<int64_t> selfShape = {4, 2}; | 107 | + std::vector<int64_t> selfShape = {4, 2}; |
| 80 | - std::vector<int64_t> outShape = {4, 2}; | 108 | + std::vector<int64_t> outShape = {4, 2}; |
| 81 | - void* selfDeviceAddr = nullptr; | 109 | + DeviceMemPtr selfDeviceAddr(nullptr, &aclrtFree); |
| 82 | - void* outDeviceAddr = nullptr; | 110 | + DeviceMemPtr outDeviceAddr(nullptr, &aclrtFree); |
| 83 | - aclTensor* self = nullptr; | 111 | + TensorPtr self(nullptr, &aclDestroyTensor); |
| 84 | - aclTensor* out = nullptr; | 112 | + TensorPtr out(nullptr, &aclDestroyTensor); |
| 85 | - std::vector<float> selfHostData = {0, 1, 2, 3, 4, 5, 6, 7}; | 113 | + std::vector<float> selfHostData = {0, 1, 2, 3, 4, 5, 6, 7}; |
| 86 | - std::vector<float> outHostData(8, 0); | 114 | + std::vector<float> outHostData(8, 0); |
| 87 | - // 创建self aclTensor | 115 | + // 创建self aclTensor |
| 88 | - ret = CreateAclTensor(selfHostData, selfShape, &selfDeviceAddr, aclDataType::ACL_FLOAT, &self); | 116 | + ret = CreateAclTensor(selfHostData, selfShape, aclDataType::ACL_FLOAT, selfDeviceAddr, self); |
| 89 | - CHECK_RET(ret == ACL_SUCCESS, return ret); | 117 | + CHECK_RET(ret == ACL_SUCCESS, return ret); |
| 90 | - // 创建out aclTensor | 118 | + // 创建out aclTensor |
| 91 | - ret = CreateAclTensor(outHostData, outShape, &outDeviceAddr, aclDataType::ACL_FLOAT, &out); | 119 | + ret = CreateAclTensor(outHostData, outShape, aclDataType::ACL_FLOAT, outDeviceAddr, out); |
| 92 | - CHECK_RET(ret == ACL_SUCCESS, return ret); | 120 | + CHECK_RET(ret == ACL_SUCCESS, return ret); |
| 93 | 121 | ||
| 94 | - // 3. 调用CANN算子库API,需要修改为具体的Api名称 | 122 | + // 3. 调用CANN算子库API,需要修改为具体的Api名称 |
| 95 | - uint64_t workspaceSize = 0; | 123 | + uint64_t workspaceSize = 0; |
| 96 | - aclOpExecutor* executor; | 124 | + aclOpExecutor* executor; |
| 97 | - // 调用aclnnLog2第一段接口 | 125 | + // 调用aclnnLog2第一段接口 |
| 98 | - ret = aclnnLog2GetWorkspaceSize(self, out, &workspaceSize, &executor); | 126 | + ret = aclnnLog2GetWorkspaceSize(self.get(), out.get(), &workspaceSize, &executor); |
| 99 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnLog2GetWorkspaceSize failed. ERROR: %d\n", ret); return ret); | 127 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnLog2GetWorkspaceSize failed. ERROR: %d\n", ret); return ret); |
| 100 | - // 根据第一段接口计算出的workspaceSize申请device内存 | 128 | + // 根据第一段接口计算出的workspaceSize申请device内存 |
| 101 | - void* workspaceAddr = nullptr; | 129 | + DeviceMemPtr workspaceAddr(nullptr, &aclrtFree); |
| 102 | - if (workspaceSize > 0) { | 130 | + if (workspaceSize > static_cast<uint64_t>(0)) { |
| 103 | - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); | 131 | + void* rawWorkspaceAddr = nullptr; |
| 104 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); | 132 | + ret = aclrtMalloc(&rawWorkspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); |
| 105 | - } | 133 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); |
| 106 | - // 调用aclnnLog2第二段接口 | 134 | + workspaceAddr.reset(rawWorkspaceAddr); |
| 107 | - ret = aclnnLog2(workspaceAddr, workspaceSize, executor, stream); | 135 | + } |
| 108 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnLog2 failed. ERROR: %d\n", ret); return ret); | 136 | + // 调用aclnnLog2第二段接口 |
| 137 | + ret = aclnnLog2(workspaceAddr.get(), workspaceSize, executor, stream.get()); | ||
| 138 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnLog2 failed. ERROR: %d\n", ret); return ret); | ||
| 109 | 139 | ||
| 110 | - // 4. (固定写法)同步等待任务执行结束 | 140 | + // 4. (固定写法)同步等待任务执行结束 |
| 111 | - ret = aclrtSynchronizeStream(stream); | 141 | + ret = aclrtSynchronizeStream(stream.get()); |
| 112 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); | 142 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); |
| 113 | 143 | ||
| 114 | - // 5. 获取输出的值,将device侧内存上的结果拷贝至host侧,需要根据具体API的接口定义修改 | 144 | + // 5. 获取输出的值,将device侧内存上的结果拷贝至host侧,需要根据具体API的接口定义修改 |
| 115 | - auto size = GetShapeSize(outShape); | 145 | + auto size = GetShapeSize(outShape); |
| 116 | - std::vector<float> resultData(size, 0); | 146 | + std::vector<float> resultData(size, 0); |
| 117 | - ret = aclrtMemcpy(resultData.data(), resultData.size() * sizeof(resultData[0]), outDeviceAddr, | 147 | + ret = aclrtMemcpy(resultData.data(), resultData.size() * sizeof(resultData[0]), outDeviceAddr.get(), |
| 118 | - size * sizeof(resultData[0]), ACL_MEMCPY_DEVICE_TO_HOST); | 148 | + size * sizeof(resultData[0]), ACL_MEMCPY_DEVICE_TO_HOST); |
| 119 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("copy result from device to host failed. ERROR: %d\n", ret); return ret); | 149 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("copy result from device to host failed. ERROR: %d\n", ret); return ret); |
| 120 | - for (int64_t i = 0; i < size; i++) { | 150 | + for (int64_t i = 0; i < size; i++) { |
| 121 | - LOG_PRINT("result[%ld] is: %f\n", i, resultData[i]); | 151 | + LOG_PRINT("result[%ld] is: %f\n", i, resultData[i]); |
| 122 | - } | 152 | + } |
| 123 | 153 | ||
| 124 | - // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 | 154 | + return 0; |
| 125 | - aclDestroyTensor(self); | 155 | +} |
| 126 | - aclDestroyTensor(out); | ||
| 127 | - | ||
| 128 | - // 7. 释放device资源,需要根据具体API的接口定义修改 | ||
| 129 | - aclrtFree(selfDeviceAddr); | ||
| 130 | - aclrtFree(outDeviceAddr); | ||
| 131 | - if (workspaceSize > 0) { | ||
| 132 | - aclrtFree(workspaceAddr); | ||
| 133 | - } | ||
| 134 | - aclrtDestroyStream(stream); | ||
| 135 | - aclrtResetDevice(deviceId); | ||
| 136 | - aclFinalize(); | ||
| 137 | - return 0; | ||
| 138 | -} | ||