贡献 DGL

欢迎对 DGL 做出任何贡献。本指南涵盖了关于如何贡献 DGL 的所有内容。

一般开发流程

以下是贡献类型的不完全列表

对于功能和 bug 修复,我们建议首先使用相应的 issue 模板提出一个 issue,以便在实现之前与社区充分讨论更改。对于文档改进和新模型,我们建议在我们的讨论区发帖。

在开发之前,请先阅读以下关于编码风格和测试的章节。所有更改都需要以拉取请求 (pull request) 的形式进行评审。我们的提交者 (committors)(对仓库有写入权限的人)将评审代码并提出必要的修改建议。一旦评审者批准更改,即可合并 PR。

Git 设置 (开发者用)

首先,Fork DGL GitHub 仓库。假设 Fork 后的仓库是 https://github.com/username/dgl

本地克隆你 Fork 的仓库

git clone --recursive https://github.com/username/dgl.git

设置 upstream 为 DGL 官方仓库

git remote add upstream https://github.com/dmlc/dgl.git

你可以通过输入 git -v 来验证远程设置

origin  https://github.com/username/dgl.git (fetch)
origin  https://github.com/username/dgl.git (push)
upstream        https://github.com/dmlc/dgl.git (fetch)
upstream        https://github.com/dmlc/dgl.git (push)

在开发期间,我们建议在 master 分支以外的其他分支上工作。

git branch working-branch
git checkout working-branch

更改完成后,创建一个拉取请求 (pull request),以便我们评审你的代码。

拉取请求合并后,更新你 Fork 的仓库并删除你的工作分支

git checkout master
git pull upstream master
git push origin master  # update your forked repo
git branch -D working-branch  # the local branch could be deleted

编码风格

对于 Python 代码,我们通常遵循 PEP8 风格指南。Python 注释遵循 NumPy 风格的 Python docstrings

对于 C++ 代码,我们通常遵循 Google C++ 风格指南。C++ 注释应与 Doxygen 兼容

对每个拉取请求强制执行编码风格检查。为了方便开发,请先在本地检查(需要先安装 cpplint 和 pylint)。

bash tests/scripts/task_lint.sh

Python 编码风格配置文件是 tests/lint/pylintrc。我们对标准配置做了一些微调。例如,允许使用以下变量名:

  • i,j,k: 循环变量

  • u,v: 表示节点

  • e: 表示边

  • g: 表示图

  • fn: 表示函数

  • n,m: 表示大小

  • w,x,y: 表示权重、输入、输出张量

  • _: 表示未使用变量

贡献新模型作为示例

要在特定的支持张量框架(例如 PyTorch 或 MXNet)中贡献新模型,只需

  1. 在目录 examples/${DGLBACKEND} 下创建一个以你的模型命名(例如 awesome-gnn)的目录,其中 ${DGLBACKEND} 指代框架名称。

  2. 在其中填充你的工作内容,并附带一个 README 文件。完成后,提交拉取请求 (pull request)。你的 README 至少应包含以下内容:

    • 运行程序的说明。

    • 性能结果,例如速度、准确性或任何指标,以及与某些替代实现(如果存在)的比较。

      • 你的性能指标不必超越他人的实现;它们只是表明你的代码可能是正确的信号。

      • 你的速度也不必超过他人的。

      • 然而,更好的数字总是受欢迎的。

  3. 提交者将评审它,并根据需要提出或进行修改。

  4. 解决建议和评审意见,然后回到步骤 3,直到获得批准。

  5. 合并它,祝你愉快。

数据托管

在贡献一个新的可运行的模型示例时,人们经常希望上传数据集,特别是在涉及我们现有示例中没有的新领域时。

直接将数据文件上传到 Git 仓库是一个糟糕的主意,因为我们不希望克隆仓库的人无论如何都要下载数据集。相反,我们强烈建议将数据文件托管在永久的云存储服务上(例如 DropBox、Amazon S3、百度云盘、Google Drive 等)。

你可以

  • 如果可能,让你的脚本自动下载数据(例如,使用 Amazon S3 时),或者

  • 清晰地说明下载数据集的说明(例如,使用百度云盘时,自动下载很困难)。

如果你在这方面遇到困难(例如找不到永久云存储),欢迎在我们的讨论区发帖。

根据贡献的任务、模型或数据集的普遍性,我们(DGL 团队)会将你的数据集迁移到 Amazon S3 上的官方 DGL 数据集仓库。如果你希望托管特定的数据集,你可以

  • DIY:在 dgl.data 模块中进行修改;请参阅我们的数据集 API 获取更多详情,或者,

  • (再次)在我们的讨论区发帖。

目前,所有 DGL 模型示例的数据集都托管在 Amazon S3 上。

贡献核心功能

我们将进入 Python dgl 包的功能称为核心功能

由于 DGL 支持多种张量框架,贡献核心功能并非易事。然而,我们并要求了解所有张量框架。相反,

  1. 在提交拉取请求之前,请确保你的代码在至少一个支持的框架上进行了单元测试;详细信息请参阅构建和测试章节。

  2. 完成后,提交拉取请求并总结你的更改,然后等待 CI 完成。

  3. 如果 CI 在你不熟悉的张量平台(这种情况经常发生)上失败,请参阅支持多种平台章节。

  4. 提交者将评审它,并根据需要提出或进行修改。

  5. 解决建议和评审意见,然后回到步骤 3,直到获得批准。

  6. 合并它,祝你愉快。

支持多种平台

这部分比较难,但你不需要同时了解 PyTorch 和 MXNet(也许未来还需要了解 Tensorflow、Chainer 等)。支持多种平台的基本原则很简单:

  • dgl Python 包中,始终避免直接使用框架特定的操作符(包括数组索引!)。请改用 dgl.backendnumpy 数组中的包装器。

  • 如果你在这方面遇到困难(可能是因为 dgl.backend 未涵盖所需的操作符,或者你没有 GPU,或出于任何其他原因),请为你的 PR 打上 backend support 标签,一位或多位了解 CPU 和 GPU 以及 PyTorch 和 MXNet(以及 Tensorflow 和 Chainer 等)的 DGL 团队成员将会跟进。

构建和测试

要在本地构建 DGL,请遵循从源代码安装中描述的步骤。然而,为了方便开发,我们建议不要安装 DGL,而是直接在源代码树中工作。为此,请导出以下环境变量:

export DGL_HOME=/path/to/your/dgl/clone
export DGL_LIBRARY_PATH=$DGL_HOME/build
export PYTHONPATH=$PYTHONPATH:$DGL_HOME/python

如果你正在处理性能关键的部分,你可能想开启 Cython 构建

cd python
python setup.py build_ext --inplace

你可以通过运行以下命令来测试构建,并查看你本地克隆仓库的路径。

python -c 'import dgl; print(dgl.__path__)'

单元测试

目前,我们使用 nose 进行单元测试。组织结构如下:

  • backend: 支持框架的附加统一张量接口。其中的函数仅用于单元测试,不用于 DGL 本身。请注意,其中的代码本身并非单元测试。可以通过以下方式导入附加后端:

    import backend
    

    附加后端包含以下文件:

    • backend/backend_unittest.py: 所有附加张量函数的桩文件 (stub file)。

    • backend/${DGLBACKEND}/__init__.py: 后端 ${DGLBACKEND} 的桩实现。

    • backend/__init__.py: 导入时,它会根据所选后端,用框架特定的代码替换桩实现。它还会更改一些现有后端函数的签名,以自动选择 dtypes 和 contexts。

  • compute: 所有与计算相关的、与框架无关的单元测试都放在这里。内部的任何内容都不应依赖于特定的张量库。DGL 统一张量接口(即 dgl.backend)中未提供的张量函数应放在 backend 目录中。

  • ${DGLBACKEND}(例如 pytorchmxnet):所有与计算相关的、与框架相关的单元测试都放在这里。

  • graph_index: 所有用于 C++ 图结构实现的单元测试都放在这里。此目录中正在测试的 Python API(如果存在)应尽可能简化(通常是相应 C++ 函数的简单包装器)。

  • lint: Pylint 相关文件。

  • scripts: 用于 CI 的自动化测试脚本。

要运行单元测试,请执行

sh tests/scripts/task_unit_test.sh <your-backend>

其中 <your-backend> 可以是任何支持的后端(即 pytorchmxnet)。

贡献文档

如果更改是关于文档改进,我们建议(如果更改了可运行代码则强烈建议)在提交拉取请求之前,先在本地构建文档并进行渲染查看。

本地构建文档

通常,本地构建文档涉及以下步骤:

  1. 安装 sphinxsphinx-gallerysphinx_rtd_theme

  2. 你需要安装 PyTorch 和 MXNet,因为我们的教程包含这两个框架的代码。但这并要求你了解如何使用这两个框架进行编码。

  3. 运行以下命令:

    cd docs
    ./clean.sh
    make html
    cd build/html
    python3 -m http.server 8080
    
  4. 打开 http://localhost:8080 查看你的成果。

更多详情请参见这里

通过 GitHub Web 界面贡献编辑修改

如果只是更改措辞(即完全不修改可运行代码),则可以不用 Git CLI 命令行工具,直接通过 Web 界面完成。

  1. 在 DGL 主仓库页面上点击 Fork 按钮创建你的 Fork。

  2. 在 Web 界面上对你自己的 Fork 进行任何修改。你通常可以通过检查是否可以提交到 master 分支来判断你是在自己的 Fork 中还是在主仓库中:如果不能,则说明你在错误的地方。

  3. 完成后,提交拉取请求 (pull request)(在 Web 界面上)。

  4. 提交者将评审它,并根据需要提出或进行修改。

  5. 解决建议和评审意见,然后回到步骤 4,直到获得批准。

  6. 合并它,祝你愉快。

贡献代码修改

修改代码时,请务必在本地构建并检查是否出错。