来自 NNIE_Mapper 的 .wk 文件在运行时 运行 时无效

.wk file from NNIE_Mapper not valid when running for runtime

首先,一些背景:

有 2 个 ML 模型:

  1. 有 50 个输出节点
  2. 有 5 个输出节点

两者都首先使用 https://github.com/dwayo-gh/AER-CNN-KERAS 进行训练,然后使用 https://github.com/uhfband/keras2caffe.git.

转换为 caffemodel

具有 50 个输出节点的模型的故事: 在 Windows10 环境下使用 RuyiStudio,我将 prototxt + 权重转换为 .wk 文件。生成的 .wk 文件的大小为 594112 字节。

然后我将 HiSVP SDK 的 "sample_runtime" 示例修改为 运行 这个新的 .wk 文件(来源如下)。功能模拟效果很好!它给出了输入文件的前 5 个推理结果。

具有 5 个输出节点的模型的故事: 再次使用RuyiStudio,在Win10环境下,我将文件转换为.wk,更改了运行时间源中的路径。生成的 .wk 文件的大小为 329776 字节。以下是我遇到的错误:

Thu Mar 12 11:08:01 2020 I Try to open [nnie_sim.ini] in execute workspace...
Thu Mar 12 11:08:01 2020 W        open [nnie_sim.ini] in execute workspace failure
Thu Mar 12 11:08:01 2020 I Try to open [nnie_sim.ini] in Env NNIE_SIM_INI_DIR...
Thu Mar 12 11:08:01 2020 I        getenv(NNIE_SIM_INI_DIR): C:\Users\admin\Downloads\HiSVP_PC_V1.2.2.2\software\hisilicon ...
Thu Mar 12 11:08:01 2020 I        open [nnie_sim.ini] success(path: C:/Users/admin/Downloads/HiSVP_PC_V1.2.2.2/software/hisilicon/nnie_sim.ini)
Thu Mar 12 11:08:01 2020 I ============= nnie_sim.ini setting ==============
Thu Mar 12 11:08:01 2020 I [LOG_LEVEL]                      DBG
Thu Mar 12 11:08:01 2020 I =================================================


====================start to run====================



=======================File: ..\Release.wav.json.bin==========================


I[HiRT] Runtime version: 1.2.2.7
build sha1: 580506f9
compile date: Aug  9 2019 17:24:44

Runtime WK Length: 329776
I[hirt] Model size: 1 Connector size: 0
E[hirt] invalid wk file, total u32Size(329776) should greater than nnie wk u32Size(329776)
E[hirt] parseNnieWK error
E[hirt] model is loading
E[hirt] addModel error
E[hirt] parseModelAndConnector  error
E[hirt] load group in addGroup by sync error
E[hirt] AddGroup fail
HI_SVPRT_RUNTIME_LoadModelGroup error
SAMPLE_RUNTIME_LoadModelGroup_Aernet failed!
[Total], TIME SPEND: 1503ms

==========run success==========

main.c

#include <stdio.h>
#include <stdlib.h>
#include "string.h"
#ifdef ON_BOARD
#include "mpi_sys.h"
#include "mpi_vb.h"
#else
#include "hi_comm_svp.h"
#include "hi_nnie.h"
#include "mpi_nnie.h"
#include "hi_type.h"
#endif
#include "math.h"
#include "sample_log.h"
#include "sample_save_blob.h"
#include "sample_data_utils.h"
#include "sample_runtime_classify.h"
static HI_VOID SAMPLE_RUNTIME_Usage(const char *pchPrgName)
{
    SAMPLE_LOG_INFO("Usage : %s <filepath>", pchPrgName);
}

#ifdef ON_BOARD
static HI_S32 SAMPLE_COMM_SVP_SysInit(HI_VOID)
{
    HI_MPI_SYS_Exit();
    HI_MPI_VB_Exit();

    VB_CONFIG_S struVbConf = {0};
    struVbConf.u32MaxPoolCnt = 2;
    struVbConf.astCommPool[1].u64BlkSize = 768 * 576 * 2;
    struVbConf.astCommPool[1].u32BlkCnt = 1;

    HI_S32 s32Ret = HI_MPI_VB_SetConfig((const VB_CONFIG_S *)&struVbConf);

    if (s32Ret != HI_SUCCESS) {
        SAMPLE_LOG_INFO("HI_MPI_VB_SetConfig error");
        return HI_FAILURE;
    }

    s32Ret = HI_MPI_VB_Init();

    if (s32Ret != HI_SUCCESS) {
        SAMPLE_LOG_INFO("HI_MPI_VB_Init error");
        return HI_FAILURE;
    }

    s32Ret = HI_MPI_SYS_Init();

    if (s32Ret != HI_SUCCESS) {
        SAMPLE_LOG_INFO("HI_MPI_SYS_Init error");
        return HI_FAILURE;
    }

    return s32Ret;
}

static HI_S32 SAMPLE_COMM_SVP_SysExit(HI_VOID)
{
    HI_S32 s32Ret = HI_MPI_SYS_Exit();

    if (s32Ret != HI_SUCCESS) {
        SAMPLE_LOG_INFO("HI_MPI_SYS_Exit error");
        return HI_FAILURE;
    }

    s32Ret = HI_MPI_VB_Exit();

    if (s32Ret != HI_SUCCESS) {
        SAMPLE_LOG_INFO("HI_MPI_VB_Exit error");
        return HI_FAILURE;
    }

    return HI_SUCCESS;
}
#endif

HI_S32 HandleSampleNet(const HI_CHAR* filename)
{
    HI_S32 ret = HI_FAILURE;
    SAMPLE_LOG_INFO("\n\n=======================File: %s==========================\n\n", filename);
    ret = SAMPLE_AerNet(filename);

    return ret;
}

HI_S32 main(HI_S32 argc, HI_CHAR* argv[])
{
    if ((argc != 2)) {
        SAMPLE_RUNTIME_Usage(argv[0]);
        return HI_FAILURE;
    }

    if (!strncmp(argv[1], "-h", 2)) {
        SAMPLE_RUNTIME_Usage(argv[0]);
        return HI_SUCCESS;
    }

    const HI_CHAR *pcSrcFile = argv[1];

    SAMPLE_LOG_INFO("\n\n====================start to run====================\n");

#ifdef ON_BOARD
    HI_S32 s32Ret = SAMPLE_COMM_SVP_SysInit();
    SAMPLE_CHK_RET(s32Ret != HI_SUCCESS, HI_FAILURE, "SAMPLE_COMM_SVP_SysInit fail");
    s32Ret = HandleSampleNet(pcSrcFile);
#else
    HI_S32 s32Ret = HandleSampleNet(pcSrcFile);
#endif

    SAMPLE_CHK_PRINTF((s32Ret == HI_SUCCESS), "\n==========run success==========\n");
    SAMPLE_CHK_PRINTF((s32Ret != HI_SUCCESS), "\n==========run fail==========\n");

#ifdef ON_BOARD
    s32Ret = SAMPLE_COMM_SVP_SysExit();
    SAMPLE_CHK_RET(s32Ret != HI_SUCCESS, HI_FAILURE, "SAMPLE_COMM_SVP_SysExit fail");
#endif

    return s32Ret;
}

aernet.modelgroup

name: "single_aernet"
priority: 0
max_tmpbuf_size_mb: 4096
align_size: 32

input {
    name: "data"
}

model {
    name: "aernet"
    bottom: {name: "data"}
    top: {name: "dense_2"}
}

sample_runtime_classify.c

#include "sample_runtime_classify.h"
#include <stdio.h>
#include <stdlib.h>
#ifdef ON_BOARD
#include "mpi_sys.h"
#include "mpi_vb.h"
#else
#include "hi_comm_svp.h"
#include "hi_nnie.h"
#include "mpi_nnie.h"
#endif
#include "hi_runtime_api.h"
#include "string.h"
#include "sample_log.h"
#include "sample_runtime_define.h"
#include "sample_memory_ops.h"
#include "sample_data_utils.h"
#include "sample_model_classification.h"

static const HI_U32 ALEXNET_OUTPUT_TOP_FIVE = 5;
const HI_U32 ALEXNET_DEBUG_PRINT_NUM = 10;

static const HI_U32 AERNET_OUTPUT_TOP_FIVE = 5;
const HI_U32 AERNET_DEBUG_PRINT_NUM = 10;

static BlobInfo aer_stSrcBlobInfo = {
    "", "data", "",
    HI_RUNTIME_BLOB_TYPE_S32,
    { 1, 1, 128, 300 },
    HI_TRUE, ALIGN_16
};

static BlobInfo aer_stDstBlobInfo = {
    "aernet", "dense_2", "",
    HI_RUNTIME_BLOB_TYPE_VEC_S32,
    { 1, 50, 1, 1 },
    HI_FALSE, ALIGN_16
};

HI_S32 SAMPLE_RUNTIME_LoadModelGroup_Aernet(const HI_CHAR *pcModelFileAer, HI_RUNTIME_WK_INFO_S *pstWkInfo,
                                             HI_RUNTIME_GROUP_HANDLE *phGroupHandle)
{
    HI_CHAR *pacConfig = NULL;
    HI_RUNTIME_GROUP_INFO_S stGroupInfo = {0};
    memset(&stGroupInfo, 0, sizeof(HI_RUNTIME_GROUP_INFO_S));

    strncpy(pstWkInfo[0].acModelName, "aernet", MAX_NAME_LEN);
    HI_S32 s32Ret = SAMPLE_RUNTIME_LoadModelFile(pcModelFileAer, &(pstWkInfo[0].stWKMemory));
    SAMPLE_CHK_GOTO((s32Ret != HI_SUCCESS), FAIL, "SAMPLE_RUNTIME_LoadModelFile %s failed!", pcModelFileAer);
    stGroupInfo.stWKsInfo.u32WKNum = 1;
    stGroupInfo.stWKsInfo.pstAttrs = &(pstWkInfo[0]);

    SAMPLE_RUNTIME_ReadConfig(CONFIG_DIR "aernet.modelgroup", &pacConfig);
    SAMPLE_CHK_GOTO((pacConfig == NULL), FAIL, "HI_SVPRT_RUNTIME_ReadConfig error");

    s32Ret = HI_SVPRT_RUNTIME_LoadModelGroup(pacConfig, &stGroupInfo, phGroupHandle);
    SAMPLE_CHK_GOTO((s32Ret != HI_SUCCESS), FAIL, "HI_SVPRT_RUNTIME_LoadModelGroup error");

    SAMPLE_LOG_INFO("LoadGroup succ, group handle[%p]", phGroupHandle);

    SAMPLE_FREE(pacConfig);
    return HI_SUCCESS;
FAIL:
    SAMPLE_FREE(pacConfig);
    return HI_FAILURE;
}

HI_S32 SAMPLE_RUNTIME_ForwardGroup_Aernet(const HI_CHAR *pcSrcFile, HI_RUNTIME_GROUP_HANDLE hGroupHandle)
{
    HI_RUNTIME_GROUP_SRC_BLOB_ARRAY_S stGroupSrcBlob = {0};
    HI_RUNTIME_GROUP_DST_BLOB_ARRAY_S stGroupDstBlob = {0};

    strncpy(aer_stSrcBlobInfo.acSrcFilePath, pcSrcFile, sizeof(aer_stSrcBlobInfo.acSrcFilePath));
    aer_stSrcBlobInfo.acSrcFilePath[sizeof(aer_stSrcBlobInfo.acSrcFilePath) - 1] = '[=15=]';
    HI_S32 s32Ret = InitBlobs(&stGroupSrcBlob, 1, &aer_stSrcBlobInfo);
    SAMPLE_CHK_RET(s32Ret != HI_SUCCESS, HI_FAILURE, "InitBlobs fail");
    s32Ret = InitBlobs(&stGroupDstBlob, 1, &aer_stDstBlobInfo);
    SAMPLE_CHK_GOTO(s32Ret != HI_SUCCESS, FAIL_0, "InitBlobs fail");

#if PERFORMANCE_TEST
    struct timespec start, end;
    clock_gettime(0, &start);
#endif

    s32Ret = HI_SVPRT_RUNTIME_ForwardGroupSync(hGroupHandle, &stGroupSrcBlob, &stGroupDstBlob, 0);
    SAMPLE_CHK_GOTO(s32Ret != HI_SUCCESS, FAIL_0, "HI_SVPRT_RUNTIME_ForwardGroupSync failed!");
#if PERFORMANCE_TEST
    clock_gettime(0, &end);
    timeSpendMs(&start, &end, "Forward");
#endif

    SAMPLE_LOG_INFO("Pic: %s", pcSrcFile);
    s32Ret = SAMPLE_RUNTIME_Cnn_TopN_Output(stGroupDstBlob.pstBlobs[0].pstBlob, AERNET_OUTPUT_TOP_FIVE);
    SAMPLE_CHK_PRINTF((s32Ret != HI_SUCCESS), "SAMPLE_RUNTIME_Cnn_TopN_Output error");
#if DEBUG
    printDebugData((HI_CHAR *)"alexnet", stDst[0].u64VirAddr, ALEXNET_DEBUG_PRINT_NUM);
    s32Ret = HI_SUCCESS;
#endif

FAIL_0:
    DeinitBlobs(&stGroupDstBlob);
    DeinitBlobs(&stGroupSrcBlob);
    return s32Ret;
}

HI_S32 SAMPLE_AerNet(HI_CHAR *pcSrcFile)
{
    const HI_CHAR *pcRuntimeModelName = MODEL_AERNET_NAME;

    HI_RUNTIME_GROUP_HANDLE hGroupHandle = HI_NULL;
    HI_RUNTIME_WK_INFO_S astWkInfo[1];

    memset(&astWkInfo[0], 0, sizeof(astWkInfo));

    struct timespec start, next, end;
    clock_gettime(0, &start);

    HI_S32 s32Ret = HI_SVPRT_RUNTIME_Init(CPU_TASK_AFFINITY, NULL);
    SAMPLE_CHK_GOTO(s32Ret != HI_SUCCESS, FAIL_1, "HI_SVPRT_RUNTIME_Init failed!");

    s32Ret = SAMPLE_RUNTIME_LoadModelGroup_Aernet(pcRuntimeModelName, astWkInfo, &hGroupHandle);
    SAMPLE_CHK_GOTO(s32Ret != HI_SUCCESS, FAIL_0, "SAMPLE_RUNTIME_LoadModelGroup_Aernet failed!");

    clock_gettime(0, &end);
    timeSpendMs(&start, &end, "Load");

    s32Ret = SAMPLE_RUNTIME_ForwardGroup_Aernet(pcSrcFile, hGroupHandle);
    SAMPLE_CHK_PRINTF((s32Ret != HI_SUCCESS), "SAMPLE_RUNTIME_ForwardGroup_Alexnet error");

    clock_gettime(0, &next);
    timeSpendMs(&end, &next, "Forward total");

    s32Ret = HI_SVPRT_RUNTIME_UnloadModelGroup(hGroupHandle);
    SAMPLE_CHK_PRINTF((s32Ret != HI_SUCCESS), "HI_SVPRT_RUNTIME_UnloadModelGroup error");

FAIL_0:
    s32Ret = HI_SVPRT_RUNTIME_DeInit();
    SAMPLE_CHK_PRINTF((s32Ret != HI_SUCCESS), "HI_SVPRT_RUNTIME_DeInit error");
    SAMPLE_FreeMem(&(astWkInfo[0].stWKMemory));

    clock_gettime(0, &end);
    timeSpendMs(&start, &end, "Total");
FAIL_1:
    return s32Ret;
}

sample_data_utils.c

/*
 * Copyright (C) Hisilicon Technologies Co., Ltd. 2018-2019. All rights reserved.
 * Description:
 * Author:
 * Create: 2018-05-19
 */

#include "sample_data_utils.h"
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#ifdef _WIN32
#include <Windows.h>
#endif
#include "math.h"
#include "sample_log.h"
#include "sample_memory_ops.h"
#include "sample_save_blob.h"

HI_S32 InitBlobs(HI_RUNTIME_GROUP_BLOB_ARRAY_S *pstGroupBlob, HI_U32 u32BlobNum, BlobInfo *pBlobInfos)
{
    pstGroupBlob->u32BlobNum = u32BlobNum;
    HI_RUNTIME_GROUP_BLOB_S *astGroupBlobs = (HI_RUNTIME_GROUP_BLOB_S *)malloc(
            sizeof(HI_RUNTIME_GROUP_BLOB_S) * u32BlobNum);
    SAMPLE_CHK_RET(astGroupBlobs == HI_NULL, HI_FAILURE, "malloc src group blobs fail");
    pstGroupBlob->pstBlobs = astGroupBlobs;
    HI_RUNTIME_BLOB_S *astBlobs = (HI_RUNTIME_BLOB_S *)malloc(sizeof(HI_RUNTIME_BLOB_S) * u32BlobNum);
    SAMPLE_CHK_GOTO(astBlobs == HI_NULL, FREE_SRC_GRROUP_BLOBS, "malloc src blobs fail");
    memset(astBlobs, 0, sizeof(HI_RUNTIME_BLOB_S) * u32BlobNum);
    for (HI_U32 i = 0; i < u32BlobNum; i++) {
        strncpy(astGroupBlobs[i].acOwnerName, pBlobInfos[i].acOwnerName, MAX_NAME_LEN);
        astGroupBlobs[i].acOwnerName[MAX_NAME_LEN] = 0;
        strncpy(astGroupBlobs[i].acBlobName, pBlobInfos[i].acBlobName, MAX_NAME_LEN);
        astGroupBlobs[i].acBlobName[MAX_NAME_LEN] = 0;
        astGroupBlobs[i].pstBlob = &astBlobs[i];
        HI_S32 s32Ret = SAMPLE_RUNTIME_SetBlob(&astBlobs[i], pBlobInfos[i].enBlobType,
                                               &pBlobInfos[i].stShape,
                                               pBlobInfos[i].u32Align);
        SAMPLE_CHK_GOTO(s32Ret != HI_SUCCESS, FREE_SRC_BLOBS_CONTENT,
                        "SAMPLE_RUNTIME_SetBlob alexnet failed!");

        if (pBlobInfos[i].bIsSrc) {
            s32Ret = SAMPLE_RUNTIME_ReadSrcFile(pBlobInfos[i].acSrcFilePath, &astBlobs[i]);
            SAMPLE_CHK_GOTO(s32Ret != HI_SUCCESS, FREE_SRC_BLOBS_CONTENT,
                            "SAMPLE_RUNTIME_ReadFile failed!");
        } else {
            HI_U32 u32BlobSize = astBlobs[i].u32Stride * astBlobs[i].unShape.stWhc.u32Height *
                                 astBlobs[i].unShape.stWhc.u32Chn *
                                 astBlobs[i].u32Num;
            memset ((HI_VOID *)(uintptr_t)(astBlobs[i].u64VirAddr), 0, u32BlobSize);
        }
    }
    return HI_SUCCESS;
FREE_SRC_BLOBS_CONTENT:
    for (HI_U32 i = 0; i < u32BlobNum; i++) {
        if (astBlobs[i].u64VirAddr != 0) {
            HI_RUNTIME_MEM_S stMem = {0};
            stMem.u64PhyAddr = astBlobs[i].u64PhyAddr;
            stMem.u64VirAddr = astBlobs[i].u64VirAddr;
            SAMPLE_FreeMem(&stMem);
        }
    }
    SAMPLE_FREE(astBlobs);
FREE_SRC_GRROUP_BLOBS:
    SAMPLE_FREE(astGroupBlobs);
    pstGroupBlob->u32BlobNum = 0;
    pstGroupBlob->pstBlobs = HI_NULL;
    return HI_FAILURE;
}

HI_VOID DeinitBlobs(HI_RUNTIME_GROUP_BLOB_ARRAY_S *pstGroupBlob)
{
    if (pstGroupBlob == HI_NULL || pstGroupBlob->pstBlobs == HI_NULL) {
        return;
    }
    HI_RUNTIME_BLOB_S *pstBlobs = pstGroupBlob->pstBlobs[0].pstBlob;
    for (HI_U32 i = 0; i < pstGroupBlob->u32BlobNum; i++) {
        if (pstBlobs[i].u64VirAddr != 0) {
            HI_RUNTIME_MEM_S stMem = {0};
            stMem.u64PhyAddr = pstBlobs[i].u64PhyAddr;
            stMem.u64VirAddr = pstBlobs[i].u64VirAddr;
            SAMPLE_FreeMem(&stMem);
        }
    }
    SAMPLE_FREE(pstBlobs);
    SAMPLE_FREE(pstGroupBlob->pstBlobs);
}

HI_U32 getAlignSize(HI_U32 align, HI_U32 num)
{
    if (align == 0) {
        align = 1;
        SAMPLE_LOG_INFO("getAlignSize input Align == 0, set it to 1 to prevent zero divide");
    }

    return ((num + align - 1) / align * align);
}

HI_VOID SAMPLE_DATA_GetStride(HI_RUNTIME_BLOB_TYPE_E type, HI_U32 width, HI_U32 align, HI_U32 *pStride)
{
    HI_U32 u32Size = 0;

    if ((HI_RUNTIME_BLOB_TYPE_U8 == type) ||
        (HI_RUNTIME_BLOB_TYPE_YVU420SP == type) ||
        (type == HI_RUNTIME_BLOB_TYPE_YVU422SP)) {
        u32Size = sizeof(HI_U8);
    } else {
        u32Size = sizeof(HI_U32);
    }

    *pStride = getAlignSize(align, width * u32Size);
    return;
}

HI_U32 SAMPLE_DATA_GetBlobSize(HI_U32 stride, HI_U32 num, HI_U32 height, HI_U32 chn)
{
    return num * stride * height * chn;
}

HI_VOID printDebugData(const HI_CHAR *pcName, HI_U64 u64VirAddr, HI_U32 u32PrintLine)
{
    HI_U8 *pu8Tmp = HI_NULL;
    SAMPLE_LOG_INFO("\n%s result print start", pcName);
    pu8Tmp = (HI_U8 *)((uintptr_t)(u64VirAddr));

    for (HI_U32 i = 0; i < u32PrintLine; i++) {
        for (HI_U32 j = 0; j < 16; j++) { // Output 15 detection frames
            printf("%02x ", pu8Tmp[i * 16 + j]);
        }

        SAMPLE_LOG_INFO("\n");
    }

    SAMPLE_LOG_INFO("%s result print end\n", pcName);
}

HI_S32 SAMPLE_RUNTIME_HiMemAlloc(HI_RUNTIME_MEM_S *pstMem, HI_BOOL bCached)
{
    pstMem->u64VirAddr = 0;
    HI_S32 s32Ret = SAMPLE_AllocMem(pstMem, bCached);
    SAMPLE_CHK_GOTO(s32Ret != HI_SUCCESS, FAIL_0, "SAMPLE_Utils_AllocMem failed!");

    if (bCached == HI_FALSE) {
        return s32Ret;
    }

    s32Ret = SAMPLE_FlushCache(pstMem);
    SAMPLE_CHK_GOTO(s32Ret != HI_SUCCESS, FAIL_0, "SAMPLE_Utils_FlushCache failed!");

    return s32Ret;
FAIL_0:
    SAMPLE_FreeMem(pstMem);
    return HI_FAILURE;
}

HI_S32 SAMPLE_RUNTIME_HiBlobAlloc(HI_RUNTIME_BLOB_S *pstBlob, HI_U32 u32BlobSize, HI_BOOL bCached)
{
    HI_RUNTIME_MEM_S stMem;
    memset(&stMem, 0, sizeof(stMem));
    stMem.u32Size = u32BlobSize;
    HI_S32 s32Ret = SAMPLE_AllocMem(&stMem, bCached);
    SAMPLE_CHK_GOTO(s32Ret != HI_SUCCESS, FAIL_0, "SAMPLE_Utils_AllocMem failed!");
    pstBlob->u64PhyAddr = stMem.u64PhyAddr;
    pstBlob->u64VirAddr = stMem.u64VirAddr;

    if (bCached == HI_FALSE) {
        return s32Ret;
    }

    memset ((HI_VOID *)((uintptr_t)pstBlob->u64VirAddr), 0, u32BlobSize);

    s32Ret = SAMPLE_FlushCache(&stMem);
    SAMPLE_CHK_GOTO(s32Ret != HI_SUCCESS, FAIL_0, "SAMPLE_Utils_FlushCache failed!");

    return s32Ret;
FAIL_0:
    (HI_VOID)SAMPLE_FreeMem(&stMem);
    return HI_FAILURE;
}

HI_S32 SAMPLE_RUNTIME_LoadModelFile(const HI_CHAR *pcModelFile, HI_RUNTIME_MEM_S *pstMemInfo)
{
    FILE *fp = HI_NULL;
    HI_CHAR acCanonicalPath[PATH_MAX + 1] = {0};

#ifdef _WIN32
    SAMPLE_CHK_RET((strlen(pcModelFile) > PATH_MAX) ||
                   HI_NULL == _fullpath(acCanonicalPath, pcModelFile,
                                        PATH_MAX),
                   HI_FAILURE, "fullpath fail %s", pcModelFile);
#else
    SAMPLE_CHK_RET((strlen(pcModelFile) > PATH_MAX) ||
                   (HI_NULL == realpath(pcModelFile, acCanonicalPath)),
                   HI_FAILURE, "realpath fail %s", pcModelFile);
#endif
    fp = fopen(acCanonicalPath, "rb");
    SAMPLE_CHK_RET(fp == NULL, HI_FAILURE, "Open model file  %s failed!", pcModelFile);

    HI_S32 s32Ret = fseek(fp, 0L, SEEK_END);
    SAMPLE_CHK_GOTO(s32Ret != HI_SUCCESS, CLOSE_FILE, "SAMPLE_RUNTIME_MemAlloc failed!");

    HI_U32 s32RuntimeWkLen = ftell(fp);
    // Divide by 16 to verify that the length of WK is correct
    SAMPLE_CHK_GOTO(0 != s32RuntimeWkLen % 16, CLOSE_FILE, "Runtime WK Len %% 16 != 0 ");

    SAMPLE_LOG_INFO("Runtime WK Length: %d", s32RuntimeWkLen);

    SAMPLE_CHK_GOTO(0 != fseek(fp, 0L, SEEK_SET), CLOSE_FILE, "fseek fail");

    pstMemInfo->u32Size = s32RuntimeWkLen;
    s32Ret = SAMPLE_RUNTIME_HiMemAlloc(pstMemInfo, HI_FALSE);
    SAMPLE_CHK_GOTO(s32Ret != HI_SUCCESS, CLOSE_FILE, "SAMPLE_RUNTIME_MemAlloc failed!");

    s32Ret = (HI_S32)fread((HI_VOID *)((uintptr_t)pstMemInfo->u64VirAddr), s32RuntimeWkLen, 1, fp);
    SAMPLE_CHK_GOTO(s32Ret != 1, FREE_MEM, "Read runtime WK failed!");

    fclose(fp);
    return HI_SUCCESS;
FREE_MEM:
    SAMPLE_FreeMem(pstMemInfo);
CLOSE_FILE:
    fclose(fp);
    return HI_FAILURE;
}

HI_S32 SAMPLE_RUNTIME_SetBlob(HI_RUNTIME_BLOB_S *pstBlob,
                              HI_RUNTIME_BLOB_TYPE_E enType,
                              BlobShape *pstBlobShape,
                              HI_U32 u32Align)
{
    pstBlob->enBlobType = enType;
    pstBlob->u32Num = pstBlobShape->u32Num;
    if (enType == HI_RUNTIME_BLOB_TYPE_VEC_S32) {
        pstBlob->unShape.stWhc.u32Width = pstBlobShape->u32Chn;
        pstBlob->unShape.stWhc.u32Chn = pstBlobShape->u32Width;
    } else {
        pstBlob->unShape.stWhc.u32Width = pstBlobShape->u32Width;
        pstBlob->unShape.stWhc.u32Chn = pstBlobShape->u32Chn;
    }

    pstBlob->unShape.stWhc.u32Height = pstBlobShape->u32Height;
    SAMPLE_DATA_GetStride(enType, pstBlob->unShape.stWhc.u32Width, u32Align, &(pstBlob->u32Stride));
    HI_U64 u64Size = pstBlob->u32Num * pstBlob->u32Stride * pstBlob->unShape.stWhc.u32Height *
                     pstBlob->unShape.stWhc.u32Chn;
    SAMPLE_CHK_RET((u64Size > (HI_U32)-1), HI_FAILURE, "the blobsize is too large [%llu]", u64Size);
    HI_U32 u32BlobSize = SAMPLE_DATA_GetBlobSize(pstBlob->u32Stride, pstBlobShape->u32Num, pstBlobShape->u32Height,
        pstBlob->unShape.stWhc.u32Chn);

    HI_S32 s32Ret = SAMPLE_RUNTIME_HiBlobAlloc(pstBlob, u32BlobSize, HI_TRUE);
    SAMPLE_CHK_RET(s32Ret != HI_SUCCESS, HI_FAILURE, "SAMPLE_Utils_AllocMem failed!");

    return HI_SUCCESS;
}

HI_S32 SAMPLE_RUNTIME_ReadSrcFile(const HI_CHAR acFileName[MAX_FILE_NAME_LENGTH],
    HI_RUNTIME_BLOB_S *pstSrcBlob)
{
    HI_U32 c, h;
    HI_U8 *pu8Ptr = NULL;
    FILE *imgFp = NULL;
    HI_U32 s32Ret = HI_FAILURE;
    HI_RUNTIME_MEM_S stMem;
    HI_CHAR acCanonicalPath[PATH_MAX + 1] = {0};
#ifdef _WIN32
    SAMPLE_CHK_RET((strlen(acFileName) > PATH_MAX) ||
                   HI_NULL == _fullpath(acCanonicalPath, acFileName,
                                        PATH_MAX),
                   HI_FAILURE, "fullpath fail %s", acFileName);
#else
    SAMPLE_CHK_RET((strlen(acFileName) > PATH_MAX) ||
                   (HI_NULL == realpath(acFileName, acCanonicalPath)),
                   HI_FAILURE, "realpath fail %s", acFileName);
#endif
    pu8Ptr = (HI_U8 *)((uintptr_t)(pstSrcBlob->u64VirAddr));
    imgFp = fopen(acCanonicalPath, "rb");
    SAMPLE_CHK_GOTO(imgFp == NULL, FAIL_0, "open img fp error[%s]", acFileName);

    for (c = 0; c < pstSrcBlob->unShape.stWhc.u32Chn; c++) {
        for (h = 0; h < pstSrcBlob->unShape.stWhc.u32Height; h++) {
            s32Ret = (HI_S32)fread(pu8Ptr, pstSrcBlob->unShape.stWhc.u32Width * sizeof(HI_U8), 1, imgFp);
            SAMPLE_CHK_GOTO(s32Ret != 1, FAIL_0, "fread failed, (c,h)=(%d,%d)!", c, h);
            pu8Ptr += pstSrcBlob->u32Stride;
        }
    }

    fclose(imgFp);
    imgFp = HI_NULL;

    HI_U32 u32BlobSize = SAMPLE_DATA_GetBlobSize(pstSrcBlob->u32Stride, pstSrcBlob->u32Num,
                                                 pstSrcBlob->unShape.stWhc.u32Height,
                                                 pstSrcBlob->unShape.stWhc.u32Chn);
    stMem.u64PhyAddr = pstSrcBlob->u64PhyAddr;
    stMem.u64VirAddr = pstSrcBlob->u64VirAddr;
    stMem.u32Size = u32BlobSize;
    s32Ret = SAMPLE_FlushCache(&stMem);
    SAMPLE_CHK_GOTO(s32Ret != HI_SUCCESS, FAIL_0, "SAMPLE_Utils_FlushCache failed!");

    return HI_SUCCESS;
FAIL_0:

    if (imgFp != HI_NULL) {
        fclose(imgFp);
    }

    return HI_FAILURE;
}

HI_S32 SAMPLE_RUNTIME_ReadConfig(const HI_CHAR *pcConfigFile, HI_CHAR **acBuff)
{
    HI_CHAR acCanonicalPath[PATH_MAX + 1] = {0};
    FILE *f = NULL;
    HI_CHAR *tempBuff = NULL;

#ifdef _WIN32
    SAMPLE_CHK_RET((strlen(pcConfigFile) > PATH_MAX) ||
                   HI_NULL == _fullpath(acCanonicalPath, pcConfigFile,
                                        PATH_MAX),
                   HI_FAILURE, "fullpath fail %s", pcConfigFile);
#else
    SAMPLE_CHK_RET((strlen(pcConfigFile) > PATH_MAX) ||
                   (HI_NULL == realpath(pcConfigFile, acCanonicalPath)),
                   HI_FAILURE, "realpath fail %s", pcConfigFile);
#endif
    f = fopen(acCanonicalPath, "r");
    SAMPLE_CHK_RET(f == HI_NULL, HI_FAILURE, "config file %s not exists", acCanonicalPath);

    HI_S32 s32Ret = fseek(f, 0L, SEEK_END);
    SAMPLE_CHK_GOTO(s32Ret != HI_SUCCESS, CLOSE_FILE, "SAMPLE_RUNTIME_ReadConfig Failed");

    HI_S64 s64FileSize = ftell(f);
    SAMPLE_CHK_GOTO(-1 == s64FileSize, CLOSE_FILE, "SAMPLE_RUNTIME_ReadConfig Failed");

    tempBuff = (HI_CHAR *)malloc(s64FileSize + 1);
    SAMPLE_CHK_GOTO(tempBuff == HI_NULL, CLOSE_FILE, "SAMPLE_RUNTIME_ReadConfig Failed");

    rewind(f);
    size_t readSize = fread(tempBuff, 1, s64FileSize, f);
    if (((HI_S64)readSize != s64FileSize) && !feof(f)) {
        SAMPLE_FREE(tempBuff);
        *acBuff = NULL;
        fclose(f);
        return HI_FAILURE;
    }
    tempBuff[readSize] = '[=16=]';
    *acBuff = tempBuff;
    fclose(f);
    return HI_SUCCESS;

CLOSE_FILE:
    fclose(f);
    return HI_FAILURE;
}


sample_memory_ops.c

/*
 * Copyright (C) Hisilicon Technologies Co., Ltd. 2018-2019. All rights reserved.
 * Description:
 * Author:
 * Create: 2018-05-19
 */

#include "sample_memory_ops.h"
#include <stdlib.h>
#ifdef ON_BOARD
#include "mpi_sys.h"
#endif
#include "sample_log.h"

HI_S32 SAMPLE_AllocMem(HI_RUNTIME_MEM_S *pstMemInfo, HI_BOOL bCached)
{
//    SAMPLE_CHK_RET((pstMemInfo == HI_NULL), HI_FAILURE, "param pstMemInfo is NULL");
//    SAMPLE_CHK_RET((HI_NULL == pstMemInfo->u64PhyAddr), HI_FAILURE, "param u64PhyAddr is 0");
#ifdef ON_BOARD
    HI_S32 s32Ret = HI_SUCCESS;
    if (bCached) {
        s32Ret = HI_MPI_SYS_MmzAlloc_Cached(&pstMemInfo->u64PhyAddr,
                                            (HI_VOID **)&(pstMemInfo->u64VirAddr), NULL, HI_NULL,
                                            pstMemInfo->u32Size);
    } else {
        s32Ret = HI_MPI_SYS_MmzAlloc(&pstMemInfo->u64PhyAddr, (HI_VOID **)&(pstMemInfo->u64VirAddr), NULL, HI_NULL,
                                     pstMemInfo->u32Size);
    }
#else
    pstMemInfo->u64VirAddr = (HI_U32)((uintptr_t)malloc(pstMemInfo->u32Size));
    HI_S32 s32Ret = pstMemInfo->u64VirAddr == 0 ? HI_FAILURE : HI_SUCCESS;
    pstMemInfo->u64PhyAddr = pstMemInfo->u64VirAddr;
#endif

    return s32Ret;
}

HI_S32 SAMPLE_FlushCache(HI_RUNTIME_MEM_S *pstMemInfo)
{
    SAMPLE_CHK_RET((pstMemInfo->u64VirAddr == 0), HI_FAILURE, "param pu8VirAddr is NULL");
#ifdef ON_BOARD
    return HI_MPI_SYS_MmzFlushCache(pstMemInfo->u64PhyAddr, (HI_VOID *)((uintptr_t)pstMemInfo->u64VirAddr),
                                    pstMemInfo->u32Size);
#endif
    return HI_SUCCESS;
}

HI_S32 SAMPLE_FreeMem(HI_RUNTIME_MEM_S *pstMemInfo)
{
    SAMPLE_CHK_RET((pstMemInfo->u64VirAddr == 0), HI_FAILURE, "param pu8VirAddr is NULL");
#ifdef ON_BOARD
    return HI_MPI_SYS_MmzFree (pstMemInfo->u64PhyAddr, (HI_VOID *)((uintptr_t)pstMemInfo->u64VirAddr));
#else
    free ((HI_U8 *)((uintptr_t) pstMemInfo->u64VirAddr));
    pstMemInfo->u64PhyAddr = 0;
    pstMemInfo->u64VirAddr = 0;
#endif
    return HI_SUCCESS;
}

WK 文件 有 50 个输出:https://drive.google.com/file/d/1chePxF3j3KF4KvFvhRGGUKQz7ZDipeBx/view?usp=sharing

有 5 个输出:https://drive.google.com/file/d/1chePxF3j3KF4KvFvhRGGUKQz7ZDipeBx/view?usp=sharing

问题

这是什么错误?我在哪里分配 RAM 失败?这是模拟器吗error/bug?

创建的 .wk 使用 NNIE_Mapper 生成的格式不可用于运行时模拟。

在RuyiStudio中创建类型为"Runtime"的项目,或在Linux下使用runtime_mapper生成有效的.wk并解决问题![​​=13=]

希望错误消息更好,但是哦,好吧!

感谢 Telegram 上的 OpenPIC 社区!