贡献给DGL

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

通用开发流程

以下是非包含性的贡献类型列表:

对于新功能和错误修复,我们建议首先使用相应的问题模板在问题页面提出问题,以便在实施之前与社区充分讨论变更。对于文档改进和新模型,我们建议在我们的讨论论坛中发布一个帖子。

在开发之前,请首先阅读以下关于编码风格和测试的部分。 所有的更改都需要以pull request的形式进行审查。 我们的committors (拥有仓库写权限的人)将审查代码并建议必要的更改。一旦审查者批准更改,PR 就可以合并。

Git 设置(针对开发者)

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

在本地克隆你分叉的仓库:

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

设置上游到DGL官方仓库:

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

您可以通过输入git remote -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)

在开发过程中,我们建议在非主分支上工作。

git branch working-branch
git checkout working-branch

一旦更改完成,创建一个拉取请求,以便我们能够审查您的代码。

一旦拉取请求被合并,更新你的分叉仓库并删除你的工作分支:

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文档字符串

对于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。完成后提交一个拉取请求。你的README至少应包含以下内容:

    • 运行程序的说明。

    • 性能结果,如速度或准确性或任何指标,以及与一些替代实现的比较(如果有的话)。

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

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

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

  3. 提交者将对其进行审查,根据需要提出或进行更改。

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

  5. 合并它并享受你的一天。

数据托管

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

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

可以选择

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

  • 明确说明下载数据集的指示(例如,使用百度时,自动下载较为困难)。

如果您在操作过程中遇到困难(例如找不到永久云存储),请随时在我们的讨论论坛发帖。

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

  • DIY: 在 dgl.data 模块中进行更改;查看我们的 dataset APIs 以获取更多详细信息,或者,

  • 再次在我们的讨论论坛发帖。

目前,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: 所有额外张量函数的存根文件。

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

    • backend/__init__.py: 当导入时,它会根据所选择的后端,将存根实现替换为特定框架的代码。它还会更改一些现有后端函数的签名,以自动选择数据类型和上下文。

  • 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>

其中 可以是任何支持的后端(例如 pytorchmxnet)。

贡献文档

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

本地构建文档

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

  1. 安装 sphinx, sphinx-gallery, 和 sphinx_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网页界面贡献编辑更改

如果只是更改措辞(即完全不触及可运行代码),可以简单地不使用 Git CLI:

  1. 通过点击DGL主仓库网页上的Fork按钮来创建你的分支。

  2. 你自己的分支中的网络界面中进行任何更改。通常,你可以通过检查是否可以提交到master分支来判断你是在自己的分支中还是在主仓库中:如果不能,那么你就在错误的地方。

  3. 完成后,在网页界面上发起一个拉取请求。

  4. 提交者将对其进行审查,根据需要提出或进行更改。

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

  6. 合并它并享受你的一天。

贡献代码更改

更改代码时,请确保在本地构建并查看是否失败。