Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
机器未来
Paddle
提交
baf890ac
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看板
提交
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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录