未验证 提交 0d959bde 编写于 作者: O openharmony_ci 提交者: Gitee

!19883 翻译已完成18039+18640+18662+18806+18955

Merge pull request !19883 from shawn_he/18955-c
# IPC & RPC Development
# IPC & RPC Development Guidelines
## When to Use
......@@ -11,8 +11,8 @@ Table 1 Native IPC APIs
| Class| API| Description|
| -------- | -------- | -------- |
| [IRemoteBroker](../reference/apis/js-apis-rpc.md#iremotebroker) | sptr<IRemoteObject> AsObject() | Holder of a remote proxy object. If you call this API on the stub, the **RemoteObject** is returned; if you call this API on the proxy, the proxy object is returned.|
| IRemoteStub | virtual int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) | Callback used to process a request from the proxy and return the result. Derived classes need to override this API.|
| [IRemoteBroker](../reference/apis/js-apis-rpc.md#iremotebroker) | sptr<IRemoteObject> AsObject() | Obtains the holder of a remote proxy object. If you call this API on the stub, the **RemoteObject** is returned; if you call this API on the proxy, the proxy object is returned.|
| IRemoteStub | virtual int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) | Called to process a request from the proxy and return the result. Derived classes need to override this API.|
| IRemoteProxy | | Service proxy class, which is derived from the **IRemoteProxy** class.|
......@@ -52,7 +52,7 @@ Table 1 Native IPC APIs
#include "iremote_broker.h"
// Define message codes.
const int TRANS_ID_PING_ABILITY = 5
const int TRANS_ID_PING_ABILITY = 5;
const std::string DESCRIPTOR = "test.ITestAbility";
......@@ -180,137 +180,177 @@ Table 1 Native IPC APIs
1. Add dependencies.
```ts
import rpc from "@ohos.rpc"
import featureAbility from "@ohos.ability.featureAbility"
import rpc from "@ohos.rpc";
// Import @ohos.ability.featureAbility only for the application developed based on the FA model.
// import featureAbility from "@ohos.ability.featureAbility";
```
If you use the stage model, you need to obtain the context. The sample code is as follows:
```ts
import Ability from "@ohos.app.ability.UIAbility";
export default class MainAbility extends Ability {
onCreate(want, launchParam) {
console.log("[Demo] MainAbility onCreate");
globalThis.context = this.context;
}
onDestroy() {
console.log("[Demo] MainAbility onDestroy");
}
onWindowStageCreate(windowStage) {
// Main window is created, set main page for this ability
console.log("[Demo] MainAbility onWindowStageCreate");
}
onWindowStageDestroy() {
// Main window is destroyed, release UI related resources
console.log("[Demo] MainAbility onWindowStageDestroy");
}
onForeground() {
// Ability has brought to foreground
console.log("[Demo] MainAbility onForeground");
}
onBackground() {
// Ability has back to background
console.log("[Demo] MainAbility onBackground");
}
}
```
2. Bind the desired ability.
Construct the **want** variable, and specify the bundle name and component name of the application where the ability is located. If cross-device communication is involved, also specify the network ID of the target device, which can be obtained through **deviceManager**. Then, construct the **connect** variable, and specify the callback that is called when the binding is successful, the binding fails, or the ability is disconnected. After that, call the API provided by **featureAbility** to bind an ability.
Construct the **want** variable, and specify the bundle name and component name of the application where the ability is located. If cross-device communication is involved, also specify the network ID of the target device, which can be obtained through **deviceManager**. Then, construct the **connect** variable, and specify the callback that is called when the binding is successful, the binding fails, or the ability is disconnected. If you use the FA model, call the API provided by **featureAbility** to bind an ability. If you use the stage model, obtain a service instance through **Context**, and then call the API provided by **featureAbility** to bind an ability.
```ts
import rpc from "@ohos.rpc"
import featureAbility from "@ohos.ability.featureAbility"
import rpc from "@ohos.rpc";
// Import @ohos.ability.featureAbility only for the application developed based on the FA model.
// import featureAbility from "@ohos.ability.featureAbility";
let proxy = null
let connectId = null
let proxy = null;
let connectId = null;
// Bind the ability on a single device.
let want = {
// Enter the bundle name and ability name.
"bundleName": "ohos.rpc.test.server",
"abilityName": "ohos.rpc.test.server.ServiceAbility",
}
};
let connect = {
onConnect:function(elementName, remote) {
proxy = remote
proxy = remote;
},
onDisconnect:function(elementName) {
},
onFailed:function() {
proxy = null
proxy = null;
}
}
connectId = featureAbility.connectAbility(want, connect)
};
// Use this method to connect to the ability in the FA model.
// connectId = featureAbility.connectAbility(want, connect);
connectId = globalThis.context.connectServiceExtensionAbility(want,connect);
// If you're binding the ability across devices, use deviceManager to obtain the network ID of the target device.
import deviceManager from '@ohos.distributedHardware.deviceManager'
import deviceManager from '@ohos.distributedHardware.deviceManager';
function deviceManagerCallback(deviceManager) {
let deviceList = deviceManager.getTrustedDeviceListSync()
let networkId = deviceList[0].networkId
let deviceList = deviceManager.getTrustedDeviceListSync();
let networkId = deviceList[0].networkId;
let want = {
"bundleName": "ohos.rpc.test.server",
"abilityName": "ohos.rpc.test.service.ServiceAbility",
"networkId": networkId,
"flags": 256
}
connectId = featureAbility.connectAbility(want, connect)
};
// The ID returned after the connection is set up must be saved. The ID will be passed for service disconnection.
// Use this method to connect to the ability in the FA model.
// connectId = featureAbility.connectAbility(want, connect);
connectId = globalThis.context.connectServiceExtensionAbility(want,connect);
}
// The first parameter specifies the bundle name of the application, and the second parameter specifies the callback used to return the device ID obtained by using DeviceManager.
deviceManager.createDeviceManager("ohos.rpc.test", deviceManagerCallback)
deviceManager.createDeviceManager("ohos.rpc.test", deviceManagerCallback);
```
3. Process requests sent from the client.
Call the **onConnect** API to return a proxy object inherited from **rpc.RemoteObject** after the ability is successfully bound. Implement the **onRemoteMessageRequest** API for the proxy object to process requests sent from the client.
```ts
onConnect(want: Want) {
var robj:rpc.RemoteObject = new Stub("rpcTestAbility")
return robj
var robj:rpc.RemoteObject = new Stub("rpcTestAbility");
return robj;
}
class Stub extends rpc.RemoteObject {
constructor(descriptor) {
super(descriptor)
super(descriptor);
}
onRemoteMessageRequest(code, data, reply, option) {
// Process requests sent from the client based on the code.
return true
return true;
}
}
```
4. Process responses sent from the server.
Obtain the proxy object from the **onConnect** callback, call **sendRequestAsync** to send a request, and receive the response using a callback or a promise (an object representing the eventual completion or failure of an asynchronous operation and its result value).
Obtain the proxy object from the **onConnect** callback, call **sendRequest** to send a request, and receive the response using a callback or a promise (an object representing the eventual completion or failure of an asynchronous operation and its result value).
```ts
// Use a promise.
let option = new rpc.MessageOption()
let data = rpc.MessageParcel.create()
let reply = rpc.MessageParcel.create()
let option = new rpc.MessageOption();
let data = rpc.MessageParcel.create();
let reply = rpc.MessageParcel.create();
// Write parameters to data.
proxy.sendRequestAsync(1, data, reply, option)
proxy.sendRequest(1, data, reply, option)
.then(function(result) {
if (result.errCode != 0) {
console.error("send request failed, errCode: " + result.errCode)
return
console.error("send request failed, errCode: " + result.errCode);
return;
}
// Read the result from result.reply.
})
.catch(function(e) {
console.error("send request got exception: " + e)
}
console.error("send request got exception: " + e);
})
.finally(() => {
data.reclaim()
reply.reclaim()
data.reclaim();
reply.reclaim();
})
// Use a callback.
function sendRequestCallback(result) {
try {
if (result.errCode != 0) {
console.error("send request failed, errCode: " + result.errCode)
return
console.error("send request failed, errCode: " + result.errCode);
return;
}
// Read the result from result.reply.
} finally {
result.data.reclaim()
result.reply.reclaim()
result.data.reclaim();
result.reply.reclaim();
}
}
let option = new rpc.MessageOption()
let data = rpc.MessageParcel.create()
let reply = rpc.MessageParcel.create()
let option = new rpc.MessageOption();
let data = rpc.MessageParcel.create();
let reply = rpc.MessageParcel.create();
// Write parameters to data.
proxy.sendRequest(1, data, reply, option, sendRequestCallback)
proxy.sendRequest(1, data, reply, option, sendRequestCallback);
```
5. Tear down the connection.
Use the API provided by **featureAbility** to tear down the connection when the communication is over.
If you use the FA model, call the API provided by **featureAbility** to tear down the connection when the communication is over. If you use the stage model, obtain a service instance through **Context**, and then call the API provided by **featureAbility** to tear down the connection.
```ts
import rpc from "@ohos.rpc"
import featureAbility from "@ohos.ability.featureAbility"
import rpc from "@ohos.rpc";
// Import @ohos.ability.featureAbility only for the application developed based on the FA model.
// import featureAbility from "@ohos.ability.featureAbility";
function disconnectCallback() {
console.info("disconnect ability done")
console.info("disconnect ability done");
}
featureAbility.disconnectAbility(connectId, disconnectCallback)
// Use this method to disconnect from the ability in the FA model.
// featureAbility.disconnectAbility(connectId, disconnectCallback);
globalThis.context.disconnectServiceExtensionAbility(connectId);
```
......@@ -3,42 +3,25 @@
## Basic Concepts
The inter-process communication (IPC) and remote procedure call (RPC) mechanisms are used to implement cross-process communication. The difference between them lies in that IPC uses the Binder driver to implement cross-process communication within a device, whereas RPC uses the DSoftBus driver to implement cross-process communication across devices.
The inter-process communication (IPC) and remote procedure call (RPC) mechanisms are used to implement cross-process communication. The difference between them lies in that IPC uses the Binder driver to implement cross-process communication within a device, whereas RPC uses the DSoftBus driver to implement cross-process communication across devices. The reason why cross-process communication is needed is that each process has its own independent resources and memory space and one process is not allowed to access the resources and memory space of other processes.
The reason why cross-process communication is needed is that each process has its own independent resources and memory space and one process is not allowed to access the resources and memory space of other processes. IPC and RPC usually use the client-server model, where the client (service requester, that is, the process that requests a service) obtains the proxy of the server (service provider, that is, the process that provides the service) and uses the proxy to read and write data to implement data communication across processes. More specifically, the client constructs a proxy object of the server. The proxy object has the same functions as the server. To access a certain API of the server, you only need to access the corresponding API in the proxy object. The proxy object sends the request to the server, and the server processes the received request and returns the processing result to the proxy object through the driver. Then, the proxy object forwards the processing result to the client. The server registers system abilities (SAs) with the system ability manager (SAMgr), which manages the SAs and provides APIs for clients. To communicate with a specific SA, the client must obtain the proxy of the SA from SAMgr.
> **NOTE**
> The applications in the stage model cannot use IPC or RPC directly, and must use the following capabilities to implement related service scenarios:
>- [Background services](../application-models/background-services.md): use IPC to implement service invocation across processes.
>- [Multi-device collaboration](../application-models/hop-multi-device-collaboration.md): uses RPC to call remote interfaces and transfer data.
In the following sections, proxy represents the service requester, and stub represents the service provider.
![IPC&RPC communication mechanisms](figures/IPC_RPC_communication.PNG)
## Implementation Principles
IPC and RPC usually use the client-server model, where the client (service requester, that is, the process that requests a service) obtains the proxy of the server (service provider, that is, the process that provides the service) and uses the proxy to read and write data to implement data communication across processes. More specifically, the client constructs a proxy object of the server. The proxy object has the same functions as the server. To access a certain API of the server, you only need to access the corresponding API in the proxy object. The proxy object sends the request to the server, and the server processes the received request and returns the processing result to the proxy object through the driver. Then, the proxy object forwards the processing result to the client. The server registers system abilities (SAs) with the system ability manager (SAMgr), which manages the SAs and provides APIs for clients. To communicate with a specific SA, the client must obtain the proxy of the SA from SAMgr. In the following sections, proxy represents the service requester, and stub represents the service provider.
## Constraints
- During cross-process communication within a single device, the maximum amount of data to be transmitted is about 1 MB. If the amount of data to be transmitted exceeds this limit, use the [anonymous shared memory](https://gitee.com/openharmony/docs/blob/master/en/application-dev/reference/apis/js-apis-rpc.md#ashmem8).
- Subscription to death notifications of anonymous stub objects (not registered with SAMgr) is prohibited in RPC.
- During cross-process communication across processes, a proxy object cannot be passed back to the device that hosts the stub object pointed by the proxy object. That is, the proxy object pointing to the stub object of the remote device cannot be passed across processes twice on the local device.
## **Recommendations**
First, compile an API class and define message codes in the API class for both communication parties to identify operations. Unimplemented APIs are allowed in the API class because it must be inherited by both communication parties and its inheritance classes cannot be abstract classes. When inheriting the API class, both communication parties must implement the unimplemented APIs, so as to make sure that the inheritance classes are not abstract classes.
Then, implement the API class specific to the stub, and override the **AsObject** and **OnRemoteRequest** APIs. In addition, compile the proxy to implement the APIs in the API class and override the **AsObject** API. You can also encapsulate an additional API for calling **SendRequest** to send data to the peer.
After the preceding operations are done, register a system ability (SA) with SAMgr. Note that the registration should be completed in the process that hosts the stub. Then, obtain the proxy from SAMgr as needed to implement cross-process communication with the stub.
![IPC & RPC communication mechanisms] (figures/IPC_RPC_communication.PNG)
Related steps are as follows:
- Implementing the API class: Inherit **IRemoteBroker**, define message codes, and declare APIs that are not implemented in the API class.
- Implementing the service provider (stub): Inherit **IRemoteStub** or **RemoteObject**, and override the **AsObject** and **OnRemoteRequest** APIs.
- Implementing the service requester (proxy): Inherit **IRemoteProxy** or **RemoteProxy**, override the **AsObject** API, and encapsulate the required API to call **SendRequest**.
- Registering the SA: Apply for a unique ID for the SA, and register the SA with SAMgr.
- Obtaining the SA: Obtain the proxy based on the SA ID and device ID, and use the proxy to communicate with the remote end.
## Constraints
- A maximum of 1 MB data can be transferred in cross-process communication on a single device. If the amount of data to be transmitted is larger than 1 MB, use [anonymous shared memory](../reference/apis/js-apis-rpc.md#ashmem8).
## Related Modules
- Subscription to death notifications of anonymous stub objects (not registered with SAMgr) is prohibited in RPC.
[Distributed Ability Manager Service Framework](https://gitee.com/openharmony/ability_dmsfwk)
- During cross-process communication across processes, a proxy object cannot be passed back to the device that hosts the stub object pointed by the proxy object. That is, the proxy object pointing to the stub object of the remote device cannot be passed across processes twice on the local device.
......@@ -2,12 +2,12 @@
Network management functions include:
- [HTTP data request](http-request.md): initiates a data request through HTTP.
- [WebSocket connection](websocket-connection.md): establishes a bidirectional connection between the server and client through WebSocket.
- [Socket connection](socket-connection.md): transmits data through Socket.
- [Network sharing](net-sharing.md): shares a device's Internet connection with other connected devices by means of Wi-Fi hotspot, Bluetooth, and USB sharing, and queries the network sharing state and shared mobile data volume.
- [Ethernet connection](net-ethernet.md): provides wired network capabilities, which allow you to set the IP address, subnet mask, gateway, and Domain Name System (DNS) server of a wired network.
- [Network connection management](net-connection-manager.md): provides basic network management capabilities, including management of Wi-Fi/cellular/Ethernet connection priorities, network quality evaluation, subscription to network connection status changes, query of network connection information, and DNS resolution.
- [HTTP data request](http-request.md): Initiates a data request through HTTP.
- [WebSocket connection](websocket-connection.md): Establishes a bidirectional connection between the server and client through WebSocket.
- [Socket connection](socket-connection.md): Transmits data through Socket.
- [Network sharing](net-sharing.md): Shares a device's Internet connection with other connected devices by means of Wi-Fi hotspot, Bluetooth, and USB sharing, and queries the network sharing state and shared mobile data volume.
- [Ethernet connection](net-ethernet.md): Provides wired network capabilities, which allow you to set the IP address, subnet mask, gateway, and Domain Name System (DNS) server of a wired network.
- [Network connection management](net-connection-manager.md): Provides basic network management capabilities, including management of Wi-Fi/cellular/Ethernet connection priorities, network quality evaluation, subscription to network connection status changes, query of network connection information, and DNS resolution.
- [mDNS management](net-mdns.md): provides Multicast DNS (mDNS) management capabilities, such as adding, removing, discovering, and resolving local services on a LAN.
## Constraints
......
......@@ -7,7 +7,7 @@ IPC/RPC allows you to subscribe to the state changes of a remote stub object. Wh
This subscription mechanism is applicable when the local proxy object needs to detect death of the process hosting the remote stub object or network detach of the device hosting the remote stub object. When the proxy detects death of the remote stub object, the proxy can clear local resources. Currently, IPC supports death notification for anonymous objects, but RPC does not. That is, you can only subscribe to death notifications of services that have been registered with SAMgr.
## **Using Native APIs**
## **Development Using Native APIs**
| API| Return Value Type| Feature Description|
| -------- | -------- | -------- |
......@@ -21,7 +21,6 @@ This subscription mechanism is applicable when the local proxy object needs to d
#include "iremote_broker.h"
#include "iremote_stub.h"
// Define message codes.
enum {
TRANS_ID_PING_ABILITY = 5,
......@@ -61,9 +60,6 @@ int TestServiceProxy::TestPingAbility(const std::u16string &dummy){
}
```
```c++
#include "iremote_object.h"
......@@ -84,18 +80,54 @@ bool result = object->AddDeathRecipient(deathRecipient); // Add a recipient for
result = object->RemoveDeathRecipient(deathRecipient); // Remove the recipient for death notifications.
```
## **Using JS APIs**
## **Development Using JS APIs**
| API | Return Value Type| Feature Description |
| -------------------- | ---------- | ------------------------------------------------------------ |
| addDeathRecippient | boolean | Adds a recipient for death notifications of the remote object, including death notifications of the remote proxy.|
| removeDeathRecipient | boolean | Removes the recipient for death notifications of the remote object. |
| onRemoteDied | void | Called to perform subsequent operations when a death notification of the remote object is received.|
| ------------------------ | ---------- | ----------------------------------------------------------------- |
| registerDeathRecipient | void | Adds a recipient for death notifications of the remote object, including death notifications of the remote proxy.|
| unregisterDeathRecipient | void | Removes the recipient for death notifications of the remote object. |
| onRemoteDied | void | Called to perform subsequent operations when a death notification of the remote object is received. |
### Obtaining the Context
If you use the stage model, you need to obtain the context before connecting to an ability.
```ts
import Ability from "@ohos.app.ability.UIAbility";
export default class MainAbility extends Ability {
onCreate(want, launchParam) {
console.log("[Demo] MainAbility onCreate");
globalThis.context = this.context;
}
onDestroy() {
console.log("[Demo] MainAbility onDestroy");
}
onWindowStageCreate(windowStage) {
// Main window is created, set main page for this ability
console.log("[Demo] MainAbility onWindowStageCreate");
}
onWindowStageDestroy() {
// Main window is destroyed, release UI related resources
console.log("[Demo] MainAbility onWindowStageDestroy");
}
onForeground() {
// Ability has brought to foreground
console.log("[Demo] MainAbility onForeground");
}
onBackground() {
// Ability has back to background
console.log("[Demo] MainAbility onBackground");
}
}
```
### Sample Code
```ts
import FA from "@ohos.ability.featureAbility";
// Import @ohos.ability.featureAbility only for the application developed based on the FA model.
// import FA from "@ohos.ability.featureAbility";
let proxy;
let connect = {
onConnect: function(elementName, remoteProxy) {
......@@ -113,31 +145,35 @@ let want = {
"bundleName": "com.ohos.server",
"abilityName": "com.ohos.server.EntryAbility",
};
FA.connectAbility(want, connect);
// Use this method to connect to the ability in the FA model.
// FA.connectAbility(want, connect);
globalThis.context.connectServiceExtensionAbility(want, connect);
class MyDeathRecipient {
onRemoteDied() {
console.log("server died");
}
}
let deathRecipient = new MyDeathRecipient();
proxy.addDeathRecippient(deathRecipient, 0);
proxy.removeDeathRecipient(deathRecipient, 0);
proxy.registerDeathRecippient(deathRecipient, 0);
proxy.unregisterDeathRecipient(deathRecipient, 0);
```
## Reverse Death Notification (Anonymous Stub)
Forward dead notification is a mechanism that allows the proxy to detect death notifications of the stub. To achieve reverse dead notification, we can leverage the forward dead notification mechanism to allow the stub to detect death notifications of the proxy.
Forward dead notification is a mechanism that allows the proxy to detect death notifications of the stub. To achieve reverse dead notification, we can leverage the forward dead notification mechanism to allow the stub to detect death notifications of the proxy. Suppose there are two processes, A (the process hosting the original stub) and B (the process hosting the original proxy). After obtaining the proxy object of process A, process B creates an anonymous stub object (that is, a stub object not registered with SAMgr), which can be called a callback stub. Then, process B calls **SendRequest** to send the callback stub to the original stub of process A. As a result, process A obtains the callback proxy of process B. When process B dies or the device hosting process B detaches from the network, the callback stub dies. The callback proxy detects the death of the callback stub and sends a death notification to the original stub. In this way, reverse death notification is implemented.
Note:
Suppose there are two processes, A (the process hosting the original stub) and B (the process hosting the original proxy). After obtaining the proxy object of process A, process B creates an anonymous stub object (that is, a stub object not registered with SAMgr), which can be called a callback stub. Then, process B calls **SendRequest** to send the callback stub to the original stub of process A. As a result, process A obtains the callback proxy of process B. When process B dies or the device hosting process B detaches from the network, the callback stub dies. The callback proxy detects the death of the callback stub and sends a death notification to the original stub. In this way, reverse death notification is implemented.
> Reverse death notification can only be used for cross-process communication within a device.
> NOTE
> - Reverse death notification can only be used for cross-process communication within a device.
> - When an anonymous stub object is not pointed by any proxy, the kernel automatically reclaims the object.
> When an anonymous stub object is not pointed by any proxy, the kernel automatically reclaims the object.
### Sample Code
```c++
// Proxy
//Proxy
int TestAbilityProxy::TestAnonymousStub()
{
MessageOption option;
......@@ -149,7 +185,7 @@ int TestAbilityProxy::TestAnonymousStub()
return result;
}
// Stub
//Stub
int TestAbilityStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
{
......
......@@ -10,9 +10,10 @@ This document describes the general development process for MindSpore Lite model
Before getting started, you need to understand the following basic concepts:
**Tensor**: a special data structure that is similar to arrays and matrices. It is a basic data structure used in MindSpore Lite network operations.
**Tensor**: a special data structure that is similar to arrays and matrices. It is basic data structure used in MindSpore Lite network operations.
**Float16 inference mode**: a mode that uses half-precision inference. Float16 uses 16 bits to represent a number and therefore it is also called half-precision.
**Float16 inference**: a mode in which Float16 is used for inference. Float16, also called half-precision, uses 16 bits to represent a number.
## Available APIs
......@@ -23,7 +24,7 @@ APIs involved in MindSpore Lite model inference are categorized into context API
| ------------------ | ----------------- |
|OH_AI_ContextHandle OH_AI_ContextCreate()|Creates a context object.|
|void OH_AI_ContextSetThreadNum(OH_AI_ContextHandle context, int32_t thread_num)|Sets the number of runtime threads.|
| void OH_AI_ContextSetThreadAffinityMode(OH_AI_ContextHandle context, int mode)|Sets the affinity mode for binding runtime threads to CPU cores, which are classified into large, medium, and small cores based on the CPU frequency. You only need to bind the large or medium cores, but not small cores.|
| void OH_AI_ContextSetThreadAffinityMode(OH_AI_ContextHandle context, int mode)|Sets the affinity mode for binding runtime threads to CPU cores, which are classified into large, medium, and small cores based on the CPU frequency. You only need to bind the large or medium cores, but not small cores.
|OH_AI_DeviceInfoHandle OH_AI_DeviceInfoCreate(OH_AI_DeviceType device_type)|Creates a runtime device information object.|
|void OH_AI_ContextDestroy(OH_AI_ContextHandle *context)|Destroys a context object.|
|void OH_AI_DeviceInfoSetEnableFP16(OH_AI_DeviceInfoHandle device_info, bool is_fp16)|Sets whether to enable float16 inference. This function is available only for CPU and GPU devices.|
......@@ -53,9 +54,7 @@ The following figure shows the development process for MindSpore Lite model infe
**Figure 1** Development process for MindSpore Lite model inference
![how-to-use-mindspore-lite](figures/01.png)
Before moving to the main process, you need to reference related header files and compile functions to generate random input.
Example code:
Before moving to the development process, you need to reference related header files and compile functions to generate random input. The sample code is as follows:
```c
#include <stdlib.h>
......@@ -81,16 +80,19 @@ int GenerateInputDataWithRandom(OH_AI_TensorHandleArray inputs) {
```
The development process consists of the following main steps:
1. Prepare the required model.
The required model can be downloaded directly or obtained using the model conversion tool.
- If the downloaded model is in the `.ms` format, you can use it directly for inference. The following uses the **mobilenetv2.ms** model as an example.
- If the downloaded model uses a third-party framework, such as TensorFlow, TensorFlow Lite, Caffe, or ONNX, you can use the [model conversion tool](https://www.mindspore.cn/lite/docs/en/r1.5/use/downloads.html#id1) to convert it to the `.ms` format.
- If the downloaded model uses a third-party framework, such as TensorFlow, TensorFlow Lite, Caffe, or ONNX, you can use the [model conversion tool](https://www.mindspore.cn/lite/docs/zh-CN/r1.5/use/downloads.html#id1) to convert it to the .ms format.
2. Create a context, and set parameters such as the number of runtime threads and device type.
The following describes two typical scenarios:
Scenario 1: Only the CPU inference context is created.
```c
// Create a context, and set the number of runtime threads to 2 and the thread affinity mode to 1 (big cores first).
OH_AI_ContextHandle context = OH_AI_ContextCreate();
......@@ -112,6 +114,44 @@ The development process consists of the following main steps:
OH_AI_ContextAddDeviceInfo(context, cpu_device_info);
```
Scenario 2: The neural network runtime (NNRT) and CPU heterogeneous inference contexts are created.
NNRT is the runtime for cross-chip inference computing in the AI field. Generally, the acceleration hardware connected to NNRT, such as the NPU, has strong inference capabilities but supports only a limited number of operators, whereas the general-purpose CPU has weak inference capabilities but supports a wide range of operators. MindSpore Lite supports NNRT/CPU heterogeneous inference. Model operators are preferentially scheduled to NNRT inference. If certain operators are not supported by NNRT, then they are scheduled to the CPU for inference. The following is the sample code for configuring NNRT/CPU heterogeneous inference:
> **NOTE**
>
> NNRT/CPU heterogeneous inference requires access of NNRT hardware. For details, see [OpenHarmony/ai_neural_network_runtime](https://gitee.com/openharmony/ai_neural_network_runtime).
```c
// Create a context, and set the number of runtime threads to 2 and the thread affinity mode to 1 (big cores first).
OH_AI_ContextHandle context = OH_AI_ContextCreate();
if (context == NULL) {
printf("OH_AI_ContextCreate failed.\n");
return OH_AI_STATUS_LITE_ERROR;
}
// Preferentially use NNRT inference.
// Use the NNRT hardware of the first ACCELERATORS class to create the NNRT device information and configure the high-performance inference mode for the NNRT hardware. You can also use OH_AI_GetAllNNRTDeviceDescs() to obtain the list of NNRT devices in the current environment, search for a specific device by device name or type, and use the device as the NNRT inference hardware.
OH_AI_DeviceInfoHandle nnrt_device_info = OH_AI_CreateNNRTDeviceInfoByType(OH_AI_NNRTDEVICE_ACCELERATORS);
if (nnrt_device_info == NULL) {
printf("OH_AI_DeviceInfoCreate failed.\n");
OH_AI_ContextDestroy(&context);
return OH_AI_STATUS_LITE_ERROR;
}
OH_AI_DeviceInfoSetPerformaceMode(nnrt_device_info, OH_AI_PERFORMANCE_HIGH);
OH_AI_ContextAddDeviceInfo(context, nnrt_device_info);
// Configure CPU inference.
OH_AI_DeviceInfoHandle cpu_device_info = OH_AI_DeviceInfoCreate(OH_AI_DEVICETYPE_CPU);
if (cpu_device_info == NULL) {
printf("OH_AI_DeviceInfoCreate failed.\n");
OH_AI_ContextDestroy(&context);
return OH_AI_STATUS_LITE_ERROR;
}
OH_AI_ContextAddDeviceInfo(context, cpu_device_info);
```
3. Create, load, and build the model.
Call **OH_AI_ModelBuildFromFile** to load and build the model.
......@@ -127,7 +167,7 @@ The development process consists of the following main steps:
return OH_AI_STATUS_LITE_ERROR;
}
// Load and build the model. The model type is OH_AI_MODELTYPE_MINDIR.
// Load and build the inference model. The model type is OH_AI_MODELTYPE_MINDIR.
int ret = OH_AI_ModelBuildFromFile(model, argv[1], OH_AI_MODELTYPE_MINDIR, context);
if (ret != OH_AI_STATUS_SUCCESS) {
printf("OH_AI_ModelBuildFromFile failed, ret: %d.\n", ret);
......@@ -219,7 +259,7 @@ The development process consists of the following main steps:
dl
)
```
- To use ohos-sdk for cross compilation, you need to set the native toolchain path for the CMake tool as follows: `-DCMAKE_TOOLCHAIN_FILE="/xxx/ohos-sdk/linux/native/build/cmake/ohos.toolchain.camke"`.
- To use ohos-sdk for cross compilation, you need to set the native toolchain path for the CMake tool as follows: `-DCMAKE_TOOLCHAIN_FILE="/xxx/native/build/cmake/ohos.toolchain.camke"`.
- The toolchain builds a 64-bit application by default. To build a 32-bit application, add the following configuration: `-DOHOS_ARCH="armeabi-v7a"`.
......@@ -240,3 +280,7 @@ The development process consists of the following main steps:
output data is:
0.000018 0.000012 0.000026 0.000194 0.000156 0.001501 0.000240 0.000825 0.000016 0.000006 0.000007 0.000004 0.000004 0.000004 0.000015 0.000099 0.000011 0.000013 0.000005 0.000023 0.000004 0.000008 0.000003 0.000003 0.000008 0.000014 0.000012 0.000006 0.000019 0.000006 0.000018 0.000024 0.000010 0.000002 0.000028 0.000372 0.000010 0.000017 0.000008 0.000004 0.000007 0.000010 0.000007 0.000012 0.000005 0.000015 0.000007 0.000040 0.000004 0.000085 0.000023
```
## Samples
The following sample is provided to help you better understand how to use MindSpore Lite:
- [Simple MindSpore Lite Tutorial](https://gitee.com/openharmony/third_party_mindspore/tree/OpenHarmony-3.2-Release/mindspore/lite/examples/quick_start_c)
......@@ -31,7 +31,7 @@ The Short Messaging Service (SMS) module provides basic SMS management functions
| Name | Description |
| ------------------------------------------------------------ | ------------------------------------------------------- |
| createMessage(pdu: Array<number>, specification: string, callback: AsyncCallback\<ShortMessage>): void | Creates an SMS message instance based on the PDU and the specified SMS protocol.|
| createMessage(pdu: Array\<number>, specification: string, callback: AsyncCallback\<ShortMessage>): void | Creates an SMS message instance based on the PDU and the specified SMS protocol.|
| sendMessage(options: SendMessageOptions): void | Sends text or data SMS messages. |
| getDefaultSmsSlotId(callback: AsyncCallback\<number>): void | Obtains the ID of the default SIM card used to send SMS messages. |
| setSmscAddr(slotId: number, smscAddr: string, callback: AsyncCallback\<void>): void | Sets the SMSC address based on the specified slot ID. |
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册