[INFO] Initializing environment for https://gitcode.com/pre-commit/pre-commit-hooks. [WARNING] repo `https://gitcode.com/pre-commit/pre-commit-hooks` uses deprecated stage names (commit, push) which will be removed in a future version. Hint: often `pre-commit autoupdate --repo https://gitcode.com/pre-commit/pre-commit-hooks` will fix this. if it does not -- consider reporting an issue to that repo. [INFO] Initializing environment for https://gitcode.com/pre-commit-clang/mirrors-clang-format. [INFO] Initializing environment for https://gitcode.com/gh_mirrors/ru/ruff-pre-commit. [INFO] Initializing environment for https://gitcode.com/gh_mirrors/co/codespell. [INFO] Installing environment for https://gitcode.com/pre-commit/pre-commit-hooks. [INFO] Once installed this environment will be reused. [INFO] This may take a few minutes... [INFO] Installing environment for https://gitcode.com/pre-commit-clang/mirrors-clang-format. [INFO] Once installed this environment will be reused. [INFO] This may take a few minutes... [INFO] Installing environment for https://gitcode.com/gh_mirrors/ru/ruff-pre-commit. [INFO] Once installed this environment will be reused. [INFO] This may take a few minutes... [INFO] Installing environment for https://gitcode.com/gh_mirrors/co/codespell. [INFO] Once installed this environment will be reused. [INFO] This may take a few minutes... trim trailing whitespace.................................................Failed - hook id: trailing-whitespace - exit code: 1 - files were modified by this hook Fixing foreach/foreach_addcmul_scalar/docs/aclnnForeachAddcmulScalar.md Fixing foreach/foreach_minimum_scalar/docs/aclnnForeachMinimumScalarV2.md Fixing foreach/foreach_expm1/docs/aclnnForeachExpm1.md Fixing foreach/foreach_sign/docs/aclnnForeachSign.md Fixing foreach/foreach_sub_scalar/docs/aclnnForeachSubScalarV2.md Fixing foreach/foreach_add_scalar_list/docs/aclnnForeachAddScalarList.md Fixing foreach/foreach_tan/docs/aclnnForeachTan.md Fixing foreach/foreach_log2/docs/aclnnForeachLog2.md Fixing foreach/foreach_lerp_scalar/docs/aclnnForeachLerpScalar.md Fixing foreach/foreach_cosh/docs/aclnnForeachCosh.md Fixing foreach/foreach_erf/docs/aclnnForeachErf.md Fixing foreach/foreach_round_off_number/docs/aclnnForeachRoundOffNumberV2.md Fixing foreach/foreach_log1p/docs/aclnnForeachLog1p.md Fixing foreach/foreach_asin/docs/aclnnForeachAsin.md Fixing foreach/foreach_addcdiv_scalar/docs/aclnnForeachAddcdivScalar.md Fixing foreach/foreach_addcdiv_scalar/docs/aclnnForeachAddcdivScalarV2.md Fixing foreach/foreach_mul_scalar_list/docs/aclnnForeachMulScalarList.md Fixing foreach/foreach_pow_scalar/docs/aclnnForeachPowScalar.md Fixing foreach/foreach_cos/docs/aclnnForeachCos.md Fixing foreach/foreach_maximum_scalar/examples/test_aclnn_foreach_maximum_scalar.cpp Fixing foreach/foreach_atan/docs/aclnnForeachAtan.md Fixing foreach/foreach_reciprocal/docs/aclnnForeachReciprocal.md Fixing foreach/foreach_sinh/docs/aclnnForeachSinh.md Fixing foreach/foreach_addcdiv_list/docs/aclnnForeachAddcdivList.md Fixing foreach/foreach_mul_scalar/docs/aclnnForeachMulScalarV2.md Fixing foreach/foreach_minimum_list/docs/aclnnForeachMinimumList.md Fixing foreach/foreach_div_list/docs/aclnnForeachDivList.md Fixing foreach/foreach_pow_scalar/docs/aclnnForeachPowScalarV2.md Fixing foreach/foreach_mul_scalar/docs/aclnnForeachMulScalar.md Fixing foreach/foreach_minimum_scalar_list/docs/aclnnForeachMinimumScalarList.md Fixing foreach/foreach_lerp_list/docs/aclnnForeachLerpList.md Fixing foreach/foreach_minimum_scalar/docs/aclnnForeachMinimumScalar.md Fixing foreach/foreach_maximum_scalar/docs/aclnnForeachMaximumScalar.md Fixing foreach/foreach_norm/docs/aclnnForeachNorm.md Fixing foreach/foreach_neg/docs/aclnnForeachNeg.md Fixing foreach/foreach_add_list/docs/aclnnForeachAddList.md Fixing foreach/foreach_maximum_list/docs/aclnnForeachMaximumList.md Fixing foreach/foreach_zero_inplace/docs/aclnnForeachZeroInplace.md Fixing foreach/foreach_maximum_scalar_list/docs/aclnnForeachMaximumScalarList.md Fixing foreach/foreach_div_scalar/docs/aclnnForeachDivScalar.md Fixing foreach/foreach_sub_list/docs/aclnnForeachSubListV2.md Fixing foreach/foreach_pow_list/docs/aclnnForeachPowList.md Fixing foreach/foreach_sqrt/docs/aclnnForeachSqrt.md Fixing foreach/foreach_div_scalar_list/docs/aclnnForeachDivScalarList.md Fixing foreach/foreach_add_scalar/docs/aclnnForeachAddScalarV2.md Fixing foreach/foreach_addcmul_scalar_list/docs/aclnnForeachAddcmulScalarList.md Fixing foreach/foreach_abs/docs/aclnnForeachAbs.md Fixing foreach/foreach_addcmul_scalar/docs/aclnnForeachAddcmulScalarV2.md Fixing foreach/foreach_acos/docs/aclnnForeachAcos.md Fixing foreach/foreach_maximum_scalar/docs/aclnnForeachMaximumScalarV2.md Fixing foreach/foreach_add_list/docs/aclnnForeachAddListV2.md Fixing foreach/foreach_tanh/docs/aclnnForeachTanh.md Fixing foreach/foreach_pow_scalar_and_tensor/docs/aclnnForeachPowScalarAndTensor.md Fixing foreach/foreach_log10/docs/aclnnForeachLog10.md Fixing foreach/foreach_erfc/docs/aclnnForeachErfc.md Fixing foreach/foreach_add_scalar/docs/aclnnForeachAddScalar.md Fixing foreach/foreach_div_scalar/docs/aclnnForeachDivScalarV2.md Fixing foreach/foreach_round_off_number/docs/aclnnForeachRoundOffNumber.md Fixing foreach/foreach_addcdiv_scalar_list/docs/aclnnForeachAddcdivScalarList.md Fixing foreach/foreach_addcmul_list/docs/aclnnForeachAddcmulList.md Fixing foreach/foreach_pow_scalar_list/docs/aclnnForeachPowScalarList.md Fixing foreach/foreach_copy/docs/aclnnForeachCopy.md Fixing foreach/foreach_log/docs/aclnnForeachLog.md Fixing foreach/foreach_mul_list/docs/aclnnForeachMulList.md Fixing foreach/foreach_exp/docs/aclnnForeachExp.md Fixing foreach/foreach_sub_list/docs/aclnnForeachSubList.md fix end of files.........................................................Failed - hook id: end-of-file-fixer - exit code: 1 - files were modified by this hook Fixing foreach/foreach_sqrt/examples/test_aclnn_foreach_sqrt.cpp Fixing foreach/foreach_pow_list/examples/test_aclnn_foreach_pow_list.cpp Fixing foreach/foreach_mul_scalar/examples/test_aclnn_foreach_mul_scalar.cpp Fixing foreach/foreach_expm1/examples/test_aclnn_foreach_expm1.cpp Fixing foreach/foreach_addcdiv_scalar/examples/test_aclnn_foreach_addcdiv_scalar_v2.cpp Fixing foreach/foreach_sign/examples/test_aclnn_foreach_sign.cpp Fixing foreach/foreach_sub_list/examples/test_aclnn_foreach_sub_list_v2.cpp Fixing foreach/foreach_mul_list/examples/test_aclnn_foreach_mul_list.cpp Fixing foreach/foreach_addcdiv_scalar/examples/test_aclnn_foreach_addcdiv_scalar.cpp Fixing foreach/foreach_log/examples/test_aclnn_foreach_log.cpp Fixing foreach/foreach_reciprocal/examples/test_aclnn_foreach_reciprocal.cpp Fixing foreach/foreach_pow_scalar_and_tensor/examples/test_aclnn_foreach_pow_scalar_and_tensor.cpp Fixing foreach/foreach_neg/examples/test_aclnn_foreach_neg.cpp Fixing foreach/foreach_addcmul_scalar_list/examples/test_aclnn_foreach_addcmul_scalar_list.cpp Fixing foreach/foreach_lerp_list/examples/test_aclnn_foreach_lerp_list.cpp Fixing foreach/foreach_add_scalar_list/examples/test_aclnn_foreach_add_scalar_list.cpp Fixing foreach/foreach_tanh/examples/test_aclnn_foreach_tanh.cpp Fixing foreach/foreach_sin/examples/test_aclnn_foreach_sin.cpp Fixing foreach/foreach_maximum_scalar_list/examples/test_aclnn_foreach_maximum_scalar_list.cpp Fixing foreach/foreach_pow_scalar/examples/test_aclnn_foreach_pow_scalar_v2.cpp Fixing foreach/foreach_minimum_list/examples/test_aclnn_foreach_minimum_list.cpp Fixing foreach/foreach_abs/examples/test_aclnn_foreach_abs.cpp Fixing foreach/foreach_sub_scalar_list/examples/test_aclnn_foreach_sub_scalar_list.cpp Fixing foreach/foreach_maximum_scalar/examples/test_aclnn_foreach_maximum_scalar.cpp Fixing foreach/foreach_div_scalar/examples/test_aclnn_foreach_div_scalar.cpp Fixing foreach/foreach_log2/examples/test_aclnn_foreach_log2.cpp Fixing foreach/foreach_norm/examples/test_aclnn_foreach_norm.cpp Fixing foreach/foreach_exp/examples/test_aclnn_foreach_exp.cpp Fixing foreach/foreach_minimum_scalar_list/examples/test_aclnn_foreach_minimum_scalar_list.cpp Fixing foreach/foreach_sigmoid/examples/test_aclnn_foreach_sigmoid.cpp Fixing foreach/foreach_lerp_scalar/examples/test_aclnn_foreach_lerp_scalar.cpp Fixing foreach/foreach_tan/examples/test_aclnn_foreach_tan.cpp Fixing foreach/foreach_cosh/examples/test_aclnn_foreach_cosh.cpp Fixing foreach/foreach_addcdiv_list/examples/test_aclnn_foreach_addcdiv_list.cpp Fixing foreach/foreach_sub_scalar/examples/test_aclnn_foreach_sub_scalar.cpp Fixing foreach/foreach_addcmul_list/examples/test_aclnn_foreach_addcmul_list.cpp Fixing foreach/foreach_cos/examples/test_aclnn_foreach_cos.cpp Fixing foreach/foreach_zero_inplace/examples/test_aclnn_foreach_zero_inplace.cpp Fixing foreach/foreach_sinh/examples/test_aclnn_foreach_sinh.cpp Fixing foreach/foreach_sub_scalar/examples/test_aclnn_foreach_sub_scalar_v2.cpp Fixing foreach/foreach_acos/examples/test_aclnn_foreach_acos.cpp Fixing foreach/foreach_pow_scalar_list/examples/test_aclnn_foreach_pow_scalar_list.cpp Fixing foreach/foreach_maximum_scalar/examples/test_aclnn_foreach_maximum_scalar_v2.cpp Fixing foreach/foreach_maximum_list/examples/test_aclnn_foreach_maximum_list.cpp Fixing foreach/foreach_minimum_scalar/examples/test_aclnn_foreach_minimum_scalar_v2.cpp Fixing foreach/foreach_erf/examples/test_aclnn_foreach_erf.cpp Fixing foreach/foreach_mul_scalar_list/examples/test_aclnn_foreach_mul_scalar_list.cpp Fixing foreach/foreach_addcdiv_scalar_list/examples/test_aclnn_foreach_addcdiv_scalar_list.cpp Fixing foreach/foreach_log10/examples/test_aclnn_foreach_log10.cpp Fixing foreach/foreach_addcmul_scalar/examples/test_aclnn_foreach_addcmul_scalar_v2.cpp Fixing foreach/foreach_add_list/examples/test_aclnn_foreach_add_list_v2.cpp Fixing foreach/foreach_mul_scalar/examples/test_aclnn_foreach_mul_scalar_v2.cpp Fixing foreach/foreach_copy/examples/test_aclnn_foreach_copy.cpp Fixing foreach/foreach_round_off_number/examples/test_aclnn_foreach_round_off_number.cpp Fixing foreach/foreach_div_scalar/examples/test_aclnn_foreach_div_scalar_v2.cpp Fixing foreach/foreach_asin/examples/test_aclnn_foreach_asin.cpp Fixing foreach/foreach_div_list/examples/test_aclnn_foreach_div_list.cpp Fixing foreach/foreach_add_scalar/examples/test_aclnn_foreach_add_scalar_v2.cpp Fixing foreach/foreach_div_scalar_list/examples/test_aclnn_foreach_div_scalar_list.cpp Fixing foreach/foreach_erfc/examples/test_aclnn_foreach_erfc.cpp Fixing foreach/foreach_atan/examples/test_aclnn_foreach_atan.cpp Fixing foreach/foreach_add_scalar/examples/test_aclnn_foreach_add_scalar.cpp Fixing foreach/foreach_addcmul_scalar/examples/test_aclnn_foreach_addcmul_scalar.cpp Fixing foreach/foreach_round_off_number/examples/test_aclnn_foreach_round_off_number_v2.cpp Fixing foreach/foreach_sub_list/examples/test_aclnn_foreach_sub_list.cpp Fixing foreach/foreach_minimum_scalar/examples/test_aclnn_foreach_minimum_scalar.cpp check yaml...........................................(no files to check)Skipped check for added large files..............................................Passed check for merge conflicts................................................Passed detect private key.......................................................Passed check json...........................................(no files to check)Skipped clang-format.............................................................Failed - hook id: clang-format - files were modified by this hook Formatting [1/9] foreach/foreach_log1p/examples/test_aclnn_foreach_log1p.cpp Formatting [2/9] foreach/foreach_addcdiv_scalar/examples/test_aclnn_foreach_addcdiv_scalar_v2.cpp Formatting [3/9] foreach/foreach_addcmul_scalar_list/examples/test_aclnn_foreach_addcmul_scalar_list.cpp Formatting [4/9] foreach/foreach_mul_scalar/examples/test_aclnn_foreach_mul_scalar_v2.cpp Formatting [5/9] foreach/foreach_sub_scalar/examples/test_aclnn_foreach_sub_scalar_v2.cpp Formatting [6/9] foreach/foreach_log2/examples/test_aclnn_foreach_log2.cpp Formatting [7/9] foreach/foreach_sub_scalar/examples/test_aclnn_foreach_sub_scalar.cpp Formatting [8/9] foreach/foreach_pow_list/examples/test_aclnn_foreach_pow_list.cpp Formatting [9/9] foreach/foreach_pow_scalar_and_tensor/examples/test_aclnn_foreach_pow_scalar_and_tensor.cpp Formatting [1/9] foreach/foreach_cos/examples/test_aclnn_foreach_cos.cpp Formatting [2/9] foreach/foreach_add_scalar_list/examples/test_aclnn_foreach_add_scalar_list.cpp Formatting [3/9] foreach/foreach_lerp_scalar/examples/test_aclnn_foreach_lerp_scalar.cpp Formatting [4/9] foreach/foreach_norm/examples/test_aclnn_foreach_norm.cpp Formatting [5/9] foreach/foreach_sin/examples/test_aclnn_foreach_sin.cpp Formatting [6/9] foreach/foreach_pow_scalar/examples/test_aclnn_foreach_pow_scalar.cpp Formatting [7/9] foreach/foreach_cosh/examples/test_aclnn_foreach_cosh.cpp Formatting [8/9] foreach/foreach_addcdiv_scalar_list/examples/test_aclnn_foreach_addcdiv_scalar_list.cpp Formatting [9/9] foreach/foreach_sign/examples/test_aclnn_foreach_sign.cpp Formatting [1/9] foreach/foreach_zero_inplace/examples/test_aclnn_foreach_zero_inplace.cpp Formatting [2/9] foreach/foreach_lerp_list/examples/test_aclnn_foreach_lerp_list.cpp Formatting [3/9] foreach/foreach_maximum_scalar/examples/test_aclnn_foreach_maximum_scalar_v2.cpp Formatting [4/9] foreach/foreach_erf/examples/test_aclnn_foreach_erf.cpp Formatting [5/9] foreach/foreach_addcmul_list/examples/test_aclnn_foreach_addcmul_list.cpp Formatting [6/9] foreach/foreach_mul_scalar/examples/test_aclnn_foreach_mul_scalar.cpp Formatting [7/9] foreach/foreach_minimum_scalar/examples/test_aclnn_foreach_minimum_scalar.cpp Formatting [8/9] foreach/foreach_addcdiv_list/examples/test_aclnn_foreach_addcdiv_list.cpp Formatting [9/9] foreach/foreach_minimum_list/examples/test_aclnn_foreach_minimum_list.cpp Formatting [1/9] foreach/foreach_abs/examples/test_aclnn_foreach_abs.cpp Formatting [2/9] foreach/foreach_round_off_number/examples/test_aclnn_foreach_round_off_number.cpp Formatting [3/9] foreach/foreach_neg/examples/test_aclnn_foreach_neg.cpp Formatting [4/9] foreach/foreach_minimum_scalar_list/examples/test_aclnn_foreach_minimum_scalar_list.cpp Formatting [5/9] foreach/foreach_addcmul_scalar/examples/test_aclnn_foreach_addcmul_scalar.cpp Formatting [6/9] foreach/foreach_reciprocal/examples/test_aclnn_foreach_reciprocal.cpp Formatting [7/9] foreach/foreach_maximum_scalar_list/examples/test_aclnn_foreach_maximum_scalar_list.cpp Formatting [8/9] foreach/foreach_acos/examples/test_aclnn_foreach_acos.cpp Formatting [9/9] foreach/foreach_maximum_scalar/examples/test_aclnn_foreach_maximum_scalar.cpp Formatting [1/9] foreach/foreach_copy/examples/test_aclnn_foreach_copy.cpp Formatting [2/9] foreach/foreach_add_list/examples/test_aclnn_foreach_add_list_v2.cpp Formatting [3/9] foreach/foreach_sqrt/examples/test_aclnn_foreach_sqrt.cpp Formatting [4/9] foreach/foreach_add_list/examples/test_aclnn_foreach_add_list.cpp Formatting [5/9] foreach/foreach_div_scalar/examples/test_aclnn_foreach_div_scalar_v2.cpp Formatting [6/9] foreach/foreach_asin/examples/test_aclnn_foreach_asin.cpp Formatting [7/9] foreach/foreach_sub_scalar_list/examples/test_aclnn_foreach_sub_scalar_list.cpp Formatting [8/9] foreach/foreach_log10/examples/test_aclnn_foreach_log10.cpp Formatting [9/9] foreach/foreach_pow_scalar/examples/test_aclnn_foreach_pow_scalar_v2.cpp Formatting [1/9] foreach/foreach_div_list/examples/test_aclnn_foreach_div_list.cpp Formatting [2/9] foreach/foreach_pow_scalar_list/examples/test_aclnn_foreach_pow_scalar_list.cpp Formatting [3/9] foreach/foreach_div_scalar_list/examples/test_aclnn_foreach_div_scalar_list.cpp Formatting [4/9] foreach/foreach_add_scalar/examples/test_aclnn_foreach_add_scalar.cpp Formatting [5/9] foreach/foreach_div_scalar/examples/test_aclnn_foreach_div_scalar.cpp Formatting [6/9] foreach/foreach_erfc/examples/test_aclnn_foreach_erfc.cpp Formatting [7/9] foreach/foreach_atan/examples/test_aclnn_foreach_atan.cpp Formatting [8/9] foreach/foreach_round_off_number/examples/test_aclnn_foreach_round_off_number_v2.cpp Formatting [9/9] foreach/foreach_addcmul_scalar/examples/test_aclnn_foreach_addcmul_scalar_v2.cpp Formatting [1/9] foreach/foreach_expm1/examples/test_aclnn_foreach_expm1.cpp Formatting [2/9] foreach/foreach_sigmoid/examples/test_aclnn_foreach_sigmoid.cpp Formatting [3/9] foreach/foreach_add_scalar/examples/test_aclnn_foreach_add_scalar_v2.cpp Formatting [4/9] foreach/foreach_mul_scalar_list/examples/test_aclnn_foreach_mul_scalar_list.cpp Formatting [5/9] foreach/foreach_tanh/examples/test_aclnn_foreach_tanh.cpp Formatting [6/9] foreach/foreach_tan/examples/test_aclnn_foreach_tan.cpp Formatting [7/9] foreach/foreach_sinh/examples/test_aclnn_foreach_sinh.cpp Formatting [8/9] foreach/foreach_addcdiv_scalar/examples/test_aclnn_foreach_addcdiv_scalar.cpp Formatting [9/9] foreach/foreach_maximum_list/examples/test_aclnn_foreach_maximum_list.cpp Formatting [1/6] foreach/foreach_log/examples/test_aclnn_foreach_log.cpp Formatting [2/6] foreach/foreach_sub_list/examples/test_aclnn_foreach_sub_list_v2.cpp Formatting [3/6] foreach/foreach_mul_list/examples/test_aclnn_foreach_mul_list.cpp Formatting [4/6] foreach/foreach_minimum_scalar/examples/test_aclnn_foreach_minimum_scalar_v2.cpp Formatting [5/6] foreach/foreach_exp/examples/test_aclnn_foreach_exp.cpp Formatting [6/6] foreach/foreach_sub_list/examples/test_aclnn_foreach_sub_list.cpp ruff check...........................................(no files to check)Skipped ruff format..........................................(no files to check)Skipped codespell................................................................Passed All changes made by hooks: diff --git a/foreach/foreach_abs/docs/aclnnForeachAbs.md b/foreach/foreach_abs/docs/aclnnForeachAbs.md index 11a9fdfa..15ffed97 100644 --- a/foreach/foreach_abs/docs/aclnnForeachAbs.md +++ b/foreach/foreach_abs/docs/aclnnForeachAbs.md @@ -121,7 +121,7 @@ aclnnStatus aclnnForeachAbs( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - + diff --git a/foreach/foreach_abs/examples/test_aclnn_foreach_abs.cpp b/foreach/foreach_abs/examples/test_aclnn_foreach_abs.cpp index f8ad8ae6..1bc7c9d4 100644 --- a/foreach/foreach_abs/examples/test_aclnn_foreach_abs.cpp +++ b/foreach/foreach_abs/examples/test_aclnn_foreach_abs.cpp @@ -14,26 +14,27 @@ #include "aclnnop/aclnn_foreach_abs.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,128 +47,134 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachAbs第一段接口 - ret = aclnnForeachAbsGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAbsGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachAbs第二段接口 - ret = aclnnForeachAbs(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAbs failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachAbs第一段接口 + ret = aclnnForeachAbsGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAbsGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachAbs第二段接口 + ret = aclnnForeachAbs(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAbs failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_acos/docs/aclnnForeachAcos.md b/foreach/foreach_acos/docs/aclnnForeachAcos.md index 722cfb45..8ba2fcc8 100644 --- a/foreach/foreach_acos/docs/aclnnForeachAcos.md +++ b/foreach/foreach_acos/docs/aclnnForeachAcos.md @@ -17,7 +17,7 @@ - 接口功能:对输入张量列表中的每个张量执行逐元素反余弦运算。 - 计算公式: - + $$ x = [{x_0}, {x_1}, ... {x_{n-1}}]\\ y = [{y_0}, {y_1}, ... {y_{n-1}}]\\ @@ -121,7 +121,7 @@ aclnnStatus aclnnForeachAcos( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_acos/examples/test_aclnn_foreach_acos.cpp b/foreach/foreach_acos/examples/test_aclnn_foreach_acos.cpp index 7745f076..c64e1655 100644 --- a/foreach/foreach_acos/examples/test_aclnn_foreach_acos.cpp +++ b/foreach/foreach_acos/examples/test_aclnn_foreach_acos.cpp @@ -14,26 +14,27 @@ #include "aclnnop/aclnn_foreach_acos.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,128 +47,134 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6}; - std::vector input2HostData = {0.7, 0.8, 0.9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachAcos第一段接口 - ret = aclnnForeachAcosGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAcosGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachAcos第二段接口 - ret = aclnnForeachAcos(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAcos failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6}; + std::vector input2HostData = {0.7, 0.8, 0.9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachAcos第一段接口 + ret = aclnnForeachAcosGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAcosGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachAcos第二段接口 + ret = aclnnForeachAcos(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAcos failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_add_list/docs/aclnnForeachAddList.md b/foreach/foreach_add_list/docs/aclnnForeachAddList.md index 5edb9eaa..16cba57e 100644 --- a/foreach/foreach_add_list/docs/aclnnForeachAddList.md +++ b/foreach/foreach_add_list/docs/aclnnForeachAddList.md @@ -144,7 +144,7 @@ aclnnStatus aclnnForeachAddList( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_add_list/docs/aclnnForeachAddListV2.md b/foreach/foreach_add_list/docs/aclnnForeachAddListV2.md index 1409a73a..1fa0c375 100644 --- a/foreach/foreach_add_list/docs/aclnnForeachAddListV2.md +++ b/foreach/foreach_add_list/docs/aclnnForeachAddListV2.md @@ -139,7 +139,7 @@ aclnnStatus aclnnForeachAddListV2(
- Atlas A2 训练系列产品/Atlas A2 推理系列产品Atlas A3 训练系列产品/Atlas A3 推理系列产品: - + `scalar`的数据类型与入参`x1`的数据类型具有一定对应关系: - 当`x1`的数据类型为FLOAT32、BFLOAT16时,数据类型支持FLOAT32、DOUBLE。 - 当`x1`的数据类型为FLOAT16时,数据类型支持FLOAT16、DOUBLE。 @@ -154,7 +154,7 @@ aclnnStatus aclnnForeachAddListV2( - **返回值** aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 - + 第一段接口完成入参校验,出现以下场景时报错: diff --git a/foreach/foreach_add_list/examples/test_aclnn_foreach_add_list.cpp b/foreach/foreach_add_list/examples/test_aclnn_foreach_add_list.cpp index cbe9ebb8..41ad79c2 100644 --- a/foreach/foreach_add_list/examples/test_aclnn_foreach_add_list.cpp +++ b/foreach/foreach_add_list/examples/test_aclnn_foreach_add_list.cpp @@ -14,184 +14,194 @@ #include "aclnnop/aclnn_foreach_add_list.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& 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; +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 -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector otherShape1 = {2, 3}; - std::vector otherShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - std::vector alphaShape = {1}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* other1DeviceAddr = nullptr; - void* other2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - void* alphaDeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* other1 = nullptr; - aclTensor* other2 = nullptr; - aclTensor* alpha = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector other1HostData = {1, 2, 3, 4, 5, 6}; - std::vector other2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - std::vector alphaValueHostData = {1.2f}; - float alphaValue = 1.2f; - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other1 aclTensor - ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other2 aclTensor - ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建alpha aclTensor - ret = CreateAclTensor(alphaValueHostData, alphaShape, &alphaDeviceAddr, aclDataType::ACL_FLOAT, &alpha); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput1{input1, input2}; - aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); - std::vector tempInput2{other1, other2}; - aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachAddList第一段接口 - ret = aclnnForeachAddListGetWorkspaceSize(tensorListInput1, tensorListInput2, alpha, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddListGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachAddList第二段接口 - ret = aclnnForeachAddList(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddList failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput1); - aclDestroyTensorList(tensorListInput2); - aclDestroyTensorList(tensorListOutput); - aclDestroyTensor(alpha); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(other1DeviceAddr); - aclrtFree(other2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - aclrtFree(alphaDeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector otherShape1 = {2, 3}; + std::vector otherShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + std::vector alphaShape = {1}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* other1DeviceAddr = nullptr; + void* other2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + void* alphaDeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* other1 = nullptr; + aclTensor* other2 = nullptr; + aclTensor* alpha = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector other1HostData = {1, 2, 3, 4, 5, 6}; + std::vector other2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + std::vector alphaValueHostData = {1.2f}; + float alphaValue = 1.2f; + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other1 aclTensor + ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other2 aclTensor + ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建alpha aclTensor + ret = CreateAclTensor(alphaValueHostData, alphaShape, &alphaDeviceAddr, aclDataType::ACL_FLOAT, &alpha); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput1{input1, input2}; + aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); + std::vector tempInput2{other1, other2}; + aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachAddList第一段接口 + ret = aclnnForeachAddListGetWorkspaceSize( + tensorListInput1, tensorListInput2, alpha, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddListGetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachAddList第二段接口 + ret = aclnnForeachAddList(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddList failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput1); + aclDestroyTensorList(tensorListInput2); + aclDestroyTensorList(tensorListOutput); + aclDestroyTensor(alpha); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(other1DeviceAddr); + aclrtFree(other2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + aclrtFree(alphaDeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; } diff --git a/foreach/foreach_add_list/examples/test_aclnn_foreach_add_list_v2.cpp b/foreach/foreach_add_list/examples/test_aclnn_foreach_add_list_v2.cpp index 2a1b82ab..d6a659d5 100644 --- a/foreach/foreach_add_list/examples/test_aclnn_foreach_add_list_v2.cpp +++ b/foreach/foreach_add_list/examples/test_aclnn_foreach_add_list_v2.cpp @@ -14,180 +14,190 @@ #include "aclnnop/aclnn_foreach_add_list_v2.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& 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; +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 -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector otherShape1 = {2, 3}; - std::vector otherShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* other1DeviceAddr = nullptr; - void* other2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* other1 = nullptr; - aclTensor* other2 = nullptr; - aclScalar* alpha = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector other1HostData = {1, 2, 3, 4, 5, 6}; - std::vector other2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - float alphaValue = 1.2f; - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other1 aclTensor - ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other2 aclTensor - ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建alpha aclScalar - alpha = aclCreateScalar(&alphaValue, aclDataType::ACL_FLOAT); - CHECK_RET(alpha != nullptr, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput1{input1, input2}; - aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); - std::vector tempInput2{other1, other2}; - aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachAddListV2第一段接口 - ret = aclnnForeachAddListV2GetWorkspaceSize(tensorListInput1, tensorListInput2, alpha, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddListV2GetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachAddListV2第二段接口 - ret = aclnnForeachAddListV2(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddListV2 failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput1); - aclDestroyTensorList(tensorListInput2); - aclDestroyTensorList(tensorListOutput); - aclDestroyScalar(alpha); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(other1DeviceAddr); - aclrtFree(other2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector otherShape1 = {2, 3}; + std::vector otherShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* other1DeviceAddr = nullptr; + void* other2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* other1 = nullptr; + aclTensor* other2 = nullptr; + aclScalar* alpha = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector other1HostData = {1, 2, 3, 4, 5, 6}; + std::vector other2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + float alphaValue = 1.2f; + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other1 aclTensor + ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other2 aclTensor + ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建alpha aclScalar + alpha = aclCreateScalar(&alphaValue, aclDataType::ACL_FLOAT); + CHECK_RET(alpha != nullptr, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput1{input1, input2}; + aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); + std::vector tempInput2{other1, other2}; + aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachAddListV2第一段接口 + ret = aclnnForeachAddListV2GetWorkspaceSize( + tensorListInput1, tensorListInput2, alpha, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddListV2GetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachAddListV2第二段接口 + ret = aclnnForeachAddListV2(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddListV2 failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput1); + aclDestroyTensorList(tensorListInput2); + aclDestroyTensorList(tensorListOutput); + aclDestroyScalar(alpha); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(other1DeviceAddr); + aclrtFree(other2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_add_scalar/docs/aclnnForeachAddScalar.md b/foreach/foreach_add_scalar/docs/aclnnForeachAddScalar.md index 9a79c778..35b9eb76 100644 --- a/foreach/foreach_add_scalar/docs/aclnnForeachAddScalar.md +++ b/foreach/foreach_add_scalar/docs/aclnnForeachAddScalar.md @@ -129,7 +129,7 @@ aclnnStatus aclnnForeachAddScalar(
- Atlas A2 训练系列产品/Atlas A2 推理系列产品Atlas A3 训练系列产品/Atlas A3 推理系列产品: - + 参数`scalar`数据类型与入参`x`的数据类型具有一定对应关系: - 当`x`的数据类型为FLOAT32、FLOAT16、INT32时,数据类型与`x`的数据类型保持一致。 - 当`x`的数据类型为BFLOAT16时,数据类型支持FLOAT32。 @@ -145,7 +145,7 @@ aclnnStatus aclnnForeachAddScalar( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - + diff --git a/foreach/foreach_add_scalar/docs/aclnnForeachAddScalarV2.md b/foreach/foreach_add_scalar/docs/aclnnForeachAddScalarV2.md index 43925000..4ab008c1 100644 --- a/foreach/foreach_add_scalar/docs/aclnnForeachAddScalarV2.md +++ b/foreach/foreach_add_scalar/docs/aclnnForeachAddScalarV2.md @@ -17,7 +17,7 @@ - 接口功能:将指定的标量值加到张量列表中的每个张量中。本接口相较于[aclnnForeachAddScalar](aclnnForeachAddScalar.md),修改入参scalar的结构类型aclTensor为aclScalar,请根据实际情况选择合适的接口。 - 计算公式: - + $$ x = [{x_0}, {x_1}, ... {x_{n-1}}]\\ y = [{y_0}, {y_1}, ... {y_{n-1}}]\\ @@ -145,7 +145,7 @@ aclnnStatus aclnnForeachAddScalarV2( - **返回值** aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 - + 第一段接口完成入参校验,出现以下场景时报错:
@@ -171,7 +171,7 @@ aclnnStatus aclnnForeachAddScalarV2( - + diff --git a/foreach/foreach_add_scalar/examples/test_aclnn_foreach_add_scalar.cpp b/foreach/foreach_add_scalar/examples/test_aclnn_foreach_add_scalar.cpp index 8efc70ce..a1bc95c3 100644 --- a/foreach/foreach_add_scalar/examples/test_aclnn_foreach_add_scalar.cpp +++ b/foreach/foreach_add_scalar/examples/test_aclnn_foreach_add_scalar.cpp @@ -14,163 +14,172 @@ #include "aclnnop/aclnn_foreach_add_scalar.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& 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; +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 -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - std::vector alphaShape = {1}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - void* alphaDeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* alpha = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - std::vector alphaValueHostData = {1.2f}; - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建alpha aclTensor - ret = CreateAclTensor(alphaValueHostData, alphaShape, &alphaDeviceAddr, aclDataType::ACL_FLOAT, &alpha); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachAddScalar第一段接口 - ret = aclnnForeachAddScalarGetWorkspaceSize(tensorListInput, alpha, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddScalarGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachAddScalar第二段接口 - ret = aclnnForeachAddScalar(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddScalar failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - aclDestroyTensor(alpha); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - aclrtFree(alphaDeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + std::vector alphaShape = {1}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + void* alphaDeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* alpha = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + std::vector alphaValueHostData = {1.2f}; + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建alpha aclTensor + ret = CreateAclTensor(alphaValueHostData, alphaShape, &alphaDeviceAddr, aclDataType::ACL_FLOAT, &alpha); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachAddScalar第一段接口 + ret = aclnnForeachAddScalarGetWorkspaceSize(tensorListInput, alpha, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddScalarGetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachAddScalar第二段接口 + ret = aclnnForeachAddScalar(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddScalar failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + aclDestroyTensor(alpha); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + aclrtFree(alphaDeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_add_scalar/examples/test_aclnn_foreach_add_scalar_v2.cpp b/foreach/foreach_add_scalar/examples/test_aclnn_foreach_add_scalar_v2.cpp index c7661324..f1bb3133 100644 --- a/foreach/foreach_add_scalar/examples/test_aclnn_foreach_add_scalar_v2.cpp +++ b/foreach/foreach_add_scalar/examples/test_aclnn_foreach_add_scalar_v2.cpp @@ -14,160 +14,169 @@ #include "aclnnop/aclnn_foreach_add_scalar_v2.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& 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; +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 -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclScalar* alpha = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - float alphaValue = 1.2f; - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建alpha aclScalar - alpha = aclCreateScalar(&alphaValue, aclDataType::ACL_FLOAT); - CHECK_RET(alpha != nullptr, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachAddScalarV2第一段接口 - ret = aclnnForeachAddScalarV2GetWorkspaceSize(tensorListInput, alpha, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddScalarV2GetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachAddScalarV2第二段接口 - ret = aclnnForeachAddScalarV2(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddScalarV2 failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - aclDestroyScalar(alpha); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclScalar* alpha = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + float alphaValue = 1.2f; + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建alpha aclScalar + alpha = aclCreateScalar(&alphaValue, aclDataType::ACL_FLOAT); + CHECK_RET(alpha != nullptr, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachAddScalarV2第一段接口 + ret = aclnnForeachAddScalarV2GetWorkspaceSize(tensorListInput, alpha, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddScalarV2GetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachAddScalarV2第二段接口 + ret = aclnnForeachAddScalarV2(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddScalarV2 failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + aclDestroyScalar(alpha); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_add_scalar_list/docs/aclnnForeachAddScalarList.md b/foreach/foreach_add_scalar_list/docs/aclnnForeachAddScalarList.md index 5e34c05a..5be4136d 100644 --- a/foreach/foreach_add_scalar_list/docs/aclnnForeachAddScalarList.md +++ b/foreach/foreach_add_scalar_list/docs/aclnnForeachAddScalarList.md @@ -134,7 +134,7 @@ aclnnStatus aclnnForeachAddScalarList( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
161002
x、scalar和out的数据类型不在支持的范围之内。x、scalar和out的数据类型不在支持的范围之内。
x和out的数据类型不一致。
@@ -214,14 +214,14 @@ aclnnStatus aclnnForeachAddScalarList(
- **返回值** - + aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 ## 约束说明 - 确定性计算: - aclnnForeachAddScalarList默认确定性实现。 - + ## 调用示例 示例代码如下,仅供参考,具体编译和执行过程请参考[编译与运行样例](../../../docs/zh/context/编译与运行样例.md)。 diff --git a/foreach/foreach_add_scalar_list/examples/test_aclnn_foreach_add_scalar_list.cpp b/foreach/foreach_add_scalar_list/examples/test_aclnn_foreach_add_scalar_list.cpp index 2cd89b37..063ccb72 100644 --- a/foreach/foreach_add_scalar_list/examples/test_aclnn_foreach_add_scalar_list.cpp +++ b/foreach/foreach_add_scalar_list/examples/test_aclnn_foreach_add_scalar_list.cpp @@ -14,167 +14,177 @@ #include "aclnnop/aclnn_foreach_add_scalar_list.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& 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; +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 -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclScalar* alpha1 = nullptr; - aclScalar* alpha2 = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - float alpha1Value = 1.2f; - float alpha2Value = 2.2f; - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建alpha1 aclScalar - alpha1 = aclCreateScalar(&alpha1Value, aclDataType::ACL_FLOAT); - CHECK_RET(alpha1 != nullptr, return ret); - // 创建alpha2 aclScalar - alpha2 = aclCreateScalar(&alpha2Value, aclDataType::ACL_FLOAT); - CHECK_RET(alpha2 != nullptr, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - std::vector tempscalar{alpha1, alpha2}; - aclScalarList* scalarlist = aclCreateScalarList(tempscalar.data(), tempscalar.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachAddScalarList第一段接口 - ret = aclnnForeachAddScalarListGetWorkspaceSize(tensorListInput, scalarlist, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddScalarListGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachAddScalarList第二段接口 - ret = aclnnForeachAddScalarList(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddScalarList failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - aclDestroyScalarList(scalarlist); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclScalar* alpha1 = nullptr; + aclScalar* alpha2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + float alpha1Value = 1.2f; + float alpha2Value = 2.2f; + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建alpha1 aclScalar + alpha1 = aclCreateScalar(&alpha1Value, aclDataType::ACL_FLOAT); + CHECK_RET(alpha1 != nullptr, return ret); + // 创建alpha2 aclScalar + alpha2 = aclCreateScalar(&alpha2Value, aclDataType::ACL_FLOAT); + CHECK_RET(alpha2 != nullptr, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + std::vector tempscalar{alpha1, alpha2}; + aclScalarList* scalarlist = aclCreateScalarList(tempscalar.data(), tempscalar.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachAddScalarList第一段接口 + ret = aclnnForeachAddScalarListGetWorkspaceSize( + tensorListInput, scalarlist, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddScalarListGetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachAddScalarList第二段接口 + ret = aclnnForeachAddScalarList(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddScalarList failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + aclDestroyScalarList(scalarlist); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_addcdiv_list/docs/aclnnForeachAddcdivList.md b/foreach/foreach_addcdiv_list/docs/aclnnForeachAddcdivList.md index 6265d8db..80aafabd 100644 --- a/foreach/foreach_addcdiv_list/docs/aclnnForeachAddcdivList.md +++ b/foreach/foreach_addcdiv_list/docs/aclnnForeachAddcdivList.md @@ -17,9 +17,9 @@ - 接口功能:对多个张量进行逐元素加、乘、除操作,$x2_{i}$和$x3_{i}$进行逐元素相除,并将结果乘以scalars,再与$x1_{i}$相加。 - 计算公式: - + $$ - x1 = [{x1_0}, {x1_1}, ... {x1_{n-1}}], x2 = [{x2_0}, {x2_1}, ... {x2_{n-1}}], x3 = [{x3_0}, {x3_1}, ... {x3_{n-1}}]\\ + x1 = [{x1_0}, {x1_1}, ... {x1_{n-1}}], x2 = [{x2_0}, {x2_1}, ... {x2_{n-1}}], x3 = [{x3_0}, {x3_1}, ... {x3_{n-1}}]\\ y = [{y_0}, {y_1}, ... {y_{n-1}}]\\ $$ @@ -154,7 +154,7 @@ aclnnStatus aclnnForeachAddcdivList( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - + diff --git a/foreach/foreach_addcdiv_list/examples/test_aclnn_foreach_addcdiv_list.cpp b/foreach/foreach_addcdiv_list/examples/test_aclnn_foreach_addcdiv_list.cpp index dcc5c0fa..d8d494af 100644 --- a/foreach/foreach_addcdiv_list/examples/test_aclnn_foreach_addcdiv_list.cpp +++ b/foreach/foreach_addcdiv_list/examples/test_aclnn_foreach_addcdiv_list.cpp @@ -14,26 +14,27 @@ #include "aclnnop/aclnn_foreach_addcdiv_list.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,171 +47,179 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector scalarShape = {1, 2}; - std::vector otherShape1 = {2, 3}; - std::vector otherShape2 = {1, 3}; - std::vector anotherShape1 = {2, 3}; - std::vector anotherShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* other1DeviceAddr = nullptr; - void* other2DeviceAddr = nullptr; - void* another1DeviceAddr = nullptr; - void* another2DeviceAddr = nullptr; - void* scalarDeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* other1 = nullptr; - aclTensor* other2 = nullptr; - aclTensor* another1 = nullptr; - aclTensor* another2 = nullptr; - aclTensor* scalar = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector other1HostData = {4, 3, 8, 9, 3, 5}; - std::vector other2HostData = {5, 6, 7}; - std::vector another1HostData = {1, 2, 3, 4, 5, 6}; - std::vector another2HostData = {7, 8, 9}; - std::vector scalarHostData = {1, 2}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建scalar aclTensor - ret = CreateAclTensor(scalarHostData, scalarShape, &scalarDeviceAddr, aclDataType::ACL_FLOAT, &scalar); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other1 aclTensor - ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other2 aclTensor - ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建another1 aclTensor - ret = CreateAclTensor(another1HostData, anotherShape1, &another1DeviceAddr, aclDataType::ACL_FLOAT, &another1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建another2 aclTensor - ret = CreateAclTensor(another2HostData, anotherShape2, &another2DeviceAddr, aclDataType::ACL_FLOAT, &another2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput1{input1, input2}; - aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); - std::vector tempInput2{other1, other2}; - aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); - std::vector tempAnother{another1, another2}; - aclTensorList* tensorListAnother = aclCreateTensorList(tempAnother.data(), tempAnother.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachAddcdivList第一段接口 - ret = aclnnForeachAddcdivListGetWorkspaceSize(tensorListInput1, tensorListInput2, tensorListAnother, scalar, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddcdivListGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachAddcdivList第二段接口 - ret = aclnnForeachAddcdivList(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddcdivList failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput1); - aclDestroyTensorList(tensorListInput2); - aclDestroyTensorList(tensorListAnother); - aclDestroyTensor(scalar); - aclDestroyTensorList(tensorListOutput); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(other1DeviceAddr); - aclrtFree(other2DeviceAddr); - aclrtFree(another1DeviceAddr); - aclrtFree(another2DeviceAddr); - aclrtFree(scalarDeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector scalarShape = {1, 2}; + std::vector otherShape1 = {2, 3}; + std::vector otherShape2 = {1, 3}; + std::vector anotherShape1 = {2, 3}; + std::vector anotherShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* other1DeviceAddr = nullptr; + void* other2DeviceAddr = nullptr; + void* another1DeviceAddr = nullptr; + void* another2DeviceAddr = nullptr; + void* scalarDeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* other1 = nullptr; + aclTensor* other2 = nullptr; + aclTensor* another1 = nullptr; + aclTensor* another2 = nullptr; + aclTensor* scalar = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector other1HostData = {4, 3, 8, 9, 3, 5}; + std::vector other2HostData = {5, 6, 7}; + std::vector another1HostData = {1, 2, 3, 4, 5, 6}; + std::vector another2HostData = {7, 8, 9}; + std::vector scalarHostData = {1, 2}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建scalar aclTensor + ret = CreateAclTensor(scalarHostData, scalarShape, &scalarDeviceAddr, aclDataType::ACL_FLOAT, &scalar); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other1 aclTensor + ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other2 aclTensor + ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建another1 aclTensor + ret = CreateAclTensor(another1HostData, anotherShape1, &another1DeviceAddr, aclDataType::ACL_FLOAT, &another1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建another2 aclTensor + ret = CreateAclTensor(another2HostData, anotherShape2, &another2DeviceAddr, aclDataType::ACL_FLOAT, &another2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput1{input1, input2}; + aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); + std::vector tempInput2{other1, other2}; + aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); + std::vector tempAnother{another1, another2}; + aclTensorList* tensorListAnother = aclCreateTensorList(tempAnother.data(), tempAnother.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachAddcdivList第一段接口 + ret = aclnnForeachAddcdivListGetWorkspaceSize( + tensorListInput1, tensorListInput2, tensorListAnother, scalar, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddcdivListGetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachAddcdivList第二段接口 + ret = aclnnForeachAddcdivList(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddcdivList failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput1); + aclDestroyTensorList(tensorListInput2); + aclDestroyTensorList(tensorListAnother); + aclDestroyTensor(scalar); + aclDestroyTensorList(tensorListOutput); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(other1DeviceAddr); + aclrtFree(other2DeviceAddr); + aclrtFree(another1DeviceAddr); + aclrtFree(another2DeviceAddr); + aclrtFree(scalarDeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_addcdiv_scalar/docs/aclnnForeachAddcdivScalar.md b/foreach/foreach_addcdiv_scalar/docs/aclnnForeachAddcdivScalar.md index 47fa49b3..09212c48 100644 --- a/foreach/foreach_addcdiv_scalar/docs/aclnnForeachAddcdivScalar.md +++ b/foreach/foreach_addcdiv_scalar/docs/aclnnForeachAddcdivScalar.md @@ -155,7 +155,7 @@ aclnnStatus aclnnForeachAddcdivScalar( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_addcdiv_scalar/docs/aclnnForeachAddcdivScalarV2.md b/foreach/foreach_addcdiv_scalar/docs/aclnnForeachAddcdivScalarV2.md index 7a17a7e7..740724b0 100644 --- a/foreach/foreach_addcdiv_scalar/docs/aclnnForeachAddcdivScalarV2.md +++ b/foreach/foreach_addcdiv_scalar/docs/aclnnForeachAddcdivScalarV2.md @@ -17,7 +17,7 @@ - 接口功能:对多个张量进行逐元素加、乘、除操作,$x2_{i}$和$x3_{i}$进行逐元素相除,并将结果乘以scalar,再与$x1_{i}$相加。本接口相较于[aclnnForeachAddcdivScalar](aclnnForeachAddcdivScalar.md),修改入参scalar的结构类型aclTensor为aclScalar,请根据实际情况选择合适的接口。 - 计算公式: - + $$ x1 = [{x1_0}, {x1_1}, ... {x1_{n-1}}], x2 = [{x2_0}, {x2_1}, ... {x2_{n-1}}], x3 = [{x3_0}, {x3_1}, ... {x3_{n-1}}]\\ y = [{y_0}, {y_1}, ... {y_{n-1}}]\\ @@ -148,11 +148,11 @@ aclnnStatus aclnnForeachAddcdivScalarV2(
- + - **返回值** aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 - + 第一段接口完成入参校验,出现以下场景时报错: diff --git a/foreach/foreach_addcdiv_scalar/examples/test_aclnn_foreach_addcdiv_scalar.cpp b/foreach/foreach_addcdiv_scalar/examples/test_aclnn_foreach_addcdiv_scalar.cpp index 0aa6b899..30c387e7 100644 --- a/foreach/foreach_addcdiv_scalar/examples/test_aclnn_foreach_addcdiv_scalar.cpp +++ b/foreach/foreach_addcdiv_scalar/examples/test_aclnn_foreach_addcdiv_scalar.cpp @@ -14,26 +14,27 @@ #include "aclnnop/aclnn_foreach_addcdiv_scalar.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,171 +47,179 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector otherShape1 = {2, 3}; - std::vector otherShape2 = {1, 3}; - std::vector anotherShape1 = {2, 3}; - std::vector anotherShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - std::vector alphaShape = {1}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* other1DeviceAddr = nullptr; - void* other2DeviceAddr = nullptr; - void* another1DeviceAddr = nullptr; - void* another2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - void* alphaDeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* other1 = nullptr; - aclTensor* other2 = nullptr; - aclTensor* another1 = nullptr; - aclTensor* another2 = nullptr; - aclTensor* alpha = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector other1HostData = {1, 2, 3, 4, 5, 6}; - std::vector other2HostData = {7, 8, 9}; - std::vector another1HostData = {1, 2, 3, 4, 5, 6}; - std::vector another2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - std::vector alphaValueHostData = {1.2f}; - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other1 aclTensor - ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other2 aclTensor - ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建another1 aclTensor - ret = CreateAclTensor(another1HostData, anotherShape1, &another1DeviceAddr, aclDataType::ACL_FLOAT, &another1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建another2 aclTensor - ret = CreateAclTensor(another2HostData, anotherShape2, &another2DeviceAddr, aclDataType::ACL_FLOAT, &another2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建alpha aclTensor - ret = CreateAclTensor(alphaValueHostData, alphaShape, &alphaDeviceAddr, aclDataType::ACL_FLOAT, &alpha); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput1{input1, input2}; - aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); - std::vector tempInput2{other1, other2}; - aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); - std::vector tempAnother{another1, another2}; - aclTensorList* tensorListAnother = aclCreateTensorList(tempAnother.data(), tempAnother.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachAddcdivScalar第一段接口 - ret = aclnnForeachAddcdivScalarGetWorkspaceSize(tensorListInput1, tensorListInput2, tensorListAnother, alpha, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddcdivScalarGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachAddcdivScalar第二段接口 - ret = aclnnForeachAddcdivScalar(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddcdivScalar failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput1); - aclDestroyTensorList(tensorListInput2); - aclDestroyTensorList(tensorListAnother); - aclDestroyTensorList(tensorListOutput); - aclDestroyTensor(alpha); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(other1DeviceAddr); - aclrtFree(other2DeviceAddr); - aclrtFree(another1DeviceAddr); - aclrtFree(another2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - aclrtFree(alphaDeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector otherShape1 = {2, 3}; + std::vector otherShape2 = {1, 3}; + std::vector anotherShape1 = {2, 3}; + std::vector anotherShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + std::vector alphaShape = {1}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* other1DeviceAddr = nullptr; + void* other2DeviceAddr = nullptr; + void* another1DeviceAddr = nullptr; + void* another2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + void* alphaDeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* other1 = nullptr; + aclTensor* other2 = nullptr; + aclTensor* another1 = nullptr; + aclTensor* another2 = nullptr; + aclTensor* alpha = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector other1HostData = {1, 2, 3, 4, 5, 6}; + std::vector other2HostData = {7, 8, 9}; + std::vector another1HostData = {1, 2, 3, 4, 5, 6}; + std::vector another2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + std::vector alphaValueHostData = {1.2f}; + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other1 aclTensor + ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other2 aclTensor + ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建another1 aclTensor + ret = CreateAclTensor(another1HostData, anotherShape1, &another1DeviceAddr, aclDataType::ACL_FLOAT, &another1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建another2 aclTensor + ret = CreateAclTensor(another2HostData, anotherShape2, &another2DeviceAddr, aclDataType::ACL_FLOAT, &another2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建alpha aclTensor + ret = CreateAclTensor(alphaValueHostData, alphaShape, &alphaDeviceAddr, aclDataType::ACL_FLOAT, &alpha); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput1{input1, input2}; + aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); + std::vector tempInput2{other1, other2}; + aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); + std::vector tempAnother{another1, another2}; + aclTensorList* tensorListAnother = aclCreateTensorList(tempAnother.data(), tempAnother.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachAddcdivScalar第一段接口 + ret = aclnnForeachAddcdivScalarGetWorkspaceSize( + tensorListInput1, tensorListInput2, tensorListAnother, alpha, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddcdivScalarGetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachAddcdivScalar第二段接口 + ret = aclnnForeachAddcdivScalar(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddcdivScalar failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput1); + aclDestroyTensorList(tensorListInput2); + aclDestroyTensorList(tensorListAnother); + aclDestroyTensorList(tensorListOutput); + aclDestroyTensor(alpha); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(other1DeviceAddr); + aclrtFree(other2DeviceAddr); + aclrtFree(another1DeviceAddr); + aclrtFree(another2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + aclrtFree(alphaDeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_addcdiv_scalar/examples/test_aclnn_foreach_addcdiv_scalar_v2.cpp b/foreach/foreach_addcdiv_scalar/examples/test_aclnn_foreach_addcdiv_scalar_v2.cpp index d809bca0..5a2a025f 100644 --- a/foreach/foreach_addcdiv_scalar/examples/test_aclnn_foreach_addcdiv_scalar_v2.cpp +++ b/foreach/foreach_addcdiv_scalar/examples/test_aclnn_foreach_addcdiv_scalar_v2.cpp @@ -14,26 +14,27 @@ #include "aclnnop/aclnn_foreach_addcdiv_scalar_v2.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,168 +47,176 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector otherShape1 = {2, 3}; - std::vector otherShape2 = {1, 3}; - std::vector anotherShape1 = {2, 3}; - std::vector anotherShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* other1DeviceAddr = nullptr; - void* other2DeviceAddr = nullptr; - void* another1DeviceAddr = nullptr; - void* another2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* other1 = nullptr; - aclTensor* other2 = nullptr; - aclTensor* another1 = nullptr; - aclTensor* another2 = nullptr; - aclScalar* alpha = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector other1HostData = {1, 2, 3, 4, 5, 6}; - std::vector other2HostData = {7, 8, 9}; - std::vector another1HostData = {1, 2, 3, 4, 5, 6}; - std::vector another2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - float alphaValue = 1.2f; - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other1 aclTensor - ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other2 aclTensor - ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建another1 aclTensor - ret = CreateAclTensor(another1HostData, anotherShape1, &another1DeviceAddr, aclDataType::ACL_FLOAT, &another1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建another2 aclTensor - ret = CreateAclTensor(another2HostData, anotherShape2, &another2DeviceAddr, aclDataType::ACL_FLOAT, &another2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建alpha aclScalar - alpha = aclCreateScalar(&alphaValue, aclDataType::ACL_FLOAT); - CHECK_RET(alpha != nullptr, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput1{input1, input2}; - aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); - std::vector tempInput2{other1, other2}; - aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); - std::vector tempAnother{another1, another2}; - aclTensorList* tensorListAnother = aclCreateTensorList(tempAnother.data(), tempAnother.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachAddcdivScalarV2第一段接口 - ret = aclnnForeachAddcdivScalarV2GetWorkspaceSize(tensorListInput1, tensorListInput2, tensorListAnother, alpha, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddcdivScalarV2GetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachAddcdivScalarV2第二段接口 - ret = aclnnForeachAddcdivScalarV2(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddcdivScalarV2 failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput1); - aclDestroyTensorList(tensorListInput2); - aclDestroyTensorList(tensorListAnother); - aclDestroyTensorList(tensorListOutput); - aclDestroyScalar(alpha); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(other1DeviceAddr); - aclrtFree(other2DeviceAddr); - aclrtFree(another1DeviceAddr); - aclrtFree(another2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector otherShape1 = {2, 3}; + std::vector otherShape2 = {1, 3}; + std::vector anotherShape1 = {2, 3}; + std::vector anotherShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* other1DeviceAddr = nullptr; + void* other2DeviceAddr = nullptr; + void* another1DeviceAddr = nullptr; + void* another2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* other1 = nullptr; + aclTensor* other2 = nullptr; + aclTensor* another1 = nullptr; + aclTensor* another2 = nullptr; + aclScalar* alpha = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector other1HostData = {1, 2, 3, 4, 5, 6}; + std::vector other2HostData = {7, 8, 9}; + std::vector another1HostData = {1, 2, 3, 4, 5, 6}; + std::vector another2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + float alphaValue = 1.2f; + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other1 aclTensor + ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other2 aclTensor + ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建another1 aclTensor + ret = CreateAclTensor(another1HostData, anotherShape1, &another1DeviceAddr, aclDataType::ACL_FLOAT, &another1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建another2 aclTensor + ret = CreateAclTensor(another2HostData, anotherShape2, &another2DeviceAddr, aclDataType::ACL_FLOAT, &another2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建alpha aclScalar + alpha = aclCreateScalar(&alphaValue, aclDataType::ACL_FLOAT); + CHECK_RET(alpha != nullptr, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput1{input1, input2}; + aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); + std::vector tempInput2{other1, other2}; + aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); + std::vector tempAnother{another1, another2}; + aclTensorList* tensorListAnother = aclCreateTensorList(tempAnother.data(), tempAnother.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachAddcdivScalarV2第一段接口 + ret = aclnnForeachAddcdivScalarV2GetWorkspaceSize( + tensorListInput1, tensorListInput2, tensorListAnother, alpha, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddcdivScalarV2GetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachAddcdivScalarV2第二段接口 + ret = aclnnForeachAddcdivScalarV2(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddcdivScalarV2 failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput1); + aclDestroyTensorList(tensorListInput2); + aclDestroyTensorList(tensorListAnother); + aclDestroyTensorList(tensorListOutput); + aclDestroyScalar(alpha); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(other1DeviceAddr); + aclrtFree(other2DeviceAddr); + aclrtFree(another1DeviceAddr); + aclrtFree(another2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_addcdiv_scalar_list/docs/aclnnForeachAddcdivScalarList.md b/foreach/foreach_addcdiv_scalar_list/docs/aclnnForeachAddcdivScalarList.md index 637062a8..662ccc89 100644 --- a/foreach/foreach_addcdiv_scalar_list/docs/aclnnForeachAddcdivScalarList.md +++ b/foreach/foreach_addcdiv_scalar_list/docs/aclnnForeachAddcdivScalarList.md @@ -17,7 +17,7 @@ - 接口功能:对多个张量进行逐元素加、乘、除操作,$x2_{i}$和$x3_{i}$进行逐元素相除,并将结果乘以$scalars_{i}$,再与$x1_{i}$相加。 - 计算公式: - + $$ x1 = [{x1_0}, {x1_1}, ... {x1_{n-1}}], x2 = [{x2_0}, {x2_1}, ... {x2_{n-1}}], x3 = [{x3_0}, {x3_1}, ... {x3_{n-1}}]\\ scalars = [{scalars_0}, {scalars_1}, ... {scalars_{n-1}}]\\ @@ -155,7 +155,7 @@ aclnnStatus aclnnForeachAddcdivScalarList( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_addcdiv_scalar_list/examples/test_aclnn_foreach_addcdiv_scalar_list.cpp b/foreach/foreach_addcdiv_scalar_list/examples/test_aclnn_foreach_addcdiv_scalar_list.cpp index 5ed116b2..5c5478e5 100644 --- a/foreach/foreach_addcdiv_scalar_list/examples/test_aclnn_foreach_addcdiv_scalar_list.cpp +++ b/foreach/foreach_addcdiv_scalar_list/examples/test_aclnn_foreach_addcdiv_scalar_list.cpp @@ -14,26 +14,27 @@ #include "aclnnop/aclnn_foreach_addcdiv_scalar_list.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,171 +47,179 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector otherShape1 = {2, 3}; - std::vector otherShape2 = {1, 3}; - std::vector anotherShape1 = {2, 3}; - std::vector anotherShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - std::vector scalarsShape = {2}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* other1DeviceAddr = nullptr; - void* other2DeviceAddr = nullptr; - void* another1DeviceAddr = nullptr; - void* another2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - void* scalarsDeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* other1 = nullptr; - aclTensor* other2 = nullptr; - aclTensor* another1 = nullptr; - aclTensor* another2 = nullptr; - aclTensor* scalars = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector other1HostData = {4, 3, 8, 9, 3, 5}; - std::vector other2HostData = {5, 6, 7}; - std::vector another1HostData = {1, 2, 3, 4, 5, 6}; - std::vector another2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - std::vector scalarsHostData{1.2f, 2.2f}; - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other1 aclTensor - ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other2 aclTensor - ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建another1 aclTensor - ret = CreateAclTensor(another1HostData, anotherShape1, &another1DeviceAddr, aclDataType::ACL_FLOAT, &another1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建another2 aclTensor - ret = CreateAclTensor(another2HostData, anotherShape2, &another2DeviceAddr, aclDataType::ACL_FLOAT, &another2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建scalars aclTensor - ret = CreateAclTensor(scalarsHostData, scalarsShape, &scalarsDeviceAddr, aclDataType::ACL_FLOAT, &scalars); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput1{input1, input2}; - aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); - std::vector tempInput2{other1, other2}; - aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); - std::vector tempAnother{another1, another2}; - aclTensorList* tensorListAnother = aclCreateTensorList(tempAnother.data(), tempAnother.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachAddcdivScalarList第一段接口 - ret = aclnnForeachAddcdivScalarListGetWorkspaceSize(tensorListInput1, tensorListInput2, tensorListAnother, scalars, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddcdivScalarListGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachAddcdivScalarList第二段接口 - ret = aclnnForeachAddcdivScalarList(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddcdivScalarList failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput1); - aclDestroyTensorList(tensorListInput2); - aclDestroyTensorList(tensorListAnother); - aclDestroyTensorList(tensorListOutput); - aclDestroyTensor(scalars); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(other1DeviceAddr); - aclrtFree(other2DeviceAddr); - aclrtFree(another1DeviceAddr); - aclrtFree(another2DeviceAddr); - aclrtFree(scalarsDeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector otherShape1 = {2, 3}; + std::vector otherShape2 = {1, 3}; + std::vector anotherShape1 = {2, 3}; + std::vector anotherShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + std::vector scalarsShape = {2}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* other1DeviceAddr = nullptr; + void* other2DeviceAddr = nullptr; + void* another1DeviceAddr = nullptr; + void* another2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + void* scalarsDeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* other1 = nullptr; + aclTensor* other2 = nullptr; + aclTensor* another1 = nullptr; + aclTensor* another2 = nullptr; + aclTensor* scalars = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector other1HostData = {4, 3, 8, 9, 3, 5}; + std::vector other2HostData = {5, 6, 7}; + std::vector another1HostData = {1, 2, 3, 4, 5, 6}; + std::vector another2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + std::vector scalarsHostData{1.2f, 2.2f}; + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other1 aclTensor + ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other2 aclTensor + ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建another1 aclTensor + ret = CreateAclTensor(another1HostData, anotherShape1, &another1DeviceAddr, aclDataType::ACL_FLOAT, &another1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建another2 aclTensor + ret = CreateAclTensor(another2HostData, anotherShape2, &another2DeviceAddr, aclDataType::ACL_FLOAT, &another2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建scalars aclTensor + ret = CreateAclTensor(scalarsHostData, scalarsShape, &scalarsDeviceAddr, aclDataType::ACL_FLOAT, &scalars); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput1{input1, input2}; + aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); + std::vector tempInput2{other1, other2}; + aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); + std::vector tempAnother{another1, another2}; + aclTensorList* tensorListAnother = aclCreateTensorList(tempAnother.data(), tempAnother.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachAddcdivScalarList第一段接口 + ret = aclnnForeachAddcdivScalarListGetWorkspaceSize( + tensorListInput1, tensorListInput2, tensorListAnother, scalars, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddcdivScalarListGetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachAddcdivScalarList第二段接口 + ret = aclnnForeachAddcdivScalarList(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddcdivScalarList failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput1); + aclDestroyTensorList(tensorListInput2); + aclDestroyTensorList(tensorListAnother); + aclDestroyTensorList(tensorListOutput); + aclDestroyTensor(scalars); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(other1DeviceAddr); + aclrtFree(other2DeviceAddr); + aclrtFree(another1DeviceAddr); + aclrtFree(another2DeviceAddr); + aclrtFree(scalarsDeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_addcmul_list/docs/aclnnForeachAddcmulList.md b/foreach/foreach_addcmul_list/docs/aclnnForeachAddcmulList.md index e0c48d0b..388cbdf0 100644 --- a/foreach/foreach_addcmul_list/docs/aclnnForeachAddcmulList.md +++ b/foreach/foreach_addcmul_list/docs/aclnnForeachAddcmulList.md @@ -17,7 +17,7 @@ - 接口功能:先对张量列表x2和张量列表x3执行逐元素乘法,并将结果乘以张量scalars,最后将之前计算的结果与张量列表x1执行逐元素相加。 - 计算公式: - + $$ x1 = [{x1_0}, {x1_1}, ... {x1_{n-1}}], x2 = [{x2_0}, {x2_1}, ... {x2_{n-1}}], x3 = [{x3_0}, {x3_1}, ... {x3_{n-1}}]\\ y = [{y_0}, {y_1}, ... {y_{n-1}}]\\ @@ -154,7 +154,7 @@ aclnnStatus aclnnForeachAddcmulList( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_addcmul_list/examples/test_aclnn_foreach_addcmul_list.cpp b/foreach/foreach_addcmul_list/examples/test_aclnn_foreach_addcmul_list.cpp index ec1890b6..e835c313 100644 --- a/foreach/foreach_addcmul_list/examples/test_aclnn_foreach_addcmul_list.cpp +++ b/foreach/foreach_addcmul_list/examples/test_aclnn_foreach_addcmul_list.cpp @@ -14,26 +14,27 @@ #include "aclnnop/aclnn_foreach_addcmul_list.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,171 +47,179 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector scalarShape = {1, 2}; - std::vector otherShape1 = {2, 3}; - std::vector otherShape2 = {1, 3}; - std::vector anotherShape1 = {2, 3}; - std::vector anotherShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* other1DeviceAddr = nullptr; - void* other2DeviceAddr = nullptr; - void* another1DeviceAddr = nullptr; - void* another2DeviceAddr = nullptr; - void* scalarDeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* other1 = nullptr; - aclTensor* other2 = nullptr; - aclTensor* another1 = nullptr; - aclTensor* another2 = nullptr; - aclTensor* scalar = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector other1HostData = {4, 3, 8, 9, 3, 5}; - std::vector other2HostData = {5, 6, 7}; - std::vector another1HostData = {1, 2, 3, 4, 5, 6}; - std::vector another2HostData = {7, 8, 9}; - std::vector scalarHostData = {1, 2}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建scalar aclTensor - ret = CreateAclTensor(scalarHostData, scalarShape, &scalarDeviceAddr, aclDataType::ACL_FLOAT, &scalar); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other1 aclTensor - ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other2 aclTensor - ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建another1 aclTensor - ret = CreateAclTensor(another1HostData, anotherShape1, &another1DeviceAddr, aclDataType::ACL_FLOAT, &another1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建another2 aclTensor - ret = CreateAclTensor(another2HostData, anotherShape2, &another2DeviceAddr, aclDataType::ACL_FLOAT, &another2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput1{input1, input2}; - aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); - std::vector tempInput2{other1, other2}; - aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); - std::vector tempAnother{another1, another2}; - aclTensorList* tensorListAnother = aclCreateTensorList(tempAnother.data(), tempAnother.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachAddcmulList第一段接口 - ret = aclnnForeachAddcmulListGetWorkspaceSize(tensorListInput1, tensorListInput2, tensorListAnother, scalar, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddcmulListGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachAddcmulList第二段接口 - ret = aclnnForeachAddcmulList(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddcmulList failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput1); - aclDestroyTensorList(tensorListInput2); - aclDestroyTensorList(tensorListAnother); - aclDestroyTensor(scalar); - aclDestroyTensorList(tensorListOutput); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(other1DeviceAddr); - aclrtFree(other2DeviceAddr); - aclrtFree(another1DeviceAddr); - aclrtFree(another2DeviceAddr); - aclrtFree(scalarDeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector scalarShape = {1, 2}; + std::vector otherShape1 = {2, 3}; + std::vector otherShape2 = {1, 3}; + std::vector anotherShape1 = {2, 3}; + std::vector anotherShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* other1DeviceAddr = nullptr; + void* other2DeviceAddr = nullptr; + void* another1DeviceAddr = nullptr; + void* another2DeviceAddr = nullptr; + void* scalarDeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* other1 = nullptr; + aclTensor* other2 = nullptr; + aclTensor* another1 = nullptr; + aclTensor* another2 = nullptr; + aclTensor* scalar = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector other1HostData = {4, 3, 8, 9, 3, 5}; + std::vector other2HostData = {5, 6, 7}; + std::vector another1HostData = {1, 2, 3, 4, 5, 6}; + std::vector another2HostData = {7, 8, 9}; + std::vector scalarHostData = {1, 2}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建scalar aclTensor + ret = CreateAclTensor(scalarHostData, scalarShape, &scalarDeviceAddr, aclDataType::ACL_FLOAT, &scalar); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other1 aclTensor + ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other2 aclTensor + ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建another1 aclTensor + ret = CreateAclTensor(another1HostData, anotherShape1, &another1DeviceAddr, aclDataType::ACL_FLOAT, &another1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建another2 aclTensor + ret = CreateAclTensor(another2HostData, anotherShape2, &another2DeviceAddr, aclDataType::ACL_FLOAT, &another2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput1{input1, input2}; + aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); + std::vector tempInput2{other1, other2}; + aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); + std::vector tempAnother{another1, another2}; + aclTensorList* tensorListAnother = aclCreateTensorList(tempAnother.data(), tempAnother.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachAddcmulList第一段接口 + ret = aclnnForeachAddcmulListGetWorkspaceSize( + tensorListInput1, tensorListInput2, tensorListAnother, scalar, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddcmulListGetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachAddcmulList第二段接口 + ret = aclnnForeachAddcmulList(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddcmulList failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput1); + aclDestroyTensorList(tensorListInput2); + aclDestroyTensorList(tensorListAnother); + aclDestroyTensor(scalar); + aclDestroyTensorList(tensorListOutput); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(other1DeviceAddr); + aclrtFree(other2DeviceAddr); + aclrtFree(another1DeviceAddr); + aclrtFree(another2DeviceAddr); + aclrtFree(scalarDeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_addcmul_scalar/docs/aclnnForeachAddcmulScalar.md b/foreach/foreach_addcmul_scalar/docs/aclnnForeachAddcmulScalar.md index d29042a1..9e640beb 100644 --- a/foreach/foreach_addcmul_scalar/docs/aclnnForeachAddcmulScalar.md +++ b/foreach/foreach_addcmul_scalar/docs/aclnnForeachAddcmulScalar.md @@ -18,7 +18,7 @@ - 接口功能:先对张量列表x2和张量列表x3执行逐元素乘法,再乘以张量scalar,最后将之前计算的结果与张量列表x1执行逐元素相加。 - 计算公式: - + $$ x1 = [{x1_0}, {x1_1}, ... {x1_{n-1}}], x2 = [{x2_0}, {x2_1}, ... {x2_{n-1}}], x3 = [{x3_0}, {x3_1}, ... {x3_{n-1}}]\\ y = [{y_0}, {y_1}, ... {y_{n-1}}]\\ @@ -151,7 +151,7 @@ aclnnStatus aclnnForeachAddcmulScalar(
- Atlas A2 训练系列产品/Atlas A2 推理系列产品Atlas A3 训练系列产品/Atlas A3 推理系列产品: - + 参数`scalar`数据类型与入参`x1`的数据类型具有一定对应关系: - 当`x1`的数据类型为FLOAT32、FLOAT16、INT32时,数据类型与`x1`的数据类型保持一致。 - 当`x1`的数据类型为BFLOAT16时,数据类型支持FLOAT32。 @@ -167,7 +167,7 @@ aclnnStatus aclnnForeachAddcmulScalar( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - + diff --git a/foreach/foreach_addcmul_scalar/docs/aclnnForeachAddcmulScalarV2.md b/foreach/foreach_addcmul_scalar/docs/aclnnForeachAddcmulScalarV2.md index 2ccd0787..3f0b0e47 100644 --- a/foreach/foreach_addcmul_scalar/docs/aclnnForeachAddcmulScalarV2.md +++ b/foreach/foreach_addcmul_scalar/docs/aclnnForeachAddcmulScalarV2.md @@ -150,7 +150,7 @@ aclnnStatus aclnnForeachAddcmulScalarV2(
- Atlas A2 训练系列产品/Atlas A2 推理系列产品Atlas A3 训练系列产品/Atlas A3 推理系列产品: - + `scalar`的数据类型与入参`x1`的数据类型具有一定对应关系: - 当`x1`的数据类型为FLOAT32、BFLOAT16时,数据类型支持FLOAT32、DOUBLE。 - 当`x1`的数据类型为FLOAT16时,数据类型支持FLOAT16、DOUBLE。 @@ -165,7 +165,7 @@ aclnnStatus aclnnForeachAddcmulScalarV2( - **返回值** aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 - + 第一段接口完成入参校验,出现以下场景时报错: diff --git a/foreach/foreach_addcmul_scalar/examples/test_aclnn_foreach_addcmul_scalar.cpp b/foreach/foreach_addcmul_scalar/examples/test_aclnn_foreach_addcmul_scalar.cpp index f3e09acb..f6d79a23 100644 --- a/foreach/foreach_addcmul_scalar/examples/test_aclnn_foreach_addcmul_scalar.cpp +++ b/foreach/foreach_addcmul_scalar/examples/test_aclnn_foreach_addcmul_scalar.cpp @@ -4,8 +4,9 @@ * This file is a part of the CANN Open Software. * Licensed under CANN Open Software License Agreement Version 2.0 (the "License"). * Please refer to the License for details. You may not use this file except in compliance with the License. - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. - * See LICENSE in the root of the software repository for the full text of the License. + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. See LICENSE in the root of + * the software repository for the full text of the License. */ #include @@ -14,26 +15,27 @@ #include "aclnnop/aclnn_foreach_addcmul_scalar.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,171 +48,179 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector otherShape1 = {2, 3}; - std::vector otherShape2 = {1, 3}; - std::vector anotherShape1 = {2, 3}; - std::vector anotherShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - std::vector alphaShape = {1}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* other1DeviceAddr = nullptr; - void* other2DeviceAddr = nullptr; - void* another1DeviceAddr = nullptr; - void* another2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - void* alphaDeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* other1 = nullptr; - aclTensor* other2 = nullptr; - aclTensor* another1 = nullptr; - aclTensor* another2 = nullptr; - aclTensor* alpha = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector other1HostData = {1, 2, 3, 4, 5, 6}; - std::vector other2HostData = {7, 8, 9}; - std::vector another1HostData = {1, 2, 3, 4, 5, 6}; - std::vector another2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - std::vector alphaValueHostData = {1.2f}; - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other1 aclTensor - ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other2 aclTensor - ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建another1 aclTensor - ret = CreateAclTensor(another1HostData, anotherShape1, &another1DeviceAddr, aclDataType::ACL_FLOAT, &another1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建another2 aclTensor - ret = CreateAclTensor(another2HostData, anotherShape2, &another2DeviceAddr, aclDataType::ACL_FLOAT, &another2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建alpha aclTensor - ret = CreateAclTensor(alphaValueHostData, alphaShape, &alphaDeviceAddr, aclDataType::ACL_FLOAT, &alpha); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput1{input1, input2}; - aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); - std::vector tempInput2{other1, other2}; - aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); - std::vector tempAnother{another1, another2}; - aclTensorList* tensorListAnother = aclCreateTensorList(tempAnother.data(), tempAnother.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachAddcmulScalar第一段接口 - ret = aclnnForeachAddcmulScalarGetWorkspaceSize(tensorListInput1, tensorListInput2, tensorListAnother, alpha, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddcmulScalarGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachAddcmulScalar第二段接口 - ret = aclnnForeachAddcmulScalar(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddcmulScalar failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput1); - aclDestroyTensorList(tensorListInput2); - aclDestroyTensorList(tensorListAnother); - aclDestroyTensorList(tensorListOutput); - aclDestroyTensor(alpha); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(other1DeviceAddr); - aclrtFree(other2DeviceAddr); - aclrtFree(another1DeviceAddr); - aclrtFree(another2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - aclrtFree(alphaDeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector otherShape1 = {2, 3}; + std::vector otherShape2 = {1, 3}; + std::vector anotherShape1 = {2, 3}; + std::vector anotherShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + std::vector alphaShape = {1}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* other1DeviceAddr = nullptr; + void* other2DeviceAddr = nullptr; + void* another1DeviceAddr = nullptr; + void* another2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + void* alphaDeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* other1 = nullptr; + aclTensor* other2 = nullptr; + aclTensor* another1 = nullptr; + aclTensor* another2 = nullptr; + aclTensor* alpha = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector other1HostData = {1, 2, 3, 4, 5, 6}; + std::vector other2HostData = {7, 8, 9}; + std::vector another1HostData = {1, 2, 3, 4, 5, 6}; + std::vector another2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + std::vector alphaValueHostData = {1.2f}; + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other1 aclTensor + ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other2 aclTensor + ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建another1 aclTensor + ret = CreateAclTensor(another1HostData, anotherShape1, &another1DeviceAddr, aclDataType::ACL_FLOAT, &another1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建another2 aclTensor + ret = CreateAclTensor(another2HostData, anotherShape2, &another2DeviceAddr, aclDataType::ACL_FLOAT, &another2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建alpha aclTensor + ret = CreateAclTensor(alphaValueHostData, alphaShape, &alphaDeviceAddr, aclDataType::ACL_FLOAT, &alpha); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput1{input1, input2}; + aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); + std::vector tempInput2{other1, other2}; + aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); + std::vector tempAnother{another1, another2}; + aclTensorList* tensorListAnother = aclCreateTensorList(tempAnother.data(), tempAnother.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachAddcmulScalar第一段接口 + ret = aclnnForeachAddcmulScalarGetWorkspaceSize( + tensorListInput1, tensorListInput2, tensorListAnother, alpha, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddcmulScalarGetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachAddcmulScalar第二段接口 + ret = aclnnForeachAddcmulScalar(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddcmulScalar failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput1); + aclDestroyTensorList(tensorListInput2); + aclDestroyTensorList(tensorListAnother); + aclDestroyTensorList(tensorListOutput); + aclDestroyTensor(alpha); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(other1DeviceAddr); + aclrtFree(other2DeviceAddr); + aclrtFree(another1DeviceAddr); + aclrtFree(another2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + aclrtFree(alphaDeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_addcmul_scalar/examples/test_aclnn_foreach_addcmul_scalar_v2.cpp b/foreach/foreach_addcmul_scalar/examples/test_aclnn_foreach_addcmul_scalar_v2.cpp index 741a67f1..955edd14 100644 --- a/foreach/foreach_addcmul_scalar/examples/test_aclnn_foreach_addcmul_scalar_v2.cpp +++ b/foreach/foreach_addcmul_scalar/examples/test_aclnn_foreach_addcmul_scalar_v2.cpp @@ -4,8 +4,9 @@ * This file is a part of the CANN Open Software. * Licensed under CANN Open Software License Agreement Version 2.0 (the "License"). * Please refer to the License for details. You may not use this file except in compliance with the License. - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. - * See LICENSE in the root of the software repository for the full text of the License. + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. See LICENSE in the root of + * the software repository for the full text of the License. */ #include @@ -14,26 +15,27 @@ #include "aclnnop/aclnn_foreach_addcmul_scalar_v2.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,168 +48,176 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector otherShape1 = {2, 3}; - std::vector otherShape2 = {1, 3}; - std::vector anotherShape1 = {2, 3}; - std::vector anotherShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* other1DeviceAddr = nullptr; - void* other2DeviceAddr = nullptr; - void* another1DeviceAddr = nullptr; - void* another2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* other1 = nullptr; - aclTensor* other2 = nullptr; - aclTensor* another1 = nullptr; - aclTensor* another2 = nullptr; - aclScalar* alpha = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector other1HostData = {1, 2, 3, 4, 5, 6}; - std::vector other2HostData = {7, 8, 9}; - std::vector another1HostData = {1, 2, 3, 4, 5, 6}; - std::vector another2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - float alphaValue = 1.2f; - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other1 aclTensor - ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other2 aclTensor - ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建another1 aclTensor - ret = CreateAclTensor(another1HostData, anotherShape1, &another1DeviceAddr, aclDataType::ACL_FLOAT, &another1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建another2 aclTensor - ret = CreateAclTensor(another2HostData, anotherShape2, &another2DeviceAddr, aclDataType::ACL_FLOAT, &another2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建alpha aclScalar - alpha = aclCreateScalar(&alphaValue, aclDataType::ACL_FLOAT); - CHECK_RET(alpha != nullptr, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput1{input1, input2}; - aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); - std::vector tempInput2{other1, other2}; - aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); - std::vector tempAnother{another1, another2}; - aclTensorList* tensorListAnother = aclCreateTensorList(tempAnother.data(), tempAnother.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachAddcmulScalarV2第一段接口 - ret = aclnnForeachAddcmulScalarV2GetWorkspaceSize(tensorListInput1, tensorListInput2, tensorListAnother, alpha, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddcmulScalarV2GetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachAddcmulScalarV2第二段接口 - ret = aclnnForeachAddcmulScalarV2(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddcmulScalarV2 failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput1); - aclDestroyTensorList(tensorListInput2); - aclDestroyTensorList(tensorListAnother); - aclDestroyTensorList(tensorListOutput); - aclDestroyScalar(alpha); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(other1DeviceAddr); - aclrtFree(other2DeviceAddr); - aclrtFree(another1DeviceAddr); - aclrtFree(another2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector otherShape1 = {2, 3}; + std::vector otherShape2 = {1, 3}; + std::vector anotherShape1 = {2, 3}; + std::vector anotherShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* other1DeviceAddr = nullptr; + void* other2DeviceAddr = nullptr; + void* another1DeviceAddr = nullptr; + void* another2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* other1 = nullptr; + aclTensor* other2 = nullptr; + aclTensor* another1 = nullptr; + aclTensor* another2 = nullptr; + aclScalar* alpha = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector other1HostData = {1, 2, 3, 4, 5, 6}; + std::vector other2HostData = {7, 8, 9}; + std::vector another1HostData = {1, 2, 3, 4, 5, 6}; + std::vector another2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + float alphaValue = 1.2f; + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other1 aclTensor + ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other2 aclTensor + ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建another1 aclTensor + ret = CreateAclTensor(another1HostData, anotherShape1, &another1DeviceAddr, aclDataType::ACL_FLOAT, &another1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建another2 aclTensor + ret = CreateAclTensor(another2HostData, anotherShape2, &another2DeviceAddr, aclDataType::ACL_FLOAT, &another2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建alpha aclScalar + alpha = aclCreateScalar(&alphaValue, aclDataType::ACL_FLOAT); + CHECK_RET(alpha != nullptr, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput1{input1, input2}; + aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); + std::vector tempInput2{other1, other2}; + aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); + std::vector tempAnother{another1, another2}; + aclTensorList* tensorListAnother = aclCreateTensorList(tempAnother.data(), tempAnother.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachAddcmulScalarV2第一段接口 + ret = aclnnForeachAddcmulScalarV2GetWorkspaceSize( + tensorListInput1, tensorListInput2, tensorListAnother, alpha, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddcmulScalarV2GetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachAddcmulScalarV2第二段接口 + ret = aclnnForeachAddcmulScalarV2(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddcmulScalarV2 failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput1); + aclDestroyTensorList(tensorListInput2); + aclDestroyTensorList(tensorListAnother); + aclDestroyTensorList(tensorListOutput); + aclDestroyScalar(alpha); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(other1DeviceAddr); + aclrtFree(other2DeviceAddr); + aclrtFree(another1DeviceAddr); + aclrtFree(another2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_addcmul_scalar_list/docs/aclnnForeachAddcmulScalarList.md b/foreach/foreach_addcmul_scalar_list/docs/aclnnForeachAddcmulScalarList.md index 36051a5d..6d31d11d 100644 --- a/foreach/foreach_addcmul_scalar_list/docs/aclnnForeachAddcmulScalarList.md +++ b/foreach/foreach_addcmul_scalar_list/docs/aclnnForeachAddcmulScalarList.md @@ -17,7 +17,7 @@ - 接口功能:先对张量列表x2和张量列表x3执行逐元素乘法,再与张量scalars进行逐元素乘法,最后将之前计算的结果与张量列表x1执行逐元素相加。 - 计算公式: - + $$ x1 = [{x1_0}, {x1_1}, ... {x1_{n-1}}], x2 = [{x2_0}, {x2_1}, ... {x2_{n-1}}], x3 = [{x3_0}, {x3_1}, ... {x3_{n-1}}]\\ scalars = [{scalars_0}, {scalars_1}, ... {scalars_{n-1}}]\\ @@ -155,7 +155,7 @@ aclnnStatus aclnnForeachAddcmulScalarList( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_addcmul_scalar_list/examples/test_aclnn_foreach_addcmul_scalar_list.cpp b/foreach/foreach_addcmul_scalar_list/examples/test_aclnn_foreach_addcmul_scalar_list.cpp index b36dd44f..06b5d4e6 100644 --- a/foreach/foreach_addcmul_scalar_list/examples/test_aclnn_foreach_addcmul_scalar_list.cpp +++ b/foreach/foreach_addcmul_scalar_list/examples/test_aclnn_foreach_addcmul_scalar_list.cpp @@ -14,26 +14,27 @@ #include "aclnnop/aclnn_foreach_addcmul_scalar_list.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,171 +47,179 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector otherShape1 = {2, 3}; - std::vector otherShape2 = {1, 3}; - std::vector anotherShape1 = {2, 3}; - std::vector anotherShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - std::vector scalarsShape = {2}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* other1DeviceAddr = nullptr; - void* other2DeviceAddr = nullptr; - void* another1DeviceAddr = nullptr; - void* another2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - void* scalarsDeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* other1 = nullptr; - aclTensor* other2 = nullptr; - aclTensor* another1 = nullptr; - aclTensor* another2 = nullptr; - aclTensor* scalars = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector other1HostData = {4, 3, 8, 9, 3, 5}; - std::vector other2HostData = {5, 6, 7}; - std::vector another1HostData = {1, 2, 3, 4, 5, 6}; - std::vector another2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - std::vector scalarsHostData{1.2f, 2.2f}; - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other1 aclTensor - ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other2 aclTensor - ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建another1 aclTensor - ret = CreateAclTensor(another1HostData, anotherShape1, &another1DeviceAddr, aclDataType::ACL_FLOAT, &another1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建another2 aclTensor - ret = CreateAclTensor(another2HostData, anotherShape2, &another2DeviceAddr, aclDataType::ACL_FLOAT, &another2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建scalars aclTensor - ret = CreateAclTensor(scalarsHostData, scalarsShape, &scalarsDeviceAddr, aclDataType::ACL_FLOAT, &scalars); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput1{input1, input2}; - aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); - std::vector tempInput2{other1, other2}; - aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); - std::vector tempAnother{another1, another2}; - aclTensorList* tensorListAnother = aclCreateTensorList(tempAnother.data(), tempAnother.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachAddcmulScalarList第一段接口 - ret = aclnnForeachAddcmulScalarListGetWorkspaceSize(tensorListInput1, tensorListInput2, tensorListAnother, scalars, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddcmulScalarListGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachAddcmulScalarList第二段接口 - ret = aclnnForeachAddcmulScalarList(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddcmulScalarList failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput1); - aclDestroyTensorList(tensorListInput2); - aclDestroyTensorList(tensorListAnother); - aclDestroyTensorList(tensorListOutput); - aclDestroyTensor(scalars); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(other1DeviceAddr); - aclrtFree(other2DeviceAddr); - aclrtFree(another1DeviceAddr); - aclrtFree(another2DeviceAddr); - aclrtFree(scalarsDeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector otherShape1 = {2, 3}; + std::vector otherShape2 = {1, 3}; + std::vector anotherShape1 = {2, 3}; + std::vector anotherShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + std::vector scalarsShape = {2}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* other1DeviceAddr = nullptr; + void* other2DeviceAddr = nullptr; + void* another1DeviceAddr = nullptr; + void* another2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + void* scalarsDeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* other1 = nullptr; + aclTensor* other2 = nullptr; + aclTensor* another1 = nullptr; + aclTensor* another2 = nullptr; + aclTensor* scalars = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector other1HostData = {4, 3, 8, 9, 3, 5}; + std::vector other2HostData = {5, 6, 7}; + std::vector another1HostData = {1, 2, 3, 4, 5, 6}; + std::vector another2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + std::vector scalarsHostData{1.2f, 2.2f}; + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other1 aclTensor + ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other2 aclTensor + ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建another1 aclTensor + ret = CreateAclTensor(another1HostData, anotherShape1, &another1DeviceAddr, aclDataType::ACL_FLOAT, &another1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建another2 aclTensor + ret = CreateAclTensor(another2HostData, anotherShape2, &another2DeviceAddr, aclDataType::ACL_FLOAT, &another2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建scalars aclTensor + ret = CreateAclTensor(scalarsHostData, scalarsShape, &scalarsDeviceAddr, aclDataType::ACL_FLOAT, &scalars); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput1{input1, input2}; + aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); + std::vector tempInput2{other1, other2}; + aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); + std::vector tempAnother{another1, another2}; + aclTensorList* tensorListAnother = aclCreateTensorList(tempAnother.data(), tempAnother.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachAddcmulScalarList第一段接口 + ret = aclnnForeachAddcmulScalarListGetWorkspaceSize( + tensorListInput1, tensorListInput2, tensorListAnother, scalars, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddcmulScalarListGetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachAddcmulScalarList第二段接口 + ret = aclnnForeachAddcmulScalarList(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAddcmulScalarList failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput1); + aclDestroyTensorList(tensorListInput2); + aclDestroyTensorList(tensorListAnother); + aclDestroyTensorList(tensorListOutput); + aclDestroyTensor(scalars); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(other1DeviceAddr); + aclrtFree(other2DeviceAddr); + aclrtFree(another1DeviceAddr); + aclrtFree(another2DeviceAddr); + aclrtFree(scalarsDeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_asin/docs/aclnnForeachAsin.md b/foreach/foreach_asin/docs/aclnnForeachAsin.md index 1d3a4ead..caa3d1e8 100644 --- a/foreach/foreach_asin/docs/aclnnForeachAsin.md +++ b/foreach/foreach_asin/docs/aclnnForeachAsin.md @@ -121,7 +121,7 @@ aclnnStatus aclnnForeachAsin( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_asin/examples/test_aclnn_foreach_asin.cpp b/foreach/foreach_asin/examples/test_aclnn_foreach_asin.cpp index ccbbe45c..e973fb41 100644 --- a/foreach/foreach_asin/examples/test_aclnn_foreach_asin.cpp +++ b/foreach/foreach_asin/examples/test_aclnn_foreach_asin.cpp @@ -14,26 +14,27 @@ #include "aclnnop/aclnn_foreach_asin.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,128 +47,134 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6}; - std::vector input2HostData = {0.7, 0.8, 0.9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachAsin第一段接口 - ret = aclnnForeachAsinGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAsinGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachAsin第二段接口 - ret = aclnnForeachAsin(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAsin failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6}; + std::vector input2HostData = {0.7, 0.8, 0.9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachAsin第一段接口 + ret = aclnnForeachAsinGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAsinGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachAsin第二段接口 + ret = aclnnForeachAsin(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAsin failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_atan/docs/aclnnForeachAtan.md b/foreach/foreach_atan/docs/aclnnForeachAtan.md index bbd89488..213725ff 100644 --- a/foreach/foreach_atan/docs/aclnnForeachAtan.md +++ b/foreach/foreach_atan/docs/aclnnForeachAtan.md @@ -121,7 +121,7 @@ aclnnStatus aclnnForeachAtan( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
@@ -205,7 +205,7 @@ aclnnStatus aclnnForeachAtan( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 ## 约束说明 - + - 确定性计算: - aclnnForeachAtan默认确定性实现。 diff --git a/foreach/foreach_atan/examples/test_aclnn_foreach_atan.cpp b/foreach/foreach_atan/examples/test_aclnn_foreach_atan.cpp index 29772f3f..fe4c76be 100644 --- a/foreach/foreach_atan/examples/test_aclnn_foreach_atan.cpp +++ b/foreach/foreach_atan/examples/test_aclnn_foreach_atan.cpp @@ -14,26 +14,27 @@ #include "aclnnop/aclnn_foreach_atan.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,128 +47,134 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachAtan第一段接口 - ret = aclnnForeachAtanGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAtanGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachAtan第二段接口 - ret = aclnnForeachAtan(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAtan failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachAtan第一段接口 + ret = aclnnForeachAtanGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAtanGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachAtan第二段接口 + ret = aclnnForeachAtan(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachAtan failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_copy/docs/aclnnForeachCopy.md b/foreach/foreach_copy/docs/aclnnForeachCopy.md index c68894d3..045715c7 100644 --- a/foreach/foreach_copy/docs/aclnnForeachCopy.md +++ b/foreach/foreach_copy/docs/aclnnForeachCopy.md @@ -122,7 +122,7 @@ aclnnStatus aclnnForeachCopy( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_copy/examples/test_aclnn_foreach_copy.cpp b/foreach/foreach_copy/examples/test_aclnn_foreach_copy.cpp index 4e4b598e..4977fa6b 100644 --- a/foreach/foreach_copy/examples/test_aclnn_foreach_copy.cpp +++ b/foreach/foreach_copy/examples/test_aclnn_foreach_copy.cpp @@ -22,7 +22,7 @@ do { \ printf(message, ##__VA_ARGS__); \ } while (0) -int64_t GetShapeSize(const std::vector &shape) +int64_t GetShapeSize(const std::vector& shape) { int64_t shapeSize = 1; for (auto i : shape) { @@ -30,7 +30,7 @@ int64_t GetShapeSize(const std::vector &shape) } return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -42,8 +42,9 @@ int Init(int32_t deviceId, aclrtStream *stream) return 0; } template -int CreateAclTensor(const std::vector &hostData, const std::vector &shape, void **deviceAddr, - aclDataType dataType, aclTensor **tensor) +int CreateAclTensor( + const std::vector& hostData, const std::vector& shape, void** deviceAddr, aclDataType dataType, + aclTensor** tensor) { auto size = GetShapeSize(shape) * sizeof(T); // 调用aclrtMalloc申请device侧内存 @@ -58,14 +59,8 @@ int CreateAclTensor(const std::vector &hostData, const std::vector & strides[i] = shape[i + 1] * strides[i + 1]; } // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), - shape.size(), - dataType, - strides.data(), - 0, - aclFormat::ACL_FORMAT_ND, - shape.data(), - shape.size(), + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), *deviceAddr); return 0; } @@ -82,14 +77,14 @@ int main() std::vector selfShape2 = {1, 3}; std::vector outShape1 = {2, 3}; std::vector outShape2 = {1, 3}; - void *input1DeviceAddr = nullptr; - void *input2DeviceAddr = nullptr; - void *out1DeviceAddr = nullptr; - void *out2DeviceAddr = nullptr; - aclTensor *input1 = nullptr; - aclTensor *input2 = nullptr; - aclTensor *out1 = nullptr; - aclTensor *out2 = nullptr; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; std::vector input1HostData = {1, 2, 3, 4, 5, 6}; std::vector input2HostData = {7, 8, 9}; std::vector out1HostData(6, 0); @@ -106,18 +101,18 @@ int main() // 创建out2 aclTensor ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); CHECK_RET(ret == ACL_SUCCESS, return ret); - std::vector tempInput{input1, input2}; - aclTensorList *tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList *tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); // 3. 调用CANN算子库API,需要修改为具体的API名称 uint64_t workspaceSize = 0; - aclOpExecutor *executor; + aclOpExecutor* executor; // 调用aclnnForeachCopy第一段接口 ret = aclnnForeachCopyGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachCopyGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); // 根据第一段接口计算出的workspaceSize申请device内存 - void *workspaceAddr = nullptr; + void* workspaceAddr = nullptr; if (workspaceSize > 0) { ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); @@ -131,10 +126,8 @@ int main() // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 auto size = GetShapeSize(outShape1); std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), - out1Data.size() * sizeof(out1Data[0]), - out1DeviceAddr, - size * sizeof(out1Data[0]), + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); CHECK_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++) { @@ -142,10 +135,8 @@ int main() } size = GetShapeSize(outShape2); std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), - out2Data.size() * sizeof(out2Data[0]), - out2DeviceAddr, - size * sizeof(out2Data[0]), + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); CHECK_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++) { @@ -166,4 +157,4 @@ int main() aclrtResetDevice(deviceId); aclFinalize(); return 0; -} \ No newline at end of file +} diff --git a/foreach/foreach_cos/docs/aclnnForeachCos.md b/foreach/foreach_cos/docs/aclnnForeachCos.md index 39d4721c..7d174aff 100644 --- a/foreach/foreach_cos/docs/aclnnForeachCos.md +++ b/foreach/foreach_cos/docs/aclnnForeachCos.md @@ -127,7 +127,7 @@ aclnnStatus aclnnForeachCos( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_cos/examples/test_aclnn_foreach_cos.cpp b/foreach/foreach_cos/examples/test_aclnn_foreach_cos.cpp index 13c77c17..eef5eef8 100644 --- a/foreach/foreach_cos/examples/test_aclnn_foreach_cos.cpp +++ b/foreach/foreach_cos/examples/test_aclnn_foreach_cos.cpp @@ -14,26 +14,27 @@ #include "aclnnop/aclnn_foreach_cos.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,128 +47,134 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachCos第一段接口 - ret = aclnnForeachCosGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachCosGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachCos第二段接口 - ret = aclnnForeachCos(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachCos failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果拷贝至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachCos第一段接口 + ret = aclnnForeachCosGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachCosGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachCos第二段接口 + ret = aclnnForeachCos(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachCos failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果拷贝至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_cosh/docs/aclnnForeachCosh.md b/foreach/foreach_cosh/docs/aclnnForeachCosh.md index ef34250a..d9594610 100644 --- a/foreach/foreach_cosh/docs/aclnnForeachCosh.md +++ b/foreach/foreach_cosh/docs/aclnnForeachCosh.md @@ -121,7 +121,7 @@ aclnnStatus aclnnForeachCosh( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_cosh/examples/test_aclnn_foreach_cosh.cpp b/foreach/foreach_cosh/examples/test_aclnn_foreach_cosh.cpp index 3ead09e2..7a7c9476 100644 --- a/foreach/foreach_cosh/examples/test_aclnn_foreach_cosh.cpp +++ b/foreach/foreach_cosh/examples/test_aclnn_foreach_cosh.cpp @@ -14,26 +14,27 @@ #include "aclnnop/aclnn_foreach_cosh.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,128 +47,134 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachCosh第一段接口 - ret = aclnnForeachCoshGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachCoshGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachCosh第二段接口 - ret = aclnnForeachCosh(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachCosh failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachCosh第一段接口 + ret = aclnnForeachCoshGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachCoshGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachCosh第二段接口 + ret = aclnnForeachCosh(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachCosh failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_div_list/docs/aclnnForeachDivList.md b/foreach/foreach_div_list/docs/aclnnForeachDivList.md index 4740b402..3a174fe8 100644 --- a/foreach/foreach_div_list/docs/aclnnForeachDivList.md +++ b/foreach/foreach_div_list/docs/aclnnForeachDivList.md @@ -133,7 +133,7 @@ aclnnStatus aclnnForeachDivList( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_div_list/examples/test_aclnn_foreach_div_list.cpp b/foreach/foreach_div_list/examples/test_aclnn_foreach_div_list.cpp index 9d43d47a..a8814945 100644 --- a/foreach/foreach_div_list/examples/test_aclnn_foreach_div_list.cpp +++ b/foreach/foreach_div_list/examples/test_aclnn_foreach_div_list.cpp @@ -14,174 +14,184 @@ #include "aclnnop/aclnn_foreach_div_list.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& 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; +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 -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector otherShape1 = {2, 3}; - std::vector otherShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* other1DeviceAddr = nullptr; - void* other2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* other1 = nullptr; - aclTensor* other2 = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector other1HostData = {6, 5, 4, 3, 2, 1}; - std::vector other2HostData = {9, 8, 7}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other1 aclTensor - ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other2 aclTensor - ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput1{input1, input2}; - aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); - std::vector tempInput2{other1, other2}; - aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachDivList第一段接口 - ret = aclnnForeachDivListGetWorkspaceSize(tensorListInput1, tensorListInput2, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachDivListGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachDivList第二段接口 - ret = aclnnForeachDivList(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachDivList failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput1); - aclDestroyTensorList(tensorListInput2); - aclDestroyTensorList(tensorListOutput); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(other1DeviceAddr); - aclrtFree(other2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector otherShape1 = {2, 3}; + std::vector otherShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* other1DeviceAddr = nullptr; + void* other2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* other1 = nullptr; + aclTensor* other2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector other1HostData = {6, 5, 4, 3, 2, 1}; + std::vector other2HostData = {9, 8, 7}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other1 aclTensor + ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other2 aclTensor + ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput1{input1, input2}; + aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); + std::vector tempInput2{other1, other2}; + aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachDivList第一段接口 + ret = aclnnForeachDivListGetWorkspaceSize( + tensorListInput1, tensorListInput2, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachDivListGetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachDivList第二段接口 + ret = aclnnForeachDivList(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachDivList failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput1); + aclDestroyTensorList(tensorListInput2); + aclDestroyTensorList(tensorListOutput); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(other1DeviceAddr); + aclrtFree(other2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_div_scalar/docs/aclnnForeachDivScalar.md b/foreach/foreach_div_scalar/docs/aclnnForeachDivScalar.md index 5c5b744a..55cff4d9 100644 --- a/foreach/foreach_div_scalar/docs/aclnnForeachDivScalar.md +++ b/foreach/foreach_div_scalar/docs/aclnnForeachDivScalar.md @@ -133,7 +133,7 @@ aclnnStatus aclnnForeachDivScalar( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_div_scalar/docs/aclnnForeachDivScalarV2.md b/foreach/foreach_div_scalar/docs/aclnnForeachDivScalarV2.md index 007fb3e9..fa850c2f 100644 --- a/foreach/foreach_div_scalar/docs/aclnnForeachDivScalarV2.md +++ b/foreach/foreach_div_scalar/docs/aclnnForeachDivScalarV2.md @@ -17,7 +17,7 @@ - 接口功能:计算张量列表x除以标量scalar。本接口相较于[aclnnForeachDivScalar](aclnnForeachDivScalar.md),修改入参scalar的结构类型aclTensor为aclScalar,请根据实际情况选择合适的接口 - 计算公式: - + $$ x = [{x_0}, {x_1}, ... {x_{n-1}}]\\ y = [{y_0}, {y_1}, ... {y_{n-1}}]\\ @@ -130,7 +130,7 @@ aclnnStatus aclnnForeachDivScalarV2( - **返回值** aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 - + 第一段接口完成入参校验,出现以下场景时报错:
diff --git a/foreach/foreach_div_scalar/examples/test_aclnn_foreach_div_scalar.cpp b/foreach/foreach_div_scalar/examples/test_aclnn_foreach_div_scalar.cpp index f03b3dd8..93b4e3ba 100644 --- a/foreach/foreach_div_scalar/examples/test_aclnn_foreach_div_scalar.cpp +++ b/foreach/foreach_div_scalar/examples/test_aclnn_foreach_div_scalar.cpp @@ -14,164 +14,173 @@ #include "aclnnop/aclnn_foreach_div_scalar.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& 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; +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 -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - std::vector alphaShape = {1}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - void* alphaDeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* alpha = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - std::vector alphaValueHostData = {1.2f}; - float alphaValue = 1.2f; - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建alpha aclTensor - ret = CreateAclTensor(alphaValueHostData, alphaShape, &alphaDeviceAddr, aclDataType::ACL_FLOAT, &alpha); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachDivScalar第一段接口 - ret = aclnnForeachDivScalarGetWorkspaceSize(tensorListInput, alpha, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachDivScalarGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachDivScalar第二段接口 - ret = aclnnForeachDivScalar(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachDivScalar failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - aclDestroyTensor(alpha); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - aclrtFree(alphaDeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + std::vector alphaShape = {1}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + void* alphaDeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* alpha = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + std::vector alphaValueHostData = {1.2f}; + float alphaValue = 1.2f; + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建alpha aclTensor + ret = CreateAclTensor(alphaValueHostData, alphaShape, &alphaDeviceAddr, aclDataType::ACL_FLOAT, &alpha); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachDivScalar第一段接口 + ret = aclnnForeachDivScalarGetWorkspaceSize(tensorListInput, alpha, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachDivScalarGetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachDivScalar第二段接口 + ret = aclnnForeachDivScalar(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachDivScalar failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + aclDestroyTensor(alpha); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + aclrtFree(alphaDeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_div_scalar/examples/test_aclnn_foreach_div_scalar_v2.cpp b/foreach/foreach_div_scalar/examples/test_aclnn_foreach_div_scalar_v2.cpp index 76820f88..339fe1dc 100644 --- a/foreach/foreach_div_scalar/examples/test_aclnn_foreach_div_scalar_v2.cpp +++ b/foreach/foreach_div_scalar/examples/test_aclnn_foreach_div_scalar_v2.cpp @@ -14,160 +14,169 @@ #include "aclnnop/aclnn_foreach_div_scalar_v2.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& 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; +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 -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclScalar* alpha = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - float alphaValue = 1.2f; - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建alpha aclScalar - alpha = aclCreateScalar(&alphaValue, aclDataType::ACL_FLOAT); - CHECK_RET(alpha != nullptr, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachDivScalarV2第一段接口 - ret = aclnnForeachDivScalarV2GetWorkspaceSize(tensorListInput, alpha, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachDivScalarV2GetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachDivScalarV2第二段接口 - ret = aclnnForeachDivScalarV2(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachDivScalarV2 failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - aclDestroyScalar(alpha); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclScalar* alpha = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + float alphaValue = 1.2f; + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建alpha aclScalar + alpha = aclCreateScalar(&alphaValue, aclDataType::ACL_FLOAT); + CHECK_RET(alpha != nullptr, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachDivScalarV2第一段接口 + ret = aclnnForeachDivScalarV2GetWorkspaceSize(tensorListInput, alpha, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachDivScalarV2GetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachDivScalarV2第二段接口 + ret = aclnnForeachDivScalarV2(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachDivScalarV2 failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + aclDestroyScalar(alpha); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_div_scalar_list/docs/aclnnForeachDivScalarList.md b/foreach/foreach_div_scalar_list/docs/aclnnForeachDivScalarList.md index a2130489..b6605c15 100644 --- a/foreach/foreach_div_scalar_list/docs/aclnnForeachDivScalarList.md +++ b/foreach/foreach_div_scalar_list/docs/aclnnForeachDivScalarList.md @@ -134,7 +134,7 @@ aclnnStatus aclnnForeachDivScalarList( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_div_scalar_list/examples/test_aclnn_foreach_div_scalar_list.cpp b/foreach/foreach_div_scalar_list/examples/test_aclnn_foreach_div_scalar_list.cpp index bb493ddf..89a7bcf1 100644 --- a/foreach/foreach_div_scalar_list/examples/test_aclnn_foreach_div_scalar_list.cpp +++ b/foreach/foreach_div_scalar_list/examples/test_aclnn_foreach_div_scalar_list.cpp @@ -14,167 +14,177 @@ #include "aclnnop/aclnn_foreach_div_scalar_list.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& 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; +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 -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclScalar* alpha1 = nullptr; - aclScalar* alpha2 = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - float alpha1Value = 1.2f; - float alpha2Value = 2.2f; - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建alpha1 aclScalar - alpha1 = aclCreateScalar(&alpha1Value, aclDataType::ACL_FLOAT); - CHECK_RET(alpha1 != nullptr, return ret); - // 创建alpha2 aclScalar - alpha2 = aclCreateScalar(&alpha2Value, aclDataType::ACL_FLOAT); - CHECK_RET(alpha2 != nullptr, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - std::vector tempscalar{alpha1, alpha2}; - aclScalarList* scalarlist = aclCreateScalarList(tempscalar.data(), tempscalar.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachDivScalarList第一段接口 - ret = aclnnForeachDivScalarListGetWorkspaceSize(tensorListInput, scalarlist, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachDivScalarListGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachDivScalarList第二段接口 - ret = aclnnForeachDivScalarList(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachDivScalarList failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - aclDestroyScalarList(scalarlist); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclScalar* alpha1 = nullptr; + aclScalar* alpha2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + float alpha1Value = 1.2f; + float alpha2Value = 2.2f; + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建alpha1 aclScalar + alpha1 = aclCreateScalar(&alpha1Value, aclDataType::ACL_FLOAT); + CHECK_RET(alpha1 != nullptr, return ret); + // 创建alpha2 aclScalar + alpha2 = aclCreateScalar(&alpha2Value, aclDataType::ACL_FLOAT); + CHECK_RET(alpha2 != nullptr, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + std::vector tempscalar{alpha1, alpha2}; + aclScalarList* scalarlist = aclCreateScalarList(tempscalar.data(), tempscalar.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachDivScalarList第一段接口 + ret = aclnnForeachDivScalarListGetWorkspaceSize( + tensorListInput, scalarlist, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachDivScalarListGetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachDivScalarList第二段接口 + ret = aclnnForeachDivScalarList(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachDivScalarList failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + aclDestroyScalarList(scalarlist); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_erf/docs/aclnnForeachErf.md b/foreach/foreach_erf/docs/aclnnForeachErf.md index 4d6f52ae..99cc51ed 100644 --- a/foreach/foreach_erf/docs/aclnnForeachErf.md +++ b/foreach/foreach_erf/docs/aclnnForeachErf.md @@ -121,7 +121,7 @@ aclnnStatus aclnnForeachErf( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_erf/examples/test_aclnn_foreach_erf.cpp b/foreach/foreach_erf/examples/test_aclnn_foreach_erf.cpp index ed842fbc..4fade6c4 100644 --- a/foreach/foreach_erf/examples/test_aclnn_foreach_erf.cpp +++ b/foreach/foreach_erf/examples/test_aclnn_foreach_erf.cpp @@ -14,26 +14,27 @@ #include "aclnnop/aclnn_foreach_erf.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,128 +47,134 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachErf第一段接口 - ret = aclnnForeachErfGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachErfGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachErf第二段接口 - ret = aclnnForeachErf(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachErf failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachErf第一段接口 + ret = aclnnForeachErfGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachErfGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachErf第二段接口 + ret = aclnnForeachErf(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachErf failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_erfc/docs/aclnnForeachErfc.md b/foreach/foreach_erfc/docs/aclnnForeachErfc.md index 8b247a4c..da2de31a 100644 --- a/foreach/foreach_erfc/docs/aclnnForeachErfc.md +++ b/foreach/foreach_erfc/docs/aclnnForeachErfc.md @@ -121,7 +121,7 @@ aclnnStatus aclnnForeachErfc( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_erfc/examples/test_aclnn_foreach_erfc.cpp b/foreach/foreach_erfc/examples/test_aclnn_foreach_erfc.cpp index ddf0192f..b95cdaff 100644 --- a/foreach/foreach_erfc/examples/test_aclnn_foreach_erfc.cpp +++ b/foreach/foreach_erfc/examples/test_aclnn_foreach_erfc.cpp @@ -14,26 +14,27 @@ #include "aclnnop/aclnn_foreach_erfc.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,128 +47,134 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachErfc第一段接口 - ret = aclnnForeachErfcGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachErfcGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachErfc第二段接口 - ret = aclnnForeachErfc(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachErfc failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachErfc第一段接口 + ret = aclnnForeachErfcGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachErfcGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachErfc第二段接口 + ret = aclnnForeachErfc(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachErfc failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_exp/docs/aclnnForeachExp.md b/foreach/foreach_exp/docs/aclnnForeachExp.md index 26cf0540..42f14d4e 100644 --- a/foreach/foreach_exp/docs/aclnnForeachExp.md +++ b/foreach/foreach_exp/docs/aclnnForeachExp.md @@ -121,7 +121,7 @@ aclnnStatus aclnnForeachExp( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_exp/examples/test_aclnn_foreach_exp.cpp b/foreach/foreach_exp/examples/test_aclnn_foreach_exp.cpp index bbf56838..08e1bf60 100644 --- a/foreach/foreach_exp/examples/test_aclnn_foreach_exp.cpp +++ b/foreach/foreach_exp/examples/test_aclnn_foreach_exp.cpp @@ -14,26 +14,27 @@ #include "aclnnop/aclnn_foreach_exp.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,128 +47,134 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachExp第一段接口 - ret = aclnnForeachExpGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachExpGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachExp第二段接口 - ret = aclnnForeachExp(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachExp failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachExp第一段接口 + ret = aclnnForeachExpGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachExpGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachExp第二段接口 + ret = aclnnForeachExp(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachExp failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_expm1/docs/aclnnForeachExpm1.md b/foreach/foreach_expm1/docs/aclnnForeachExpm1.md index a67aae31..b5b4eae6 100644 --- a/foreach/foreach_expm1/docs/aclnnForeachExpm1.md +++ b/foreach/foreach_expm1/docs/aclnnForeachExpm1.md @@ -17,7 +17,7 @@ - 接口功能:对输入张量列表的每个张量执行指数运算,然后将得到的结果减1。 - 计算公式: - + $$ x = [{x_0}, {x_1}, ... {x_{n-1}}]\\ y = [{y_0}, {y_1}, ... {y_{n-1}}]\\ @@ -121,7 +121,7 @@ aclnnStatus aclnnForeachExpm1( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_expm1/examples/test_aclnn_foreach_expm1.cpp b/foreach/foreach_expm1/examples/test_aclnn_foreach_expm1.cpp index ce22f932..8883d7a2 100644 --- a/foreach/foreach_expm1/examples/test_aclnn_foreach_expm1.cpp +++ b/foreach/foreach_expm1/examples/test_aclnn_foreach_expm1.cpp @@ -14,26 +14,27 @@ #include "aclnnop/aclnn_foreach_expm1.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,128 +47,134 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachExpm1第一段接口 - ret = aclnnForeachExpm1GetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachExpm1GetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachExpm1第二段接口 - ret = aclnnForeachExpm1(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachExpm1 failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachExpm1第一段接口 + ret = aclnnForeachExpm1GetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachExpm1GetWorkspaceSize failed. ERROR: %d\n", ret); return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachExpm1第二段接口 + ret = aclnnForeachExpm1(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachExpm1 failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_lerp_list/docs/aclnnForeachLerpList.md b/foreach/foreach_lerp_list/docs/aclnnForeachLerpList.md index 0e675910..2db365b9 100644 --- a/foreach/foreach_lerp_list/docs/aclnnForeachLerpList.md +++ b/foreach/foreach_lerp_list/docs/aclnnForeachLerpList.md @@ -144,7 +144,7 @@ aclnnStatus aclnnForeachLerpList( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_lerp_list/examples/test_aclnn_foreach_lerp_list.cpp b/foreach/foreach_lerp_list/examples/test_aclnn_foreach_lerp_list.cpp index dc43a12e..8b0feb3e 100644 --- a/foreach/foreach_lerp_list/examples/test_aclnn_foreach_lerp_list.cpp +++ b/foreach/foreach_lerp_list/examples/test_aclnn_foreach_lerp_list.cpp @@ -14,26 +14,27 @@ #include "aclnnop/aclnn_foreach_lerp_list.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,162 +47,170 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector otherShape1 = {2, 3}; - std::vector otherShape2 = {1, 3}; - std::vector weightShape1 = {2, 3}; - std::vector weightShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* other1DeviceAddr = nullptr; - void* other2DeviceAddr = nullptr; - void* weight1DeviceAddr = nullptr; - void* weight2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* other1 = nullptr; - aclTensor* other2 = nullptr; - aclTensor* weight1 = nullptr; - aclTensor* weight2 = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector other1HostData = {1, 2, 3, 4, 5, 6}; - std::vector other2HostData = {7, 8, 9}; - std::vector weight1HostData = {1, 2, 3, 4, 5, 6}; - std::vector weight2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other1 aclTensor - ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other2 aclTensor - ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建weight1 aclTensor - ret = CreateAclTensor(weight1HostData, weightShape1, &weight1DeviceAddr, aclDataType::ACL_FLOAT, &weight1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建weight2 aclTensor - ret = CreateAclTensor(weight2HostData, weightShape2, &weight2DeviceAddr, aclDataType::ACL_FLOAT, &weight2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput1{input1, input2}; - aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); - std::vector tempInput2{other1, other2}; - aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); - std::vector tempWeight{weight1, weight2}; - aclTensorList* tensorListWeight = aclCreateTensorList(tempWeight.data(), tempWeight.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachLerpList第一段接口 - ret = aclnnForeachLerpListGetWorkspaceSize(tensorListInput1, tensorListInput2, tensorListWeight, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachLerpListGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachLerpList第二段接口 - ret = aclnnForeachLerpList(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachLerpList failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput1); - aclDestroyTensorList(tensorListInput2); - aclDestroyTensorList(tensorListWeight); - aclDestroyTensorList(tensorListOutput); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(other1DeviceAddr); - aclrtFree(other2DeviceAddr); - aclrtFree(weight1DeviceAddr); - aclrtFree(weight2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector otherShape1 = {2, 3}; + std::vector otherShape2 = {1, 3}; + std::vector weightShape1 = {2, 3}; + std::vector weightShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* other1DeviceAddr = nullptr; + void* other2DeviceAddr = nullptr; + void* weight1DeviceAddr = nullptr; + void* weight2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* other1 = nullptr; + aclTensor* other2 = nullptr; + aclTensor* weight1 = nullptr; + aclTensor* weight2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector other1HostData = {1, 2, 3, 4, 5, 6}; + std::vector other2HostData = {7, 8, 9}; + std::vector weight1HostData = {1, 2, 3, 4, 5, 6}; + std::vector weight2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other1 aclTensor + ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other2 aclTensor + ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建weight1 aclTensor + ret = CreateAclTensor(weight1HostData, weightShape1, &weight1DeviceAddr, aclDataType::ACL_FLOAT, &weight1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建weight2 aclTensor + ret = CreateAclTensor(weight2HostData, weightShape2, &weight2DeviceAddr, aclDataType::ACL_FLOAT, &weight2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput1{input1, input2}; + aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); + std::vector tempInput2{other1, other2}; + aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); + std::vector tempWeight{weight1, weight2}; + aclTensorList* tensorListWeight = aclCreateTensorList(tempWeight.data(), tempWeight.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachLerpList第一段接口 + ret = aclnnForeachLerpListGetWorkspaceSize( + tensorListInput1, tensorListInput2, tensorListWeight, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachLerpListGetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachLerpList第二段接口 + ret = aclnnForeachLerpList(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachLerpList failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput1); + aclDestroyTensorList(tensorListInput2); + aclDestroyTensorList(tensorListWeight); + aclDestroyTensorList(tensorListOutput); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(other1DeviceAddr); + aclrtFree(other2DeviceAddr); + aclrtFree(weight1DeviceAddr); + aclrtFree(weight2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_lerp_scalar/docs/aclnnForeachLerpScalar.md b/foreach/foreach_lerp_scalar/docs/aclnnForeachLerpScalar.md index ea15abcb..63bfaf43 100644 --- a/foreach/foreach_lerp_scalar/docs/aclnnForeachLerpScalar.md +++ b/foreach/foreach_lerp_scalar/docs/aclnnForeachLerpScalar.md @@ -142,7 +142,7 @@ aclnnStatus aclnnForeachLerpScalar( - 参数`x1`、`x2`的shape保持一致。 - 参数`out`的shape size大于等于入参`x1`的shape size。 - Ascend 950PR/Ascend 950DT: - + 参数`x1`、`x2`、`out`的shape size保持一致。支持包含的最大Tensor个数为50。 - **返回值** @@ -150,7 +150,7 @@ aclnnStatus aclnnForeachLerpScalar( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_lerp_scalar/examples/test_aclnn_foreach_lerp_scalar.cpp b/foreach/foreach_lerp_scalar/examples/test_aclnn_foreach_lerp_scalar.cpp index a21529b5..53172e78 100644 --- a/foreach/foreach_lerp_scalar/examples/test_aclnn_foreach_lerp_scalar.cpp +++ b/foreach/foreach_lerp_scalar/examples/test_aclnn_foreach_lerp_scalar.cpp @@ -8,33 +8,33 @@ * See LICENSE in the root of the software repository for the full text of the License. */ - #include #include #include "acl/acl.h" #include "aclnnop/aclnn_foreach_lerp_scalar.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -47,149 +47,157 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector otherShape1 = {2, 3}; - std::vector otherShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* other1DeviceAddr = nullptr; - void* other2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* other1 = nullptr; - aclTensor* other2 = nullptr; - aclScalar* weight = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector other1HostData = {4, 6, 7, 8, 4, 3}; - std::vector other2HostData = {5, 2, 1}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - float weightValue = 0.5f; - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other1 aclTensor - ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other2 aclTensor - ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建weight aclScalar - weight = aclCreateScalar(&weightValue, aclDataType::ACL_FLOAT); - CHECK_RET(weight != nullptr, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput1{input1, input2}; - aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); - std::vector tempInput2{other1, other2}; - aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachLerpScalar第一段接口 - ret = aclnnForeachLerpScalarGetWorkspaceSize(tensorListInput1, tensorListInput2, weight, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachLerpScalarGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachLerpScalar第二段接口 - ret = aclnnForeachLerpScalar(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachLerpScalar failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput1); - aclDestroyTensorList(tensorListInput2); - aclDestroyTensorList(tensorListOutput); - aclDestroyScalar(weight); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(other1DeviceAddr); - aclrtFree(other2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector otherShape1 = {2, 3}; + std::vector otherShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* other1DeviceAddr = nullptr; + void* other2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* other1 = nullptr; + aclTensor* other2 = nullptr; + aclScalar* weight = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector other1HostData = {4, 6, 7, 8, 4, 3}; + std::vector other2HostData = {5, 2, 1}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + float weightValue = 0.5f; + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other1 aclTensor + ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other2 aclTensor + ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建weight aclScalar + weight = aclCreateScalar(&weightValue, aclDataType::ACL_FLOAT); + CHECK_RET(weight != nullptr, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput1{input1, input2}; + aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); + std::vector tempInput2{other1, other2}; + aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachLerpScalar第一段接口 + ret = aclnnForeachLerpScalarGetWorkspaceSize( + tensorListInput1, tensorListInput2, weight, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachLerpScalarGetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachLerpScalar第二段接口 + ret = aclnnForeachLerpScalar(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachLerpScalar failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput1); + aclDestroyTensorList(tensorListInput2); + aclDestroyTensorList(tensorListOutput); + aclDestroyScalar(weight); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(other1DeviceAddr); + aclrtFree(other2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_log/docs/aclnnForeachLog.md b/foreach/foreach_log/docs/aclnnForeachLog.md index 4f541731..201af228 100644 --- a/foreach/foreach_log/docs/aclnnForeachLog.md +++ b/foreach/foreach_log/docs/aclnnForeachLog.md @@ -121,7 +121,7 @@ aclnnStatus aclnnForeachLog( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_log/examples/test_aclnn_foreach_log.cpp b/foreach/foreach_log/examples/test_aclnn_foreach_log.cpp index bdc35f04..71511b82 100644 --- a/foreach/foreach_log/examples/test_aclnn_foreach_log.cpp +++ b/foreach/foreach_log/examples/test_aclnn_foreach_log.cpp @@ -14,26 +14,27 @@ #include "aclnnop/aclnn_foreach_log.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,128 +47,134 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachLog第一段接口 - ret = aclnnForeachLogGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachLogGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachLog第二段接口 - ret = aclnnForeachLog(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachLog failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachLog第一段接口 + ret = aclnnForeachLogGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachLogGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachLog第二段接口 + ret = aclnnForeachLog(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachLog failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_log10/docs/aclnnForeachLog10.md b/foreach/foreach_log10/docs/aclnnForeachLog10.md index 9fb13d5d..de85007c 100644 --- a/foreach/foreach_log10/docs/aclnnForeachLog10.md +++ b/foreach/foreach_log10/docs/aclnnForeachLog10.md @@ -121,7 +121,7 @@ aclnnStatus aclnnForeachLog10( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_log10/examples/test_aclnn_foreach_log10.cpp b/foreach/foreach_log10/examples/test_aclnn_foreach_log10.cpp index c7f5759f..d42e0466 100644 --- a/foreach/foreach_log10/examples/test_aclnn_foreach_log10.cpp +++ b/foreach/foreach_log10/examples/test_aclnn_foreach_log10.cpp @@ -14,26 +14,27 @@ #include "aclnnop/aclnn_foreach_log10.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,128 +47,134 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachLog10第一段接口 - ret = aclnnForeachLog10GetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachLog10GetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachLog10第二段接口 - ret = aclnnForeachLog10(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachLog10 failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachLog10第一段接口 + ret = aclnnForeachLog10GetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachLog10GetWorkspaceSize failed. ERROR: %d\n", ret); return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachLog10第二段接口 + ret = aclnnForeachLog10(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachLog10 failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_log1p/docs/aclnnForeachLog1p.md b/foreach/foreach_log1p/docs/aclnnForeachLog1p.md index 18c4c3de..2daf1f7e 100644 --- a/foreach/foreach_log1p/docs/aclnnForeachLog1p.md +++ b/foreach/foreach_log1p/docs/aclnnForeachLog1p.md @@ -121,7 +121,7 @@ aclnnStatus aclnnForeachLog1p( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_log1p/examples/test_aclnn_foreach_log1p.cpp b/foreach/foreach_log1p/examples/test_aclnn_foreach_log1p.cpp index a75cfad4..a30ecd6c 100644 --- a/foreach/foreach_log1p/examples/test_aclnn_foreach_log1p.cpp +++ b/foreach/foreach_log1p/examples/test_aclnn_foreach_log1p.cpp @@ -14,26 +14,27 @@ #include "aclnnop/aclnn_foreach_log1p.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,128 +47,134 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachLog1p第一段接口 - ret = aclnnForeachLog1pGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachLog1pGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachLog1p第二段接口 - ret = aclnnForeachLog1p(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachLog1p failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachLog1p第一段接口 + ret = aclnnForeachLog1pGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachLog1pGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachLog1p第二段接口 + ret = aclnnForeachLog1p(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachLog1p failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; } diff --git a/foreach/foreach_log2/docs/aclnnForeachLog2.md b/foreach/foreach_log2/docs/aclnnForeachLog2.md index 0ce523a4..2a6dd42b 100644 --- a/foreach/foreach_log2/docs/aclnnForeachLog2.md +++ b/foreach/foreach_log2/docs/aclnnForeachLog2.md @@ -17,7 +17,7 @@ - 接口功能:对张量列表中的每一个元素执行以2为底的对数函数运算。 - 计算公式: - + $$ x = [{x_0}, {x_1}, ... {x_{n-1}}]\\ y = [{y_0}, {y_1}, ... {y_{n-1}}]\\ @@ -121,7 +121,7 @@ aclnnStatus aclnnForeachLog2( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_log2/examples/test_aclnn_foreach_log2.cpp b/foreach/foreach_log2/examples/test_aclnn_foreach_log2.cpp index 1a07f1bb..94446c38 100644 --- a/foreach/foreach_log2/examples/test_aclnn_foreach_log2.cpp +++ b/foreach/foreach_log2/examples/test_aclnn_foreach_log2.cpp @@ -14,26 +14,27 @@ #include "aclnnop/aclnn_foreach_log2.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,128 +47,134 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachLog2第一段接口 - ret = aclnnForeachLog2GetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachLog2GetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachLog2第二段接口 - ret = aclnnForeachLog2(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachLog2 failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachLog2第一段接口 + ret = aclnnForeachLog2GetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachLog2GetWorkspaceSize failed. ERROR: %d\n", ret); return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachLog2第二段接口 + ret = aclnnForeachLog2(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachLog2 failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_maximum_list/docs/aclnnForeachMaximumList.md b/foreach/foreach_maximum_list/docs/aclnnForeachMaximumList.md index e0e151a0..9f158332 100644 --- a/foreach/foreach_maximum_list/docs/aclnnForeachMaximumList.md +++ b/foreach/foreach_maximum_list/docs/aclnnForeachMaximumList.md @@ -17,7 +17,7 @@ - 接口功能:对张量列表x1和张量列表x2执行逐元素比较,计算每个元素对应的最大值。 - 计算公式: - + $$ x1 = [{x1_0}, {x1_1}, ... {x1_{n-1}}], x2 = [{x2_0}, {x2_1}, ... {x2_{n-1}}]\\ y = [{y_0}, {y_1}, ... {y_{n-1}}]\\ @@ -132,7 +132,7 @@ aclnnStatus aclnnForeachMaximumList( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_maximum_list/examples/test_aclnn_foreach_maximum_list.cpp b/foreach/foreach_maximum_list/examples/test_aclnn_foreach_maximum_list.cpp index 5e2f3603..93478119 100644 --- a/foreach/foreach_maximum_list/examples/test_aclnn_foreach_maximum_list.cpp +++ b/foreach/foreach_maximum_list/examples/test_aclnn_foreach_maximum_list.cpp @@ -14,26 +14,27 @@ #include "aclnnop/aclnn_foreach_maximum_list.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,143 +47,151 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector otherShape1 = {2, 3}; - std::vector otherShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* other1DeviceAddr = nullptr; - void* other2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* other1 = nullptr; - aclTensor* other2 = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector other1HostData = {6, 5, 4, 3, 2, 1}; - std::vector other2HostData = {9, 8, 7}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other1 aclTensor - ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other2 aclTensor - ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput1{input1, input2}; - aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); - std::vector tempInput2{other1, other2}; - aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachMaximumList第一段接口 - ret = aclnnForeachMaximumListGetWorkspaceSize(tensorListInput1, tensorListInput2, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMaximumListGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachMaximumList第二段接口 - ret = aclnnForeachMaximumList(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMaximumList failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput1); - aclDestroyTensorList(tensorListInput2); - aclDestroyTensorList(tensorListOutput); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(other1DeviceAddr); - aclrtFree(other2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector otherShape1 = {2, 3}; + std::vector otherShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* other1DeviceAddr = nullptr; + void* other2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* other1 = nullptr; + aclTensor* other2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector other1HostData = {6, 5, 4, 3, 2, 1}; + std::vector other2HostData = {9, 8, 7}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other1 aclTensor + ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other2 aclTensor + ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput1{input1, input2}; + aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); + std::vector tempInput2{other1, other2}; + aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachMaximumList第一段接口 + ret = aclnnForeachMaximumListGetWorkspaceSize( + tensorListInput1, tensorListInput2, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMaximumListGetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachMaximumList第二段接口 + ret = aclnnForeachMaximumList(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMaximumList failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput1); + aclDestroyTensorList(tensorListInput2); + aclDestroyTensorList(tensorListOutput); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(other1DeviceAddr); + aclrtFree(other2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_maximum_scalar/docs/aclnnForeachMaximumScalar.md b/foreach/foreach_maximum_scalar/docs/aclnnForeachMaximumScalar.md index 19caa752..00331c49 100644 --- a/foreach/foreach_maximum_scalar/docs/aclnnForeachMaximumScalar.md +++ b/foreach/foreach_maximum_scalar/docs/aclnnForeachMaximumScalar.md @@ -133,7 +133,7 @@ aclnnStatus aclnnForeachMaximumScalar( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
@@ -317,7 +317,7 @@ int main() { std::vector out1HostData(6, 0); std::vector out2HostData(3, 0); std::vector alphaValueHostData = {1.2f}; - + // 创建input1 aclTensor ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); CHECK_RET(ret == ACL_SUCCESS, return ret); diff --git a/foreach/foreach_maximum_scalar/docs/aclnnForeachMaximumScalarV2.md b/foreach/foreach_maximum_scalar/docs/aclnnForeachMaximumScalarV2.md index 2bbe66a2..be531069 100644 --- a/foreach/foreach_maximum_scalar/docs/aclnnForeachMaximumScalarV2.md +++ b/foreach/foreach_maximum_scalar/docs/aclnnForeachMaximumScalarV2.md @@ -17,7 +17,7 @@ - 接口功能:对张量列表和标量值scalar执行逐元素比较,计算每个元素对应的最大值。本接口相较于[aclnnForeachMaximumScalar](aclnnForeachMaximumScalar.md),修改入参scalar的结构类型aclTensor为aclScalar,请根据实际情况选择合适的接口。 - 计算公式: - + $$ x = [{x_0}, {x_1}, ... {x_{n-1}}]\\ y = [{y_0}, {y_1}, ... {y_{n-1}}]\\ @@ -132,7 +132,7 @@ aclnnStatus aclnnForeachMaximumScalarV2( - **返回值** aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 - + 第一段接口完成入参校验,出现以下场景时报错:
diff --git a/foreach/foreach_maximum_scalar/examples/test_aclnn_foreach_maximum_scalar.cpp b/foreach/foreach_maximum_scalar/examples/test_aclnn_foreach_maximum_scalar.cpp index 494762eb..e4e1b803 100644 --- a/foreach/foreach_maximum_scalar/examples/test_aclnn_foreach_maximum_scalar.cpp +++ b/foreach/foreach_maximum_scalar/examples/test_aclnn_foreach_maximum_scalar.cpp @@ -14,164 +14,174 @@ #include "aclnnop/aclnn_foreach_maximum_scalar.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& 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; +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 -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - std::vector alphaShape = {1}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - void* alphaDeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* alpha = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - std::vector alphaValueHostData = {1.2f}; - - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建alpha aclTensor - ret = CreateAclTensor(alphaValueHostData, alphaShape, &alphaDeviceAddr, aclDataType::ACL_FLOAT, &alpha); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachMaximumScalar第一段接口 - ret = aclnnForeachMaximumScalarGetWorkspaceSize(tensorListInput, alpha, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMaximumScalarGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachMaximumScalar第二段接口 - ret = aclnnForeachMaximumScalar(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMaximumScalar failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - aclDestroyTensor(alpha); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - aclrtFree(alphaDeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + std::vector alphaShape = {1}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + void* alphaDeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* alpha = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + std::vector alphaValueHostData = {1.2f}; + + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建alpha aclTensor + ret = CreateAclTensor(alphaValueHostData, alphaShape, &alphaDeviceAddr, aclDataType::ACL_FLOAT, &alpha); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachMaximumScalar第一段接口 + ret = + aclnnForeachMaximumScalarGetWorkspaceSize(tensorListInput, alpha, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMaximumScalarGetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachMaximumScalar第二段接口 + ret = aclnnForeachMaximumScalar(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMaximumScalar failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + aclDestroyTensor(alpha); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + aclrtFree(alphaDeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_maximum_scalar/examples/test_aclnn_foreach_maximum_scalar_v2.cpp b/foreach/foreach_maximum_scalar/examples/test_aclnn_foreach_maximum_scalar_v2.cpp index 5ed761b3..cf7150a2 100644 --- a/foreach/foreach_maximum_scalar/examples/test_aclnn_foreach_maximum_scalar_v2.cpp +++ b/foreach/foreach_maximum_scalar/examples/test_aclnn_foreach_maximum_scalar_v2.cpp @@ -14,160 +14,170 @@ #include "aclnnop/aclnn_foreach_maximum_scalar_v2.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& 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; +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 -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclScalar* alpha = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - float alphaValue = 5.2f; - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建alpha aclScalar - alpha = aclCreateScalar(&alphaValue, aclDataType::ACL_FLOAT); - CHECK_RET(alpha != nullptr, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachMaximumScalarV2第一段接口 - ret = aclnnForeachMaximumScalarV2GetWorkspaceSize(tensorListInput, alpha, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMaximumScalarV2GetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachMaximumScalarV2第二段接口 - ret = aclnnForeachMaximumScalarV2(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMaximumScalarV2 failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - aclDestroyScalar(alpha); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclScalar* alpha = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + float alphaValue = 5.2f; + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建alpha aclScalar + alpha = aclCreateScalar(&alphaValue, aclDataType::ACL_FLOAT); + CHECK_RET(alpha != nullptr, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachMaximumScalarV2第一段接口 + ret = aclnnForeachMaximumScalarV2GetWorkspaceSize( + tensorListInput, alpha, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMaximumScalarV2GetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachMaximumScalarV2第二段接口 + ret = aclnnForeachMaximumScalarV2(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMaximumScalarV2 failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + aclDestroyScalar(alpha); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_maximum_scalar_list/docs/aclnnForeachMaximumScalarList.md b/foreach/foreach_maximum_scalar_list/docs/aclnnForeachMaximumScalarList.md index 3af23cdd..8e15a286 100644 --- a/foreach/foreach_maximum_scalar_list/docs/aclnnForeachMaximumScalarList.md +++ b/foreach/foreach_maximum_scalar_list/docs/aclnnForeachMaximumScalarList.md @@ -128,13 +128,13 @@ aclnnStatus aclnnForeachMaximumScalarList(
- + - **返回值** aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - + diff --git a/foreach/foreach_maximum_scalar_list/examples/test_aclnn_foreach_maximum_scalar_list.cpp b/foreach/foreach_maximum_scalar_list/examples/test_aclnn_foreach_maximum_scalar_list.cpp index e170d730..bae6bdbe 100644 --- a/foreach/foreach_maximum_scalar_list/examples/test_aclnn_foreach_maximum_scalar_list.cpp +++ b/foreach/foreach_maximum_scalar_list/examples/test_aclnn_foreach_maximum_scalar_list.cpp @@ -14,167 +14,177 @@ #include "aclnnop/aclnn_foreach_maximum_scalar_list.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& 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; +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 -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclScalar* alpha1 = nullptr; - aclScalar* alpha2 = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - float alpha1Value = 4.2f; - float alpha2Value = 8.2f; - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建alpha1 aclScalar - alpha1 = aclCreateScalar(&alpha1Value, aclDataType::ACL_FLOAT); - CHECK_RET(alpha1 != nullptr, return ret); - // 创建alpha2 aclScalar - alpha2 = aclCreateScalar(&alpha2Value, aclDataType::ACL_FLOAT); - CHECK_RET(alpha2 != nullptr, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - std::vector tempscalar{alpha1, alpha2}; - aclScalarList* scalarlist = aclCreateScalarList(tempscalar.data(), tempscalar.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachMaximumScalarList第一段接口 - ret = aclnnForeachMaximumScalarListGetWorkspaceSize(tensorListInput, scalarlist, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMaximumScalarListGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachMaximumScalarList第二段接口 - ret = aclnnForeachMaximumScalarList(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMaximumScalarList failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - aclDestroyScalarList(scalarlist); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclScalar* alpha1 = nullptr; + aclScalar* alpha2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + float alpha1Value = 4.2f; + float alpha2Value = 8.2f; + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建alpha1 aclScalar + alpha1 = aclCreateScalar(&alpha1Value, aclDataType::ACL_FLOAT); + CHECK_RET(alpha1 != nullptr, return ret); + // 创建alpha2 aclScalar + alpha2 = aclCreateScalar(&alpha2Value, aclDataType::ACL_FLOAT); + CHECK_RET(alpha2 != nullptr, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + std::vector tempscalar{alpha1, alpha2}; + aclScalarList* scalarlist = aclCreateScalarList(tempscalar.data(), tempscalar.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachMaximumScalarList第一段接口 + ret = aclnnForeachMaximumScalarListGetWorkspaceSize( + tensorListInput, scalarlist, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMaximumScalarListGetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachMaximumScalarList第二段接口 + ret = aclnnForeachMaximumScalarList(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMaximumScalarList failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + aclDestroyScalarList(scalarlist); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_minimum_list/docs/aclnnForeachMinimumList.md b/foreach/foreach_minimum_list/docs/aclnnForeachMinimumList.md index 938b9d5c..24617987 100644 --- a/foreach/foreach_minimum_list/docs/aclnnForeachMinimumList.md +++ b/foreach/foreach_minimum_list/docs/aclnnForeachMinimumList.md @@ -17,7 +17,7 @@ - 接口功能:对张量列表x1和张量列表x2执行逐元素比较,计算每个元素对应的最小值。 - 计算公式: - + $$ x1 = [{x1_0}, {x1_1}, ... {x1_{n-1}}], x2 = [{x2_0}, {x2_1}, ... {x2_{n-1}}]\\ y = [{y_0}, {y_1}, ... {y_{n-1}}]\\ @@ -132,7 +132,7 @@ aclnnStatus aclnnForeachMinimumList( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_minimum_list/examples/test_aclnn_foreach_minimum_list.cpp b/foreach/foreach_minimum_list/examples/test_aclnn_foreach_minimum_list.cpp index 0121a690..a80b90f9 100644 --- a/foreach/foreach_minimum_list/examples/test_aclnn_foreach_minimum_list.cpp +++ b/foreach/foreach_minimum_list/examples/test_aclnn_foreach_minimum_list.cpp @@ -14,26 +14,27 @@ #include "aclnnop/aclnn_foreach_minimum_list.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,143 +47,151 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector otherShape1 = {2, 3}; - std::vector otherShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* other1DeviceAddr = nullptr; - void* other2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* other1 = nullptr; - aclTensor* other2 = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector other1HostData = {6, 5, 4, 3, 2, 1}; - std::vector other2HostData = {9, 8, 7}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other1 aclTensor - ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other2 aclTensor - ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput1{input1, input2}; - aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); - std::vector tempInput2{other1, other2}; - aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachMinimumList第一段接口 - ret = aclnnForeachMinimumListGetWorkspaceSize(tensorListInput1, tensorListInput2, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMinimumListGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachMinimumList第二段接口 - ret = aclnnForeachMinimumList(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMinimumList failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput1); - aclDestroyTensorList(tensorListInput2); - aclDestroyTensorList(tensorListOutput); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(other1DeviceAddr); - aclrtFree(other2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector otherShape1 = {2, 3}; + std::vector otherShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* other1DeviceAddr = nullptr; + void* other2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* other1 = nullptr; + aclTensor* other2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector other1HostData = {6, 5, 4, 3, 2, 1}; + std::vector other2HostData = {9, 8, 7}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other1 aclTensor + ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other2 aclTensor + ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput1{input1, input2}; + aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); + std::vector tempInput2{other1, other2}; + aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachMinimumList第一段接口 + ret = aclnnForeachMinimumListGetWorkspaceSize( + tensorListInput1, tensorListInput2, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMinimumListGetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachMinimumList第二段接口 + ret = aclnnForeachMinimumList(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMinimumList failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput1); + aclDestroyTensorList(tensorListInput2); + aclDestroyTensorList(tensorListOutput); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(other1DeviceAddr); + aclrtFree(other2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_minimum_scalar/docs/aclnnForeachMinimumScalar.md b/foreach/foreach_minimum_scalar/docs/aclnnForeachMinimumScalar.md index d6bbbe63..80a6598b 100644 --- a/foreach/foreach_minimum_scalar/docs/aclnnForeachMinimumScalar.md +++ b/foreach/foreach_minimum_scalar/docs/aclnnForeachMinimumScalar.md @@ -133,7 +133,7 @@ aclnnStatus aclnnForeachMinimumScalar( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_minimum_scalar/docs/aclnnForeachMinimumScalarV2.md b/foreach/foreach_minimum_scalar/docs/aclnnForeachMinimumScalarV2.md index 345ebd1e..2b67c9ec 100644 --- a/foreach/foreach_minimum_scalar/docs/aclnnForeachMinimumScalarV2.md +++ b/foreach/foreach_minimum_scalar/docs/aclnnForeachMinimumScalarV2.md @@ -132,7 +132,7 @@ aclnnStatus aclnnForeachMinimumScalarV2( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_minimum_scalar/examples/test_aclnn_foreach_minimum_scalar.cpp b/foreach/foreach_minimum_scalar/examples/test_aclnn_foreach_minimum_scalar.cpp index 1a991a8e..33363d4e 100644 --- a/foreach/foreach_minimum_scalar/examples/test_aclnn_foreach_minimum_scalar.cpp +++ b/foreach/foreach_minimum_scalar/examples/test_aclnn_foreach_minimum_scalar.cpp @@ -14,164 +14,174 @@ #include "aclnnop/aclnn_foreach_minimum_scalar.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& 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; +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 -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - std::vector alphaShape = {1}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - void* alphaDeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* alpha = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - std::vector alphaValueHostData = {1.2f}; - float alphaValue = 5.2f; - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建alpha aclTensor - ret = CreateAclTensor(alphaValueHostData, alphaShape, &alphaDeviceAddr, aclDataType::ACL_FLOAT, &alpha); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachMinimumScalar第一段接口 - ret = aclnnForeachMinimumScalarGetWorkspaceSize(tensorListInput, alpha, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMinimumScalarGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachMinimumScalar第二段接口 - ret = aclnnForeachMinimumScalar(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMinimumScalar failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - aclDestroyTensor(alpha); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - aclrtFree(alphaDeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + std::vector alphaShape = {1}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + void* alphaDeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* alpha = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + std::vector alphaValueHostData = {1.2f}; + float alphaValue = 5.2f; + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建alpha aclTensor + ret = CreateAclTensor(alphaValueHostData, alphaShape, &alphaDeviceAddr, aclDataType::ACL_FLOAT, &alpha); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachMinimumScalar第一段接口 + ret = + aclnnForeachMinimumScalarGetWorkspaceSize(tensorListInput, alpha, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMinimumScalarGetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachMinimumScalar第二段接口 + ret = aclnnForeachMinimumScalar(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMinimumScalar failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + aclDestroyTensor(alpha); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + aclrtFree(alphaDeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_minimum_scalar/examples/test_aclnn_foreach_minimum_scalar_v2.cpp b/foreach/foreach_minimum_scalar/examples/test_aclnn_foreach_minimum_scalar_v2.cpp index 6c08832e..fd639a15 100644 --- a/foreach/foreach_minimum_scalar/examples/test_aclnn_foreach_minimum_scalar_v2.cpp +++ b/foreach/foreach_minimum_scalar/examples/test_aclnn_foreach_minimum_scalar_v2.cpp @@ -14,160 +14,170 @@ #include "aclnnop/aclnn_foreach_minimum_scalar_v2.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& 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; +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 -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclScalar* alpha = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - float alphaValue = 5.2f; - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建alpha aclScalar - alpha = aclCreateScalar(&alphaValue, aclDataType::ACL_FLOAT); - CHECK_RET(alpha != nullptr, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachMinimumScalarV2第一段接口 - ret = aclnnForeachMinimumScalarV2GetWorkspaceSize(tensorListInput, alpha, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMinimumScalarV2GetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachMinimumScalarV2第二段接口 - ret = aclnnForeachMinimumScalarV2(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMinimumScalarV2 failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - aclDestroyScalar(alpha); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclScalar* alpha = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + float alphaValue = 5.2f; + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建alpha aclScalar + alpha = aclCreateScalar(&alphaValue, aclDataType::ACL_FLOAT); + CHECK_RET(alpha != nullptr, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachMinimumScalarV2第一段接口 + ret = aclnnForeachMinimumScalarV2GetWorkspaceSize( + tensorListInput, alpha, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMinimumScalarV2GetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachMinimumScalarV2第二段接口 + ret = aclnnForeachMinimumScalarV2(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMinimumScalarV2 failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + aclDestroyScalar(alpha); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_minimum_scalar_list/docs/aclnnForeachMinimumScalarList.md b/foreach/foreach_minimum_scalar_list/docs/aclnnForeachMinimumScalarList.md index 6958b479..fcdedb25 100644 --- a/foreach/foreach_minimum_scalar_list/docs/aclnnForeachMinimumScalarList.md +++ b/foreach/foreach_minimum_scalar_list/docs/aclnnForeachMinimumScalarList.md @@ -134,7 +134,7 @@ aclnnStatus aclnnForeachMinimumScalarList( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_minimum_scalar_list/examples/test_aclnn_foreach_minimum_scalar_list.cpp b/foreach/foreach_minimum_scalar_list/examples/test_aclnn_foreach_minimum_scalar_list.cpp index 26480b17..0330e407 100644 --- a/foreach/foreach_minimum_scalar_list/examples/test_aclnn_foreach_minimum_scalar_list.cpp +++ b/foreach/foreach_minimum_scalar_list/examples/test_aclnn_foreach_minimum_scalar_list.cpp @@ -14,167 +14,177 @@ #include "aclnnop/aclnn_foreach_minimum_scalar_list.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& 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; +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 -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclScalar* alpha1 = nullptr; - aclScalar* alpha2 = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - float alpha1Value = 4.2f; - float alpha2Value = 8.2f; - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建alpha1 aclScalar - alpha1 = aclCreateScalar(&alpha1Value, aclDataType::ACL_FLOAT); - CHECK_RET(alpha1 != nullptr, return ret); - // 创建alpha2 aclScalar - alpha2 = aclCreateScalar(&alpha2Value, aclDataType::ACL_FLOAT); - CHECK_RET(alpha2 != nullptr, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - std::vector tempscalar{alpha1, alpha2}; - aclScalarList* scalarlist = aclCreateScalarList(tempscalar.data(), tempscalar.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachMinimumScalarList第一段接口 - ret = aclnnForeachMinimumScalarListGetWorkspaceSize(tensorListInput, scalarlist, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMinimumScalarListGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachMinimumScalarList第二段接口 - ret = aclnnForeachMinimumScalarList(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMinimumScalarList failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - aclDestroyScalarList(scalarlist); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclScalar* alpha1 = nullptr; + aclScalar* alpha2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + float alpha1Value = 4.2f; + float alpha2Value = 8.2f; + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建alpha1 aclScalar + alpha1 = aclCreateScalar(&alpha1Value, aclDataType::ACL_FLOAT); + CHECK_RET(alpha1 != nullptr, return ret); + // 创建alpha2 aclScalar + alpha2 = aclCreateScalar(&alpha2Value, aclDataType::ACL_FLOAT); + CHECK_RET(alpha2 != nullptr, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + std::vector tempscalar{alpha1, alpha2}; + aclScalarList* scalarlist = aclCreateScalarList(tempscalar.data(), tempscalar.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachMinimumScalarList第一段接口 + ret = aclnnForeachMinimumScalarListGetWorkspaceSize( + tensorListInput, scalarlist, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMinimumScalarListGetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachMinimumScalarList第二段接口 + ret = aclnnForeachMinimumScalarList(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMinimumScalarList failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + aclDestroyScalarList(scalarlist); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_mul_list/docs/aclnnForeachMulList.md b/foreach/foreach_mul_list/docs/aclnnForeachMulList.md index 0739144b..c2129d9d 100644 --- a/foreach/foreach_mul_list/docs/aclnnForeachMulList.md +++ b/foreach/foreach_mul_list/docs/aclnnForeachMulList.md @@ -133,7 +133,7 @@ aclnnStatus aclnnForeachMulList( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_mul_list/examples/test_aclnn_foreach_mul_list.cpp b/foreach/foreach_mul_list/examples/test_aclnn_foreach_mul_list.cpp index 4781f6cb..6852a0eb 100644 --- a/foreach/foreach_mul_list/examples/test_aclnn_foreach_mul_list.cpp +++ b/foreach/foreach_mul_list/examples/test_aclnn_foreach_mul_list.cpp @@ -14,174 +14,184 @@ #include "aclnnop/aclnn_foreach_mul_list.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& 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; +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 -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector otherShape1 = {2, 3}; - std::vector otherShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* other1DeviceAddr = nullptr; - void* other2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* other1 = nullptr; - aclTensor* other2 = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector other1HostData = {6, 5, 4, 3, 2, 1}; - std::vector other2HostData = {9, 8, 7}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other1 aclTensor - ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other2 aclTensor - ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput1{input1, input2}; - aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); - std::vector tempInput2{other1, other2}; - aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachMulList第一段接口 - ret = aclnnForeachMulListGetWorkspaceSize(tensorListInput1, tensorListInput2, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMulListGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachMulList第二段接口 - ret = aclnnForeachMulList(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMulList failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput1); - aclDestroyTensorList(tensorListInput2); - aclDestroyTensorList(tensorListOutput); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(other1DeviceAddr); - aclrtFree(other2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector otherShape1 = {2, 3}; + std::vector otherShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* other1DeviceAddr = nullptr; + void* other2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* other1 = nullptr; + aclTensor* other2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector other1HostData = {6, 5, 4, 3, 2, 1}; + std::vector other2HostData = {9, 8, 7}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other1 aclTensor + ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other2 aclTensor + ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput1{input1, input2}; + aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); + std::vector tempInput2{other1, other2}; + aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachMulList第一段接口 + ret = aclnnForeachMulListGetWorkspaceSize( + tensorListInput1, tensorListInput2, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMulListGetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachMulList第二段接口 + ret = aclnnForeachMulList(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMulList failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput1); + aclDestroyTensorList(tensorListInput2); + aclDestroyTensorList(tensorListOutput); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(other1DeviceAddr); + aclrtFree(other2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_mul_scalar/docs/aclnnForeachMulScalar.md b/foreach/foreach_mul_scalar/docs/aclnnForeachMulScalar.md index ad17dede..52721be5 100644 --- a/foreach/foreach_mul_scalar/docs/aclnnForeachMulScalar.md +++ b/foreach/foreach_mul_scalar/docs/aclnnForeachMulScalar.md @@ -129,7 +129,7 @@ aclnnStatus aclnnForeachMulScalar(
- Atlas A2 训练系列产品/Atlas A2 推理系列产品Atlas A3 训练系列产品/Atlas A3 推理系列产品: - + 参数`scalar`的数据类型与入参`x`的数据类型具有一定对应关系: - 当`x`的数据类型为FLOAT32、FLOAT16、INT32时,数据类型与`x`的数据类型保持一致。 - 当`x`的数据类型为BFLOAT16时,数据类型支持FLOAT32。 @@ -145,7 +145,7 @@ aclnnStatus aclnnForeachMulScalar( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - + diff --git a/foreach/foreach_mul_scalar/docs/aclnnForeachMulScalarV2.md b/foreach/foreach_mul_scalar/docs/aclnnForeachMulScalarV2.md index a53c5291..b0e2cd56 100644 --- a/foreach/foreach_mul_scalar/docs/aclnnForeachMulScalarV2.md +++ b/foreach/foreach_mul_scalar/docs/aclnnForeachMulScalarV2.md @@ -146,7 +146,7 @@ aclnnStatus aclnnForeachMulScalarV2( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_mul_scalar/examples/test_aclnn_foreach_mul_scalar.cpp b/foreach/foreach_mul_scalar/examples/test_aclnn_foreach_mul_scalar.cpp index 89becf32..5607f6c4 100644 --- a/foreach/foreach_mul_scalar/examples/test_aclnn_foreach_mul_scalar.cpp +++ b/foreach/foreach_mul_scalar/examples/test_aclnn_foreach_mul_scalar.cpp @@ -8,170 +8,178 @@ * See LICENSE in the root of the software repository for the full text of the License. */ - #include #include #include "acl/acl.h" #include "aclnnop/aclnn_foreach_mul_scalar.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& 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; +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 -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - std::vector alphaShape = {1}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - void* alphaDeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* alpha = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - std::vector alphaValueHostData = {1.2f}; - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建alpha aclTensor - ret = CreateAclTensor(alphaValueHostData, alphaShape, &alphaDeviceAddr, aclDataType::ACL_FLOAT, &alpha); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachMulScalar第一段接口 - ret = aclnnForeachMulScalarGetWorkspaceSize(tensorListInput, alpha, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMulScalarGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachMulScalar第二段接口 - ret = aclnnForeachMulScalar(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMulScalar failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - aclDestroyTensor(alpha); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - aclrtFree(alphaDeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + std::vector alphaShape = {1}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + void* alphaDeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* alpha = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + std::vector alphaValueHostData = {1.2f}; + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建alpha aclTensor + ret = CreateAclTensor(alphaValueHostData, alphaShape, &alphaDeviceAddr, aclDataType::ACL_FLOAT, &alpha); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachMulScalar第一段接口 + ret = aclnnForeachMulScalarGetWorkspaceSize(tensorListInput, alpha, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMulScalarGetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachMulScalar第二段接口 + ret = aclnnForeachMulScalar(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMulScalar failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + aclDestroyTensor(alpha); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + aclrtFree(alphaDeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_mul_scalar/examples/test_aclnn_foreach_mul_scalar_v2.cpp b/foreach/foreach_mul_scalar/examples/test_aclnn_foreach_mul_scalar_v2.cpp index 6afaf778..98873022 100644 --- a/foreach/foreach_mul_scalar/examples/test_aclnn_foreach_mul_scalar_v2.cpp +++ b/foreach/foreach_mul_scalar/examples/test_aclnn_foreach_mul_scalar_v2.cpp @@ -8,167 +8,175 @@ * See LICENSE in the root of the software repository for the full text of the License. */ - #include #include #include "acl/acl.h" #include "aclnnop/aclnn_foreach_mul_scalar_v2.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& 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; +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 -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclScalar* alpha = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - float alphaValue = 1.2f; - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建alpha aclScalar - alpha = aclCreateScalar(&alphaValue, aclDataType::ACL_FLOAT); - CHECK_RET(alpha != nullptr, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachMulScalarV2第一段接口 - ret = aclnnForeachMulScalarV2GetWorkspaceSize(tensorListInput, alpha, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMulScalarV2GetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachMulScalarV2第二段接口 - ret = aclnnForeachMulScalarV2(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMulScalarV2 failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - aclDestroyScalar(alpha); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclScalar* alpha = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + float alphaValue = 1.2f; + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建alpha aclScalar + alpha = aclCreateScalar(&alphaValue, aclDataType::ACL_FLOAT); + CHECK_RET(alpha != nullptr, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachMulScalarV2第一段接口 + ret = aclnnForeachMulScalarV2GetWorkspaceSize(tensorListInput, alpha, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMulScalarV2GetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachMulScalarV2第二段接口 + ret = aclnnForeachMulScalarV2(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMulScalarV2 failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + aclDestroyScalar(alpha); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_mul_scalar_list/docs/aclnnForeachMulScalarList.md b/foreach/foreach_mul_scalar_list/docs/aclnnForeachMulScalarList.md index bb9ebe27..81c38686 100644 --- a/foreach/foreach_mul_scalar_list/docs/aclnnForeachMulScalarList.md +++ b/foreach/foreach_mul_scalar_list/docs/aclnnForeachMulScalarList.md @@ -130,11 +130,11 @@ aclnnStatus aclnnForeachMulScalarList(
- Atlas A2 训练系列产品/Atlas A2 推理系列产品Atlas A3 训练系列产品/Atlas A3 推理系列产品: - + 参数`scalars`的数据类型仅支持FLOAT32和INT64,且与输入参数`x`的数据类型具有一定对应关系: - 当入参`x`的数据类型为FLOAT32、FLOAT16、BFLOAT16时,`scalars`的数据类型仅支持FLOAT32。 - 当入参`x`的数据类型为INT32时,`scalars`的数据类型仅支持INT64。 - + - Ascend 950PR/Ascend 950DT: - 参数`x`、`out`支持包含的最大Tensor个数均为50。且`out`的TensorList长度需要与`x`的TensorList长度相等。 - 参数`scalars`的ScalarList长度需要与`x`的TensorList长度相等。 @@ -147,7 +147,7 @@ aclnnStatus aclnnForeachMulScalarList( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - + diff --git a/foreach/foreach_mul_scalar_list/examples/test_aclnn_foreach_mul_scalar_list.cpp b/foreach/foreach_mul_scalar_list/examples/test_aclnn_foreach_mul_scalar_list.cpp index d5f3f71d..d15b5ff7 100644 --- a/foreach/foreach_mul_scalar_list/examples/test_aclnn_foreach_mul_scalar_list.cpp +++ b/foreach/foreach_mul_scalar_list/examples/test_aclnn_foreach_mul_scalar_list.cpp @@ -14,167 +14,177 @@ #include "aclnnop/aclnn_foreach_mul_scalar_list.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& 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; +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 -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclScalar* alpha1 = nullptr; - aclScalar* alpha2 = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {70, 80, 90}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - float alpha1Value = 1.2f; - float alpha2Value = 2.2f; - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建alpha1 aclScalar - alpha1 = aclCreateScalar(&alpha1Value, aclDataType::ACL_FLOAT); - CHECK_RET(alpha1 != nullptr, return ret); - // 创建alpha2 aclScalar - alpha2 = aclCreateScalar(&alpha2Value, aclDataType::ACL_FLOAT); - CHECK_RET(alpha2 != nullptr, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - std::vector tempscalar{alpha1, alpha2}; - aclScalarList* scalarlist = aclCreateScalarList(tempscalar.data(), tempscalar.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachMulScalarList第一段接口 - ret = aclnnForeachMulScalarListGetWorkspaceSize(tensorListInput, scalarlist, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMulScalarListGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachMulScalarList第二段接口 - ret = aclnnForeachMulScalarList(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMulScalarList failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - aclDestroyScalarList(scalarlist); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclScalar* alpha1 = nullptr; + aclScalar* alpha2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {70, 80, 90}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + float alpha1Value = 1.2f; + float alpha2Value = 2.2f; + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建alpha1 aclScalar + alpha1 = aclCreateScalar(&alpha1Value, aclDataType::ACL_FLOAT); + CHECK_RET(alpha1 != nullptr, return ret); + // 创建alpha2 aclScalar + alpha2 = aclCreateScalar(&alpha2Value, aclDataType::ACL_FLOAT); + CHECK_RET(alpha2 != nullptr, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + std::vector tempscalar{alpha1, alpha2}; + aclScalarList* scalarlist = aclCreateScalarList(tempscalar.data(), tempscalar.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachMulScalarList第一段接口 + ret = aclnnForeachMulScalarListGetWorkspaceSize( + tensorListInput, scalarlist, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMulScalarListGetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachMulScalarList第二段接口 + ret = aclnnForeachMulScalarList(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachMulScalarList failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + aclDestroyScalarList(scalarlist); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_neg/docs/aclnnForeachNeg.md b/foreach/foreach_neg/docs/aclnnForeachNeg.md index 64e004be..e142f0d8 100644 --- a/foreach/foreach_neg/docs/aclnnForeachNeg.md +++ b/foreach/foreach_neg/docs/aclnnForeachNeg.md @@ -18,7 +18,7 @@ - 接口功能:计算输入张量列表中每个张量的相反数。 - 计算公式: - + $$ x = [{x_0}, {x_1}, ... {x_{n-1}}]\\ y = [{y_0}, {y_1}, ... {y_{n-1}}]\\ @@ -122,7 +122,7 @@ aclnnStatus aclnnForeachNeg( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_neg/examples/test_aclnn_foreach_neg.cpp b/foreach/foreach_neg/examples/test_aclnn_foreach_neg.cpp index 4bc3a866..b7627c51 100644 --- a/foreach/foreach_neg/examples/test_aclnn_foreach_neg.cpp +++ b/foreach/foreach_neg/examples/test_aclnn_foreach_neg.cpp @@ -14,26 +14,27 @@ #include "aclnnop/aclnn_foreach_neg.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,128 +47,134 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachNeg第一段接口 - ret = aclnnForeachNegGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachNegGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachNeg第二段接口 - ret = aclnnForeachNeg(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachNeg failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachNeg第一段接口 + ret = aclnnForeachNegGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachNegGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachNeg第二段接口 + ret = aclnnForeachNeg(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachNeg failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_norm/docs/aclnnForeachNorm.md b/foreach/foreach_norm/docs/aclnnForeachNorm.md index dba532d6..f91d184a 100644 --- a/foreach/foreach_norm/docs/aclnnForeachNorm.md +++ b/foreach/foreach_norm/docs/aclnnForeachNorm.md @@ -158,7 +158,7 @@ aclnnStatus aclnnForeachNorm( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_norm/examples/test_aclnn_foreach_norm.cpp b/foreach/foreach_norm/examples/test_aclnn_foreach_norm.cpp index 8f08a5df..2575f374 100644 --- a/foreach/foreach_norm/examples/test_aclnn_foreach_norm.cpp +++ b/foreach/foreach_norm/examples/test_aclnn_foreach_norm.cpp @@ -14,26 +14,27 @@ #include "aclnnop/aclnn_foreach_norm.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,129 +47,135 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {1, 1}; - std::vector outShape2 = {1, 1}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclScalar* alpha = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(1, 0); - std::vector out2HostData(1, 0); - float alphaValue = 2; - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建alpha aclScalar - alpha = aclCreateScalar(&alphaValue, aclDataType::ACL_FLOAT); - CHECK_RET(alpha != nullptr, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachNorm第一段接口 - ret = aclnnForeachNormGetWorkspaceSize(tensorListInput, alpha, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachNormGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachNorm第二段接口 - ret = aclnnForeachNorm(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachNorm failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - aclDestroyScalar(alpha); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {1, 1}; + std::vector outShape2 = {1, 1}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclScalar* alpha = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(1, 0); + std::vector out2HostData(1, 0); + float alphaValue = 2; + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建alpha aclScalar + alpha = aclCreateScalar(&alphaValue, aclDataType::ACL_FLOAT); + CHECK_RET(alpha != nullptr, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachNorm第一段接口 + ret = aclnnForeachNormGetWorkspaceSize(tensorListInput, alpha, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachNormGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachNorm第二段接口 + ret = aclnnForeachNorm(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachNorm failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + aclDestroyScalar(alpha); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_pow_list/docs/aclnnForeachPowList.md b/foreach/foreach_pow_list/docs/aclnnForeachPowList.md index 01ffdf56..34160f64 100644 --- a/foreach/foreach_pow_list/docs/aclnnForeachPowList.md +++ b/foreach/foreach_pow_list/docs/aclnnForeachPowList.md @@ -17,7 +17,7 @@ - 接口功能:对输入张量列表的每个张量进行幂运算(底数为x1,指数为x2)。 - 计算公式: - + $$ x1 = [{x1_0}, {x1_1}, ... {x1_{n-1}}]\\ x2 = [{x2_0}, {x2_1}, ... {x2_{n-1}}]\\ @@ -133,7 +133,7 @@ aclnnStatus aclnnForeachPowList( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_pow_list/examples/test_aclnn_foreach_pow_list.cpp b/foreach/foreach_pow_list/examples/test_aclnn_foreach_pow_list.cpp index 2baec46e..73ca3dcb 100644 --- a/foreach/foreach_pow_list/examples/test_aclnn_foreach_pow_list.cpp +++ b/foreach/foreach_pow_list/examples/test_aclnn_foreach_pow_list.cpp @@ -14,26 +14,27 @@ #include "aclnnop/aclnn_foreach_pow_list.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,143 +47,151 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector otherShape1 = {2, 3}; - std::vector otherShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* other1DeviceAddr = nullptr; - void* other2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* other1 = nullptr; - aclTensor* other2 = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector other1HostData = {6, 5, 4, 3, 2, 1}; - std::vector other2HostData = {9, 8, 7}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other1 aclTensor - ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other2 aclTensor - ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput1{input1, input2}; - aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); - std::vector tempInput2{other1, other2}; - aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachPowList第一段接口 - ret = aclnnForeachPowListGetWorkspaceSize(tensorListInput1, tensorListInput2, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachPowListGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachPowList第二段接口 - ret = aclnnForeachPowList(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachPowList failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput1); - aclDestroyTensorList(tensorListInput2); - aclDestroyTensorList(tensorListOutput); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(other1DeviceAddr); - aclrtFree(other2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector otherShape1 = {2, 3}; + std::vector otherShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* other1DeviceAddr = nullptr; + void* other2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* other1 = nullptr; + aclTensor* other2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector other1HostData = {6, 5, 4, 3, 2, 1}; + std::vector other2HostData = {9, 8, 7}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other1 aclTensor + ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other2 aclTensor + ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput1{input1, input2}; + aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); + std::vector tempInput2{other1, other2}; + aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachPowList第一段接口 + ret = aclnnForeachPowListGetWorkspaceSize( + tensorListInput1, tensorListInput2, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachPowListGetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachPowList第二段接口 + ret = aclnnForeachPowList(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachPowList failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput1); + aclDestroyTensorList(tensorListInput2); + aclDestroyTensorList(tensorListOutput); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(other1DeviceAddr); + aclrtFree(other2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_pow_scalar/docs/aclnnForeachPowScalar.md b/foreach/foreach_pow_scalar/docs/aclnnForeachPowScalar.md index f823e6ce..821a687d 100644 --- a/foreach/foreach_pow_scalar/docs/aclnnForeachPowScalar.md +++ b/foreach/foreach_pow_scalar/docs/aclnnForeachPowScalar.md @@ -133,7 +133,7 @@ aclnnStatus aclnnForeachPowScalar( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_pow_scalar/docs/aclnnForeachPowScalarV2.md b/foreach/foreach_pow_scalar/docs/aclnnForeachPowScalarV2.md index 1a7cdaf4..b9a999d9 100644 --- a/foreach/foreach_pow_scalar/docs/aclnnForeachPowScalarV2.md +++ b/foreach/foreach_pow_scalar/docs/aclnnForeachPowScalarV2.md @@ -131,7 +131,7 @@ aclnnStatus aclnnForeachPowScalarV2( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_pow_scalar/examples/test_aclnn_foreach_pow_scalar.cpp b/foreach/foreach_pow_scalar/examples/test_aclnn_foreach_pow_scalar.cpp index 1473beb8..3a6968c4 100644 --- a/foreach/foreach_pow_scalar/examples/test_aclnn_foreach_pow_scalar.cpp +++ b/foreach/foreach_pow_scalar/examples/test_aclnn_foreach_pow_scalar.cpp @@ -14,163 +14,172 @@ #include "aclnnop/aclnn_foreach_pow_scalar.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& 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; +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 -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - std::vector alphaShape = {1}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - void* alphaDeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* alpha = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - std::vector alphaValueHostData = {1.2f}; - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建alpha aclTensor - ret = CreateAclTensor(alphaValueHostData, alphaShape, &alphaDeviceAddr, aclDataType::ACL_FLOAT, &alpha); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachPowScalar第一段接口 - ret = aclnnForeachPowScalarGetWorkspaceSize(tensorListInput, alpha, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachPowScalarGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachPowScalar第二段接口 - ret = aclnnForeachPowScalar(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachPowScalar failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - aclDestroyTensor(alpha); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - aclrtFree(alphaDeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + std::vector alphaShape = {1}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + void* alphaDeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* alpha = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + std::vector alphaValueHostData = {1.2f}; + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建alpha aclTensor + ret = CreateAclTensor(alphaValueHostData, alphaShape, &alphaDeviceAddr, aclDataType::ACL_FLOAT, &alpha); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachPowScalar第一段接口 + ret = aclnnForeachPowScalarGetWorkspaceSize(tensorListInput, alpha, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachPowScalarGetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachPowScalar第二段接口 + ret = aclnnForeachPowScalar(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachPowScalar failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + aclDestroyTensor(alpha); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + aclrtFree(alphaDeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; } diff --git a/foreach/foreach_pow_scalar/examples/test_aclnn_foreach_pow_scalar_v2.cpp b/foreach/foreach_pow_scalar/examples/test_aclnn_foreach_pow_scalar_v2.cpp index 066fbaa7..101f289d 100644 --- a/foreach/foreach_pow_scalar/examples/test_aclnn_foreach_pow_scalar_v2.cpp +++ b/foreach/foreach_pow_scalar/examples/test_aclnn_foreach_pow_scalar_v2.cpp @@ -14,160 +14,169 @@ #include "aclnnop/aclnn_foreach_pow_scalar_v2.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& 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; +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 -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclScalar* alpha = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - float alphaValue = 1.2f; - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建alpha aclScalar - alpha = aclCreateScalar(&alphaValue, aclDataType::ACL_FLOAT); - CHECK_RET(alpha != nullptr, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachPowScalarV2第一段接口 - ret = aclnnForeachPowScalarV2GetWorkspaceSize(tensorListInput, alpha, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachPowScalarV2GetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachPowScalarV2第二段接口 - ret = aclnnForeachPowScalarV2(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachPowScalarV2 failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - aclDestroyScalar(alpha); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclScalar* alpha = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + float alphaValue = 1.2f; + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建alpha aclScalar + alpha = aclCreateScalar(&alphaValue, aclDataType::ACL_FLOAT); + CHECK_RET(alpha != nullptr, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachPowScalarV2第一段接口 + ret = aclnnForeachPowScalarV2GetWorkspaceSize(tensorListInput, alpha, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachPowScalarV2GetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachPowScalarV2第二段接口 + ret = aclnnForeachPowScalarV2(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachPowScalarV2 failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + aclDestroyScalar(alpha); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_pow_scalar_and_tensor/docs/aclnnForeachPowScalarAndTensor.md b/foreach/foreach_pow_scalar_and_tensor/docs/aclnnForeachPowScalarAndTensor.md index ba256fcc..f972052f 100644 --- a/foreach/foreach_pow_scalar_and_tensor/docs/aclnnForeachPowScalarAndTensor.md +++ b/foreach/foreach_pow_scalar_and_tensor/docs/aclnnForeachPowScalarAndTensor.md @@ -133,7 +133,7 @@ aclnnStatus aclnnForeachPowScalarAndTensor( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_pow_scalar_and_tensor/examples/test_aclnn_foreach_pow_scalar_and_tensor.cpp b/foreach/foreach_pow_scalar_and_tensor/examples/test_aclnn_foreach_pow_scalar_and_tensor.cpp index c867e3ca..3fd48d1f 100644 --- a/foreach/foreach_pow_scalar_and_tensor/examples/test_aclnn_foreach_pow_scalar_and_tensor.cpp +++ b/foreach/foreach_pow_scalar_and_tensor/examples/test_aclnn_foreach_pow_scalar_and_tensor.cpp @@ -14,160 +14,170 @@ #include "aclnnop/aclnn_foreach_pow_scalar_and_tensor.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& 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; +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 -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclScalar* alpha = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - float alphaValue = 1.2f; - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建alpha aclScalar - alpha = aclCreateScalar(&alphaValue, aclDataType::ACL_FLOAT); - CHECK_RET(alpha != nullptr, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachPowScalarAndTensor第一段接口 - ret = aclnnForeachPowScalarAndTensorGetWorkspaceSize(alpha, tensorListInput, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachPowScalarAndTensorGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachPowScalarAndTensor第二段接口 - ret = aclnnForeachPowScalarAndTensor(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachPowScalarAndTensor failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - aclDestroyScalar(alpha); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclScalar* alpha = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + float alphaValue = 1.2f; + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建alpha aclScalar + alpha = aclCreateScalar(&alphaValue, aclDataType::ACL_FLOAT); + CHECK_RET(alpha != nullptr, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachPowScalarAndTensor第一段接口 + ret = aclnnForeachPowScalarAndTensorGetWorkspaceSize( + alpha, tensorListInput, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachPowScalarAndTensorGetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachPowScalarAndTensor第二段接口 + ret = aclnnForeachPowScalarAndTensor(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachPowScalarAndTensor failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + aclDestroyScalar(alpha); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_pow_scalar_list/docs/aclnnForeachPowScalarList.md b/foreach/foreach_pow_scalar_list/docs/aclnnForeachPowScalarList.md index 5a80743d..2368e9b3 100644 --- a/foreach/foreach_pow_scalar_list/docs/aclnnForeachPowScalarList.md +++ b/foreach/foreach_pow_scalar_list/docs/aclnnForeachPowScalarList.md @@ -134,7 +134,7 @@ aclnnStatus aclnnForeachPowScalarList( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_pow_scalar_list/examples/test_aclnn_foreach_pow_scalar_list.cpp b/foreach/foreach_pow_scalar_list/examples/test_aclnn_foreach_pow_scalar_list.cpp index 981fa4b6..0c6aa725 100644 --- a/foreach/foreach_pow_scalar_list/examples/test_aclnn_foreach_pow_scalar_list.cpp +++ b/foreach/foreach_pow_scalar_list/examples/test_aclnn_foreach_pow_scalar_list.cpp @@ -14,167 +14,177 @@ #include "aclnnop/aclnn_foreach_pow_scalar_list.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& 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; +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 -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclScalar* alpha1 = nullptr; - aclScalar* alpha2 = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - float alpha1Value = 1.2f; - float alpha2Value = 2.2f; - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建alpha1 aclScalar - alpha1 = aclCreateScalar(&alpha1Value, aclDataType::ACL_FLOAT); - CHECK_RET(alpha1 != nullptr, return ret); - // 创建alpha2 aclScalar - alpha2 = aclCreateScalar(&alpha2Value, aclDataType::ACL_FLOAT); - CHECK_RET(alpha2 != nullptr, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - std::vector tempscalar{alpha1, alpha2}; - aclScalarList* scalarlist = aclCreateScalarList(tempscalar.data(), tempscalar.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachPowScalarList第一段接口 - ret = aclnnForeachPowScalarListGetWorkspaceSize(tensorListInput, scalarlist, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachPowScalarListGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachPowScalarList第二段接口 - ret = aclnnForeachPowScalarList(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachPowScalarList failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - aclDestroyScalarList(scalarlist); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclScalar* alpha1 = nullptr; + aclScalar* alpha2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + float alpha1Value = 1.2f; + float alpha2Value = 2.2f; + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建alpha1 aclScalar + alpha1 = aclCreateScalar(&alpha1Value, aclDataType::ACL_FLOAT); + CHECK_RET(alpha1 != nullptr, return ret); + // 创建alpha2 aclScalar + alpha2 = aclCreateScalar(&alpha2Value, aclDataType::ACL_FLOAT); + CHECK_RET(alpha2 != nullptr, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + std::vector tempscalar{alpha1, alpha2}; + aclScalarList* scalarlist = aclCreateScalarList(tempscalar.data(), tempscalar.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachPowScalarList第一段接口 + ret = aclnnForeachPowScalarListGetWorkspaceSize( + tensorListInput, scalarlist, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachPowScalarListGetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachPowScalarList第二段接口 + ret = aclnnForeachPowScalarList(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachPowScalarList failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + aclDestroyScalarList(scalarlist); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_reciprocal/docs/aclnnForeachReciprocal.md b/foreach/foreach_reciprocal/docs/aclnnForeachReciprocal.md index 57b75b0d..8058f4e0 100644 --- a/foreach/foreach_reciprocal/docs/aclnnForeachReciprocal.md +++ b/foreach/foreach_reciprocal/docs/aclnnForeachReciprocal.md @@ -121,7 +121,7 @@ aclnnStatus aclnnForeachReciprocal( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_reciprocal/examples/test_aclnn_foreach_reciprocal.cpp b/foreach/foreach_reciprocal/examples/test_aclnn_foreach_reciprocal.cpp index 608435b1..df283db8 100644 --- a/foreach/foreach_reciprocal/examples/test_aclnn_foreach_reciprocal.cpp +++ b/foreach/foreach_reciprocal/examples/test_aclnn_foreach_reciprocal.cpp @@ -14,26 +14,27 @@ #include "aclnnop/aclnn_foreach_reciprocal.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,128 +47,135 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachReciprocal第一段接口 - ret = aclnnForeachReciprocalGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachReciprocalGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachReciprocal第二段接口 - ret = aclnnForeachReciprocal(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachReciprocal failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachReciprocal第一段接口 + ret = aclnnForeachReciprocalGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachReciprocalGetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachReciprocal第二段接口 + ret = aclnnForeachReciprocal(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachReciprocal failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_round_off_number/docs/aclnnForeachRoundOffNumber.md b/foreach/foreach_round_off_number/docs/aclnnForeachRoundOffNumber.md index 61759128..6586204a 100644 --- a/foreach/foreach_round_off_number/docs/aclnnForeachRoundOffNumber.md +++ b/foreach/foreach_round_off_number/docs/aclnnForeachRoundOffNumber.md @@ -132,7 +132,7 @@ aclnnStatus aclnnForeachRoundOffNumber( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_round_off_number/docs/aclnnForeachRoundOffNumberV2.md b/foreach/foreach_round_off_number/docs/aclnnForeachRoundOffNumberV2.md index ed20cbf9..b9ae4e51 100644 --- a/foreach/foreach_round_off_number/docs/aclnnForeachRoundOffNumberV2.md +++ b/foreach/foreach_round_off_number/docs/aclnnForeachRoundOffNumberV2.md @@ -129,7 +129,7 @@ aclnnStatus aclnnForeachRoundOffNumberV2( - **返回值** aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 - + 第一段接口完成入参校验,出现以下场景时报错:
diff --git a/foreach/foreach_round_off_number/examples/test_aclnn_foreach_round_off_number.cpp b/foreach/foreach_round_off_number/examples/test_aclnn_foreach_round_off_number.cpp index 22e0ea06..9e9adf38 100644 --- a/foreach/foreach_round_off_number/examples/test_aclnn_foreach_round_off_number.cpp +++ b/foreach/foreach_round_off_number/examples/test_aclnn_foreach_round_off_number.cpp @@ -14,26 +14,27 @@ #include "aclnnop/aclnn_foreach_round_off_number.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,132 +47,140 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - std::vector alphaShape = {1}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - void* alphaDeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* alpha = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1.1, 2.2, 3.3, 4.5, 5.3, 6.12}; - std::vector input2HostData = {7.45, 8.87, 9.54}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - std::vector alphaHostData = {1}; - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建alpha aclTensor - ret = CreateAclTensor(alphaHostData, alphaShape, &alphaDeviceAddr, aclDataType::ACL_INT8, &alpha); - CHECK_RET(alpha != nullptr, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachRoundOffNumber第一段接口 - ret = aclnnForeachRoundOffNumberGetWorkspaceSize(tensorListInput, alpha, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachRoundOffNumberGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachRoundOffNumber第二段接口 - ret = aclnnForeachRoundOffNumber(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachRoundOffNumber failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - aclDestroyTensor(alpha); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - aclrtFree(alphaDeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + std::vector alphaShape = {1}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + void* alphaDeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* alpha = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1.1, 2.2, 3.3, 4.5, 5.3, 6.12}; + std::vector input2HostData = {7.45, 8.87, 9.54}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + std::vector alphaHostData = {1}; + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建alpha aclTensor + ret = CreateAclTensor(alphaHostData, alphaShape, &alphaDeviceAddr, aclDataType::ACL_INT8, &alpha); + CHECK_RET(alpha != nullptr, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachRoundOffNumber第一段接口 + ret = + aclnnForeachRoundOffNumberGetWorkspaceSize(tensorListInput, alpha, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachRoundOffNumberGetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachRoundOffNumber第二段接口 + ret = aclnnForeachRoundOffNumber(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachRoundOffNumber failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + aclDestroyTensor(alpha); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + aclrtFree(alphaDeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_round_off_number/examples/test_aclnn_foreach_round_off_number_v2.cpp b/foreach/foreach_round_off_number/examples/test_aclnn_foreach_round_off_number_v2.cpp index df8a89bf..20e507d2 100644 --- a/foreach/foreach_round_off_number/examples/test_aclnn_foreach_round_off_number_v2.cpp +++ b/foreach/foreach_round_off_number/examples/test_aclnn_foreach_round_off_number_v2.cpp @@ -14,26 +14,27 @@ #include "aclnnop/aclnn_foreach_round_off_number_v2.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,129 +47,137 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclScalar* alpha = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1.1, 2.2, 3.3, 4.5, 5.3, 6.12}; - std::vector input2HostData = {7.45, 8.87, 9.54}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - int64_t alphaValue = 3; - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建alpha aclScalar - alpha = aclCreateScalar(&alphaValue, aclDataType::ACL_INT8); - CHECK_RET(alpha != nullptr, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachRoundOffNumberV2第一段接口 - ret = aclnnForeachRoundOffNumberV2GetWorkspaceSize(tensorListInput, alpha, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachRoundOffNumberV2GetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachRoundOffNumberV2第二段接口 - ret = aclnnForeachRoundOffNumberV2(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachRoundOffNumberV2 failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - aclDestroyScalar(alpha); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclScalar* alpha = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1.1, 2.2, 3.3, 4.5, 5.3, 6.12}; + std::vector input2HostData = {7.45, 8.87, 9.54}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + int64_t alphaValue = 3; + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建alpha aclScalar + alpha = aclCreateScalar(&alphaValue, aclDataType::ACL_INT8); + CHECK_RET(alpha != nullptr, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachRoundOffNumberV2第一段接口 + ret = aclnnForeachRoundOffNumberV2GetWorkspaceSize( + tensorListInput, alpha, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachRoundOffNumberV2GetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachRoundOffNumberV2第二段接口 + ret = aclnnForeachRoundOffNumberV2(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachRoundOffNumberV2 failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + aclDestroyScalar(alpha); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_sigmoid/examples/test_aclnn_foreach_sigmoid.cpp b/foreach/foreach_sigmoid/examples/test_aclnn_foreach_sigmoid.cpp index 3bcfaa39..d67153ac 100644 --- a/foreach/foreach_sigmoid/examples/test_aclnn_foreach_sigmoid.cpp +++ b/foreach/foreach_sigmoid/examples/test_aclnn_foreach_sigmoid.cpp @@ -14,26 +14,27 @@ #include "aclnnop/aclnn_foreach_sigmoid.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,128 +47,135 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachSigmoid第一段接口 - ret = aclnnForeachSigmoidGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSigmoidGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachSigmoid第二段接口 - ret = aclnnForeachSigmoid(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSigmoid failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachSigmoid第一段接口 + ret = aclnnForeachSigmoidGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSigmoidGetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachSigmoid第二段接口 + ret = aclnnForeachSigmoid(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSigmoid failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_sign/docs/aclnnForeachSign.md b/foreach/foreach_sign/docs/aclnnForeachSign.md index f2ebcc01..bc269c6e 100644 --- a/foreach/foreach_sign/docs/aclnnForeachSign.md +++ b/foreach/foreach_sign/docs/aclnnForeachSign.md @@ -18,7 +18,7 @@ - 接口功能:计算输入张量列表中每个张量的符号值。 - 计算公式: - + $$ x = [{x_0}, {x_1}, ... {x_{n-1}}]\\ y = [{y_0}, {y_1}, ... {y_{n-1}}]\\ diff --git a/foreach/foreach_sign/examples/test_aclnn_foreach_sign.cpp b/foreach/foreach_sign/examples/test_aclnn_foreach_sign.cpp index 2b196e40..2f8be3fa 100644 --- a/foreach/foreach_sign/examples/test_aclnn_foreach_sign.cpp +++ b/foreach/foreach_sign/examples/test_aclnn_foreach_sign.cpp @@ -25,7 +25,7 @@ printf(message, ##__VA_ARGS__); \ } while (0) -int64_t GetShapeSize(const std::vector &shape) +int64_t GetShapeSize(const std::vector& shape) { int64_t shapeSize = 1; for (auto i : shape) { @@ -34,7 +34,7 @@ int64_t GetShapeSize(const std::vector &shape) return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -47,8 +47,9 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector &hostData, const std::vector &shape, void **deviceAddr, - aclDataType dataType, aclTensor **tensor) +int CreateAclTensor( + const std::vector& hostData, const std::vector& shape, void** deviceAddr, aclDataType dataType, + aclTensor** tensor) { auto size = GetShapeSize(shape) * sizeof(T); // 调用aclrtMalloc申请device侧内存 @@ -65,14 +66,8 @@ int CreateAclTensor(const std::vector &hostData, const std::vector & } // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), - shape.size(), - dataType, - strides.data(), - 0, - aclFormat::ACL_FORMAT_ND, - shape.data(), - shape.size(), + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), *deviceAddr); return 0; } @@ -91,14 +86,14 @@ int main() std::vector selfShape2 = {1, 3}; std::vector outShape1 = {2, 3}; std::vector outShape2 = {1, 3}; - void *input1DeviceAddr = nullptr; - void *input2DeviceAddr = nullptr; - void *out1DeviceAddr = nullptr; - void *out2DeviceAddr = nullptr; - aclTensor *input1 = nullptr; - aclTensor *input2 = nullptr; - aclTensor *out1 = nullptr; - aclTensor *out2 = nullptr; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; std::vector input1HostData = {1, 2, 3, 4, 5, 6}; std::vector input2HostData = {7, 8, 9}; std::vector out1HostData(6, 0); @@ -120,19 +115,19 @@ int main() ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); CHECK_RET(ret == ACL_SUCCESS, return ret); - std::vector tempInput{input1, input2}; - aclTensorList *tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList *tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); // 3. 调用CANN算子库API,需要修改为具体的API名称 uint64_t workspaceSize = 0; - aclOpExecutor *executor; + aclOpExecutor* executor; // 调用aclnnForeachSign第一段接口 ret = aclnnForeachSignGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSignGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); // 根据第一段接口计算出的workspaceSize申请device内存 - void *workspaceAddr = nullptr; + void* workspaceAddr = nullptr; if (workspaceSize > 0) { ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); @@ -148,10 +143,8 @@ int main() // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 auto size = GetShapeSize(outShape1); std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), - out1Data.size() * sizeof(out1Data[0]), - out1DeviceAddr, - size * sizeof(out1Data[0]), + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); CHECK_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++) { @@ -160,10 +153,8 @@ int main() size = GetShapeSize(outShape2); std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), - out2Data.size() * sizeof(out2Data[0]), - out2DeviceAddr, - size * sizeof(out2Data[0]), + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); CHECK_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++) { @@ -186,4 +177,4 @@ int main() aclrtResetDevice(deviceId); aclFinalize(); return 0; -} \ No newline at end of file +} diff --git a/foreach/foreach_sin/examples/test_aclnn_foreach_sin.cpp b/foreach/foreach_sin/examples/test_aclnn_foreach_sin.cpp index 21dbfe9e..ad2f8ae8 100644 --- a/foreach/foreach_sin/examples/test_aclnn_foreach_sin.cpp +++ b/foreach/foreach_sin/examples/test_aclnn_foreach_sin.cpp @@ -14,26 +14,27 @@ #include "aclnnop/aclnn_foreach_sin.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,128 +47,134 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachSin第一段接口 - ret = aclnnForeachSinGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSinGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachSin第二段接口 - ret = aclnnForeachSin(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSin failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果拷贝至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachSin第一段接口 + ret = aclnnForeachSinGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSinGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachSin第二段接口 + ret = aclnnForeachSin(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSin failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果拷贝至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_sinh/docs/aclnnForeachSinh.md b/foreach/foreach_sinh/docs/aclnnForeachSinh.md index 8fe25a7c..4067affa 100644 --- a/foreach/foreach_sinh/docs/aclnnForeachSinh.md +++ b/foreach/foreach_sinh/docs/aclnnForeachSinh.md @@ -17,7 +17,7 @@ - 接口功能:对输入张量列表的每个张量进行双曲正弦函数运算。 - 计算公式: - + $$ x = [{x_0}, {x_1}, ... {x_{n-1}}]\\ y = [{y_0}, {y_1}, ... {y_{n-1}}]\\ @@ -121,7 +121,7 @@ aclnnStatus aclnnForeachSinh( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_sinh/examples/test_aclnn_foreach_sinh.cpp b/foreach/foreach_sinh/examples/test_aclnn_foreach_sinh.cpp index 98530b1d..11a0da0e 100644 --- a/foreach/foreach_sinh/examples/test_aclnn_foreach_sinh.cpp +++ b/foreach/foreach_sinh/examples/test_aclnn_foreach_sinh.cpp @@ -14,26 +14,27 @@ #include "aclnnop/aclnn_foreach_sinh.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,128 +47,134 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachSinh第一段接口 - ret = aclnnForeachSinhGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSinhGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachSinh第二段接口 - ret = aclnnForeachSinh(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSinh failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachSinh第一段接口 + ret = aclnnForeachSinhGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSinhGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachSinh第二段接口 + ret = aclnnForeachSinh(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSinh failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_sqrt/docs/aclnnForeachSqrt.md b/foreach/foreach_sqrt/docs/aclnnForeachSqrt.md index 88c3c84c..92ffe358 100644 --- a/foreach/foreach_sqrt/docs/aclnnForeachSqrt.md +++ b/foreach/foreach_sqrt/docs/aclnnForeachSqrt.md @@ -17,7 +17,7 @@ - 接口功能:对输入张量列表的每个张量进行平方根运算。 - 计算公式: - + $$ x = [{x_0}, {x_1}, ... {x_{n-1}}]\\ y = [{y_0}, {y_1}, ... {y_{n-1}}]\\ @@ -123,7 +123,7 @@ aclnnStatus aclnnForeachSqrt( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_sqrt/examples/test_aclnn_foreach_sqrt.cpp b/foreach/foreach_sqrt/examples/test_aclnn_foreach_sqrt.cpp index 39a2ae47..b8d6995c 100644 --- a/foreach/foreach_sqrt/examples/test_aclnn_foreach_sqrt.cpp +++ b/foreach/foreach_sqrt/examples/test_aclnn_foreach_sqrt.cpp @@ -14,26 +14,27 @@ #include "aclnnop/aclnn_foreach_sqrt.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,128 +47,134 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachSqrt第一段接口 - ret = aclnnForeachSqrtGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSqrtGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachSqrt第二段接口 - ret = aclnnForeachSqrt(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSqrt failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachSqrt第一段接口 + ret = aclnnForeachSqrtGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSqrtGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachSqrt第二段接口 + ret = aclnnForeachSqrt(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSqrt failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_sub_list/docs/aclnnForeachSubList.md b/foreach/foreach_sub_list/docs/aclnnForeachSubList.md index 35e8067d..484cc654 100644 --- a/foreach/foreach_sub_list/docs/aclnnForeachSubList.md +++ b/foreach/foreach_sub_list/docs/aclnnForeachSubList.md @@ -18,13 +18,13 @@ - 接口功能:对输入的两个张量列表执行逐元素相减运算,并可以通过alpha参数调整相减系数。 - 计算公式: - + $$ x1 = [{x1_0}, {x1_1}, ... {x1_{n-1}}]\\ x2 = [{x2_0}, {x2_1}, ... {x2_{n-1}}]\\ y = [{y_0}, {y_1}, ... {y_{n-1}}]\\ $$ - + $$ y_i = x1_i-{x2_i}*alpha (i=0,1,...n-1) $$ diff --git a/foreach/foreach_sub_list/docs/aclnnForeachSubListV2.md b/foreach/foreach_sub_list/docs/aclnnForeachSubListV2.md index 666084d8..9d8aa5e5 100644 --- a/foreach/foreach_sub_list/docs/aclnnForeachSubListV2.md +++ b/foreach/foreach_sub_list/docs/aclnnForeachSubListV2.md @@ -24,7 +24,7 @@ x2 = [{x2_0}, {x2_1}, ... {x2_{n-1}}]\\ y = [{y_0}, {y_1}, ... {y_{n-1}}]\\ $$ - + $$ y_i = x1_i-{x2_i}*alpha (i=0,1,...n-1) $$ diff --git a/foreach/foreach_sub_list/examples/test_aclnn_foreach_sub_list.cpp b/foreach/foreach_sub_list/examples/test_aclnn_foreach_sub_list.cpp index d5964488..0e025026 100644 --- a/foreach/foreach_sub_list/examples/test_aclnn_foreach_sub_list.cpp +++ b/foreach/foreach_sub_list/examples/test_aclnn_foreach_sub_list.cpp @@ -14,183 +14,193 @@ #include "aclnnop/aclnn_foreach_sub_list.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& 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; +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 -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector otherShape1 = {2, 3}; - std::vector otherShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - std::vector alphaShape = {1}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* other1DeviceAddr = nullptr; - void* other2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - void* alphaDeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* other1 = nullptr; - aclTensor* other2 = nullptr; - aclTensor* alpha = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {3, 5, 7, 4, 5, 9}; - std::vector input2HostData = {5, 4, 1}; - std::vector other1HostData = {1, 2, 3, 4, 5, 6}; - std::vector other2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - std::vector alphaValueHostData = {1.2f}; - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other1 aclTensor - ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other2 aclTensor - ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建alpha aclTensor - ret = CreateAclTensor(alphaValueHostData, alphaShape, &alphaDeviceAddr, aclDataType::ACL_FLOAT, &alpha); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput1{input1, input2}; - aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); - std::vector tempInput2{other1, other2}; - aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachSubList第一段接口 - ret = aclnnForeachSubListGetWorkspaceSize(tensorListInput1, tensorListInput2, alpha, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSubListGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachSubList第二段接口 - ret = aclnnForeachSubList(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSubList failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput1); - aclDestroyTensorList(tensorListInput2); - aclDestroyTensorList(tensorListOutput); - aclDestroyTensor(alpha); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(other1DeviceAddr); - aclrtFree(other2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - aclrtFree(alphaDeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector otherShape1 = {2, 3}; + std::vector otherShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + std::vector alphaShape = {1}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* other1DeviceAddr = nullptr; + void* other2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + void* alphaDeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* other1 = nullptr; + aclTensor* other2 = nullptr; + aclTensor* alpha = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {3, 5, 7, 4, 5, 9}; + std::vector input2HostData = {5, 4, 1}; + std::vector other1HostData = {1, 2, 3, 4, 5, 6}; + std::vector other2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + std::vector alphaValueHostData = {1.2f}; + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other1 aclTensor + ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other2 aclTensor + ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建alpha aclTensor + ret = CreateAclTensor(alphaValueHostData, alphaShape, &alphaDeviceAddr, aclDataType::ACL_FLOAT, &alpha); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput1{input1, input2}; + aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); + std::vector tempInput2{other1, other2}; + aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachSubList第一段接口 + ret = aclnnForeachSubListGetWorkspaceSize( + tensorListInput1, tensorListInput2, alpha, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSubListGetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachSubList第二段接口 + ret = aclnnForeachSubList(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSubList failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput1); + aclDestroyTensorList(tensorListInput2); + aclDestroyTensorList(tensorListOutput); + aclDestroyTensor(alpha); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(other1DeviceAddr); + aclrtFree(other2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + aclrtFree(alphaDeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_sub_list/examples/test_aclnn_foreach_sub_list_v2.cpp b/foreach/foreach_sub_list/examples/test_aclnn_foreach_sub_list_v2.cpp index bb30c86d..2cf6b6fc 100644 --- a/foreach/foreach_sub_list/examples/test_aclnn_foreach_sub_list_v2.cpp +++ b/foreach/foreach_sub_list/examples/test_aclnn_foreach_sub_list_v2.cpp @@ -14,180 +14,190 @@ #include "aclnnop/aclnn_foreach_sub_list_v2.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& 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; +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 -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector otherShape1 = {2, 3}; - std::vector otherShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* other1DeviceAddr = nullptr; - void* other2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* other1 = nullptr; - aclTensor* other2 = nullptr; - aclScalar* alpha = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {3, 5, 7, 4, 5, 9}; - std::vector input2HostData = {5, 4, 1}; - std::vector other1HostData = {1, 2, 3, 4, 5, 6}; - std::vector other2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - float alphaValue = 1.2f; - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other1 aclTensor - ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建other2 aclTensor - ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建alpha aclScalar - alpha = aclCreateScalar(&alphaValue, aclDataType::ACL_FLOAT); - CHECK_RET(alpha != nullptr, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput1{input1, input2}; - aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); - std::vector tempInput2{other1, other2}; - aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachSubListV2第一段接口 - ret = aclnnForeachSubListV2GetWorkspaceSize(tensorListInput1, tensorListInput2, alpha, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSubListV2GetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachSubListV2第二段接口 - ret = aclnnForeachSubListV2(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSubListV2 failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput1); - aclDestroyTensorList(tensorListInput2); - aclDestroyTensorList(tensorListOutput); - aclDestroyScalar(alpha); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(other1DeviceAddr); - aclrtFree(other2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector otherShape1 = {2, 3}; + std::vector otherShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* other1DeviceAddr = nullptr; + void* other2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* other1 = nullptr; + aclTensor* other2 = nullptr; + aclScalar* alpha = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {3, 5, 7, 4, 5, 9}; + std::vector input2HostData = {5, 4, 1}; + std::vector other1HostData = {1, 2, 3, 4, 5, 6}; + std::vector other2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + float alphaValue = 1.2f; + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other1 aclTensor + ret = CreateAclTensor(other1HostData, otherShape1, &other1DeviceAddr, aclDataType::ACL_FLOAT, &other1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建other2 aclTensor + ret = CreateAclTensor(other2HostData, otherShape2, &other2DeviceAddr, aclDataType::ACL_FLOAT, &other2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建alpha aclScalar + alpha = aclCreateScalar(&alphaValue, aclDataType::ACL_FLOAT); + CHECK_RET(alpha != nullptr, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput1{input1, input2}; + aclTensorList* tensorListInput1 = aclCreateTensorList(tempInput1.data(), tempInput1.size()); + std::vector tempInput2{other1, other2}; + aclTensorList* tensorListInput2 = aclCreateTensorList(tempInput2.data(), tempInput2.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachSubListV2第一段接口 + ret = aclnnForeachSubListV2GetWorkspaceSize( + tensorListInput1, tensorListInput2, alpha, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSubListV2GetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachSubListV2第二段接口 + ret = aclnnForeachSubListV2(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSubListV2 failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput1); + aclDestroyTensorList(tensorListInput2); + aclDestroyTensorList(tensorListOutput); + aclDestroyScalar(alpha); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(other1DeviceAddr); + aclrtFree(other2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_sub_scalar/docs/aclnnForeachSubScalarV2.md b/foreach/foreach_sub_scalar/docs/aclnnForeachSubScalarV2.md index e8b69df0..96cd46fb 100644 --- a/foreach/foreach_sub_scalar/docs/aclnnForeachSubScalarV2.md +++ b/foreach/foreach_sub_scalar/docs/aclnnForeachSubScalarV2.md @@ -132,7 +132,7 @@ aclnnStatus aclnnForeachSubScalarV2( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_sub_scalar/examples/test_aclnn_foreach_sub_scalar.cpp b/foreach/foreach_sub_scalar/examples/test_aclnn_foreach_sub_scalar.cpp index 8348e998..ccb93d84 100644 --- a/foreach/foreach_sub_scalar/examples/test_aclnn_foreach_sub_scalar.cpp +++ b/foreach/foreach_sub_scalar/examples/test_aclnn_foreach_sub_scalar.cpp @@ -14,163 +14,172 @@ #include "aclnnop/aclnn_foreach_sub_scalar.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& 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; +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 -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - std::vector alphaShape = {1}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - void* alphaDeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* alpha = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - std::vector alphaValueHostData = {1.2f}; - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建alpha aclTensor - ret = CreateAclTensor(alphaValueHostData, alphaShape, &alphaDeviceAddr, aclDataType::ACL_FLOAT, &alpha); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachSubScalar第一段接口 - ret = aclnnForeachSubScalarGetWorkspaceSize(tensorListInput, alpha, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSubScalarGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachSubScalar第二段接口 - ret = aclnnForeachSubScalar(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSubScalar failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - aclDestroyTensor(alpha); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - aclrtFree(alphaDeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + std::vector alphaShape = {1}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + void* alphaDeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* alpha = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + std::vector alphaValueHostData = {1.2f}; + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建alpha aclTensor + ret = CreateAclTensor(alphaValueHostData, alphaShape, &alphaDeviceAddr, aclDataType::ACL_FLOAT, &alpha); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachSubScalar第一段接口 + ret = aclnnForeachSubScalarGetWorkspaceSize(tensorListInput, alpha, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSubScalarGetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachSubScalar第二段接口 + ret = aclnnForeachSubScalar(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSubScalar failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + aclDestroyTensor(alpha); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + aclrtFree(alphaDeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_sub_scalar/examples/test_aclnn_foreach_sub_scalar_v2.cpp b/foreach/foreach_sub_scalar/examples/test_aclnn_foreach_sub_scalar_v2.cpp index 277c10fe..435f0dfc 100644 --- a/foreach/foreach_sub_scalar/examples/test_aclnn_foreach_sub_scalar_v2.cpp +++ b/foreach/foreach_sub_scalar/examples/test_aclnn_foreach_sub_scalar_v2.cpp @@ -14,160 +14,169 @@ #include "aclnnop/aclnn_foreach_sub_scalar_v2.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& 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; +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 -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclScalar* alpha = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - float alphaValue = 1.2f; - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建alpha aclScalar - alpha = aclCreateScalar(&alphaValue, aclDataType::ACL_FLOAT); - CHECK_RET(alpha != nullptr, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachSubScalarV2第一段接口 - ret = aclnnForeachSubScalarV2GetWorkspaceSize(tensorListInput, alpha, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSubScalarV2GetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachSubScalarV2第二段接口 - ret = aclnnForeachSubScalarV2(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSubScalarV2 failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - aclDestroyScalar(alpha); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclScalar* alpha = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + float alphaValue = 1.2f; + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建alpha aclScalar + alpha = aclCreateScalar(&alphaValue, aclDataType::ACL_FLOAT); + CHECK_RET(alpha != nullptr, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachSubScalarV2第一段接口 + ret = aclnnForeachSubScalarV2GetWorkspaceSize(tensorListInput, alpha, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSubScalarV2GetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachSubScalarV2第二段接口 + ret = aclnnForeachSubScalarV2(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSubScalarV2 failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + aclDestroyScalar(alpha); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_sub_scalar_list/examples/test_aclnn_foreach_sub_scalar_list.cpp b/foreach/foreach_sub_scalar_list/examples/test_aclnn_foreach_sub_scalar_list.cpp index 8b30f6dd..73bcef0a 100644 --- a/foreach/foreach_sub_scalar_list/examples/test_aclnn_foreach_sub_scalar_list.cpp +++ b/foreach/foreach_sub_scalar_list/examples/test_aclnn_foreach_sub_scalar_list.cpp @@ -14,167 +14,177 @@ #include "aclnnop/aclnn_foreach_sub_scalar_list.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& 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; +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 -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclScalar* alpha1 = nullptr; - aclScalar* alpha2 = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - float alpha1Value = 1.2f; - float alpha2Value = 2.2f; - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建alpha1 aclScalar - alpha1 = aclCreateScalar(&alpha1Value, aclDataType::ACL_FLOAT); - CHECK_RET(alpha1 != nullptr, return ret); - // 创建alpha2 aclScalar - alpha2 = aclCreateScalar(&alpha2Value, aclDataType::ACL_FLOAT); - CHECK_RET(alpha2 != nullptr, return ret); - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - std::vector tempscalar{alpha1, alpha2}; - aclScalarList* scalarlist = aclCreateScalarList(tempscalar.data(), tempscalar.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachSubScalarList第一段接口 - ret = aclnnForeachSubScalarListGetWorkspaceSize(tensorListInput, scalarlist, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSubScalarListGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachSubScalarList第二段接口 - ret = aclnnForeachSubScalarList(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSubScalarList failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - aclDestroyScalarList(scalarlist); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclScalar* alpha1 = nullptr; + aclScalar* alpha2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + float alpha1Value = 1.2f; + float alpha2Value = 2.2f; + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建alpha1 aclScalar + alpha1 = aclCreateScalar(&alpha1Value, aclDataType::ACL_FLOAT); + CHECK_RET(alpha1 != nullptr, return ret); + // 创建alpha2 aclScalar + alpha2 = aclCreateScalar(&alpha2Value, aclDataType::ACL_FLOAT); + CHECK_RET(alpha2 != nullptr, return ret); + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + std::vector tempscalar{alpha1, alpha2}; + aclScalarList* scalarlist = aclCreateScalarList(tempscalar.data(), tempscalar.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachSubScalarList第一段接口 + ret = aclnnForeachSubScalarListGetWorkspaceSize( + tensorListInput, scalarlist, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSubScalarListGetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachSubScalarList第二段接口 + ret = aclnnForeachSubScalarList(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachSubScalarList failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + aclDestroyScalarList(scalarlist); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_tan/docs/aclnnForeachTan.md b/foreach/foreach_tan/docs/aclnnForeachTan.md index 1b7a8772..558aa328 100644 --- a/foreach/foreach_tan/docs/aclnnForeachTan.md +++ b/foreach/foreach_tan/docs/aclnnForeachTan.md @@ -17,7 +17,7 @@ - 接口功能:对输入张量列表的每个张量进行正切函数运算。 - 计算公式: - + $$ x = [{x_0}, {x_1}, ... {x_{n-1}}]\\ y = [{y_0}, {y_1}, ... {y_{n-1}}]\\ @@ -33,9 +33,9 @@ ```Cpp aclnnStatus aclnnForeachTanGetWorkspaceSize( - const aclTensorList *x, - const aclTensorList *out, - uint64_t *workspaceSize, + const aclTensorList *x, + const aclTensorList *out, + uint64_t *workspaceSize, aclOpExecutor **executor) ``` @@ -158,7 +158,7 @@ aclnnStatus aclnnForeachTan(
x或out中的Tensor维度超过8维。
- + ## aclnnForeachTan - **参数说明** diff --git a/foreach/foreach_tan/examples/test_aclnn_foreach_tan.cpp b/foreach/foreach_tan/examples/test_aclnn_foreach_tan.cpp index af90d0e7..4469c0a9 100644 --- a/foreach/foreach_tan/examples/test_aclnn_foreach_tan.cpp +++ b/foreach/foreach_tan/examples/test_aclnn_foreach_tan.cpp @@ -14,26 +14,27 @@ #include "aclnnop/aclnn_foreach_tan.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,128 +47,134 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachTan第一段接口 - ret = aclnnForeachTanGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachTanGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachTan第二段接口 - ret = aclnnForeachTan(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachTan failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachTan第一段接口 + ret = aclnnForeachTanGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachTanGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachTan第二段接口 + ret = aclnnForeachTan(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachTan failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_tanh/docs/aclnnForeachTanh.md b/foreach/foreach_tanh/docs/aclnnForeachTanh.md index 25fbaece..e840a96a 100644 --- a/foreach/foreach_tanh/docs/aclnnForeachTanh.md +++ b/foreach/foreach_tanh/docs/aclnnForeachTanh.md @@ -17,7 +17,7 @@ - 接口功能:对输入张量列表的每个张量进行双曲正切函数运算。 - 计算公式: - + $$ x = [{x_0}, {x_1}, ... {x_{n-1}}]\\ y = [{y_0}, {y_1}, ... {y_{n-1}}]\\ @@ -121,7 +121,7 @@ aclnnStatus aclnnForeachTanh( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - + diff --git a/foreach/foreach_tanh/examples/test_aclnn_foreach_tanh.cpp b/foreach/foreach_tanh/examples/test_aclnn_foreach_tanh.cpp index 413fe681..9efb8f0b 100644 --- a/foreach/foreach_tanh/examples/test_aclnn_foreach_tanh.cpp +++ b/foreach/foreach_tanh/examples/test_aclnn_foreach_tanh.cpp @@ -14,26 +14,27 @@ #include "aclnnop/aclnn_foreach_tanh.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& shape) +{ + int64_t shapeSize = 1; + for (auto i : shape) { + shapeSize *= i; + } + return shapeSize; } -int Init(int32_t deviceId, aclrtStream *stream) +int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法,资源初始化 auto ret = aclInit(nullptr); @@ -46,128 +47,134 @@ int Init(int32_t deviceId, aclrtStream *stream) } template -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - std::vector outShape1 = {2, 3}; - std::vector outShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - void* out1DeviceAddr = nullptr; - void* out2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - aclTensor* out1 = nullptr; - aclTensor* out2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - std::vector out1HostData(6, 0); - std::vector out2HostData(3, 0); - - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out1 aclTensor - ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建out2 aclTensor - ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - std::vector tempOutput{out1, out2}; - aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachTanh第一段接口 - ret = aclnnForeachTanhGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachTanhGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachTanh第二段接口 - ret = aclnnForeachTanh(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachTanh failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(outShape1); - std::vector out1Data(size, 0); - ret = aclrtMemcpy(out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, - size * sizeof(out1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); - } - - size = GetShapeSize(outShape2); - std::vector out2Data(size, 0); - ret = aclrtMemcpy(out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, - size * sizeof(out2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - aclDestroyTensorList(tensorListOutput); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - aclrtFree(out1DeviceAddr); - aclrtFree(out2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + std::vector outShape1 = {2, 3}; + std::vector outShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + void* out1DeviceAddr = nullptr; + void* out2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + aclTensor* out1 = nullptr; + aclTensor* out2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + std::vector out1HostData(6, 0); + std::vector out2HostData(3, 0); + + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out1 aclTensor + ret = CreateAclTensor(out1HostData, outShape1, &out1DeviceAddr, aclDataType::ACL_FLOAT, &out1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建out2 aclTensor + ret = CreateAclTensor(out2HostData, outShape2, &out2DeviceAddr, aclDataType::ACL_FLOAT, &out2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + std::vector tempOutput{out1, out2}; + aclTensorList* tensorListOutput = aclCreateTensorList(tempOutput.data(), tempOutput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachTanh第一段接口 + ret = aclnnForeachTanhGetWorkspaceSize(tensorListInput, tensorListOutput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachTanhGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachTanh第二段接口 + ret = aclnnForeachTanh(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachTanh failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(outShape1); + std::vector out1Data(size, 0); + ret = aclrtMemcpy( + out1Data.data(), out1Data.size() * sizeof(out1Data[0]), out1DeviceAddr, size * sizeof(out1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, out1Data[i]); + } + + size = GetShapeSize(outShape2); + std::vector out2Data(size, 0); + ret = aclrtMemcpy( + out2Data.data(), out2Data.size() * sizeof(out2Data[0]), out2DeviceAddr, size * sizeof(out2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, out2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + aclDestroyTensorList(tensorListOutput); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + aclrtFree(out1DeviceAddr); + aclrtFree(out2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +} diff --git a/foreach/foreach_zero_inplace/docs/aclnnForeachZeroInplace.md b/foreach/foreach_zero_inplace/docs/aclnnForeachZeroInplace.md index 03a0bf21..fc1240dd 100644 --- a/foreach/foreach_zero_inplace/docs/aclnnForeachZeroInplace.md +++ b/foreach/foreach_zero_inplace/docs/aclnnForeachZeroInplace.md @@ -110,7 +110,7 @@ aclnnStatus aclnnForeachZeroInplace( aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。 第一段接口完成入参校验,出现以下场景时报错: - +
diff --git a/foreach/foreach_zero_inplace/examples/test_aclnn_foreach_zero_inplace.cpp b/foreach/foreach_zero_inplace/examples/test_aclnn_foreach_zero_inplace.cpp index 6139a8b0..f9206980 100644 --- a/foreach/foreach_zero_inplace/examples/test_aclnn_foreach_zero_inplace.cpp +++ b/foreach/foreach_zero_inplace/examples/test_aclnn_foreach_zero_inplace.cpp @@ -14,138 +14,147 @@ #include "aclnnop/aclnn_foreach_zero_inplace.h" #define CHECK_RET(cond, return_expr) \ - do { \ - if (!(cond)) { \ - return_expr; \ - } \ - } while (0) - -#define LOG_PRINT(message, ...) \ - do { \ - printf(message, ##__VA_ARGS__); \ - } while (0) - -int64_t GetShapeSize(const std::vector& shape) { - int64_t shapeSize = 1; - for (auto i : shape) { - shapeSize *= i; - } - return shapeSize; + do { \ + if (!(cond)) { \ + return_expr; \ + } \ + } while (0) + +#define LOG_PRINT(message, ...) \ + do { \ + printf(message, ##__VA_ARGS__); \ + } while (0) + +int64_t GetShapeSize(const std::vector& 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; +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 -int CreateAclTensor(const std::vector& hostData, const std::vector& 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的strides - std::vector strides(shape.size(), 1); - for (int64_t i = shape.size() - 2; i >= 0; i--) { - strides[i] = shape[i + 1] * strides[i + 1]; - } - - // 调用aclCreateTensor接口创建aclTensor - *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, - shape.data(), shape.size(), *deviceAddr); - return 0; +int CreateAclTensor( + const std::vector& hostData, const std::vector& 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的strides + std::vector strides(shape.size(), 1); + for (int64_t i = shape.size() - 2; i >= 0; i--) { + strides[i] = shape[i + 1] * strides[i + 1]; + } + + // 调用aclCreateTensor接口创建aclTensor + *tensor = aclCreateTensor( + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), + *deviceAddr); + return 0; } -int main() { - // 1. (固定写法)device/stream初始化,参考acl API手册 - // 根据自己的实际device填写deviceId - int32_t deviceId = 0; - aclrtStream stream; - auto ret = Init(deviceId, &stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); - - // 2. 构造输入与输出,需要根据API的接口自定义构造 - std::vector selfShape1 = {2, 3}; - std::vector selfShape2 = {1, 3}; - void* input1DeviceAddr = nullptr; - void* input2DeviceAddr = nullptr; - aclTensor* input1 = nullptr; - aclTensor* input2 = nullptr; - std::vector input1HostData = {1, 2, 3, 4, 5, 6}; - std::vector input2HostData = {7, 8, 9}; - - // 创建input1 aclTensor - ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - // 创建input2 aclTensor - ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); - CHECK_RET(ret == ACL_SUCCESS, return ret); - - std::vector tempInput{input1, input2}; - aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); - - // 3. 调用CANN算子库API,需要修改为具体的API名称 - uint64_t workspaceSize = 0; - aclOpExecutor* executor; - // 调用aclnnForeachZeroInplace第一段接口 - ret = aclnnForeachZeroInplaceGetWorkspaceSize(tensorListInput, &workspaceSize, &executor); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachZeroInplaceGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); - // 根据第一段接口计算出的workspaceSize申请device内存 - void* workspaceAddr = nullptr; - if (workspaceSize > 0) { - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); - } - // 调用aclnnForeachZeroInplace第二段接口 - ret = aclnnForeachZeroInplace(workspaceAddr, workspaceSize, executor, stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachZeroInplace failed. ERROR: %d\n", ret); return ret); - - // 4. (固定写法)同步等待任务执行结束 - ret = aclrtSynchronizeStream(stream); - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); - - // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 - auto size = GetShapeSize(selfShape1); - std::vector self1Data(size, 0); - ret = aclrtMemcpy(self1Data.data(), self1Data.size() * sizeof(self1Data[0]), input1DeviceAddr, - size * sizeof(self1Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out1 result[%ld] is: %f\n", i, self1Data[i]); - } - - size = GetShapeSize(selfShape2); - std::vector self2Data(size, 0); - ret = aclrtMemcpy(self2Data.data(), self2Data.size() * sizeof(self2Data[0]), input2DeviceAddr, - size * sizeof(self2Data[0]), ACL_MEMCPY_DEVICE_TO_HOST); - CHECK_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("out2 result[%ld] is: %f\n", i, self2Data[i]); - } - - // 6. 释放aclTensor,需要根据具体API的接口定义修改 - aclDestroyTensorList(tensorListInput); - - // 7.释放device资源,需要根据具体API的接口定义修改 - aclrtFree(input1DeviceAddr); - aclrtFree(input2DeviceAddr); - if (workspaceSize > 0) { - aclrtFree(workspaceAddr); - } - aclrtDestroyStream(stream); - aclrtResetDevice(deviceId); - aclFinalize(); - return 0; -} \ No newline at end of file +int main() +{ + // 1. (固定写法)device/stream初始化,参考acl API手册 + // 根据自己的实际device填写deviceId + int32_t deviceId = 0; + aclrtStream stream; + auto ret = Init(deviceId, &stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); + + // 2. 构造输入与输出,需要根据API的接口自定义构造 + std::vector selfShape1 = {2, 3}; + std::vector selfShape2 = {1, 3}; + void* input1DeviceAddr = nullptr; + void* input2DeviceAddr = nullptr; + aclTensor* input1 = nullptr; + aclTensor* input2 = nullptr; + std::vector input1HostData = {1, 2, 3, 4, 5, 6}; + std::vector input2HostData = {7, 8, 9}; + + // 创建input1 aclTensor + ret = CreateAclTensor(input1HostData, selfShape1, &input1DeviceAddr, aclDataType::ACL_FLOAT, &input1); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + // 创建input2 aclTensor + ret = CreateAclTensor(input2HostData, selfShape2, &input2DeviceAddr, aclDataType::ACL_FLOAT, &input2); + CHECK_RET(ret == ACL_SUCCESS, return ret); + + std::vector tempInput{input1, input2}; + aclTensorList* tensorListInput = aclCreateTensorList(tempInput.data(), tempInput.size()); + + // 3. 调用CANN算子库API,需要修改为具体的API名称 + uint64_t workspaceSize = 0; + aclOpExecutor* executor; + // 调用aclnnForeachZeroInplace第一段接口 + ret = aclnnForeachZeroInplaceGetWorkspaceSize(tensorListInput, &workspaceSize, &executor); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachZeroInplaceGetWorkspaceSize failed. ERROR: %d\n", ret); + return ret); + // 根据第一段接口计算出的workspaceSize申请device内存 + void* workspaceAddr = nullptr; + if (workspaceSize > 0) { + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); + } + // 调用aclnnForeachZeroInplace第二段接口 + ret = aclnnForeachZeroInplace(workspaceAddr, workspaceSize, executor, stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnForeachZeroInplace failed. ERROR: %d\n", ret); return ret); + + // 4. (固定写法)同步等待任务执行结束 + ret = aclrtSynchronizeStream(stream); + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); + + // 5. 获取输出的值,将device侧内存上的结果复制至host侧,需要根据具体API的接口定义修改 + auto size = GetShapeSize(selfShape1); + std::vector self1Data(size, 0); + ret = aclrtMemcpy( + self1Data.data(), self1Data.size() * sizeof(self1Data[0]), input1DeviceAddr, size * sizeof(self1Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out1 result[%ld] is: %f\n", i, self1Data[i]); + } + + size = GetShapeSize(selfShape2); + std::vector self2Data(size, 0); + ret = aclrtMemcpy( + self2Data.data(), self2Data.size() * sizeof(self2Data[0]), input2DeviceAddr, size * sizeof(self2Data[0]), + ACL_MEMCPY_DEVICE_TO_HOST); + CHECK_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("out2 result[%ld] is: %f\n", i, self2Data[i]); + } + + // 6. 释放aclTensor,需要根据具体API的接口定义修改 + aclDestroyTensorList(tensorListInput); + + // 7.释放device资源,需要根据具体API的接口定义修改 + aclrtFree(input1DeviceAddr); + aclrtFree(input2DeviceAddr); + if (workspaceSize > 0) { + aclrtFree(workspaceAddr); + } + aclrtDestroyStream(stream); + aclrtResetDevice(deviceId); + aclFinalize(); + return 0; +}