# Guide of local development

You will learn how to develop programs in local environment under the guidelines of this document.

## Requirements of coding
- Please refer to the coding comment format of [Doxygen](http://www.doxygen.nl/)
- Make sure that option of builder `WITH_STYLE_CHECK` is on and the build could pass through the code style check.
- Unit test is needed for all codes.
- Pass through all unit tests.
- Please follow [regulations of submitting codes](#regulations of submitting codes).

## Use official development images(recommended)

```
# First start（CPU development）
docker run -it --cpu-shares=20000 --name=username --net=host --privileged --rm -v $(pwd):/Paddle hub.baidubce.com/paddlepaddle/paddle:latest-dev /bin/bash
# First start（GPU development）
nvidia-docker run -it --cpu-shares=20000 --name=username --net=host --privileged --rm -v $(pwd):/Paddle hub.baidubce.com/paddlepaddle/paddle:latest-dev /bin/bash
# Next start
docker exec -it username bash
```
Different developers have different commands to start docker. The above are only recommended commands. If you use the command you are used to, you must add the parameter --privileged (needed by the GPU CUPTI library call)

**It is recommended to use the official development mirror hub.baidubce.com/paddlepaddle/paddle:latest-dev to submit the code.**

**The following guidiance tells you how to submit code.**

## [Fork](https://help.github.com/articles/fork-a-repo/)

Transfer to the home page of Github [PaddlePaddle](https://github.com/PaddlePaddle/Paddle) ,and then click button `Fork`  to generate the git under your own file directory,such as <https://github.com/USERNAME/Paddle>。

## Clone

Clone remote git to local:

```bash
➜  git clone https://github.com/USERNAME/Paddle
➜  cd Paddle
```


## Create local branch

At present [Git stream branch model](http://nvie.com/posts/a-successful-git-branching-model/)  is applied to Paddle to undergo task of development,test,release and maintenance.Please refer to [branch regulation of Paddle](https://github.com/PaddlePaddle/FluidDoc/blob/develop/doc/fluid/design/others/releasing_process.md) about details。

All development tasks of feature and bug fix should be finished in a new branch which is extended from `develop` branch.

Create and switch to a new branch with command `git checkout -b`.


```bash
➜  git checkout -b my-cool-stuff
```

It is worth noting that before the checkout, you need to keep the current branch directory clean, otherwise the untracked file will be brought to the new branch, which can be viewed by  `git status` .


## Use `pre-commit` hook

Paddle developers use the [pre-commit](http://pre-commit.com/) tool to manage Git pre-commit hooks. It helps us format the source code (C++, Python) and automatically check some basic things before committing (such as having only one EOL per file, not adding large files in Git, etc.).

The `pre-commit` test is part of the unit test in CI. A PR that does not satisfy the hook cannot be submitted to Paddle. Install `pre-commit` first and then run it in current directory：


```bash
➜  pip install pre-commit
➜  pre-commit install
```

Paddle modify the format of C/C++ source code with `clang-format` .Make sure the version of `clang-format` is above 3.8.

Note：There are differences between the installation of `yapf` with `pip install pre-commit` and that with `conda install -c conda-forge pre-commit` . Paddle developers use `pip install pre-commit`, Using Paddle docker image will `pre-commit`without separate installation .

## Start development

I delete a line of README.md and create a new file in the case.

View the current state via `git status` , which will prompt some changes to the current directory, and you can also view the file's specific changes via `git diff` .


```bash
➜  git status
On branch test
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)
    modified:   README.md
Untracked files:
  (use "git add <file>..." to include in what will be committed)
    test
no changes added to commit (use "git add" and/or "git commit -a")
```

## Build

Create and enter the /Paddle/build path

    mkdir -p /Paddle/build && cd /Paddle/build

Execute cmake:


    * For users who need to compile the **CPU version PaddlePaddle**:

    For Python2: cmake .. -DWITH_GPU=OFF -DWITH_TESTING=OFF -DCMAKE_BUILD_TYPE=Release
    For Python3: cmake .. -DPY_VERSION=3.5 -DWITH_GPU=OFF -DWITH_TESTING=OFF -DCMAKE_BUILD_TYPE=Release


    * For users who need to compile the **GPU version PaddlePaddle**:

    For Python2: cmake .. -DWITH_GPU=ON -DWITH_TESTING=OFF -DCMAKE_BUILD_TYPE=Release
    For Python3: cmake .. -DPY_VERSION=3.5 -DWITH_GPU=ON -DWITH_TESTING=OFF -DCMAKE_BUILD_TYPE=Release


Execute compilation:

    make -j$(nproc)

    Such as: make -j16, using 16 core compilation

After compiling successfully, go to the `/paddle/build/python/dist` directory and find the generated `.whl` package.Install the compiled .whl package on the current machine or target machine:

    For Python2: pip install -U（whl package name）
    For Python3: pip3.5 install -U（whl package name）

Please refer to [Compile From Source Code](../../../install/compile/fromsource_en.html) about more information of building PaddlePaddle source codes.

## Test

    Run Test (Run 100 times)
    ctest --repeat-until-fail 100 -R test_xx


Please refer to [Compile From Source Code](../../../install/compile/fromsource_en.html) about more information of building PaddlePaddle source codes.
Please refer to [Op Unit Tests](../new_op/new_op_en.html#unit-tests) about more information of running unit tests.

## Commit

Next we cancel the modification of README.md,and submit new added test file.

```bash
➜  git checkout -- README.md
➜  git status
On branch test
Untracked files:
  (use "git add <file>..." to include in what will be committed)
    test
nothing added to commit but untracked files present (use "git add" to track)
➜  git add test
```

It's required that the commit message is also given on every Git commit, through which other developers will be notified of what changes have been made. Type `git commit` to realize it.

```bash
➜  git commit
CRLF end-lines remover...............................(no files to check)Skipped
yapf.................................................(no files to check)Skipped
Check for added large files..............................................Passed
Check for merge conflicts................................................Passed
Check for broken symlinks................................................Passed
Detect Private Key...................................(no files to check)Skipped
Fix End of Files.....................................(no files to check)Skipped
clang-formater.......................................(no files to check)Skipped
[my-cool-stuff c703c041] add test file
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 233
```


## Keep the latest local repository

It needs to keep up with the latest code of original repository(<https://github.com/PaddlePaddle/Paddle>）before Pull Request.

Check the name of current remote repository with `git remote`.

```bash
➜  git remote
origin
➜  git remote -v
origin    https://github.com/USERNAME/Paddle (fetch)
origin    https://github.com/USERNAME/Paddle (push)
```

origin is the name of remote repository that we clone,which is also the Paddle under your own account. Next we create a remote host of an original Paddle and name it upstream.

```bash
➜  git remote add upstream https://github.com/PaddlePaddle/Paddle
➜  git remote
origin
upstream
```

Get the latest code of upstream and update current branch.

```bash
➜  git fetch upstream
➜  git pull upstream develop
```

## Push to remote repository

Push local modification to GitHub(https://github.com/USERNAME/Paddle).

```bash
# submit it to remote git the branch my-cool-stuff of origin
➜  git push origin my-cool-stuff
```
