# Neural Network Runtime设备接入指导 ## 概述 ### 功能简介 NNRt(Neural Network Runtime,神ç»ç½‘络è¿è¡Œæ—¶ï¼‰æ˜¯é¢å‘AI领域的跨芯片推ç†è®¡ç®—è¿è¡Œæ—¶ï¼Œä½œä¸ºä¸é—´æ¡¥æ¢è¿žé€šä¸Šå±‚AIæŽ¨ç†æ¡†æž¶å’Œåº•å±‚åŠ é€ŸèŠ¯ç‰‡ï¼Œå®žçŽ°AI模型的跨芯片推ç†è®¡ç®—。 NNRt开放了设备接å£ï¼ŒèŠ¯ç‰‡åŽ‚å•†é€šè¿‡è®¾å¤‡æŽ¥å£å°†ä¸“æœ‰åŠ é€ŸèŠ¯ç‰‡æŽ¥å…¥NNRt,从而实现与OpenHarmony社区生æ€çš„对接。以下内容将介ç»èŠ¯ç‰‡å¦‚ä½•æŽ¥å…¥NNRt。 ### 基本概念 在开å‘å‰ï¼Œå¼€å‘者需è¦å…ˆäº†è§£ä»¥ä¸‹æ¦‚念,以便更好地ç†è§£å…¨æ–‡å†…容: - HDI(Hardware Device Interface):OpenHarmony硬件设备接å£ï¼Œå®šä¹‰ç³»ç»Ÿä¸è·¨è¿›ç¨‹é€šä¿¡çš„æŽ¥å£ï¼Œå®žçްæœåŠ¡é—´çš„è·¨è¿›ç¨‹é€šä¿¡ã€‚ - IDL(Interface Description Languageï¼‰ï¼šæŽ¥å£æè¿°è¯è¨€ï¼Œæ˜¯HDI接å£çš„è¯è¨€æ ¼å¼ã€‚ ### 约æŸä¸Žé™åˆ¶ - 系统版本:OpenHarmony主干版本。 - å¼€å‘环境:Ubuntu 18.04åŠä»¥ä¸Šã€‚ - 接入设备:具备AI计算能力的芯片。 ### è¿ä½œæœºåˆ¶ NNRt通过HDI接å£å®žçŽ°ä¸Žè®¾å¤‡èŠ¯ç‰‡çš„å¯¹æŽ¥ï¼Œç”±HDI接å£å®žçŽ°è·¨è¿›ç¨‹é€šä¿¡ã€‚ **图1** NNRt架构图  整个架构主è¦åˆ†ä¸ºä¸‰å±‚,AI应用在应用层,AIæŽ¨ç†æ¡†æž¶å’ŒNNRt在系统层,设备æœåŠ¡åœ¨èŠ¯ç‰‡å±‚ã€‚AI应用如果è¦ä½¿ç”¨AIä¸“ç”¨åŠ é€ŸèŠ¯ç‰‡è¿›è¡Œæ¨¡åž‹æŽ¨ç†ï¼Œéœ€è¦ç»è¿‡AIæŽ¨ç†æ¡†æž¶å’ŒNNRtæ‰èƒ½è°ƒç”¨åˆ°åº•层AIä¸“ç”¨åŠ é€ŸèŠ¯ç‰‡ï¼ŒNNRt就是负责适é…底层å„ç§AIä¸“ç”¨åŠ é€ŸèŠ¯ç‰‡çš„ä¸é—´å±‚。NNRtå¼€æ”¾äº†æ ‡å‡†ç»Ÿä¸€çš„HDI设备接å£ï¼Œä¼—多AIä¸“ç”¨åŠ é€ŸèŠ¯ç‰‡éƒ½å¯ä»¥é€šè¿‡HDIæŽ¥å£æŽ¥å…¥OpenHarmony。æ¤å¤–NNRtä¹Ÿå¼€æ”¾äº†æ ‡å‡†ç»Ÿä¸€çš„æŽ¥å£å¯¹æŽ¥ä¸Šå±‚å„ç§AIæŽ¨ç†æ¡†æž¶ã€‚ 程åºè¿è¡Œæ—¶ï¼ŒAI应用ã€AIæŽ¨ç†æ¡†æž¶ã€NNRt都è¿è¡Œåœ¨ç”¨æˆ·è¿›ç¨‹ä¸ï¼Œåº•层AI芯片设备æœåŠ¡è¿è¡Œåœ¨HDIæœåŠ¡è¿›ç¨‹ä¸ã€‚NNRtæ ¹æ®HDI接å£å®žçŽ°äº†HDI Client,æœåŠ¡ç«¯ä¹Ÿéœ€è¦æ ¹æ®HDI接å£å®žçްHDI Service,两者通过OpenHarmonyæ ‡å‡†çš„HDFå系统实现跨进程通信。 ## 开呿Œ‡å¯¼ ### åœºæ™¯ä»‹ç» å½“éœ€è¦å°†ä¸€æ¬¾AIåŠ é€ŸèŠ¯ç‰‡æŽ¥å…¥NNRt的时候,å¯ä»¥å‚考下文。下文以RK3568芯片为例,展示RK3568 CPU如何通过NNRtçš„V2.0版本HDIæŽ¥å£æŽ¥å…¥NNRt,并完æˆAI模型推ç†ã€‚V1.0版本HDIæŽ¥å£æŽ¥å…¥NNRtçš„æµç¨‹ä¸Žæ¤ç±»ä¼¼ã€‚ > ä¾èµ–说明:该教程展示的RK3568 CPU接入NNRt并没有真æ£å®žçްCPU的驱动,而是借用了MindSpore Liteçš„runtimeå’ŒCPUç®—åï¼Œå› æ¤ä¼šä¾èµ–MindSpore Lite的动æ€åº“以åŠå¤´æ–‡ä»¶ã€‚å®žé™…å¼€å‘æ—¶å¹¶ä¸éœ€è¦ä¾èµ–MindSpore Lite的任何库或者头文件。 ### 开呿µç¨‹ AIä¸“ç”¨åŠ é€ŸèŠ¯ç‰‡æŽ¥å…¥NNRt的整体æµç¨‹å¦‚下: **图2** AIä¸“ç”¨åŠ é€ŸèŠ¯ç‰‡æŽ¥å…¥NNRtæµç¨‹  ### 开呿¥éª¤ AI芯片设备HDIæœåС开å‘者具体å¯é€šè¿‡ä»¥ä¸‹æ¥éª¤å®žçްAIä¸“ç”¨åŠ é€ŸèŠ¯ç‰‡å¯¹æŽ¥NNRt: #### 生æˆHDI头文件 å¼€æºç¤¾åŒºä¸‹è½½OpenHarmony的代ç ,编译drivers_interface部件,生æˆHDI接å£çš„头文件。 1. [下载æºç ](../get-code/sourcecode-acquire.md)。 2. 进入OpenHarmonyæºç æ ¹ç›®å½•ï¼Œç¼–è¯‘NNRtçš„IDLæŽ¥å£æ–‡ä»¶ï¼ˆä»¥RK3568产å“为例): ```shell ./build.sh --product-name rk3568 –ccache --build-target drivers_interface_nnrt ``` 编译完æˆåŽï¼Œä¼šåœ¨```out/rk3568/gen/drivers/interface/nnrt/v2_0```目录下生æˆC++类型的HDI头文件。若需è¦ç”ŸæˆC类型的头文件,请在编译之å‰ä½¿ç”¨å¦‚下命令对```drivers/interface/nnrt/v2_0/BUILD.gn```文件ä¸çš„```language```é…置项进行设置。 ```shell language = "c" ``` 生æˆå¤´æ–‡ä»¶ç›®å½•如下所示: ```text out/rk3568/gen/drivers/interface/nnrt └── v2_0 ├── drivers_interface_nnrt__libnnrt_proxy_2.0_external_deps_temp.json ├── drivers_interface_nnrt__libnnrt_stub_2.0_external_deps_temp.json ├── innrt_device.h # 设备接å£å¤´æ–‡ä»¶ ├── iprepared_model.h # 编译AI模型对象头文件 ├── libnnrt_proxy_2.0__notice.d ├── libnnrt_stub_2.0__notice.d ├── model_types.cpp # AI模型结构定义实现文件 ├── model_types.h # AI模型结构定义头文件 ├── nnrt_device_driver.cpp # 设备驱动实现å‚è€ƒæ ·ä¾‹ ├── nnrt_device_proxy.cpp ├── nnrt_device_proxy.h ├── nnrt_device_service.cpp # 设备æœåŠ¡ç«¯å®žçŽ°å‚è€ƒæ ·ä¾‹ ├── nnrt_device_service.h # 设备æœåŠ¡ç«¯å¤´æ–‡ä»¶ ├── nnrt_device_stub.cpp ├── nnrt_device_stub.h ├── nnrt_types.cpp # æ•°æ®ç±»åž‹å®šä¹‰å®žçŽ°æ–‡ä»¶ ├── nnrt_types.h # æ•°æ®ç±»åž‹å®šä¹‰å¤´æ–‡ä»¶ ├── node_attr_types.cpp # AI模型算å属性定义实现文件 ├── node_attr_types.h # AI模型算å属性定义 ├── prepared_model_proxy.cpp ├── prepared_model_proxy.h ├── prepared_model_service.cpp # 编译AI模型对象æœåŠ¡ç«¯å®žçŽ°å‚è€ƒæ ·ä¾‹ ├── prepared_model_service.h # 编译AI模型对象æœåŠ¡ç«¯å¤´æ–‡ä»¶ ├── prepared_model_stub.cpp └── prepared_model_stub.h ``` #### 实现HDIæœåŠ¡ 1. 进入OpenHarmonyæºç æ ¹ç›®å½•ï¼Œåœ¨```drivers/peripheral```目录下新建开å‘目录```nnrt```,用于HDIæœåС开å‘。开å‘目录结构如下所示: ```text drivers/peripheral/nnrt ├── bundle.json ├── v2_0 ├── BUILD.gn # 代ç 编译脚本文件 └── hdi_cpu_service # 自定义目录 ├── BUILD.gn # 代ç 编译脚本文件 ├── include │  ├── nnrt_device_service.h # 设备æœåŠ¡ç«¯å¤´æ–‡ä»¶ │  ├── node_functions.h # éžå¿…须,由具体实现决定 │  ├── node_registry.h # éžå¿…须,由具体实现决定 │  └── prepared_model_service.h # 编译AI模型对象æœåŠ¡ç«¯å¤´æ–‡ä»¶ └── src ├── nnrt_device_driver.cpp # 设备驱动实现文件 ├── nnrt_device_service.cpp # 设备æœåŠ¡ç«¯å®žçŽ°æ–‡ä»¶ ├── nnrt_device_stub.cpp # éžå¿…须,由具体实现决定 ├── node_attr_types.cpp # éžå¿…须,由具体实现决定 ├── node_functions.cpp # éžå¿…须,由具体实现决定 ├── node_registry.cpp # éžå¿…须,由具体实现决定 └── prepared_model_service.cpp # 编译AI模型对象æœåŠ¡ç«¯å®žçŽ°æ–‡ä»¶ ``` 2. å®žçŽ°è®¾å¤‡é©±åŠ¨ï¼Œæ— ç‰¹æ®Šéœ€æ±‚å¯ç›´æŽ¥ä½¿ç”¨IDL文件编译生æˆçš„```nnrt_device_driver.cpp```文件,å¦åˆ™æ ¹æ®å…·ä½“驱动开å‘。 3. 实现æœåŠ¡æŽ¥å£ï¼Œå¯å‚考```nnrt_device_service.cpp```å’Œ```prepared_model_service.cpp```实现文件,接å£å®šä¹‰å¯ä»¥å‚考[NNRtçš„HDI接å£å®šä¹‰](https://gitee.com/openharmony/drivers_interface/tree/master/nnrt)。 4. 编译驱动和æœåŠ¡çš„å®žçŽ°æ–‡ä»¶ä¸ºå…±äº«åº“ã€‚ 在```drivers/peripheral/nnrt/v2_0/hdi_cpu_service/```下新建```BUILD.gn```æ–‡ä»¶ï¼Œæ–‡ä»¶å†…å®¹å¦‚ä¸‹æ‰€ç¤ºï¼Œç›¸å…³å‚æ•°é…置内容å¯å‚考[Build教程](https://gitee.com/openharmony/build)。 ```shell import("//build/ohos.gni") import("//drivers/hdf_core/adapter/uhdf2/uhdf.gni") ohos_shared_library("libnnrt_service_2.0") { include_dirs = [] sources = [ "src/nnrt_device_service.cpp", "src/node_functions.cpp", "src/node_registry.cpp", "src/prepared_model_service.cpp", "src/shared_buffer_parser.cpp", "src/validation.cpp", ] external_deps = [ "c_utils:utils", "drivers_interface_nnrt:libnnrt_stub_2.0", "hdf_core:libhdf_utils", "hilog_native:libhilog", "ipc:ipc_core", ] install_images = [ chipset_base_dir ] subsystem_name = "hdf" part_name = "drivers_peripheral_nnrt" } ohos_shared_library("libnnrt_driver") { include_dirs = [] sources = [ "src/nnr_device_driver.cpp" ] deps = [ ":libnnrt_service_2.0" ] external_deps = [ "c_utils:utils", "drivers_interface_nnrt:libnnrt_stub_2.0", "hdf_core:libhdf_host", "hdf_core:libhdf_ipc_adapter", "hdf_core:libhdf_utils", "hdf_core:libhdi", "hilog_native:libhilog", "ipc:ipc_core", ] install_images = [ chipset_base_dir ] subsystem_name = "hdf" part_name = "drivers_peripheral_nnrt" } group("hdf_nnrt_service") { deps = [ ":libnnrt_driver", ":libnnrt_service_2.0", ] } ``` å°†```group("hdf_nnrt_service")```æ·»åŠ åˆ°```drivers/peripheral/nnrt/v2_0/BUILD.gn```文件ä¸ï¼Œä»¥ä¾¿åœ¨æ›´ä¸Šç›®å½•层级就能引用。 ```shell if (defined(ohos_lite)) { group("nnrt_entry") { deps = [] } } else { group("nnrt_entry") { deps = [ "./hdi_cpu_service:hdf_nnrt_service" ] } } ``` 新建```drivers/peripheral/nnrt/bundle.json```用于定义新增的```drivers_peripheral_nnrt```部件。 ```json { "name": "drivers_peripheral_nnrt", "description": "Neural network runtime device driver", "version": "4.0", "license": "Apache License 2.0", "component": { "name": "drivers_peripheral_nnrt", "subsystem": "hdf", "syscap": [""], "adapter_system_type": ["standard"], "rom": "1024KB", "ram": "2048KB", "deps": { "components": [ "c_utils", "hdf_core", "hilog_native", "ipc" ], "third_part": [ "bounds_checking_function" ] }, "build": { "sub_component": [ "//drivers/peripheral/nnrt/v2_0:nnrt_entry" ], "test": [ ], "inner_kits": [ ] } } } ``` #### 声明HDIæœåŠ¡ 在对应产å“çš„uhdf hcsé…置文件ä¸å£°æ˜ŽNNRt的用户æ€é©±åŠ¨ä¸ŽæœåŠ¡ã€‚ä¾‹å¦‚é’ˆå¯¹RK3568,æœåŠ¡éœ€è¦åœ¨```vendor/hihope/rk3568/hdf_config/uhdf/device_info.hcs```æ–‡ä»¶ä¸æ–°å¢žå¦‚下é…置: ```text nnrt :: host { hostName = "nnrt_host"; priority = 50; uid = ""; gid = ""; caps = ["DAC_OVERRIDE", "DAC_READ_SEARCH"]; nnrt_device :: device { device0 :: deviceNode { policy = 2; priority = 100; moduleName = "libnnrt_driver.z.so"; serviceName = "nnrt_device_service"; } } } ``` > 注æ„:修改hcs文件需è¦åˆ 除outç›®å½•é‡æ–°ç¼–译,æ‰èƒ½ç”Ÿæ•ˆã€‚ #### é…ç½®host进程用户ID和组ID 对于新增的nnrt_host进程的场景,需è¦é…置对应进程的用户ID和组ID。 进程的用户ID在文件```base/startup/init/services/etc/passwd```ä¸é…置,进程的组ID在文件```base/startup/init/services/etc/group```ä¸é…置。 ```text # 在base/startup/init/services/etc/passwd新增 nnrt_host:x:3311:3311:::/bin/false # 在base/startup/init/services/etc/group新增 nnrt_host:x:3311: ``` #### é…ç½®SELinux OpenHarmonyå·²ç»å¼€å¯SELinux特性,需è¦å¯¹æ–°å¢žçš„进程和æœåŠ¡é…置相应的SELinux规则,用于è¿è¡Œhost进程访问æŸäº›èµ„æºã€å‘布HDIæœåŠ¡ç‰ã€‚ 1. 在```base/security/selinux/sepolicy/ohos_policy/drivers/adapter/public/hdf_service_contexts```æ–‡ä»¶ä¸æ–°å¢žé…置: ```text # 新增é…ç½® nnrt_device_service u:object_r:hdf_nnrt_device_service:s0 ``` > ```nnrt_host```为[声明HDIæœåŠ¡](#声明hdiæœåŠ¡)æ¥éª¤ä¸é…置的进程å称,下åŒã€‚ 2. 在```base/security/selinux/sepolicy/ohos_policy/drivers/adapter/public/hdf_service.te```æ–‡ä»¶ä¸æ–°å¢žé…置: ```text # 新增é…ç½® type hdf_nnrt_device_service, hdf_service_attr; ``` 3. 在```base/security/selinux/sepolicy/ohos_policy/drivers/adapter/public/hdfdomain.te```æ–‡ä»¶ä¸æ–°å¢žé…置: ```text # 新增é…ç½® neverallow { domain -hdfdomain -sadomain } { hdfdomain -nnrt_host -allocator_host -hdf_public_domain }:binder call; ``` 4. 在```base/security/selinux/sepolicy/ohos_policy/drivers/adapter/public/type.te```æ–‡ä»¶ä¸æ–°å¢žé…置: ```text # 新增é…ç½® type nnrt_host, hdfdomain, domain; ``` 5. 在```base/security/selinux/sepolicy/ohos_policy/drivers/adapter/vendor/hdf_devmgr.te```æ–‡ä»¶ä¸æ–°å¢žé…置: ```text # 新增é…ç½® allow hdf_devmgr nnrt_host:binder { call transfer }; allow hdf_devmgr nnrt_host:dir { search }; allow hdf_devmgr nnrt_host:file { open read write }; allow hdf_devmgr nnrt_host:process { getattr }; ``` 6. 在```base/security/selinux/sepolicy/ohos_policy/drivers/adapter/vendor/init.te```æ–‡ä»¶ä¸æ–°å¢žé…置: ```text # 新增é…ç½® allow init nnrt_host:process { rlimitinh siginh transition }; ``` 7. 在```base/security/selinux/sepolicy/ohos_policy/startup/init/public/chipset_init.te```文件ä¸ä½œå¦‚下修改: 找到chipset_init这一行: ```text allow chipset_init { light_host input_user_host wifi_host camera_host power_host audio_host }:process { rlimitinh siginh transition }; ``` 在host列表ä¸å¢žåŠ nnrt_host: ```text allow chipset_init { light_host input_user_host wifi_host camera_host power_host audio_host nnrt_host }:process { rlimitinh siginh transition }; ``` 8. 新建```nnrt_host.te```é…置文件: ```shell # 创建nnrt文件夹 mkdir base/security/selinux/sepolicy/ohos_policy/drivers/peripheral/nnrt # 创建vendor文件夹 mkdir base/security/selinux/sepolicy/ohos_policy/drivers/peripheral/nnrt/vendor # 创建nnrt_host.te文件 touch base/security/selinux/sepolicy/ohos_policy/drivers/peripheral/nnrt/vendor/nnrt_host.te ``` 9. 将所需的æƒé™å†™å…¥```nnrt_host.te```文件ä¸ï¼š ```text allow nnrt_host dev_hdf_kevent:chr_file { ioctl }; allow nnrt_host hilog_param:file { read open map }; allow nnrt_host sh:binder { transfer }; allow nnrt_host samgr:binder { call }; allow nnrt_host dev_ashmem_file:chr_file { open }; allow nnrt_host dev_unix_socket:dir { search }; allow nnrt_host hdf_device_manager:hdf_devmgr_class { get }; allow nnrt_host hdf_nnrt_device_service:hdf_devmgr_class { add get }; allow nnrt_host dev_console_file:chr_file { read write }; allow nnrt_host debug_param:file { read open map }; allow nnrt_host sa_device_service_manager:samgr_class { get }; allow nnrt_host hdf_devmgr:binder { call transfer }; allow nnrt_host hdf_nnrt_device_service:binder { call }; allow nnrt_host sysfs_devices_system_cpu:file { read open getattr }; allow sh hdf_nnrt_device_service:hdf_devmgr_class { add get }; allow sh hdf_hci_interface_service:hdf_devmgr_class { get }; allow sh nnrt_host:dir { getattr search }; allow sh nnrt_host:file { open read }; allow sh nnrt_host:process { getattr }; allow sh nnrt_host:binder { call }; allow sh nnrt_host:fd { use }; ``` 10. 由于SELinux是白åå•访问的æƒé™æœºåˆ¶ï¼Œéœ€è¦æ ¹æ®å®žé™…æƒé™éœ€æ±‚é…置。将æœåŠ¡å¯åЍ之åŽï¼Œå¯é€šè¿‡ä»¥ä¸‹dmesg命令查看avc告è¦ï¼Œ avc告è¦ä¼šç»™å‡ºç¼ºå°‘çš„æƒé™ã€‚SELinuxçš„é…置也å¯ä»¥å‚考[OpenHarmony SELinuxå系统的说明](https://gitee.com/openharmony/security_selinux/blob/master/README.md)。 ```shell hdc_std shell dmesg | grep nnrt ``` #### é…ç½®éƒ¨ä»¶ç¼–è¯‘å…¥å£ ä»¥RK3568产å“为例: ```shell vim //productdefine/common/inherit/chipset_common.json ``` 在```"subsystems"```, ```"subsystem":"hdf"```, ```"components"```䏿·»åŠ ï¼š ```shell { "component": "drivers_peripheral_nnrt", "features": [] } ``` #### åˆ é™¤out目录并编译整个系统 ```shell # åˆ é™¤out目录 rm -rf ./out # 编译 ./build.sh --product-name rk3568 –ccache --jobs=4 ``` ### è°ƒæµ‹éªŒè¯ æœåС开å‘完æˆåŽï¼Œå¯ä»¥ä½¿ç”¨XTS用例验è¯åŸºæœ¬åŠŸèƒ½å’Œå…¼å®¹æ€§ã€‚å¼€å‘者å¯é€šè¿‡ä»¥ä¸‹æ¥éª¤è¿›è¡ŒéªŒè¯ï¼š 1. 编译NNRtçš„hats用例,用例在```test/xts/hats/ai/nnrt/hdi```目录下。 ```shell # 进入hats目录 cd test/xts/hats # 编译hats测试用例 ./build.sh suite=hats system_size=standard product_name=rk3568 # å›žåˆ°ä»£ç æ ¹ç›®å½• cd - ``` ç¼–è¯‘å¥½çš„æµ‹è¯•ç”¨ä¾‹å¯æ‰§è¡Œæ–‡ä»¶```HatsHdfNnrtFunctionTest```会输出到```out/rk3568/suites/hats/testcases/```下。 2. 将测试用例push到RK3568设备的```/data/local/tmp/```目录下。 ```shell # å°†æµ‹è¯•ç”¨ä¾‹å¯æ‰§è¡Œæ–‡ä»¶æŽ¨é€åˆ°è®¾å¤‡ä¸Šï¼ŒHatsHdfNnrtFunctionTestæ˜¯æµ‹è¯•ç”¨ä¾‹å¯æ‰§è¡Œæ–‡ä»¶ã€‚ hdc_std file send out/rk3568/suites/hats/testcases/HartsHdfNnrtFunctionTest /data/local/tmp/ # ç»™æµ‹è¯•ç”¨ä¾‹å¯æ‰§è¡Œæ–‡ä»¶åŠ ä¸Šæƒé™ã€‚ hdc_std shell "chmod +x /data/local/tmp/HatsHdfNnrtFunctionTest" ``` 3. 执行用例并查看结果。 ```shell # 执行测试用例 hdc_std shell "/data/local/tmp/HatsHdfNnrtFunctionTest" ``` 测试报告显示已通过47个用例,说明所有hats用例已执行æˆåŠŸï¼ŒæœåŠ¡å·²é€šè¿‡å…¼å®¹æ€§æµ‹è¯•ã€‚ ```text ... [----------] Global test environment tear-down Gtest xml output finished [==========] 47 tests from 3 test suites ran. (515 ms total) [ PASSED ] 47 tests. ``` ### å¼€å‘实例 完整Demo代ç å¯ä»¥å‚考[社区实现](https://gitee.com/openharmony/ai_neural_network_runtime/tree/master/example/drivers)。 1. 进入OpenHarmonyæºç æ ¹ç›®å½•ï¼Œåœ¨```drivers/peripheral```路径下创建```nnrt```目录,拷è´NNRtæºç 路径```foundation/ai/neural_network_runtime```下的```example/driver/nnrt/v2_0```目录到```drivers/peripheral/nnrt```路径下。 ```shell cp -r example/drivers/nnrt/v2_0 drivers/peripheral/nnrt ``` 2. 在```drivers/peripheral/nnrt```下补充```bundle.json```文件,```bundle.json```的写法å‚考本教程上é¢[开呿¥éª¤](#开呿¥éª¤)ä¸çš„[实现HDIæœåŠ¡](#实现hdiæœåŠ¡)ç« èŠ‚ã€‚ 3. 由于Demoä¾èµ–MindSpore Lite CPUç®—åï¼Œå› æ¤éœ€è¦æ·»åŠ MindSpore Liteä¾èµ–文件: - 在OpenHarmonyæºç æ ¹ç›®å½•æ‰§è¡Œä»¥ä¸‹å‘½ä»¤ç¼–è¯‘MindSpore Lite动æ€åº“。MindSporeæºç 在OpenHarmonyæºç æ ¹ç›®å½•third_party/mindsporeä½ç½®ä¸‹ã€‚ ```shell # 编译mindspore动æ€åº“ ./build.sh --product-name rk3568 -ccaache --jobs 4 --build-target mindspore_lib ``` - 在```drivers/peripheral/nnrt/v2_0```下创建```mindspore```ç›®å½•ï¼Œç”¨äºŽå˜æ”¾mindspore动æ€åº“和头文件。 ```shell mkdir drivers/peripheral/nnrt/v2_0/mindspore ``` - å°†MindSporeæºç ä¸```mindspore-src/source/include```目录拷è´åˆ°```drivers/peripheral/nnrt/v2_0/mindspore```目录下。 ```shell cp third_party/mindspore/mindspore-src/source/include drivers/peripheral/nnrt/v2_0/mindspore ``` - Demo还ä¾èµ–mindsporeçš„```schema```文件: ```shell # 创建mindspore_schema目录 mkdir drivers/peripheral/nnrt/v2_0/hdi_cpu_service/include/mindspore_schema # 从third_party目录拷è´mindspore schema文件 cp third_party/mindspore/mindspore-src/source/mindspore/lite/schema/* drivers/peripheral/nnrt/v2_0/hdi_cpu_service/include/mindspore_schema/ ``` - 将编译好的OpenHarmonyçš„MindSpore Lite动æ€åº“æ‹·è´åˆ°```mindspore```目录下。 ```shell # 在drivers/peripheral/nnrt/v2_0/mindspore下创建mindspore目录 mkdir drivers/peripheral/nnrt/v2_0/mindspore/mindspore # 从out目录将mindspore动æ€åº“æ‹·è´åˆ°drivers/peripheral/nnrt/v2_0/mindspore/mindspore下 cp out/rk3568/package/phone/system/lib/libmindspore-lite.so drivers/peripheral/nnrt/v2_0/mindspore/mindspore/ ``` 4. å…¶ä»–é…置请å‚考本教程上é¢çš„[开呿¥éª¤](#开呿¥éª¤)ç« èŠ‚ã€‚