diff --git a/operator/ascendc/tutorials/AddCustomSample/FrameworkLaunch/AclNNInvocationNaive/gen_data.py b/operator/ascendc/tutorials/AddCustomSample/FrameworkLaunch/AclNNInvocationNaive/gen_data.py new file mode 100644 index 0000000000000000000000000000000000000000..53f4bcdef86f16b4a40311115a2d222835217afc --- /dev/null +++ b/operator/ascendc/tutorials/AddCustomSample/FrameworkLaunch/AclNNInvocationNaive/gen_data.py @@ -0,0 +1,19 @@ +#!/usr/bin/python3 +# -*- coding:utf-8 -*- +# Copyright 2022-2023 Huawei Technologies Co., Ltd +import numpy as np +import os + +def gen_golden_data_simple(): + input_x = np.random.uniform(1, 100, [8,2048]).astype(np.float16) + input_y = np.random.uniform(1, 100, [8,2048]).astype(np.float16) + golden = (input_x + input_y).astype(np.float16) + + os.system("mkdir -p input") + os.system("mkdir -p output") + input_x.tofile("./input/input_x.bin") + input_y.tofile("./input/input_y.bin") + golden.tofile("./output/golden.bin") + +if __name__ == "__main__": + gen_golden_data_simple() diff --git a/operator/ascendc/tutorials/AddCustomSample/FrameworkLaunch/AclNNInvocationNaive/main.cpp b/operator/ascendc/tutorials/AddCustomSample/FrameworkLaunch/AclNNInvocationNaive/main.cpp index ead2fac0cd012525075aaf499b2efccf13640cca..6f671c28ce970dfc19aa834c57370f2e4e735961 100644 --- a/operator/ascendc/tutorials/AddCustomSample/FrameworkLaunch/AclNNInvocationNaive/main.cpp +++ b/operator/ascendc/tutorials/AddCustomSample/FrameworkLaunch/AclNNInvocationNaive/main.cpp @@ -11,7 +11,11 @@ #include #include #include +#include +#include +#include +#include #include "acl/acl.h" #include "aclnn_add_custom.h" @@ -29,7 +33,7 @@ do { \ printf(message, ##__VA_ARGS__); \ } while (0) - +#define ERROR_LOG(fmt, args...) fprintf(stderr, "[ERROR] " fmt "\n", ##args) int64_t GetShapeSize(const std::vector &shape) { int64_t shapeSize = 1; @@ -39,6 +43,69 @@ int64_t GetShapeSize(const std::vector &shape) return shapeSize; } +bool ReadFile(const std::string &filePath, size_t fileSize, void *buffer, size_t bufferSize) +{ + struct stat sBuf; + int fileStatus = stat(filePath.data(), &sBuf); + if (fileStatus == -1) { + ERROR_LOG("failed to get file %s", filePath.c_str()); + return false; + } + if (S_ISREG(sBuf.st_mode) == 0) { + ERROR_LOG("%s is not a file, please enter a file", filePath.c_str()); + return false; + } + + std::ifstream file; + file.open(filePath, std::ios::binary); + if (!file.is_open()) { + ERROR_LOG("Open file failed. path = %s", filePath.c_str()); + return false; + } + + std::filebuf *buf = file.rdbuf(); + size_t size = buf->pubseekoff(0, std::ios::end, std::ios::in); + if (size == 0) { + ERROR_LOG("file size is 0"); + file.close(); + return false; + } + if (size > bufferSize) { + ERROR_LOG("file size is larger than buffer size"); + file.close(); + return false; + } + buf->pubseekpos(0, std::ios::in); + buf->sgetn(static_cast(buffer), size); + fileSize = size; + file.close(); + return true; +} + +bool WriteFile(const std::string &filePath, const void *buffer, size_t size) +{ + if (buffer == nullptr) { + ERROR_LOG("Write file failed. buffer is nullptr"); + return false; + } + + int fd = open(filePath.c_str(), O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWRITE); + if (fd < 0) { + ERROR_LOG("Open file failed. path = %s", filePath.c_str()); + return false; + } + + size_t writeSize = write(fd, buffer, size); + (void)close(fd); + if (writeSize != size) { + ERROR_LOG("Write file Failed."); + return false; + } + + return true; +} + + int Init(int32_t deviceId, aclrtStream *stream) { // Fixed code, acl initialization @@ -114,11 +181,13 @@ int main(int argc, char **argv) std::vector inputXHostData(inputXShape[0] * inputXShape[1]); std::vector inputYHostData(inputYShape[0] * inputYShape[1]); std::vector outputZHostData(outputZShape[0] * outputZShape[1]); - for (int i = 0; i < inputXShape[0] * inputXShape[1]; ++i) { - inputXHostData[i] = aclFloatToFloat16(1.0); - inputYHostData[i] = aclFloatToFloat16(2.0); - outputZHostData[i] = aclFloatToFloat16(0.0); - } + size_t fileSize = 0; + size_t date_type=2; + void ** input1=(void **)(&inputXHostData); + void ** input2=(void **)(&inputYHostData); + ReadFile("../input/input_x.bin", fileSize, *input1, inputXShape[0] * inputXShape[1]*date_type); + ReadFile("../input/input_y.bin", fileSize, *input2, inputYShape[0] * inputYShape[1]*date_type); + std::vector tensors = {inputX, inputY, outputZ}; std::vector deviceAddrs = {inputXDeviceAddr, inputYDeviceAddr, outputZDeviceAddr}; // Create inputX aclTensor @@ -161,25 +230,16 @@ int main(int argc, char **argv) std::vector resultData(size, 0); ret = aclrtMemcpy(resultData.data(), resultData.size() * sizeof(resultData[0]), outputZDeviceAddr, size * sizeof(aclFloat16), ACL_MEMCPY_DEVICE_TO_HOST); + + void ** output1=(void **)(&resultData); + + WriteFile("../output/output_z.bin", *output1, size*date_type); CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("copy result from device to host failed. ERROR: %d\n", ret); DestroyResources(tensors, deviceAddrs, stream, deviceId, workspaceAddr); return FAILED); // 6. Detroy resources, need to modify according to the interface of the API DestroyResources(tensors, deviceAddrs, stream, deviceId, workspaceAddr); - // print the output result - std::vector goldenData(size, aclFloatToFloat16(3.0)); - - LOG_PRINT("result is:\n"); - for (int64_t i = 0; i < 10; i++) { - LOG_PRINT("%.1f ", aclFloat16ToFloat(resultData[i])); - } - LOG_PRINT("\n"); - if (std::equal(resultData.begin(), resultData.end(), goldenData.begin())) { - LOG_PRINT("test pass\n"); - } else { - LOG_PRINT("test failed\n"); - return FAILED; - } + return SUCCESS; } diff --git a/operator/ascendc/tutorials/AddCustomSample/FrameworkLaunch/AclNNInvocationNaive/run.sh b/operator/ascendc/tutorials/AddCustomSample/FrameworkLaunch/AclNNInvocationNaive/run.sh index 7abad744e9245564546a2b97d8b1bba68b659dd5..d51fde25c2ea304519c160060dbb5ecc0791106d 100644 --- a/operator/ascendc/tutorials/AddCustomSample/FrameworkLaunch/AclNNInvocationNaive/run.sh +++ b/operator/ascendc/tutorials/AddCustomSample/FrameworkLaunch/AclNNInvocationNaive/run.sh @@ -12,15 +12,34 @@ else fi source $_ASCEND_INSTALL_PATH/bin/setenv.bash export DDK_PATH=$_ASCEND_INSTALL_PATH -export NPU_HOST_LIB=$_ASCEND_INSTALL_PATH/$(arch)-$(uname -s | tr '[:upper:]' '[:lower:]')/devlib +export NPU_HOST_LIB=$_ASCEND_INSTALL_PATH/lib64 +rm -rf $HOME/ascend/log/* +rm ./input/*.bin +rm ./output/*.bin + +python3 gen_data.py + +if [ $? -ne 0 ]; then + echo "ERROR: generate input data failed!" + return 1 +fi +echo "INFO: generate input data success!" set -e rm -rf build mkdir -p build -cmake -B build -DCMAKE_SKIP_RPATH=TRUE +cmake -B build cmake --build build -j ( cd build - export LD_LIBRARY_PATH=$_ASCEND_INSTALL_PATH/opp/vendors/customize/op_api/lib:$LD_LIBRARY_PATH ./execute_add_op ) +ret=`python3 verify_result.py output/output_z.bin output/golden.bin` +echo $ret +if [ "x$ret" == "xtest pass" ]; then + echo "" + echo "#####################################" + echo "INFO: you have passed the Precision!" + echo "#####################################" + echo "" +fi \ No newline at end of file diff --git a/operator/ascendc/tutorials/AddCustomSample/FrameworkLaunch/AclNNInvocationNaive/verify_result.py b/operator/ascendc/tutorials/AddCustomSample/FrameworkLaunch/AclNNInvocationNaive/verify_result.py new file mode 100644 index 0000000000000000000000000000000000000000..2528c9f0722286d07be23d4c4737c730aa5d58da --- /dev/null +++ b/operator/ascendc/tutorials/AddCustomSample/FrameworkLaunch/AclNNInvocationNaive/verify_result.py @@ -0,0 +1,23 @@ +import os +import sys +import numpy as np + +loss = 1e-3 # 容忍偏差,一般fp16要求绝对误差和相对误差均不超过千分之一 +minimum = 10e-10 + +def verify_result(real_result, golden): + real_result = np.fromfile(real_result, dtype=np.float16) # 从bin文件读取实际运算结果 + golden = np.fromfile(golden, dtype=np.float16) # 从bin文件读取预期运算结果 + result = np.abs(real_result - golden) # 计算运算结果和预期结果偏差 + deno = np.maximum(np.abs(real_result), np.abs(golden)) # 获取最大值并组成新数组 + result_atol = np.less_equal(result, loss) # 计算绝对误差 + result_rtol = np.less_equal(result / np.add(deno, minimum), loss) # 计算相对误差 + if not result_rtol.all() and not result_atol.all(): + if np.sum(result_rtol == False) > real_result.size * loss and np.sum(result_atol == False) > real_result.size * loss: # 误差超出预期时返回打印错误,返回对比失败 + print("[ERROR] result error") + return False + print("test pass") + return True + +if __name__ == '__main__': + verify_result(sys.argv[1],sys.argv[2])