1e41f4b71Sopenharmony_ci# AI
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci## Introduction
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ciThe AI subsystem is the part of OpenHarmony that provides native distributed AI capabilities. At the heart of the subsystem is a unified AI engine framework, which implements quick integration of AI algorithm plug-ins. The framework consists of the plug-in management, module management, and communication management modules, fulfilling lifecycle management and on-demand deployment of AI algorithms. Under this framework, AI algorithm APIs will be standardized to facilitate distributed calling of AI capabilities. In addition, unified inference APIs will be provided to adapt to different inference framework hierarchies.
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ci**Figure  1**  AI engine framework<a name="fig17296164711526"></a>  
8e41f4b71Sopenharmony_ci![](figures/ai-engine-framework.png "ai-engine-framework")
9e41f4b71Sopenharmony_ci
10e41f4b71Sopenharmony_ci## Directory Structure
11e41f4b71Sopenharmony_ci
12e41f4b71Sopenharmony_ci```
13e41f4b71Sopenharmony_ci/foundation/ai/engine                        # Home directory of the AI subsystem
14e41f4b71Sopenharmony_ci├── interfaces
15e41f4b71Sopenharmony_ci│  └── kits                                  # External APIs of the AI subsystem
16e41f4b71Sopenharmony_ci└── services
17e41f4b71Sopenharmony_ci│  ├── client                                # Client module of the AI subsystem
18e41f4b71Sopenharmony_ci│  │  ├── client_executor                    # Executor of the client module
19e41f4b71Sopenharmony_ci│  │  └── communication_adapter              # Communication adaptation layer for the client module, with extension supported
20e41f4b71Sopenharmony_ci│  ├── common                                # Common tools and protocol modules of the AI subsystem
21e41f4b71Sopenharmony_ci│  │  ├── platform
22e41f4b71Sopenharmony_ci│  │  ├── protocol
23e41f4b71Sopenharmony_ci│  │  └── utils
24e41f4b71Sopenharmony_ci│  └── server                                # Server module of the AI subsystem
25e41f4b71Sopenharmony_ci│  │  ├── communication_adapter              # Communication adaptation layer for the server module, with extension supported
26e41f4b71Sopenharmony_ci│  │  ├── plugin
27e41f4b71Sopenharmony_ci│  │     ├── asr
28e41f4b71Sopenharmony_ci│  │        └── keyword_spotting             # ASR algorithm plug-in reference: keyword spotting
29e41f4b71Sopenharmony_ci│  │     └── cv
30e41f4b71Sopenharmony_ci│  │        └── image_classification         # CV algorithm plug-in reference: image classification
31e41f4b71Sopenharmony_ci│  │  ├── plugin_manager
32e41f4b71Sopenharmony_ci│  │  └── server_executor                    # Executor of the server module
33e41f4b71Sopenharmony_ci```
34e41f4b71Sopenharmony_ci
35e41f4b71Sopenharmony_ci## Constraints
36e41f4b71Sopenharmony_ci
37e41f4b71Sopenharmony_ci* **Programming language**: C/C++
38e41f4b71Sopenharmony_ci
39e41f4b71Sopenharmony_ci* **Operating system**: OpenHarmony mini- and small-system
40e41f4b71Sopenharmony_ci
41e41f4b71Sopenharmony_ci* **Others**: The System Ability Manager \(Samgr\) has been started and is running properly.
42e41f4b71Sopenharmony_ci
43e41f4b71Sopenharmony_ci## Usage
44e41f4b71Sopenharmony_ci
45e41f4b71Sopenharmony_ci1.  Compile the AI subsystem.
46e41f4b71Sopenharmony_ci
47e41f4b71Sopenharmony_ci    The source code for lightweight AI framework is available at  **//foundation/ai/engine/services**.
48e41f4b71Sopenharmony_ci
49e41f4b71Sopenharmony_ci    The compilation procedure is as follows:
50e41f4b71Sopenharmony_ci
51e41f4b71Sopenharmony_ci    1. Set the compilation path.
52e41f4b71Sopenharmony_ci
53e41f4b71Sopenharmony_ci    ```
54e41f4b71Sopenharmony_ci    hb set -root dir (root dir is the root directory of the project code.)
55e41f4b71Sopenharmony_ci    ```
56e41f4b71Sopenharmony_ci
57e41f4b71Sopenharmony_ci    2. Specify the product for compilation. \(After the product list is displayed using the following command, move to the desired product with arrow keys and press  **Enter**.\)
58e41f4b71Sopenharmony_ci
59e41f4b71Sopenharmony_ci    ```
60e41f4b71Sopenharmony_ci    hb set -p
61e41f4b71Sopenharmony_ci    ```
62e41f4b71Sopenharmony_ci
63e41f4b71Sopenharmony_ci    3. Start compilation.
64e41f4b71Sopenharmony_ci
65e41f4b71Sopenharmony_ci    ```
66e41f4b71Sopenharmony_ci    hb build -f (Use this command if you want to compile the entire repository.)
67e41f4b71Sopenharmony_ci    hb build ai_engine (Use this command if you want to compile only the ai_engine module.)
68e41f4b71Sopenharmony_ci    ```
69e41f4b71Sopenharmony_ci
70e41f4b71Sopenharmony_ci    >**Note**: For details about the hb configuration, see the readme of the build\_lite subsystem.
71e41f4b71Sopenharmony_ci
72e41f4b71Sopenharmony_ci2.  Develop the plug-in, with keyword spotting as an example.
73e41f4b71Sopenharmony_ci
74e41f4b71Sopenharmony_ci    Directory: //foundation/ai/engine/services/server/plugin/asr/keyword\_spotting
75e41f4b71Sopenharmony_ci
76e41f4b71Sopenharmony_ci    >**Note**: The plug-in must implement the  **IPlugin**  and  **IPluginCallback**  APIs provided by the server.
77e41f4b71Sopenharmony_ci
78e41f4b71Sopenharmony_ci    ```
79e41f4b71Sopenharmony_ci    #include "plugin/i_plugin.h
80e41f4b71Sopenharmony_ci    class KWSPlugin : public IPlugin {       // Inherits the public base class of the IPlugin API for Keywords Spotting Plugin (KWSPlugin).
81e41f4b71Sopenharmony_ci        KWSPlugin();
82e41f4b71Sopenharmony_ci        ~KWSPlugin();
83e41f4b71Sopenharmony_ci    
84e41f4b71Sopenharmony_ci        const long long GetVersion() const override;
85e41f4b71Sopenharmony_ci        const char* GetName() const override;
86e41f4b71Sopenharmony_ci        const char* GetInferMode() const override;
87e41f4b71Sopenharmony_ci    
88e41f4b71Sopenharmony_ci        int32_t Prepare(long long transactionId, const DataInfo &amp;amp;inputInfo, DataInfo &amp;amp;outputInfo) override;
89e41f4b71Sopenharmony_ci        int32_t SetOption(int optionType, const DataInfo &amp;amp;inputInfo) override;
90e41f4b71Sopenharmony_ci        int32_t GetOption(int optionType, const DataInfo &amp;amp;inputInfo, DataInfo &amp;amp;outputInfo) override;
91e41f4b71Sopenharmony_ci        int32_t SyncProcess(IRequest *request, IResponse *&amp;amp;response) override;
92e41f4b71Sopenharmony_ci        int32_t AsyncProcess(IRequest *request, IPluginCallback*callback) override;
93e41f4b71Sopenharmony_ci        int32_t Release(bool isFullUnload, long long transactionId, const DataInfo &amp;amp;inputInfo) override;
94e41f4b71Sopenharmony_ci        .
95e41f4b71Sopenharmony_ci        .
96e41f4b71Sopenharmony_ci        .
97e41f4b71Sopenharmony_ci    };
98e41f4b71Sopenharmony_ci    ```
99e41f4b71Sopenharmony_ci
100e41f4b71Sopenharmony_ci    >**Note**: Depending on the algorithm in use, you only need to implement the  **SyncProcess**  or  **AsyncProcess**  API. Use an empty function as a placeholder for the other API. In this example, the KWS plug-in uses the synchronous algorithm. Therefore, you need to implement  **SyncProcess**  API and use an empty function as a placeholder for the  **SyncProcess**  API.
101e41f4b71Sopenharmony_ci
102e41f4b71Sopenharmony_ci    ```
103e41f4b71Sopenharmony_ci    #include "aie_log.h"
104e41f4b71Sopenharmony_ci    #include "aie_retcode_inner.h"
105e41f4b71Sopenharmony_ci    .
106e41f4b71Sopenharmony_ci    .
107e41f4b71Sopenharmony_ci    .
108e41f4b71Sopenharmony_ci    
109e41f4b71Sopenharmony_ci    const long long KWSPlugin::GetVersion() const
110e41f4b71Sopenharmony_ci    {
111e41f4b71Sopenharmony_ci        return ALGOTYPE_VERSION_KWS;
112e41f4b71Sopenharmony_ci    }
113e41f4b71Sopenharmony_ci    
114e41f4b71Sopenharmony_ci    const char *KWSPlugin::GetName() const
115e41f4b71Sopenharmony_ci    {
116e41f4b71Sopenharmony_ci        return ALGORITHM_NAME_KWS.c_str();
117e41f4b71Sopenharmony_ci    }
118e41f4b71Sopenharmony_ci    
119e41f4b71Sopenharmony_ci    const char *KWSPlugin::GetInferMode() const
120e41f4b71Sopenharmony_ci    {
121e41f4b71Sopenharmony_ci        return DEFAULT_INFER_MODE.c_str();
122e41f4b71Sopenharmony_ci    }
123e41f4b71Sopenharmony_ci    .
124e41f4b71Sopenharmony_ci    .
125e41f4b71Sopenharmony_ci    .
126e41f4b71Sopenharmony_ci    int32_t KWSPlugin::AsyncProcess(IRequest *request, IPluginCallback *callback)
127e41f4b71Sopenharmony_ci    {
128e41f4b71Sopenharmony_ci        return RETCODE_SUCCESS;
129e41f4b71Sopenharmony_ci    }
130e41f4b71Sopenharmony_ci    ```
131e41f4b71Sopenharmony_ci
132e41f4b71Sopenharmony_ci3.  Develop the SDK, with keyword spotting as an example.
133e41f4b71Sopenharmony_ci
134e41f4b71Sopenharmony_ci    Directory: //foundation/ai/engine/services/client/algorithm\_sdk/asr/keyword\_spotting
135e41f4b71Sopenharmony_ci
136e41f4b71Sopenharmony_ci    Keyword spotting SDK:
137e41f4b71Sopenharmony_ci
138e41f4b71Sopenharmony_ci    ```
139e41f4b71Sopenharmony_ci    class KWSSdk {
140e41f4b71Sopenharmony_ci    public:
141e41f4b71Sopenharmony_ci        KWSSdk();
142e41f4b71Sopenharmony_ci        virtual ~KWSSdk();
143e41f4b71Sopenharmony_ci    
144e41f4b71Sopenharmony_ci        /**
145e41f4b71Sopenharmony_ci         * @brief Create a new session with KWS Plugin
146e41f4b71Sopenharmony_ci         *
147e41f4b71Sopenharmony_ci         * @return Returns KWS_RETCODE_SUCCESS(0) if the operation is successful,
148e41f4b71Sopenharmony_ci         *         returns a non-zero value otherwise.
149e41f4b71Sopenharmony_ci         */
150e41f4b71Sopenharmony_ci        int32_t Create();
151e41f4b71Sopenharmony_ci    
152e41f4b71Sopenharmony_ci        /**
153e41f4b71Sopenharmony_ci         * @brief Synchronously execute keyword spotting once
154e41f4b71Sopenharmony_ci         *
155e41f4b71Sopenharmony_ci         * @param audioInput pcm data.
156e41f4b71Sopenharmony_ci         * @return Returns KWS_RETCODE_SUCCESS(0) if the operation is successful,
157e41f4b71Sopenharmony_ci         *         returns a non-zero value otherwise.
158e41f4b71Sopenharmony_ci         */
159e41f4b71Sopenharmony_ci        int32_t SyncExecute(const Array<int16_t> &audioInput);
160e41f4b71Sopenharmony_ci    
161e41f4b71Sopenharmony_ci        /**
162e41f4b71Sopenharmony_ci         * @brief Asynchronously execute keyword spotting once
163e41f4b71Sopenharmony_ci         *
164e41f4b71Sopenharmony_ci         * @param audioInput pcm data.
165e41f4b71Sopenharmony_ci         * @return Returns KWS_RETCODE_SUCCESS(0) if the operation is successful,
166e41f4b71Sopenharmony_ci         *         returns a non-zero value otherwise.
167e41f4b71Sopenharmony_ci         */
168e41f4b71Sopenharmony_ci        int32_t AsyncExecute(const Array<int16_t> &audioInput);
169e41f4b71Sopenharmony_ci    
170e41f4b71Sopenharmony_ci        /**
171e41f4b71Sopenharmony_ci         * @brief Set callback
172e41f4b71Sopenharmony_ci         *
173e41f4b71Sopenharmony_ci         * @param callback Callback function that will be called during the process.
174e41f4b71Sopenharmony_ci         * @return Returns KWS_RETCODE_SUCCESS(0) if the operation is successful,
175e41f4b71Sopenharmony_ci         *         returns a non-zero value otherwise.
176e41f4b71Sopenharmony_ci         */
177e41f4b71Sopenharmony_ci        int32_t SetCallback(const std::shared_ptr<KWSCallback> &callback);
178e41f4b71Sopenharmony_ci    
179e41f4b71Sopenharmony_ci        /**
180e41f4b71Sopenharmony_ci         * @brief Destroy the created session with KWS Plugin
181e41f4b71Sopenharmony_ci         *
182e41f4b71Sopenharmony_ci         * @return Returns KWS_RETCODE_SUCCESS(0) if the operation is successful,
183e41f4b71Sopenharmony_ci         *         returns a non-zero value otherwise.
184e41f4b71Sopenharmony_ci         */
185e41f4b71Sopenharmony_ci        int32_t Destroy();
186e41f4b71Sopenharmony_ci    }
187e41f4b71Sopenharmony_ci    ```
188e41f4b71Sopenharmony_ci
189e41f4b71Sopenharmony_ci    >**Note**: The sequence for the SDK to call client APIs of the AI engine is as follows: AieClientInit -\> AieClientPrepare -\> AieClientSyncProcess/AieClientAsyncProcess -\> AieClientRelease -\> AieClientDestroy. An exception will be thrown if the call sequence is violated. In addition, all these APIs must be called. Otherwise, a memory leakage may occur.
190e41f4b71Sopenharmony_ci
191e41f4b71Sopenharmony_ci    ```
192e41f4b71Sopenharmony_ci    int32_t KWSSdk::KWSSdkImpl::Create()
193e41f4b71Sopenharmony_ci    {
194e41f4b71Sopenharmony_ci        if (kwsHandle_ != INVALID_KWS_HANDLE) {
195e41f4b71Sopenharmony_ci            HILOGE("[KWSSdkImpl]The SDK has been created");
196e41f4b71Sopenharmony_ci            return KWS_RETCODE_FAILURE;
197e41f4b71Sopenharmony_ci        }
198e41f4b71Sopenharmony_ci        if (InitComponents() != RETCODE_SUCCESS) {
199e41f4b71Sopenharmony_ci            HILOGE("[KWSSdkImpl]Fail to init sdk components");
200e41f4b71Sopenharmony_ci            return KWS_RETCODE_FAILURE;
201e41f4b71Sopenharmony_ci        }
202e41f4b71Sopenharmony_ci        int32_t retCode = AieClientInit(configInfo_, clientInfo_, algorithmInfo_, nullptr);
203e41f4b71Sopenharmony_ci        if (retCode != RETCODE_SUCCESS) {
204e41f4b71Sopenharmony_ci            HILOGE("[KWSSdkImpl]AieClientInit failed. Error code[%d]", retCode);
205e41f4b71Sopenharmony_ci            return KWS_RETCODE_FAILURE;
206e41f4b71Sopenharmony_ci        }
207e41f4b71Sopenharmony_ci        if (clientInfo_.clientId == INVALID_CLIENT_ID) {
208e41f4b71Sopenharmony_ci            HILOGE("[KWSSdkImpl]Fail to allocate client id");
209e41f4b71Sopenharmony_ci            return KWS_RETCODE_FAILURE;
210e41f4b71Sopenharmony_ci        }
211e41f4b71Sopenharmony_ci        DataInfo inputInfo = {
212e41f4b71Sopenharmony_ci            .data = nullptr,
213e41f4b71Sopenharmony_ci            .length = 0,
214e41f4b71Sopenharmony_ci        };
215e41f4b71Sopenharmony_ci        DataInfo outputInfo = {
216e41f4b71Sopenharmony_ci            .data = nullptr,
217e41f4b71Sopenharmony_ci            .length = 0,
218e41f4b71Sopenharmony_ci        };
219e41f4b71Sopenharmony_ci        retCode = AieClientPrepare(clientInfo_, algorithmInfo_, inputInfo, outputInfo, nullptr);
220e41f4b71Sopenharmony_ci        if (retCode != RETCODE_SUCCESS) {
221e41f4b71Sopenharmony_ci            HILOGE("[KWSSdkImpl]AieclientPrepare failed. Error code[%d]", retCode);
222e41f4b71Sopenharmony_ci            return KWS_RETCODE_FAILURE;
223e41f4b71Sopenharmony_ci        }
224e41f4b71Sopenharmony_ci        if (outputInfo.data == nullptr || outputInfo.length <= 0) {
225e41f4b71Sopenharmony_ci            HILOGE("[KWSSdkImpl]The data or length of output info is invalid");
226e41f4b71Sopenharmony_ci            return KWS_RETCODE_FAILURE;
227e41f4b71Sopenharmony_ci        }
228e41f4b71Sopenharmony_ci        MallocPointerGuard<unsigned char> pointerGuard(outputInfo.data);
229e41f4b71Sopenharmony_ci        retCode = PluginHelper::UnSerializeHandle(outputInfo, kwsHandle_);
230e41f4b71Sopenharmony_ci        if (retCode != RETCODE_SUCCESS) {
231e41f4b71Sopenharmony_ci            HILOGE("[KWSSdkImpl]Get handle from inputInfo failed");
232e41f4b71Sopenharmony_ci            return KWS_RETCODE_FAILURE;
233e41f4b71Sopenharmony_ci        }
234e41f4b71Sopenharmony_ci        return KWS_RETCODE_SUCCESS;
235e41f4b71Sopenharmony_ci    }
236e41f4b71Sopenharmony_ci    
237e41f4b71Sopenharmony_ci    int32_t KWSSdk::KWSSdkImpl::SyncExecute(const Array<uint16_t> &audioInput)
238e41f4b71Sopenharmony_ci    {
239e41f4b71Sopenharmony_ci        intptr_t newHandle = 0;
240e41f4b71Sopenharmony_ci        Array<int32_t> kwsResult = {
241e41f4b71Sopenharmony_ci            .data = nullptr,
242e41f4b71Sopenharmony_ci            .size = 0
243e41f4b71Sopenharmony_ci        };
244e41f4b71Sopenharmony_ci        DataInfo inputInfo = {
245e41f4b71Sopenharmony_ci            .data = nullptr,
246e41f4b71Sopenharmony_ci            .length = 0
247e41f4b71Sopenharmony_ci        };
248e41f4b71Sopenharmony_ci        DataInfo outputInfo = {
249e41f4b71Sopenharmony_ci            .data = nullptr,
250e41f4b71Sopenharmony_ci            .length = 0
251e41f4b71Sopenharmony_ci        };
252e41f4b71Sopenharmony_ci        int32_t retCode = PluginHelper::SerializeInputData(kwsHandle_, audioInput, inputInfo);
253e41f4b71Sopenharmony_ci        if (retCode != RETCODE_SUCCESS) {
254e41f4b71Sopenharmony_ci            HILOGE("[KWSSdkImpl]Fail to serialize input data");
255e41f4b71Sopenharmony_ci            callback_->OnError(KWS_RETCODE_SERIALIZATION_ERROR);
256e41f4b71Sopenharmony_ci            return RETCODE_FAILURE;
257e41f4b71Sopenharmony_ci        }
258e41f4b71Sopenharmony_ci        retCode = AieClientSyncProcess(clientInfo_, algorithmInfo_, inputInfo, outputInfo);
259e41f4b71Sopenharmony_ci        if (retCode != RETCODE_SUCCESS) {
260e41f4b71Sopenharmony_ci            HILOGE("[KWSSdkImpl]AieClientSyncProcess failed. Error code[%d]", retCode);
261e41f4b71Sopenharmony_ci            callback_->OnError(KWS_RETCODE_PLUGIN_EXECUTION_ERROR);
262e41f4b71Sopenharmony_ci            return RETCODE_FAILURE;
263e41f4b71Sopenharmony_ci        }
264e41f4b71Sopenharmony_ci        if (outputInfo.data == nullptr || outputInfo.length <= 0) {
265e41f4b71Sopenharmony_ci            HILOGE("[KWSSdkImpl] The data or length of outputInfo is invalid. Error code[%d]", retCode);
266e41f4b71Sopenharmony_ci            callback_->OnError(KWS_RETCODE_NULL_PARAM);
267e41f4b71Sopenharmony_ci            return RETCODE_FAILURE;
268e41f4b71Sopenharmony_ci        }
269e41f4b71Sopenharmony_ci        MallocPointerGuard<unsigned char> pointerGuard(outputInfo.data);
270e41f4b71Sopenharmony_ci        retCode = PluginHelper::UnSerializeOutputData(outputInfo, newHandle, kwsResult);
271e41f4b71Sopenharmony_ci        if (retCode != RETCODE_SUCCESS) {
272e41f4b71Sopenharmony_ci            HILOGE("[KWSSdkImpl]UnSerializeOutputData failed. Error code[%d]", retCode);
273e41f4b71Sopenharmony_ci            callback_->OnError(KWS_RETCODE_UNSERIALIZATION_ERROR);
274e41f4b71Sopenharmony_ci            return retCode;
275e41f4b71Sopenharmony_ci        }
276e41f4b71Sopenharmony_ci        if (kwsHandle_ != newHandle) {
277e41f4b71Sopenharmony_ci            HILOGE("[KWSSdkImpl]The handle[%lld] of output data is not equal to the current handle[%lld]",
278e41f4b71Sopenharmony_ci                (long long)newHandle, (long long)kwsHandle_);
279e41f4b71Sopenharmony_ci            callback_->OnError(KWS_RETCODE_PLUGIN_SESSION_ERROR);
280e41f4b71Sopenharmony_ci            return RETCODE_FAILURE;
281e41f4b71Sopenharmony_ci        }
282e41f4b71Sopenharmony_ci        callback_->OnResult(kwsResult);
283e41f4b71Sopenharmony_ci        return RETCODE_SUCCESS;
284e41f4b71Sopenharmony_ci    }
285e41f4b71Sopenharmony_ci    
286e41f4b71Sopenharmony_ci    int32_t KWSSdk::KWSSdkImpl::Destroy()
287e41f4b71Sopenharmony_ci    {
288e41f4b71Sopenharmony_ci        if (kwsHandle_ == INVALID_KWS_HANDLE) {
289e41f4b71Sopenharmony_ci            return KWS_RETCODE_SUCCESS;
290e41f4b71Sopenharmony_ci        }
291e41f4b71Sopenharmony_ci        DataInfo inputInfo = {
292e41f4b71Sopenharmony_ci            .data = nullptr,
293e41f4b71Sopenharmony_ci            .length = 0
294e41f4b71Sopenharmony_ci        };
295e41f4b71Sopenharmony_ci        int32_t retCode = PluginHelper::SerializeHandle(kwsHandle_, inputInfo);
296e41f4b71Sopenharmony_ci        if (retCode != RETCODE_SUCCESS) {
297e41f4b71Sopenharmony_ci            HILOGE("[KWSSdkImpl]SerializeHandle failed. Error code[%d]", retCode);
298e41f4b71Sopenharmony_ci            return KWS_RETCODE_FAILURE;
299e41f4b71Sopenharmony_ci        }
300e41f4b71Sopenharmony_ci        retCode = AieClientRelease(clientInfo_, algorithmInfo_, inputInfo);
301e41f4b71Sopenharmony_ci        if (retCode != RETCODE_SUCCESS) {
302e41f4b71Sopenharmony_ci            HILOGE("[KWSSdkImpl]AieClientRelease failed. Error code[%d]", retCode);
303e41f4b71Sopenharmony_ci            return KWS_RETCODE_FAILURE;
304e41f4b71Sopenharmony_ci        }
305e41f4b71Sopenharmony_ci        retCode = AieClientDestroy(clientInfo_);
306e41f4b71Sopenharmony_ci        if (retCode != RETCODE_SUCCESS) {
307e41f4b71Sopenharmony_ci            HILOGE("[KWSSdkImpl]AieClientDestroy failed. Error code[%d]", retCode);
308e41f4b71Sopenharmony_ci            return KWS_RETCODE_FAILURE;
309e41f4b71Sopenharmony_ci        }
310e41f4b71Sopenharmony_ci        mfccProcessor_ = nullptr;
311e41f4b71Sopenharmony_ci        pcmIterator_ = nullptr;
312e41f4b71Sopenharmony_ci        callback_ = nullptr;
313e41f4b71Sopenharmony_ci        kwsHandle_ = INVALID_KWS_HANDLE;
314e41f4b71Sopenharmony_ci        return KWS_RETCODE_SUCCESS;
315e41f4b71Sopenharmony_ci    }
316e41f4b71Sopenharmony_ci    ```
317e41f4b71Sopenharmony_ci
318e41f4b71Sopenharmony_ci4.  Develop a sample application.
319e41f4b71Sopenharmony_ci
320e41f4b71Sopenharmony_ci    Call the  **Create**  API.
321e41f4b71Sopenharmony_ci
322e41f4b71Sopenharmony_ci    ```
323e41f4b71Sopenharmony_ci    bool KwsManager::PreparedInference()
324e41f4b71Sopenharmony_ci    {
325e41f4b71Sopenharmony_ci        if (capturer_ == nullptr) {
326e41f4b71Sopenharmony_ci            printf("[KwsManager] only load plugin after AudioCapturer ready\n");
327e41f4b71Sopenharmony_ci            return false;
328e41f4b71Sopenharmony_ci        }
329e41f4b71Sopenharmony_ci        if (plugin_ != nullptr) {
330e41f4b71Sopenharmony_ci            printf("[KwsManager] stop created InferencePlugin at first\n");
331e41f4b71Sopenharmony_ci            StopInference();
332e41f4b71Sopenharmony_ci        }
333e41f4b71Sopenharmony_ci        plugin_ = std::make_shared<KWSSdk>();
334e41f4b71Sopenharmony_ci        if (plugin_ == nullptr) {
335e41f4b71Sopenharmony_ci            printf("[KwsManager] fail to create inferencePlugin\n");
336e41f4b71Sopenharmony_ci            return false;
337e41f4b71Sopenharmony_ci        }
338e41f4b71Sopenharmony_ci        if (plugin_->Create() != SUCCESS) {
339e41f4b71Sopenharmony_ci            printf("[KwsManager] KWSSdk fail to create.\n");
340e41f4b71Sopenharmony_ci            return false;
341e41f4b71Sopenharmony_ci        }
342e41f4b71Sopenharmony_ci        std::shared_ptr<KWSCallback> callback = std::make_shared<MyKwsCallback>();
343e41f4b71Sopenharmony_ci        if (callback == nullptr) {
344e41f4b71Sopenharmony_ci            printf("[KwsManager] new Callback failed.\n");
345e41f4b71Sopenharmony_ci            return false;
346e41f4b71Sopenharmony_ci        }
347e41f4b71Sopenharmony_ci        plugin_->SetCallback(callback);
348e41f4b71Sopenharmony_ci        return true;
349e41f4b71Sopenharmony_ci    }
350e41f4b71Sopenharmony_ci    ```
351e41f4b71Sopenharmony_ci
352e41f4b71Sopenharmony_ci    Call the  **SyncExecute**  API.
353e41f4b71Sopenharmony_ci
354e41f4b71Sopenharmony_ci    ```
355e41f4b71Sopenharmony_ci    void KwsManager::ConsumeSamples()
356e41f4b71Sopenharmony_ci    {
357e41f4b71Sopenharmony_ci        uintptr_t sampleAddr = 0;
358e41f4b71Sopenharmony_ci        size_t sampleSize = 0;
359e41f4b71Sopenharmony_ci        int32_t retCode = SUCCESS;
360e41f4b71Sopenharmony_ci        while (status_ == RUNNING) {
361e41f4b71Sopenharmony_ci            {
362e41f4b71Sopenharmony_ci                std::lock_guard<std::mutex> lock(mutex_);
363e41f4b71Sopenharmony_ci                if (cache_ == nullptr) {
364e41f4b71Sopenharmony_ci                    printf("[KwsManager] cache_ is nullptr.\n");
365e41f4b71Sopenharmony_ci                    break;
366e41f4b71Sopenharmony_ci                }
367e41f4b71Sopenharmony_ci                sampleSize = cache_->GetCapturedBuffer(sampleAddr);
368e41f4b71Sopenharmony_ci            }
369e41f4b71Sopenharmony_ci            if (sampleSize == 0 || sampleAddr == 0) {
370e41f4b71Sopenharmony_ci                continue;
371e41f4b71Sopenharmony_ci            }
372e41f4b71Sopenharmony_ci            Array<int16_t> input = {
373e41f4b71Sopenharmony_ci                .data = (int16_t *)(sampleAddr),
374e41f4b71Sopenharmony_ci                .size = sampleSize >> 1
375e41f4b71Sopenharmony_ci            };
376e41f4b71Sopenharmony_ci            {
377e41f4b71Sopenharmony_ci                std::lock_guard<std::mutex> lock(mutex_);
378e41f4b71Sopenharmony_ci                if (plugin_ == nullptr) {
379e41f4b71Sopenharmony_ci                    printf("[KwsManager] cache_ is nullptr.\n");
380e41f4b71Sopenharmony_ci                    break;
381e41f4b71Sopenharmony_ci                }
382e41f4b71Sopenharmony_ci                if ((retCode = plugin_->SyncExecute(input)) != SUCCESS) {
383e41f4b71Sopenharmony_ci                    printf("[KwsManager] SyncExecute KWS failed with retCode = [%d]\n", retCode);
384e41f4b71Sopenharmony_ci                    continue;
385e41f4b71Sopenharmony_ci                }
386e41f4b71Sopenharmony_ci            }
387e41f4b71Sopenharmony_ci        }
388e41f4b71Sopenharmony_ci    }
389e41f4b71Sopenharmony_ci    ```
390e41f4b71Sopenharmony_ci
391e41f4b71Sopenharmony_ci    Call the  **Destroy**  API.
392e41f4b71Sopenharmony_ci
393e41f4b71Sopenharmony_ci    ```
394e41f4b71Sopenharmony_ci    void KwsManager::StopInference()
395e41f4b71Sopenharmony_ci    {
396e41f4b71Sopenharmony_ci        printf("[KwsManager] StopInference\n");
397e41f4b71Sopenharmony_ci        if (plugin_ != nullptr) {
398e41f4b71Sopenharmony_ci            int ret = plugin_->Destroy();
399e41f4b71Sopenharmony_ci            if (ret != SUCCESS) {
400e41f4b71Sopenharmony_ci                printf("[KwsManager] plugin_ destroy failed.\n");
401e41f4b71Sopenharmony_ci            }
402e41f4b71Sopenharmony_ci            plugin_ = nullptr;
403e41f4b71Sopenharmony_ci        }
404e41f4b71Sopenharmony_ci    }
405e41f4b71Sopenharmony_ci    ```
406e41f4b71Sopenharmony_ci
407e41f4b71Sopenharmony_ci
408e41f4b71Sopenharmony_ci## Repositories Involved
409e41f4b71Sopenharmony_ci
410e41f4b71Sopenharmony_ci[AI subsystem](https://gitee.com/openharmony/docs/blob/master/en/readme/ai.md)
411e41f4b71Sopenharmony_ci
412e41f4b71Sopenharmony_ci[ai_engine](https://gitee.com/openharmony/ai_engine)
413e41f4b71Sopenharmony_ci
414e41f4b71Sopenharmony_ci## Dependency Repositories
415e41f4b71Sopenharmony_ci
416e41f4b71Sopenharmony_ci[build\_lite](https://gitee.com/openharmony/build_lite/blob/master/README.md)
417e41f4b71Sopenharmony_ci
418e41f4b71Sopenharmony_ci[systemabilitymgr\_samgr\_lite](https://gitee.com/openharmony/systemabilitymgr_samgr_lite/blob/master/README.md)
419e41f4b71Sopenharmony_ci
420e41f4b71Sopenharmony_ci[startup\_init\_lite](https://gitee.com/openharmony/startup_init_lite/blob/master/README.md)
421e41f4b71Sopenharmony_ci
422e41f4b71Sopenharmony_ci## Reference
423e41f4b71Sopenharmony_ci
424e41f4b71Sopenharmony_ci[AI Framework Development Guide](https://gitee.com/openharmony/docs/blob/master/en/device-dev/subsystems/subsys-ai-aiframework-devguide.md)
425e41f4b71Sopenharmony_ci
426e41f4b71Sopenharmony_ci
427