【求助】调用示例AddCustom, 执行aclopInferShape [core dumped], (去掉aclopInferShape可以调用成功,结果也是正确的。)
收藏回复举报
【求助】调用示例AddCustom, 执行aclopInferShape [core dumped], (去掉aclopInferShape可以调用成功,结果也是正确的。)
t('forum.solved') 已解决
发表于2024-03-04 09:48:58
0 查看

om描述

[
    {
        "op": "AddCustom",
        "input_desc": [
            {
                "name": "x",
                "param_type": "required",
                "format": "ND",
                "shape": [-1, -1],
                "shape_range": [[1,-1],[1,-1]],
                "type": "int32"
            },
            {
                "name": "y",
                "param_type": "required",
                "format":"ND",
                "shape": [-1, -1],
                "shape_range": [[1,-1],[1,-1]],
                "type": "int32"
            }
        ],
        "output_desc": [
            {
                "name": "z",
                "param_type": "required",
                "format":  "ND",
                "shape": [-1, -1],
                "shape_range": [[1,-1],[1,-1]],
                "type": "int32"
            }
        ]
    }
]

main.cpp

#include <iostream>
#include <vector>
#include "acl/acl.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)

// 将shape相乘
int64_t GetShapeSize(const std::vector<int64_t>& shape) {
    int64_t shapeSize = 1;
    for (auto i : shape) {
        shapeSize *= i;
    }
    return shapeSize;
}

int Init(int32_t deviceId, aclrtContext* context, aclrtStream* stream) {
    // 设置Device
    auto ret = aclrtSetDevice(deviceId);
    CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSetDevice failed. ERROR: %d\n", ret); return ret);
    // 创建Context
    ret = aclrtCreateContext(context, deviceId);
    CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtCreateContext failed. ERROR: %d\n", ret); return ret);
    // 设置Context
    ret = aclrtSetCurrentContext(*context);
    CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSetCurrentContext failed. ERROR: %d\n", ret); return ret);
    // 设置Stream
    ret = aclrtCreateStream(stream);
    CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtCreateStream failed. ERROR: %d\n", ret); return ret);
    // 执行初始化
    ret = aclInit(nullptr);
    CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclInit failed. ERROR: %d\n", ret); return ret);
    return 0;
}

// 创建AclTensor
template <typename T>
int Copy2Device(
    const std::vector<T>& hostData,    // 主机数据(input)
    void** deviceAddr                 // 设备上的地址指针(output)
){
    // 计算总共需要躲到byte的内存
    auto size = hostData.size() * 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);
    return 0;
}


#define TARGET_DATA_TYPE int32_t
#define TARGET_ASCEND_DATA_TYPE aclDataType::ACL_INT32
int main(int argc, char* argv[]) {
    // 1.(固定写法)device/context/stream初始化
    // 根据自己的实际device填写deviceId
    int32_t deviceId = 0;
    aclrtContext context;
    aclrtStream stream;
    // 初始化
    auto ret = Init(deviceId, &context, &stream);
    CHECK_RET(ret == 0, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret);
    
    // 2.构造输入与输出,需要根据API的接口自定义构造
    // Tensor shape
    std::vector<int64_t> xShape = {8, 1024};
    auto yShape = xShape;
    decltype(xShape) zShape = {8, 1024};
    auto size = GetShapeSize(xShape);
    auto byte_size = size * sizeof(TARGET_DATA_TYPE);
    
    // device地址
    void* xDeviceAddr = nullptr;
    void* yDeviceAddr = nullptr;
    void* zDeviceAddr = nullptr;
    
    // host侧数据
    std::vector<TARGET_DATA_TYPE> xHostData(size, 1);
    std::vector<TARGET_DATA_TYPE> yHostData(size, 2);
    std::vector<TARGET_DATA_TYPE> zHostData(size, 0);
    
    // 拷贝数据
    ret = Copy2Device(xHostData, &xDeviceAddr);
    CHECK_RET(ret == ACL_SUCCESS, return ret);
    ret = Copy2Device(yHostData,  &yDeviceAddr);
    CHECK_RET(ret == ACL_SUCCESS, return ret);
    ret = Copy2Device(zHostData, &zDeviceAddr);
    CHECK_RET(ret == ACL_SUCCESS, return ret);
    
    // 读取算子
    ret = aclopSetModelDir(argv[1]);
    CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclopSetModelDir failed. ERROR: %d\n", ret); return ret);
    
    // 创建数据描述
    auto desc = aclCreateTensorDesc(
        TARGET_ASCEND_DATA_TYPE, 
        xShape.size(), 
        xShape.data(), 
        aclFormat::ACL_FORMAT_ND
    );
    
    auto desc_output = aclCreateTensorDesc(
        TARGET_ASCEND_DATA_TYPE, 
        zShape.size(), 
        zShape.data(), 
        aclFormat::ACL_FORMAT_ND
    );
   
    // 创建描述列表
    std::vector<decltype(desc)> input_descs = {desc, desc};
    std::vector<decltype(desc)> output_descs = {desc_output};
    
    // 创建databuffer
    auto x_buffer = aclCreateDataBuffer(xDeviceAddr, byte_size);
    auto y_buffer = aclCreateDataBuffer(yDeviceAddr, byte_size);
    auto z_buffer = aclCreateDataBuffer(zDeviceAddr, byte_size);
    
    // 创建buffer列表
    std::vector<decltype(x_buffer)> input_buffers = {x_buffer, y_buffer};
    std::vector<decltype(z_buffer)> output_buffers = {z_buffer};
    auto opType = "AddCustom";
    LOG_PRINT("执行aclopInferShape\n");
    ret = aclopInferShape(
        opType, 
        input_descs.size(), 
        input_descs.data(), 
        input_buffers.data(),                 
        output_descs.size(), 
        output_descs.data(), 
        nullptr
    );
    LOG_PRINT("执行aclopInferShape结束\n");
    CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclopInferShape failed. ERROR: %d\n", ret); return ret);
//     // inferShape之后的输出tensor的Shape
//     std::vector<std::vector<int64_t>> tensorDims; 
//     // 循环算子的每一个输出,推导或预估Shape值:
//     for (int index = 0; index < output_descs.size(); ++index) {
//         std::vector<int64_t> dimSize; // 表示执行算子时,输出的shape
//         size_t dimNums = aclGetTensorDescNumDims(output_descs[index]);
//             // 表示动态Shape场景下维度个数未知,该场景预留
//         if (dimNums == ACL_UNKNOWN_RANK)  {
//             // 由用户预估最大Shape值max shape
//             dimSize.push_back(5);
//         } else {
//             for (size_t i = 0; i < dimNums; ++i) {
//                 int64_t dim;
//                 ret = aclGetTensorDescDimV2(output_descs[index], i, &dim);
//                 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclGetTensorDescDimV2 failed. ERROR: %d\n", ret); return ret);
//                 // 表示动态Shape场景下维度值是动态的
//                 if(dim == -1) {
//                     int64_t dimRange[2];
//                     // 获取Shape范围,使用该范围中的Shape最大值来构造输出tensorDesc,作为aclopExecuteV2的输入
//                     ret = aclGetTensorDescDimRange(output_descs[index], i, 2, dimRange);
//                     CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclGetTensorDescDimRange failed. ERROR: %d\n", ret); return ret);
//                     dim = dimRange[1];
//                 }
//                 dimSize.push_back(dim);
//             }
//         }
//         tensorDims.push_back(dimSize);
//     }
    
    // 执行算子
    ret = aclopExecuteV2(
        opType, 
        input_descs.size(), 
        input_descs.data(), 
        input_buffers.data(),                 
        output_descs.size(), 
        output_descs.data(), 
        output_buffers.data(), 
        nullptr, 
        stream
    );
    CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclopExecuteV2 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的接口定义修改
    ret = aclrtMemcpy(
        zHostData.data(), 
        byte_size, 
        zDeviceAddr, 
        byte_size,
        ACL_MEMCPY_DEVICE_TO_HOST
    );
    CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("copy result from device to host failed. ERROR: %d\n", ret); return ret);
//     for (int64_t i = 0; i < size; i++) {
//         LOG_PRINT("result[%ld] is: %d\n", i, zHostData[i]);
//     }
    LOG_PRINT("result[%ld] is: %d\n", 0, zHostData[0]);
    
    aclDestroyTensorDesc(desc);
    aclDestroyTensorDesc(desc_output);
    aclDestroyDataBuffer(x_buffer);
    aclDestroyDataBuffer(y_buffer);
    aclDestroyDataBuffer(z_buffer);

    // 7.释放device资源,需要根据具体API的接口定义修改
    aclrtFree(xDeviceAddr);
    aclrtFree(yDeviceAddr);
    aclrtFree(zDeviceAddr);

    aclrtDestroyStream(stream);
    aclrtDestroyContext(context);
    aclrtResetDevice(deviceId);
    aclFinalize();
    return 0;
}

编译后,执行

./bin/om_test_dynamic ../op_om/
执行aclopInferShape
Segmentation fault (core dumped)

本帖最后由 匿名用户2024/03/04 09:57:04 编辑

我要发帖子