“bfb96c7772c1ecd4528c05d54a196db5b360722b”上不存在“packages/uni-app-plus-nvue/dist/index.legacy.js”
subsys-aiframework-tech-interface.md 7.1 KB
Newer Older
N
NEEN 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
# 接口开发规范<a name="ZH-CN_TOPIC_0000001096100171"></a>

-   [规则:SDK需按算法调用顺序,封装client对外提供接口;对于异步插件对应的SDK,需要实现client提供的回调接口IClientCb](#section15872017171616)
-   [规则:SDK接口实现中,需要保存与client交互的相关通用数据](#section011283741612)
-   [建议:SDK实现client定义的IServiceDeadCb接口](#section1199125331613)
-   [规则:SDK与plugin需要使用编解码模块,将特定算法数据转换成AI引擎的通用数据类型](#section93139389171)
-   [规则:在SDK中,对以编解码返回的出参数据类型,需要进行内存释放,否则会出现内存泄漏](#section1698441814183)
-   [规则:plugin需要实现server定义的IPlugin接口,并使用宏PLUGIN\_INTERFACE\_IMPL对外提供插件函数指针](#section20850717196)
-   [规则:plugin需要使用AI引擎提供的统一数据通道](#section1493821732019)

## 规则:SDK需按算法调用顺序,封装client对外提供接口;对于异步插件对应的SDK,需要实现client提供的回调接口IClientCb<a name="section15872017171616"></a>

AI引擎的client端对外提供的接口包括AieClientInit、AieClientPrepare、AieClientSyncProcess、AieClientAsyncProcess、AieClientRelease、AieClientDestroy、AieClientSetOption、AieClientGetOption,sdk需要根据插件的北向接口按照顺序至少封装AieClientInit、AieClientPrepare、AieClientSyncProcess/AieClientAsyncProcess、AieClientRelease、AieClientDestroy五个接口,否则会出现调用问题或者内存泄漏。比如封装过程遗漏了AieClientprepare接口,则server端无法完成插件加载,故后面的接口都无法调用成功。

对于异步插件,sdk需要实现IClientCb接口,用于接收来自client端的算法推理结果,并将该结果返回给三方调用者。

## 规则:SDK接口实现中,需要保存与client交互的相关通用数据<a name="section011283741612"></a>

AI引擎将的client端采用单例实现,对接多个SDK,因此各SDK需要保存与client交互的通用数据,用于连接server端进行任务推理、结果返回等;需保存数据包含clientInfo、algorithmInfo、configInfo三种数据类型,定义在SDK的成员变量里即可。

## 建议:SDK实现client定义的IServiceDeadCb接口<a name="section1199125331613"></a>

Server端是系统常驻进程,以系统能力的形式为多个client提供服务;client定义的IServiceDeadCb接口,是在server端异常死亡后,会被触发调用。这种异常场景,sdk可在死亡通知接口中,实现相关操作,比如停止调用或者再次拉起server端等。

IServiceDeadCb接口实现示例:

```
class ServiceDeadCb : public IServiceDeadCb {
public:
ServiceDeadCb() = default;
~ServiceDeadCb() override = default;
void OnServiceDead() override
{
printf("[ServiceDeadCb]OnServiceDead Callback happens");
}
};
```

如上示例,SDK可在OnServiceDead\(\)方法中实现自己的操作,比如停止所有的接口调用等等。

## 规则:SDK与plugin需要使用编解码模块,将特定算法数据转换成AI引擎的通用数据类型<a name="section93139389171"></a>

插件的推理数据,会由三方调用者通过client、server传递到插件中;不同的算法所需要的数据类型是不一致的,比如cv的需要图片数据、asr的需要语音数据;为了适配数据类型的差异,AI引擎对外提供了对基本数据类型的编解码能力,将不同数据类型转换为AI引擎可以使用的通用数据类型。

编码后的数据类型定义:

```
struct DataInfo {
unsigned char *data;
int length;
} DataInfo;

```

如上示例,DataInfo数据结构包括指向数据内存的指针和数据长度两个变量组成。

框架接口使用方法:

1.添加依赖的头文件:"utils/encdec/include/encdec.h"。

2.添加build.gn中的依赖项:

include\_dirs添加"//foundation/ai/engine/services/common"。

deps添加"//foundation/ai/engine/services/common/utils/encdec:encdec" 。

3.编解码示例:

```
// 编码调用函数示例:arg1,arg2,arg3等为需编码的变量,dataInfo为编码后的结果
retCode = ProcessEncode(dataInfo, arg1, arg2, arg3) //可以接收任意多个参数
// 解码调用函数示例:dataInfo为需要解码的信息,arg1,arg2,arg3等为解码后的结果
retCode = ProcessDecode(dataInfo, arg1, arg2, arg3) //可以接收任意多个参数
```

注意:

-   编码和解码调用时的参数顺序需要保证一致。
-   编码后dataInfo的内存需要调用者手动进行释放。
-   server端和client端的内存是分开管理和释放的。
-   如果包含共享内存的指针,不需要额外处理。
-   如果其他类型的指针,则需要解引用后使用ProcessEncode/ ProcessDecode。
-   该编解码模块未适配class数据类型,不建议使用。

## 规则:在SDK中,对以编解码返回的出参数据类型,需要进行内存释放,否则会出现内存泄漏<a name="section1698441814183"></a>

编码得到的通用数据,本质上是将不同类型数据封装在同一块内存中,然后将这块内存的首地址与长度封装到结构体中。通过编码返回到sdk中的出参数据,在插件中申请了内存,但插件无法释放,否则sdk将无法拿到数据;因此sdk在拿到数据之后,需要对内存进行释放。

内存释放示例:

```
DataInfo outputInfo = {
.data = nullptr,
.length = 0,
};
AieClientPrepare(clientInfo_, algorithmInfo_, inputInfo, outputInfo, nullptr);
if (outputInfo.data != nullptr) {
free(outputInfo.data);
outputInfo.data = nullptr;
outputInfo.length = 0;
}
```

## 规则:plugin需要实现server定义的IPlugin接口,并使用宏PLUGIN\_INTERFACE\_IMPL对外提供插件函数指针<a name="section20850717196"></a>

Server端管理的插件内部接口实现逻辑各不相同,为了统一插件的加载流程,AI引擎定义了插件接口IPlugin;在运行态,插件是以动态链接库的形式被AI引擎框架通过dlopen方式加载,各插件需要使用PLUGIN\_INTERFACE\_IMPL语句对外暴露函数指针,否则插件将无法被正常加载使用。

## 规则:plugin需要使用AI引擎提供的统一数据通道<a name="section1493821732019"></a>

AI Engine在server与插件之间,提供了一个统一的数据通道,用来处理来自sdk的推理请求和来自插件的结果返回;plugin在推理接口中,需按数据通道完成请求数据的获取以及推理结果的封装。

数据通道使用示例:

```
int SyncProcess(IRequest *request, IResponse *&response)
{
HILOGI("[IvpPlugin]Begin SyncProcess");
if (request == nullptr) {
HILOGE("[IvpPlugin]SyncProcess request is nullptr");
return RETCODE_NULL_PARAM;
}
DataInfo inputInfo = request->GetMsg();
if (inputInfo.data == nullptr) {
HILOGE("[IvpPlugin]InputInfo data is nullptr");
return RETCODE_NULL_PARAM;
}

...

response = IResponse::Create(request);
response->SetResult(outputInfo);
return RETCODE_SUCCESS;
}
```

示例中request和response是数据通道的内容主体,server端会将数据封装在request中,传递到插件,插件进行算法处理之后,则需要将结果封装成response进行返回。