×

签到

分享到微信

打开微信,使用扫一扫进入页面后,点击右上角菜单,

点击“发送给朋友”或“分享到朋友圈”完成分享

python调用cnrt接口封装示例 jiapeiyuan2021-07-20 15:39:32 回复 8 查看 经验交流
python调用cnrt接口封装示例
分享到:

  1. 背景

    寒武纪提供的离线模型部署的接口是c++形式的,没有提供python的接口形式。对于某些原本是python构建的应用,无法直接调用cnrt的接口去推理,需要把cnrt的接口封装成python能够调用的接口。以下是python调cnrt接口的一种实现方式。

  2. 实现原理

    通过python的ctypes库来实现。cnrt的接口比较多,涉及设备管理、内存管理、上下文管理、模型信息管理、任务调度管理等接口。如果全部暴露到python接口层面,增加了大量的工作量。这些接口可以进行适当的组合封装,按需暴露必要的高层语义的接口,不仅节省了大量的接口适配适配的工作,还可以让python应用调用推理的流程简化很多。

    1. def test_api2(api_lib, offlinemodel, img_file):
          #1. init handle
          handle = api_lib.cnpyInit(offlinemodel)
      
          #2. prepare input
          img = cv.imread(img_file)
          img_resize = cv.resize(img, (224, 224))
          img2 = img_resize - (104, 117, 124)
          img3 = img2.astype(np.float32)
      
          data = np.asarray(img3, dtype=np.float32)
          input = data.ctypes.data_as(ctypes.c_void_p)
      
          #3. inference
          api_lib.cnpyInference.restype = POINTER(POINTER(c_float))
          output = api_lib.cnpyInference(handle, input)
      
          #4. postprocess
          for i in range(1000):
              if output[0][i] > 0.1:
                  print output.contents[i]
                  
      if __name__ == "__main__":
          ll = ctypes.cdll.LoadLibrary
          api_lib = ll("../../lib/libcnrtapi.so")
      
          offlinemodel = "../../testcase/input/models/resnet50.cambricon".encode()
          image_file = "../../testcase/input/image/0001.jpg"
      
          # test_api(api_lib, offlinemodel, image_file)
          test_api2(api_lib, offlinemodel, image_file)
    2. 接口封装的核心在于c++和python之间的数据结构的转换,因为输入一般情况下是一个,输出可能有多个,所以输入的类型是一级指针(void*),输出是个二级指针(float**)。通过data.ctypes.data_as(ctypes.c_void_p)表达出输入是void*,通过api_lib.cnpyInference.restype = POINTER(POINTER(c_float)) 指示输出是float**。

  3. 代码实现

    1. cnpy.tar.gz


版权所有 © 2022 寒武纪 Cambricon.com 备案/许可证号:京ICP备17003415号-1
关闭