Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
机器未来
Paddle
提交
66230967
P
Paddle
项目概览
机器未来
/
Paddle
与 Fork 源项目一致
Fork自
PaddlePaddle / Paddle
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
66230967
编写于
3月 26, 2017
作者:
Y
Yu Yang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add Implementation documentation.
Also change previous design file, make concept consistant.
上级
6b78a11f
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
112 addition
and
6 deletion
+112
-6
doc/design/multi_language_interface/00.why_plain_c.md
doc/design/multi_language_interface/00.why_plain_c.md
+6
-6
doc/design/multi_language_interface/01.inference_implementation.md
...n/multi_language_interface/01.inference_implementation.md
+106
-0
未找到文件。
doc/design/multi_language_interface/why_plain_c.md
→
doc/design/multi_language_interface/
00.
why_plain_c.md
浏览文件 @
66230967
...
...
@@ -70,20 +70,20 @@ extern "C"
paddle_error
paddle_matrix_shape
(
paddle_matrix
matrix
,
uint64_t
*
width
,
uint64_t
*
height
)
{
auto
m
=
(
paddle
::
math
::
m
atrix
*
)(
matrix
);
auto
m
=
(
paddle
::
capi
::
CM
atrix
*
)(
matrix
);
*
width
=
m
->
width
();
*
height
=
m
->
height
();
}
```
其中
`paddle/
math/m
atrix.hpp`
文件内容为:
其中
`paddle/
capi/CM
atrix.hpp`
文件内容为:
```
cpp
namespace
paddle
{
namespace
math
{
class
Matrix
{
//...
class
C
Matrix
{
std
::
shared_ptr
<
paddle
::
Matrix
>
mat
;
};
}
// namespace math
...
...
@@ -113,6 +113,6 @@ class Matrix {
| 手写多语言绑定 | 不使用SWIG | 使用SWIG需要多语言绑定的开发人员熟练掌握SWIG配置,社区参与困难。SWIG生成的代码不能保证多语言代码风格的一致性 |
##
简单
实现
## 实现
TBD
参考
[
预测接口实现
](
./01.inference_implementation.md
)
doc/design/multi_language_interface/01.inference_implementation.md
0 → 100644
浏览文件 @
66230967
# C-API 模型推断实现文档
本文档描述Paddle C-API的实现细节。Paddle C-API是多语言API的基础部分。Paddle需要暴露的API很多。先实现模型推断的API,通过模型推断API的实现作为一个样例,来进行讨论。至于为什么需要C-API,请参考
[
这里
](
./00.why_plain_c.md
)
。
## 暴露接口原则
1.
所有的接口均为C接口。即使用
`extern "C"`
2.
除构造某种类型的函数(
`paddle_matrix_create`
等),其他函数均返回
`paddle_error`
。且调用时不能抛出异常或出现运行时错误。
3.
所有类型名为
`paddle_类型名`
,所有与类型相关的函数,函数名为
`paddle_类型名_函数名`
4.
如果某一个Paddle Core概念(GradientMachine/Matrix)需要被暴露到其他语言,那么
*
为了暴露的接口尽量简单。只暴露概念的接口,而不暴露概念的实现。即暴露
`GradientMachine`
或者
`Matrix`
但不暴露
`RecurrentGradientMachine`
和
`CpuSparseMatrix`
。
*
暴露这个概念必要函数。
`必要`
是指,即完成某一个任务的最少函数。
5.
不在
`capi`
接口层做过多封装。
*
如果某一个Paddle概念必须要暴露,但是又过于琐碎。不在
`capi`
这一层进行封装,而是直接修改Paddle Core。让Paddle核心中,这一概念不再琐碎。
## 目录结构
```
text
Paddle
`-- paddle
`-- capi
`-- examples # The example project for C-API.
`-- tests # unittests for C-API
`-- capi.h # C-API header file.
`-- capi_private.h # The shared header file between implementation sources.
`-- matrix.{h, cpp}
`-- gradient_machine.{h, cpp}
`-- ...
```
Paddle的C-API目录结构如上图表所示。这个目录中除了
`capi_private.h`
之外的所有头文件,均会被安装到include/paddle路径下。C-API生成的二进制文件会被安装到
`lib`
目录下。即,安装后的目录结构为
```
text
`-- include
`-- paddle
`-- capi.h
`-- matrix.h
`-- gradient_machine.h
`-- ...
`-- lib
`-- libpaddle_capi_shared.{so, dylib} # In mac, dynamic libary's file name extention is `dylib`
`-- libpaddle_capi_whole.a # static library for all symbols of Paddle.
```
## 实现方式
下面分别介绍某一类文件的实现方式。
### capi.h
`capi.h`
是用户使用C-API时所唯一需要引入的头文件。在
`capi.h`
中,引入了类型的头文件,
`matrix.h`
,
`gradient_machine.h`
。在引入其他类型的头文件时,使用相对路径的引用方式。即
`#include "matrix.h"`
### 具体某种类型的头文件
具体某种类型的头文件,即例如
`matrix.h`
,
`gradient_machine.h`
等。在这些头文件中,包含了某种类型的类型定义和暴露的全部函数。
这个头文件不假设其他文件的引用顺序,即使用户直接引用某种类型的头文件,也不应该报错(虽然不鼓励这样)。如果某一个类型需要引用另一个类型,例如
`gradient_machine`
需要引用
`matrix`
,则直接引入另一种类型的头文件,即
`#include "matrix.h"`
。
### capi_private.h
`capi_prviate.h`
是各个实现中共享的头文件,他主要包含了实际暴露的类型结构。在用户使用C-API时,Paddle的类型全部退化成
`void *`
,即
`typedef paddle_matrix void*`
。但,对于每种C-API暴露的类型,均是在
`capi_private.h`
中实现的结构体。
```
cpp
struct
CMatrix
{
int
type
=
MatrixType
;
std
::
shared_ptr
<
paddle
::
Matrix
>
mat
;
};
```
通常,这个结构体包含两个项目。
*
`type`
是一个类型的标志。对于每种类型,type字段均不尽相同。这样,即使C-API接受的类型全是
`void *`
,我们也可以确定每一个参数的类型。
```
cpp
void
some_c_api_function
(
void
*
some_instance
)
{
int
*
type
=
(
int
*
)
some_instance
;
switch
(
*
type
)
{
case
MatrixType
:
CMatrix
*
mat
=
(
CMatrix
*
)
some_instance
;
...
...
}
}
```
*
这个结构体中的另一个项目是,Paddle Core中这一类型接口的智能指针(shared_ptr)。
*
使用智能指针的原因是: 用户可以安全的释放某个C-API的实例,而不必在意Paddle Core是否还在使用这个实例。
*
例如,用户通过C-API获得了神经网络的参数实例。当用户使用完这个参数后,直接删除这个参数即可。即便Paddle Core中的模型还在使用这个参数,这个参数也不会一并删除。
### 具体某种类型的实现文件
具体某种类型的实现文件,即
`matrix.cpp`
,
`gradient_machine.cpp`
等文件。在这些文件中,使用C++ 11实现了C-API的接口,并且使用
`extern "C"`
导出这些接口。在实现过程中,对输入参数的安全性进行了必要的判断,并将C-API接口的参数转发给
`Paddle Core`
。
### libpaddle\_capi_shared.{so, dylib}
`libpaddle_capi_shared`
是C-API导出的动态库。这个动态库的连接参数与Paddle的其他二进制(例如
`paddle_traienr`
)类似。用户可以直接使用这个动态库来引入Paddle C-API。具体使用方法为
`-lpaddle_capi_shared`
。
### libpaddle\_capi_whole.a
`libpaddle_capi_whole`
是C-API导出的静态库。这个静态库包含了Paddle的全部符号。他是将
`libpaddle_gserver.a`
,
`libpaddle_math.a`
,
`libpaddle_capi.a`
等全部静态库中的目标文件全部打包后产生的文件。具体使用方法为
`--whole-archive -lpaddle_capi_whole --no-whole-archive`
。
### examples
在样例中,使用
`C99`
开发了模型预测的样例代码。具体请参考
[
example/README.md
](
../../../paddle/capi/examples/README.md
)
。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录