Bind multiple models in a single binary file

Hi,


  We are trying to bind two models in a Kneron binary. These two models should run in pipeline, that is "the input of model 1002 is the output of model 1001". We have already make sure both binaries work fine, separately.


  Now we are trying to run these binaries in a pipeline. Here are our tests:


  Test 1:

  1. Edit batch_compile_input_params.json, like below


{


  "input_image_folder": ["<path_to_pictures_in_model_1001>", "<path_to_pictures_in_model_1002>"],


  "img_channel": ["RGB", "RGB"],


  "model_input_width": [320, 224],


  "model_input_height": [320, 224],


  "img_preprocess_method": ["customized", "none"],


  "input_onnx_file": ["<path_to_pictures_in_model_1001.onnx>", "<path_to_pictures_in_model_1002.onnx>"],


  "keep_aspect_ratio": ["False", "False"],


  "command_addr": "0x30000000",


  "weight_addr": "0x40000000",


  "sram_addr": "0x50000000",


  "dram_addr": "0x60000000",


  "whether_encryption": "No",


  "encryption_key": "0x12345678",


  "model_id_list": [1001, 1002],


  "model_version_list": [1, 1],


  "add_norm_list": ["False", "False"],


  "dedicated_output_buffer": "True"


}


  2. Create Kneron binary by running ./fpAnalyserBatchCompile_520.sh 8 (@kneron/toolchain:520)


  (or 2. Run ./fpAnalyserBatchCompile.sh.x 8 (@kneron/toolchain:linux_command_toolchain)

    And "all_models.bin", "fw_info.bin" are created.


  3. Build and run C++ executable, here is the code snippet:

  ...

  dme_cfg[0].model_id   = 1001;   // model id when compiling in toolchain

  dme_cfg[0].output_num  = 12;    // number of output node for the model

  dme_cfg[0].image_col  = 320;

  dme_cfg[0].image_row  = 320;

  dme_cfg[0].image_ch   = 4;

  dme_cfg[0].image_format = IMAGE_FORMAT_BYPASS_PRE | IMAGE_FORMAT_RAW_OUTPUT;


  dme_cfg[1].model_id   = 1002;   // model id when compiling in toolchain

  dme_cfg[1].output_num  = 3;    // number of output node for the model

  dme_cfg[1].image_col  = 224;

  dme_cfg[1].image_row  = 224;

  dme_cfg[1].image_ch   = 4;

  dme_cfg[1].image_format = IMAGE_FORMAT_BYPASS_PRE | IMAGE_FORMAT_RAW_OUTPUT;


  uint32_t ret_model_id = 0;

{

  uint32_t model_size = 0;

  char data[512];

  int dat_size = 0;

  char* p_buf = NULL;

  uint32_t buf_len = 0;

  uint32_t ret_size = 0;


  //read firmware setup data

  memset(data, 0, sizeof(data));

  int n_len = read_file_to_buf(data, "fw_info.bin", 512);

  if (n_len <= 0) {

    printf("reading fw setup file failed:%d...\n", n_len);

    return -1;

  }


  dat_size = n_len;

  p_buf = new char[5120000];

  memset(p_buf, 0, 5120000);

  n_len = read_file_to_buf(p_buf, "all_models.bin", 5120000);

  if (n_len <= 0) {

    printf("reading model file failed:%d...\n", n_len);

    delete[] p_buf;

    return -1;

  }


  buf_len = n_len;

  model_size = n_len;

  printf("starting DME inference in [serial mode] ...\n");

  int ret = kdp_start_dme(dev_idx, model_size, data, dat_size, &ret_size, p_buf, buf_len);

  if (ret != 0) {

    printf("could not set to DME mode:%d..\n", ret_size);

    delete[] p_buf;

    return -1;

  }


  delete[] p_buf;

  printf("DME mode succeeded...\n");

  usleep(SLEEP_TIME);

}


{

  int dat_size = 0;

  dat_size = sizeof(struct kdp_dme_cfg_s);

  printf("starting DME configure ...\n");

  int ret = kdp_dme_configure(dev_idx, (char *)&dme_cfg[0], dat_size, &ret_model_id);

  if (ret != 0) {

    printf("could not set to DME configure mode..\n");

    return -1;

  }

  printf("DME configure model[%d] succeeded...\n", ret_model_id);

  usleep(SLEEP_TIME);

}

// {

//   int dat_size = 0;

//   dat_size = sizeof(struct kdp_dme_cfg_s);

//   printf("starting DME configure ...\n");

//   int ret = kdp_dme_configure(dev_idx, (char *)&dme_cfg[1], dat_size, &ret_model_id);

//   if (ret != 0) {

//     printf("could not set to DME configure mode..\n");

//     return -1;

//   }

//   printf("DME configure model[%d] succeeded...\n", ret_model_id);

//   usleep(SLEEP_TIME);

// }


  Result: DME configure model[1001] succeeded


  Test 2: Un-comment the "commented part above", the code snippet:

  ...

  dme_cfg[0].model_id   = 1001;   // model id when compiling in toolchain

  dme_cfg[0].output_num  = 12;    // number of output node for the model

  dme_cfg[0].image_col  = 320;

  dme_cfg[0].image_row  = 320;

  dme_cfg[0].image_ch   = 4;

  dme_cfg[0].image_format = IMAGE_FORMAT_BYPASS_PRE | IMAGE_FORMAT_RAW_OUTPUT;


  dme_cfg[1].model_id   = 1002;   // model id when compiling in toolchain

  dme_cfg[1].output_num  = 3;    // number of output node for the model

  dme_cfg[1].image_col  = 224;

  dme_cfg[1].image_row  = 224;

  dme_cfg[1].image_ch   = 4;

  dme_cfg[1].image_format = IMAGE_FORMAT_BYPASS_PRE | IMAGE_FORMAT_RAW_OUTPUT;


  uint32_t ret_model_id = 0;

{

  uint32_t model_size = 0;

  char data[512];

  int dat_size = 0;

  char* p_buf = NULL;

  uint32_t buf_len = 0;

  uint32_t ret_size = 0;


  //read firmware setup data

  memset(data, 0, sizeof(data));

  int n_len = read_file_to_buf(data, "fw_info.bin", 512);

  if (n_len <= 0) {

    printf("reading fw setup file failed:%d...\n", n_len);

    return -1;

  }


  dat_size = n_len;

  p_buf = new char[5120000];

  memset(p_buf, 0, 5120000);

  n_len = read_file_to_buf(p_buf, "all_models.bin", 5120000);

  if (n_len <= 0) {

    printf("reading model file failed:%d...\n", n_len);

    delete[] p_buf;

    return -1;

  }


  buf_len = n_len;

  model_size = n_len;

  printf("starting DME inference in [serial mode] ...\n");

  int ret = kdp_start_dme(dev_idx, model_size, data, dat_size, &ret_size, p_buf, buf_len);

  if (ret != 0) {

    printf("could not set to DME mode:%d..\n", ret_size);

    delete[] p_buf;

    return -1;

  }


  delete[] p_buf;

  printf("DME mode succeeded...\n");

  usleep(SLEEP_TIME);

}


// {

//   int dat_size = 0;

//   dat_size = sizeof(struct kdp_dme_cfg_s);

//   printf("starting DME configure ...\n");

//   int ret = kdp_dme_configure(dev_idx, (char *)&dme_cfg[0], dat_size, &ret_model_id);

//   if (ret != 0) {

//     printf("could not set to DME configure mode..\n");

//     return -1;

//   }

//   printf("DME configure model[%d] succeeded...\n", ret_model_id);

//   usleep(SLEEP_TIME);

// }

{

  int dat_size = 0;

  dat_size = sizeof(struct kdp_dme_cfg_s);

  printf("starting DME configure ...\n");

  int ret = kdp_dme_configure(dev_idx, (char *)&dme_cfg[1], dat_size, &ret_model_id);

  if (ret != 0) {

    printf("could not set to DME configure mode..\n");

    return -1;

  }

  printf("DME configure model[%d] succeeded...\n", ret_model_id);

  usleep(SLEEP_TIME);

}


  Result: could not set to DME configure mode..


  Test 3: switch the model order in batch_compile_input_params.json, the result is switched.


  We suspect that only the first model in the binary works but we don't know why, please help, thanks.


Here is the environment information:

Docker image: kneron/toolchain:linux_command_toolchain

Docker image: kneron/toolchain:520

host_lib__v0.8

Comments

  • I think the issue could be coursed by the old version bug, please update to the latest version and try it again.

    Please refer to Toolchain Manual http://doc.kneron.com/docs/#toolchain/manual/ to pull the latest version of toolchain.

    Download the latest host_lib from our Developers Center https://www.kneron.com/en/support/developers/

  • Hi, Ethon:

    Thanks for your reply. We found the problem. We use another USB dongle and run in two environment: (1) kneron/toolchain:520 + host_lib v0.8 (2) kneron/toolchain:latest + host_lib v0.9 and they work in both cases. We think we should update our firmware in the USB dongle. Now, we can close this issue, thanks.

The discussion has been closed due to inactivity. To continue with the topic, please feel free to post a new discussion.