Skip to content

Commit 111812f

Browse files
authored
Merge pull request #3676 from wangkuiyi/add_docker_build_doc
Add docker build doc
2 parents b047c7a + ec5e20c commit 111812f

File tree

6 files changed

+255
-8
lines changed

6 files changed

+255
-8
lines changed

Dockerfile

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,11 @@ RUN /bin/bash -c 'if [[ -n ${UBUNTU_MIRROR} ]]; then sed -i 's#http://archive.ub
1010
ARG WITH_GPU
1111
ARG WITH_AVX
1212
ARG WITH_DOC
13-
ARG WITH_STYLE_CHECK
1413

1514
ENV WOBOQ OFF
16-
ENV WITH_GPU=${WITH_GPU:-OFF}
15+
ENV WITH_GPU=${WITH_GPU:-ON}
1716
ENV WITH_AVX=${WITH_AVX:-ON}
1817
ENV WITH_DOC=${WITH_DOC:-OFF}
19-
ENV WITH_STYLE_CHECK=${WITH_STYLE_CHECK:-OFF}
2018

2119
ENV HOME /root
2220
# Add bash enhancements

doc/howto/dev/build_cn.md

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
# 编译PaddlePaddle和运行单元测试
2+
3+
## 需要的软硬件
4+
5+
为了开发PaddlePaddle,我们需要
6+
7+
1. 一台电脑,可以装的是 Linux, BSD, Windows 或者 MacOS 操作系统,以及
8+
1. Docker。
9+
10+
不需要依赖其他任何软件了。即便是 Python 和 GCC 都不需要,因为我们会把所有编译工具都安装进一个 Docker image 里。
11+
12+
## 总体流程
13+
14+
1. 获取源码
15+
16+
```bash
17+
git clone https://github.com/paddlepaddle/paddle
18+
```
19+
20+
2. 安装开发工具到 Docker image 里
21+
22+
```bash
23+
cd paddle; docker build -t paddle:dev .
24+
```
25+
26+
请注意这个命令结尾处的 `.`;它表示 `docker build` 应该读取当前目录下的 [`Dockerfile`文件](https://github.com/PaddlePaddle/Paddle/blob/develop/Dockerfile),按照其内容创建一个名为 `paddle:dev` 的 Docker image,并且把各种开发工具安装进去。
27+
28+
3. 编译
29+
30+
以下命令启动一个 Docker container 来执行 `paddle:dev` 这个 Docker image,同时把当前目录(源码树根目录)映射为 container 里的 `/paddle` 目录,并且运行 `Dockerfile` 描述的默认入口程序 [`build.sh`](https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/scripts/docker/build.sh)。这个脚本调用 `cmake``make` 来编译 `/paddle` 里的源码,结果输出到 `/paddle/build`,也就是本地的源码树根目录里的 `build` 子目录。
31+
32+
```bash
33+
docker run --rm -v $PWD:/paddle paddle:dev
34+
```
35+
36+
上述命令编译出一个 CUDA-enabled 版本。如果我们只需要编译一个只支持 CPU 的版本,可以用
37+
38+
```bash
39+
docker run --rm -e WITH_GPU=OFF -v $PWD:/paddle paddle:dev
40+
```
41+
42+
4. 运行单元测试
43+
44+
用本机的第一个 GPU 来运行包括 GPU 单元测试在内的所有单元测试:
45+
46+
```bash
47+
NV_GPU=0 nvidia-docker run --rm -v $PWD:/paddle paddle:dev bash -c "cd /paddle/build; ctest"
48+
```
49+
50+
如果编译的时候我们用了 `WITH_GPU=OFF` 选项,那么编译过程只会产生 CPU-based 单元测试,那么我们也就不需要 nvidia-docker 来运行单元测试了。我们只需要:
51+
52+
```bash
53+
docker run --rm -v $PWD:/paddle paddle:dev bash -c "cd /paddle/build; ctest"
54+
```
55+
56+
有时候我们只想运行一个特定的单元测试,比如 `memory_test`,我们可以
57+
58+
```bash
59+
nvidia-docker run --rm -v $PWD:/paddle paddle:dev bash -c "cd /paddle/build; ctest -V -R memory_test"
60+
```
61+
62+
5. 清理
63+
64+
有时候我们会希望清理掉已经下载的第三方依赖以及已经编译的二进制文件。此时只需要:
65+
66+
```bash
67+
rm -rf build
68+
```
69+
70+
## 为什么要 Docker 呀?
71+
72+
- 什么是 Docker?
73+
74+
如果您没有听说 Docker,可以把它想象为一个类似 virtualenv 的系统,但是虚拟的不仅仅是 Python 的运行环境。
75+
76+
- Docker 还是虚拟机?
77+
78+
有人用虚拟机来类比 Docker。需要强调的是:Docker 不会虚拟任何硬件,Docker container 里运行的编译工具实际上都是在本机的 CPU 和操作系统上直接运行的,性能和把编译工具安装在本机运行一样。
79+
80+
- 为什么用 Docker?
81+
82+
把工具和配置都安装在一个 Docker image 里可以标准化编译环境。这样如果遇到问题,其他人可以复现问题以便帮助。
83+
84+
另外,对于习惯使用Windows和MacOS的开发者来说,使用Docker就不用配置交叉编译环境了。
85+
86+
- 我可以选择不用Docker吗?
87+
88+
当然可以。大家可以用把开发工具安装进入 Docker image 一样的方式,把这些工具安装到本机。这篇文档介绍基于 Docker 的开发流程,是因为这个流程比其他方法都更简便。
89+
90+
- 学习 Docker 有多难?
91+
92+
理解 Docker 并不难,大概花十分钟看一下[这篇文章](https://zhuanlan.zhihu.com/p/19902938)。这可以帮您省掉花一小时安装和配置各种开发工具,以及切换机器时需要新安装的辛苦。别忘了 PaddlePaddle 更新可能导致需要新的开发工具。更别提简化问题复现带来的好处了。
93+
94+
- 我可以用 IDE 吗?
95+
96+
当然可以,因为源码就在本机上。IDE 默认调用 make 之类的程序来编译源码,我们只需要配置 IDE 来调用 Docker 命令编译源码即可。
97+
98+
很多 PaddlePaddle 开发者使用 Emacs。他们在自己的 `~/.emacs` 配置文件里加两行
99+
100+
```emacs
101+
(global-set-key "\C-cc" 'compile)
102+
(setq compile-command
103+
"docker run --rm -it -v $(git rev-parse --show-toplevel):/paddle paddle:dev")
104+
```
105+
106+
就可以按 `Ctrl-C``c` 键来启动编译了。
107+
108+
- 可以并行编译吗?
109+
110+
是的。我们的 Docker image 运行一个 [Bash 脚本](https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/scripts/docker/build.sh)。这个脚本调用 `make -j$(nproc)` 来启动和 CPU 核一样多的进程来并行编译。
111+
112+
## 可能碰到的问题
113+
114+
- Docker 需要 sudo
115+
116+
如果用自己的电脑开发,自然也就有管理员权限(sudo)了。如果用公用的电脑开发,需要请管理员安装和配置好 Docker。此外,PaddlePaddle 项目在努力开始支持其他不需要 sudo 的集装箱技术,比如 rkt。
117+
118+
- 在 Windows/MacOS 上编译很慢
119+
120+
Docker 在 Windows 和 MacOS 都可以运行。不过实际上是运行在一个 Linux 虚拟机上。可能需要注意给这个虚拟机多分配一些 CPU 和内存,以保证编译高效。具体做法请参考[这个issue](https://github.com/PaddlePaddle/Paddle/issues/627)
121+
122+
- 磁盘不够
123+
124+
本文中的例子里,`docker run` 命令里都用了 `--rm` 参数,这样保证运行结束之后的 containers 不会保留在磁盘上。可以用 `docker ps -a` 命令看到停止后但是没有删除的 containers。`docker build` 命令有时候会产生一些中间结果,是没有名字的 images,也会占用磁盘。可以参考[这篇文章](https://zaiste.net/posts/removing_docker_containers/)来清理这些内容。

doc/howto/dev/build_en.md

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
# Build PaddlePaddle from Source Code and Run Unit Test
2+
3+
## What Developers Need
4+
5+
To contribute to PaddlePaddle, you need
6+
7+
1. A computer -- Linux, BSD, Windows, MacOS, and
8+
1. Docker.
9+
10+
Nothing else. Not even Python and GCC, because you can install all build tools into a Docker image. We run all the tools by running this image.
11+
12+
## General Process
13+
14+
1. Retrieve source code.
15+
16+
```bash
17+
git clone https://github.com/paddlepaddle/paddle
18+
```
19+
20+
2. Install build tools into a Docker image.
21+
22+
```bash
23+
cd paddle; docker build -t paddle:dev .
24+
```
25+
26+
Please be aware of the `.` at the end of the command, which refers to the [`./Dockerfile` file](https://github.com/PaddlePaddle/Paddle/blob/develop/Dockerfile). `docker build` follows instructions in this file to create a Docker image named `paddle:dev`, and installs building tools into it.
27+
28+
3. Build from source.
29+
30+
This following command starts a Docker container that executes the Docker image `paddle:dev`, mapping the current directory to `/paddle/` in the container, and runs the default entry-point [`build.sh`](https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/scripts/docker/build.sh) as specified in the Dockefile. `build.sh` invokes `cmake` and `make` to build PaddlePaddle source code, which had been mapped to `/paddle`, and writes outputs to `/paddle/build`, which maps to `build` in the current source directory on the computer.
31+
32+
```bash
33+
docker run -v $PWD:/paddle paddle:dev
34+
```
35+
36+
Above command builds a CUDA-enabled version. If we want to build a CPU-only version, we can type
37+
38+
```bash
39+
docker run -e WITH_GPU=OFF -v $PWD:/paddle paddle:dev
40+
```
41+
42+
4. Run unit tests.
43+
44+
To run all unit tests using the first GPU of a node:
45+
46+
```bash
47+
NV_GPU=0 nvidia-docker run -v $PWD:/paddle paddle:dev bash -c "cd /paddle/build; ctest"
48+
```
49+
50+
If we used `WITH_GPU=OFF` at build time, it generates only CPU-based unit tests, and we don't need nvidia-docker to run them. We can just run
51+
52+
```bash
53+
docker run -v $PWD:/paddle paddle:dev bash -c "cd /paddle/build; ctest"
54+
```
55+
56+
Sometimes we want to run a specific unit test, say `memory_test`, we can run
57+
58+
```bash
59+
nvidia-docker run -v $PWD:/paddle paddle:dev bash -c "cd /paddle/build; ctest -V -R memory_test"
60+
```
61+
62+
5. Clean Build.
63+
64+
Sometimes, we might want to clean all thirt-party dependents and built binaries. To do so, just
65+
66+
```bash
67+
rm -rf build
68+
```
69+
70+
## Docker, Or Not?
71+
72+
- What is Docker?
73+
74+
If you haven't heard of it, consider it something like Python's virtualenv.
75+
76+
- Docker or virtual machine?
77+
78+
Some people compare Docker with VMs, but Docker doesn't virtualize any hardware nor running a guest OS, which means there is no compromise on the performance.
79+
80+
- Why Docker?
81+
82+
Using a Docker image of build tools standardizes the building environment, which makes it easier for others to reproduce your problems and to help.
83+
84+
Also, some build tools don't run on Windows or Mac or BSD, but Docker runs almost everywhere, so developers can use whatever computer they want.
85+
86+
- Can I choose not to use Docker?
87+
88+
Sure, you don't have to install build tools into a Docker image; instead, you can install them in your local computer. This document exists because Docker would make the development way easier.
89+
90+
- How difficult is it to learn Docker?
91+
92+
It takes you ten minutes to read [an introductory article](https://docs.docker.com/get-started) and saves you more than one hour to install all required build tools, configure them, especially when new versions of PaddlePaddle require some new tools. Not even to mention the time saved when other people trying to reproduce the issue you have.
93+
94+
- Can I use my favorite IDE?
95+
96+
Yes, of course. The source code resides on your local computer, and you can edit it using whatever editor you like.
97+
98+
Many PaddlePaddle developers are using Emacs. They add the following few lines into their `~/.emacs` configure file:
99+
100+
```emacs
101+
(global-set-key "\C-cc" 'compile)
102+
(setq compile-command
103+
"docker run --rm -it -v $(git rev-parse --show-toplevel):/paddle paddle:dev")
104+
```
105+
106+
so they could type `Ctrl-C` and `c` to build PaddlePaddle from source.
107+
108+
- Does Docker do parallel building?
109+
110+
Our building Docker image runs a [Bash script](https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/scripts/docker/build.sh), which calls `make -j$(nproc)` to starts as many processes as the number of your CPU cores.
111+
112+
## Some Gotchas
113+
114+
- Docker requires sudo
115+
116+
An owner of a computer has the administrative privilege, a.k.a., sudo, and Docker requires this privilege to work properly. If you use a shared computer for development, please ask the administrator to install and configure Docker. We will do our best to support rkt, another container technology that doesn't require sudo.
117+
118+
- Docker on Windows/MacOS builds slowly
119+
120+
On Windows and MacOS, Docker containers run in a Linux VM. You might want to give this VM some more memory and CPUs so to make the building efficient. Please refer to [this issue](https://github.com/PaddlePaddle/Paddle/issues/627) for details.
121+
122+
- Not enough disk space
123+
124+
Examples in this article uses option `--rm` with the `docker run` command. This option ensures that stopped containers do not exist on hard disks. We can use `docker ps -a` to list all containers, including stopped. Sometimes `docker build` generates some intermediate dangling images, which also take disk space. To clean them, please refer to [this article](https://zaiste.net/posts/removing_docker_containers/).

doc/howto/index_cn.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
.. toctree::
2020
:maxdepth: 1
2121

22+
dev/build_cn.rst
2223
dev/write_docs_cn.rst
2324
dev/contribute_to_paddle_cn.md
2425

doc/howto/index_en.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Development
1818
.. toctree::
1919
:maxdepth: 1
2020

21+
dev/build_en.rst
2122
dev/new_layer_en.rst
2223
dev/contribute_to_paddle_en.md
2324

paddle/scripts/docker/build.sh

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ Configuring cmake in /paddle/build ...
3838
-DWITH_SWIG_PY=${WITH_SWIG_PY:-ON}
3939
-DCUDNN_ROOT=/usr/
4040
-DWITH_STYLE_CHECK=${WITH_STYLE_CHECK:-OFF}
41-
-DWITH_TESTING=${WITH_TESTING:-OFF}
41+
-DWITH_TESTING=${WITH_TESTING:-ON}
4242
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
4343
========================================
4444
EOF
@@ -56,19 +56,18 @@ cmake .. \
5656
-DWITH_C_API=${WITH_C_API:-OFF} \
5757
-DWITH_PYTHON=${WITH_PYTHON:-ON} \
5858
-DCUDNN_ROOT=/usr/ \
59-
-DWITH_STYLE_CHECK=${WITH_STYLE_CHECK:-OFF} \
60-
-DWITH_TESTING=${WITH_TESTING:-OFF} \
59+
-DWITH_STYLE_CHECK=${WITH_STYLE_CHECK:-ON} \
60+
-DWITH_TESTING=${WITH_TESTING:-ON} \
6161
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
6262

6363
cat <<EOF
6464
============================================
6565
Building in /paddle/build ...
66-
Build unit tests: ${WITH_TESTING:-OFF}
6766
============================================
6867
EOF
6968
make -j `nproc`
7069

71-
if [ ${WITH_TESTING:-OFF} == "ON" ] && [ ${RUN_TEST:-OFF} == "ON" ] ; then
70+
if [ ${WITH_TESTING:-ON} == "ON" ] && [ ${RUN_TEST:-OFF} == "ON" ] ; then
7271
cat <<EOF
7372
========================================
7473
Running unit tests ...

0 commit comments

Comments
 (0)