forked from openvinotoolkit/openvino
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[C API DOC][DG] C API developer documentation (openvinotoolkit#13499)
* [C API DOC] add c api docs Signed-off-by: xuejun <[email protected]> * Update OpenVINO_Runtime_C_API_User_Guide.md Add mapping relationship about C++ API 2.0 and C API * [C API][DG] Add some roles for developping C API Signed-off-by: xuejun <[email protected]> * [C API DOC][DG] Implement the developer guide Signed-off-by: xuejun <[email protected]> * [C API DOC][DG] Fix comments Signed-off-by: xuejun <[email protected]> * [C API DOC][DG] Fix format issue Signed-off-by: xuejun <[email protected]> * [C API][DG] Fix review issues including add reference link, clear description Signed-off-by: xuejun <[email protected]> * [C API][DOC] Fix review comments Signed-off-by: xuejun <[email protected]> * [C API][DOC] remove the mapping relationship of interface & object Signed-off-by: xuejun <[email protected]> * [C API][DOC] Fix review comments Signed-off-by: xuejun <[email protected]> * [C API][DOC] add descriptions for unit test Signed-off-by: xuejun <[email protected]> Signed-off-by: xuejun <[email protected]>
- Loading branch information
1 parent
8786fbe
commit 1910f42
Showing
5 changed files
with
240 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
# OpenVINO C API | ||
|
||
OpenVINO C API is a key part of the OpenVINO extension for C API users. This component provides C API for OpenVINO Toolkit. | ||
|
||
```mermaid | ||
flowchart LR | ||
c_application[("C Application")] | ||
openvino_c{{openvino::c}} | ||
openvino{{openvino}} | ||
style c_application fill:#427cb0 | ||
style openvino_c fill:#6c9f7f | ||
style openvino fill:#6c9f7f | ||
c_application-->openvino_c-->openvino | ||
``` | ||
|
||
OpenVINO C API uses [the common coding style rules](../../../docs/dev/coding_style.md). | ||
|
||
## Key contacts | ||
|
||
People from the [openvino-c-api-maintainers](https://github.com/orgs/openvinotoolkit/teams/openvino-c-api-maintainers) group have the rights to approve and merge PRs to the C API component. They can assist with any questions about C API component. | ||
|
||
## Components | ||
|
||
OpenVINO C API has the following structure: | ||
* [docs](./docs) contains developer documentation for OpenVINO C APIs. | ||
* [include](./include) contains all provided C API headers. [Learn more](https://docs.openvino.ai/latest/api/api_reference.html). | ||
* [src](./src) contains the implementations of all C APIs. | ||
* [tests](./tests) contains all tests for OpenVINO C APIs. [Learn more](./docs/how_to_write_unit_test.md). | ||
|
||
> **NOTE**: Using API 2.0 is strongly recommended. Legacy API (for C) [header file](./include/c_api/ie_c_api.h), [source file](./src/ie_c_api.cpp), [unit test](./tests/ie_c_api_test.cpp) are also included in the component, but the legacy API is no longer extended. | ||
## Tutorials | ||
|
||
* [How to integrate OpenVINO C API with Your Application](https://docs.openvino.ai/latest/openvino_docs_OV_UG_Integrate_OV_with_your_application.html) | ||
* [How to wrap OpenVINO objects with C](./docs/how_to_wrap_openvino_objects_with_c.md) | ||
* [How to wrap OpenVINO interfaces with C](./docs/how_to_wrap_openvino_interfaces_with_c.md) | ||
* [Samples implemented by OpenVINO C API](../../../samples/c/) | ||
* [How to debug C API issues](./docs/how_to_debug_c_api_issues.md) | ||
* [How to write unit test](./docs/how_to_write_unit_test.md) | ||
|
||
## How to contribute to the OpenVINO repository | ||
|
||
See [CONTRIBUTING](../../../CONTRIBUTING.md) for details. | ||
|
||
## See also | ||
|
||
* [OpenVINO™ README](../../../README.md) | ||
* [OpenVINO Runtime C API User Guide](https://docs.openvino.ai/latest/openvino_docs_OV_UG_Integrate_OV_with_your_application.html) | ||
* [Migration of OpenVINO C API](https://docs.openvino.ai/latest/openvino_2_0_transition_guide.html) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# How to Debug C API Issues | ||
|
||
C API provides exception handling, here are all possible return values of the functions: | ||
|
||
https://github.com/openvinotoolkit/openvino/blob/d96c25844d6cfd5ad131539c8a0928266127b05a/src/bindings/c/include/openvino/c/ov_common.h#L68-L96 | ||
|
||
There are two main types of possible issues: | ||
* parameter checking issue: return value is -14, check the input parameters | ||
* C++ call exception issue: if C++ called by C interface throw exception, C interface will catch the exception but no throw to C user, just returns the status value, without a detailed message. If you want details, can print it in exception macro. | ||
|
||
## See also | ||
* [OpenVINO™ README](../../../../README.md) | ||
* [C API developer guide](../README.md) | ||
* [OpenVINO Debug Capabilities](../../../../docs/dev/debug_capabilities.md) |
81 changes: 81 additions & 0 deletions
81
src/bindings/c/docs/how_to_wrap_openvino_interfaces_with_c.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
# How to wrap OpenVINO interfaces with C | ||
|
||
The library `openvino_c` implements most C++ interfaces provided in OpenVINO with C. | ||
This page describes how to wrap C++ interfaces from OpenVINO to C interfaces: | ||
1) Define C interface name and input parameters | ||
2) Check the validation of input parameters | ||
3) Convert C input parameters to C++ interface parameters | ||
4) Call C++ interface and get return object | ||
5) Convert C++ return object to C object | ||
|
||
```mermaid | ||
flowchart LR | ||
subgraph c_wrap_process[Wrapping C++ by C Flow] | ||
c_interface["Define C name"] | ||
c_check_parameter["Input parameter checking"] | ||
c_return_invalid["return ov_status_e::INVALID_C_PARAM"] | ||
subgraph c_wrap_call_cpp[Try Call C++] | ||
c_parameter_convert["convert C parameters to C++ parameters"] | ||
c_call_cpp_interface["call C++ interface"] | ||
cpp_parameter_convert["convert C++ returned objects to C object"] | ||
end | ||
c_return_success["return ov_status_e::OK"] | ||
c_return_exception["catch EXCEPTION and return"] | ||
c_interface-->c_check_parameter | ||
c_check_parameter--valid-->c_parameter_convert | ||
c_check_parameter--invalid-->c_return_invalid | ||
c_parameter_convert-->c_call_cpp_interface | ||
c_call_cpp_interface-->cpp_parameter_convert | ||
cpp_parameter_convert-->c_return_success | ||
c_wrap_call_cpp-->c_return_exception | ||
end | ||
``` | ||
|
||
All C-provided interfaces can be classified into three types of methods: | ||
- Wrap C++ interface to create an object | ||
- Wrap C++ interface to operate an object | ||
- Interfaces implemented by C | ||
|
||
## Wrap C++ interface to create an object | ||
Like the C++ programming create `class` instance, C also need to create related object such as creating `ov::Core`, `ov::Model`, `ov::InferRequest` and so on. C wrap this operation directly and save a shared pointer to the object(C++) back to C `struct` object. Based on the above wrapping method, example about creating `ov::Core` instance will be introduction for more details to illustrate how to wrap C++ interfaces. | ||
|
||
Thinking about the C++ interface: | ||
|
||
https://github.com/openvinotoolkit/openvino/blob/d96c25844d6cfd5ad131539c8a0928266127b05a/src/inference/include/openvino/runtime/core.hpp#L46-L58 | ||
|
||
C wrap as following: | ||
|
||
https://github.com/openvinotoolkit/openvino/blob/d96c25844d6cfd5ad131539c8a0928266127b05a/src/bindings/c/src/ov_core.cpp#L48-L64 | ||
|
||
Because the C++ core create API has default parameter `const std::string& xml_config_file = {}`, C has to create two APIs for it. For default parameter missing case, C calls the func with default parameter but value is NULL. So the following introduction focus on the func with default parameter. The first define the API name `ov_core_create_with_config` and than do the input parameters checking. For core creates no need C parameters convert to C++, call C++ API directly and make a shared pointer `std::make_shared<ov::Core>(xml_config_file)`. Than get result from C++ call and save to C object `*core = _core.release()`. If no error, return success `return ov_status_e::OK;`. Note that almost all C interfaces pass a pointer parameter to save result, which also need to be freed after use. | ||
|
||
## Wrap C++ interface to operate object | ||
C++ interface provides many ways to operate instances, such as set/get property for core, infer request do infer, get info from model and so on. C also need provides those related operations. Here is an example about doing inference: | ||
|
||
https://github.com/openvinotoolkit/openvino/blob/d96c25844d6cfd5ad131539c8a0928266127b05a/src/bindings/c/src/ov_infer_request.cpp#L236-L247 | ||
|
||
This interface call C++ API directly without return value need to save. But need to note the input parameter, which is a C `struct` pointer for providing operation object. | ||
|
||
## C implement interface | ||
To provide more convenience for C users, C implements some C++ class by rewriting including `shape`, `dimension`, `partial shape` and so on. Because of this, C also implements some interface to create/operate C `struct` objects, which also needs the conversion from C object to C++ object before C++ call. | ||
|
||
For example, the C `shape` created by | ||
|
||
https://github.com/openvinotoolkit/openvino/blob/d96c25844d6cfd5ad131539c8a0928266127b05a/src/bindings/c/src/ov_shape.cpp#L17-L33 | ||
|
||
As we can see no C++ interface called. But when the object needs to be used for C++ call, which will provide info to create the related C++ object before call, such as: | ||
|
||
https://github.com/openvinotoolkit/openvino/blob/d96c25844d6cfd5ad131539c8a0928266127b05a/src/bindings/c/src/ov_tensor.cpp#L41-L55 | ||
|
||
The tensor create needs to specify the shape info, so C shape need to be converted to C++ class before C++ interface using. Vice versa, the object needs to convert to C rewriting object for C users convenience. | ||
|
||
## See also | ||
* [OpenVINO™ README](../../../../README.md) | ||
* [C API developer guide](../README.md) | ||
* [C API Reference](https://docs.openvino.ai/latest/api/api_reference.html) |
76 changes: 76 additions & 0 deletions
76
src/bindings/c/docs/how_to_wrap_openvino_objects_with_c.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
# How to wrap OpenVINO objects with C | ||
|
||
Here is the details about how to wrap objects(C++) form OpenVINO to objects(C). | ||
|
||
In OpenVINO C++ implementation, many objects are defined with `class`, such as `ov::Core`, `ov::Model`, `ov::InferRequest`..., but for C `class` doesn't be supported. So, C need to create new object to represent those objects. Three kinds of methods had been adopted in our implementation: | ||
* C `struct` contains a shared pointer to C++ `class`, [Wrap by C++ Shared Pointer](#wrap_by_c++_shared_pointer) | ||
* C `struct` contains a instance of C++ `class`, [Wrap by C++ Object](#wrap_by_c++_object) | ||
* C `struct` rewrite the C++ `class`, [Wrap by Rewrite](#wrap_by_rewrite) | ||
|
||
Tips: | ||
1) For the objects which needs to be hided for users, C `struct` contains a shared pointer will be adopted. | ||
2) For the objects which needs to be created, operated and read by users, rewrite the C++ `class` will be better. | ||
3) For some simple objects, C `struct` contains a instance of C++ `class` will be enough. | ||
|
||
## Wrap by C++ Shared Pointer | ||
|
||
C construct a new `struct` represents the class, which contains a shared pointer to the `class` as following: | ||
|
||
``` | ||
struct ov_class_name { | ||
std::shared_ptr<ov::ClassName> object; | ||
}; | ||
``` | ||
|
||
Here is an example (core) for wrapping by shared pointer: | ||
|
||
https://github.com/openvinotoolkit/openvino/blob/d96c25844d6cfd5ad131539c8a0928266127b05a/src/inference/include/openvino/runtime/core.hpp#L41-L684 | ||
|
||
Represent by C `struct`: | ||
|
||
https://github.com/openvinotoolkit/openvino/blob/d96c25844d6cfd5ad131539c8a0928266127b05a/src/bindings/c/src/common.h#L47-L53 | ||
|
||
C provides the `struct` by `typedef struct ov_core ov_core_t;` | ||
|
||
## Wrap by C++ Object | ||
|
||
C construct a new `struct` represents the class, which contains an instance to C++ `class` as following: | ||
|
||
``` | ||
struct ov_ClassName { | ||
ov::ClassName object; | ||
}; | ||
``` | ||
|
||
Here is an example (layout) for wrapping by shared pointer: | ||
|
||
https://github.com/openvinotoolkit/openvino/blob/d96c25844d6cfd5ad131539c8a0928266127b05a/src/core/include/openvino/core/layout.hpp#L44-L107 | ||
|
||
Represent by C `struct`: | ||
|
||
https://github.com/openvinotoolkit/openvino/blob/d96c25844d6cfd5ad131539c8a0928266127b05a/src/bindings/c/src/common.h#L95-L101 | ||
|
||
C provides the `struct` by `typedef struct ov_layout ov_layout_t;` | ||
|
||
## Wrap by Rewrite | ||
|
||
C construct a new `struct` represents the class, which rewrites related info to the `class` as following: | ||
|
||
``` | ||
typedef struct { | ||
ov::ClassName object; | ||
} ov_class_name_t; | ||
``` | ||
Here is an example (shape) for wrapping by shared pointer: | ||
https://github.com/openvinotoolkit/openvino/blob/d96c25844d6cfd5ad131539c8a0928266127b05a/src/core/include/openvino/core/shape.hpp#L21-L40 | ||
|
||
Represent by C `struct` [here](../src/common.h) | ||
|
||
https://github.com/openvinotoolkit/openvino/blob/d96c25844d6cfd5ad131539c8a0928266127b05a/src/bindings/c/include/openvino/c/ov_shape.h#L15-L22 | ||
|
||
> **NOTE**: this implementation needs developer create the C++ `class` based on the C `struct` info in using this rewrite type. | ||
## See also | ||
* [OpenVINO™ README](../../../../README.md) | ||
* [C API developer guide](../README.md) | ||
* [C API Reference](https://docs.openvino.ai/latest/api/api_reference.html) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# How to Write Unit Test for C API | ||
|
||
To ensure the accuracy of C API, all interfaces need to implement function level unit test at least. According to the object define, all implemented unit test cases are located in this folder. | ||
|
||
The generated binary `ov_capi_test` included the unit cases about all implemented C API interfaces. | ||
|
||
If developer wrap new interfaces from OpenVINO C++, you also need to add the unit test case in the correct location. | ||
Here is an example wrap C++ interface to C [wrap core](./how_to_wrap_openvino_interfaces_with_c.md). | ||
|
||
Create unit test case for this interface. At first, this interface is for core operation so the location should at [ov_core_test.cpp](../tests/ov_core_test.cpp). Also, the interface has default parameter so need to make unit test case for parameter missing. The final based function level test like: | ||
|
||
https://github.com/openvinotoolkit/openvino/blob/d96c25844d6cfd5ad131539c8a0928266127b05a/src/bindings/c/tests/ov_core_test.cpp#L39-L63 | ||
|
||
## See also | ||
* [OpenVINO™ README](../../../../README.md) | ||
* [C API developer guide](../README.md) | ||
* [C API Reference](https://docs.openvino.ai/latest/api/api_reference.html) | ||
|