Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
PaddleDetection
提交
baf890ac
P
PaddleDetection
项目概览
PaddlePaddle
/
PaddleDetection
大约 1 年 前同步成功
通知
694
Star
11112
Fork
2696
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
184
列表
看板
标记
里程碑
合并请求
40
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
PaddleDetection
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
184
Issue
184
列表
看板
标记
里程碑
合并请求
40
合并请求
40
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
baf890ac
编写于
3月 14, 2017
作者:
Y
Yu Yang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add doc in chinese.
Why plain C is better for Paddle to use as a multi-language interface.
上级
51c45854
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
88 addition
and
0 deletion
+88
-0
doc/design/multi_language_interface/why_plain_c.md
doc/design/multi_language_interface/why_plain_c.md
+88
-0
未找到文件。
doc/design/multi_language_interface/why_plain_c.md
0 → 100644
浏览文件 @
baf890ac
# Paddle多语言接口实现
## 背景
Paddle需要一个多语言接口,这个接口需要做到:
*
有标准的,良好的文档
*
例如Python可以使用
[
Sphinx
](
http://www.sphinx-doc.org/en/stable/
)
生成API文档,golang可以使用
[
GoDoc
](
https://godoc.org/golang.org/x/tools/cmd/godoc
)
生成文档。这都需要这个接口按照约定俗成的规则来注释完备。
*
不同语言的接口适应不同语言的特性
*
例如Java与Python的错误处理是直接扔出来Exception,而对于golang错误处理应该使用返回值。
我们可以将计算相关的代码使用C/C++来完成,而将逻辑结构相关的代码交由其他更高级的语言完成。不同开发语言具有不同的优势领域。使用多种语言混合开发Paddle可以增加Paddle的开发效率。
## 基本要求
Paddle的多语言接口实现包括一下几个方面:
*
我们使用动态库来分发Paddle。在这个动态库中不嵌入任何其他语言的解释器,也不使用其他动态库。
*
这个动态库使用C99标准的头文件导出一些函数,不使用/导出C++符号。
*
不导出Paddle内部的结构体、类,仅仅使用
`void*`
指针作为类型的句柄(handler)。
*
不使用SWIG这种代码生成器,而是手写多语言绑定。
## 原因
### 使用动态库来分发Paddle
*
Paddle的链接方式比较复杂(使用了--whole-archieve),如果使用了静态库分发,那么要求使用Paddle库的人按照Paddle的要求链接Paddle,这通常比较复杂。
*
编译型语言,例如C/C++使用静态库和动态库难度差不多。但是含有解释器的语言,例如python或者java,基本上只能够调用动态库。
### 动态库中不嵌入任何其他语言的解释器
*
目前Paddle的进程模型是C++内部驱动Python解释器进行模型配置解析和数据读取
*
我们最终的动态库中不嵌入Python或者其他任何语言的解释器。模型配置解析,数据读取均交由其他语言完成
现阶段Paddle有一个问题是,Paddle内嵌的Python解释器和外部使用的Python如果版本不同,会直接报错退出。
### Paddle动态库中,不引用其他动态库
*
即这个动态库是不依赖于其他任何文件的,可以在任何机器上执行的。
### 这个动态库使用C99标准的头文件导出一些函数,不使用/导出C++符号
*
由于C++编译器没有
[
名字修饰
](
https://en.wikipedia.org/wiki/Name_mangling#C.2B.2B
)
的规范,不同版本的编译器之间,对于同一段C++代码生成的符号可能不一致。而多语言接口需要直接读取生成的二进制(动态库),需要有稳定的导出符号。
*
C语言是有导出符号的标准的,并且在常见的平台上,都是ABI调用标准的。
*
大多数语言都支持使用C语言API
### 不导出Paddle内部的结构体、类,仅仅使用`void*`指针作为类型的句柄(handler)
*
Paddle内部的类为C++书写,直接导出到C的接口比较困难。
*
在C-API中使用
`void*`
来表示Paddle内部类。再在每一个API中自己检查类型。
```
C
// in matrix.cpp
struct PaddleMatrix {
int type;
paddle::MatrixPtr mat;
};
// in Paddle.h
typedef void* PD_Matrix;
extern "C" PD_Error getShape(PD_Matrix, uint64_t* height, uint64_t* width);
```
### 不使用SWIG这种代码生成器,而是手写多语言绑定
*
[
SWIG
](
http://www.swig.org/
)
是一个多语言接口的代码生成器。他的目标是使用C/C++写代码,SWIG直接读取C/C++的头文件,生成各种语言的绑定代码。
*
对于多语言接口,SWIG需要写一个interface文件。这个文件具有独特的语法,学习成本高。且增加一个第三方语言,就需要对这个第三方语言增加一些定义。有的时候,interface文件的写法非常
[
tricky
](
https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/api/Paddle.swig#L36
)
。社区贡献代码学习成本高。
*
SWIG暴露的接口保留了C++的接口样式,很难保证多语言代码风格的一致性。(函数命名,错误处理)
*
对于大多数语言,直接使用C语言的.h并不困难。例如Python的
[
cffi
](
https://cffi.readthedocs.io/en/latest/overview.html#simple-example-abi-level-in-line
)
或者
[
Cython
](
http://cython.org/
)
, golang的
[
cgo
](
https://golang.org/cmd/cgo/
)
。
*
swig支持的语言或者解释器有局限。例如对于Python,使用SWIG只支持CPython解释器,而不支持PyPy解释器。
## 原因列表
| 结论 | 对比 | 原因 |
|---| --- | --- |
| 使用动态库 | 不实用静态库 | 解释型语言只能调用动态库,Paddle静态库链接复杂 |
| 不嵌入其他语言解释器 | 不嵌入Python解释器 | Paddle C++目前嵌入Python解释器,会导致不同版本Python在一个进程里的bug |
| 不引用其他动态库 | | Paddle一个动态库可以在任何Linux系统上运行 |
| 使用C99做接口 | 不使用C++做接口 | C有标准的ABI,C99是目前C最广泛的使用标准(而不是C11,和C89) |
| 使用void
*
作为类句柄 | 不显示的写每个类具体包含什么| 实现简单,并且让接口脱离实现细节 |
| 手写多语言绑定 | 不使用SWIG | 写SWIG很tricky,社区参与难。SWIG生成的代码不能保证多语言代码风格的一致性 |
## 简单实现
TBD
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录