LoginSignup
3
1

More than 5 years have passed since last update.

nixpkgsにPull Request送ってchainerを入れてもらった

Posted at

使用するもの

NixOS

  • Linuxディストリビューションの1つ
    • 関数型パッケージ管理ツールNixを使用している
    • パッケージ自体はnixpkgsのリポジトリで管理・開発されている(個々のパッケージはhttps://nixos.org/nixos/packages.html# で検索できる)
  • 環境の構築が楽にできる
    • 1つのファイルでシステム全体の設定ができる -> 管理が楽
    • システムのアップデート -> システムのロールバック ということが楽にできる
    • sudoとかしなくてもパッケージを用意できる(たとえばpythonでnumpyとmatplotlibを使いたい時は以下のようにする)
$ nix-shell -p python3 -p pythonPackages.numpy -p pythonPackages.matplotlib
  • NixOpsを使ってリモートに環境のデプロイができる

はじめに

前回の続きです。
前回はNixOS上でchainerを使えるよう、パッケージングを行うDerivationコードを書いてみました。
せっかくパッケージングを行うコードを書いたので、nix-shell -p pythonPackages.chainerとかで環境を構築できるようにしたいです。
そこで、今回はchainerをnixpkgsに入れてもらえるようPull Requestを送ってみた時の顛末を書きます。

Pull Requestをする前にやったこと

私はこれまでPull Requestなんて過去に1回ぐらいしか送ったこと無いので、始める前からなんとなく緊張してしました。
とりあえずGitHubでnixpkgsのリポジトリをForkをしようと思ったら、過去に(NixOS 16.09の頃)すでにForkしたリポジトリがありました。
Forkしただけでとくに何かしてはいなかったです。なぜForkしたのか。
ForkしていたNixOS 16.09の頃のnixpkgsのリポジトリをこの記事を参考に最新の状態に更新しました。

Pull Requestの手順自体については、検索すればまとまった記事がいくつか出るので割愛します。(この記事とか)

Pull Request

顛末自体は、ここに記録が残っているので読めばわかりますが、本題なので一応何か書いておきます。

最初に送った変更はこんな感じでした。
一応、送る前にnix-shell -p pythonPackages.chainer -I ./nixpkgs等でもビルドの確認をしています。

diff --git a/pkgs/development/libraries/science/math/nccl/default.nix b/pkgs/development/libraries/science/math/nccl/default.nix
new file mode 100644
index 00000000000..6d7ffd2a70c
--- /dev/null
+++ b/pkgs/development/libraries/science/math/nccl/default.nix
@@ -0,0 +1,43 @@
+{ stdenv, pkgs, fetchurl, cudatoolkit }:
+
+with pkgs;
+
+stdenv.mkDerivation rec {
+  name = "cudatoolkit-${cudatoolkit.majorVersion}-nccl-${version}";
+  version = "1.3.4-1";
+
+  src = fetchurl {
+    url = "https://github.com/NVIDIA/nccl/archive/v${version}.tar.gz";
+    sha256 = "117qz8zvc4r0zjd737knr482gf208v5xlwyrpaf8pcjvam2fpr0i";
+  };
+
+  nativeBuildInputs = [
+    gcc5
+    eject
+  ];
+
+  propagatedBuildInputs = [
+    cudatoolkit
+  ];
+
+  BUILDDIR = "./";
+  PREFIX = "$out";
+  CUDA_HOME = "${cudatoolkit}";
+  CUDA_LIB = "${cudatoolkit.lib}/lib";
+
+  postInstall = ''
+    cp -r ./lib $out
+    cp -r ./include $out
+  '';
+
+  meta = with stdenv.lib; {
+    description = ''
+      NVIDIA Collective Communications Library.
+      Multi-GPU and multi-node collective communication primitives.
+    '';
+    homepage = "https://developer.nvidia.com/nccl";
+    license = licenses.bsd3;
+    platforms = [ "x86_64-linux" ];
+    maintainers = with maintainers; [ hyphon81 ];
+  };
+}
diff --git a/pkgs/development/python-modules/chainer/default.nix b/pkgs/development/python-modules/chainer/default.nix
new file mode 100644
index 00000000000..3997e64c7b6
--- /dev/null
+++ b/pkgs/development/python-modules/chainer/default.nix
@@ -0,0 +1,34 @@
+{ stdenv, pkgs, lib
+, python, buildPythonPackage, fetchPypi
+, numpy, cudaSupport ? false
+}:
+
+with pkgs;
+with python.pkgs;
+
+buildPythonPackage rec {
+  name = "${pname}-${version}";
+  pname = "chainer";
+  version = "3.2.0";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "0mbc8kwk7pvg03bf0j57a48gr6rsdg4lzmyj0dak8y2l4lmyskpw";
+  };
+
+  propagatedBuildInputs = [
+    filelock
+    protobuf
+    numpy
+  ] ++ lib.optionals cudaSupport [ cupy ];
+
+  # In python3, test was failed...
+  doCheck = !isPy3k;
+
+  meta = with stdenv.lib; {
+    description = "A flexible framework of neural networks for deep learning";
+    homepage = "https://chainer.org/";
+    license = licenses.mit;
+    maintainers = with maintainers; [ hyphon81 ];
+  };
+}
diff --git a/pkgs/development/python-modules/cupy/default.nix b/pkgs/development/python-modules/cupy/default.nix
new file mode 100644
index 00000000000..597bb2febd7
--- /dev/null
+++ b/pkgs/development/python-modules/cupy/default.nix
@@ -0,0 +1,48 @@
+{ stdenv, pkgs, python, buildPythonPackage
+, fetchPypi, isPy3k, numpy
+, cudatoolkit, cudnn, nccl
+}:
+
+with pkgs;
+with python.pkgs;
+
+buildPythonPackage rec {
+  name = "${pname}-${version}";
+  pname = "cupy";
+  version = "2.2.0";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "0si0ri8azxvxh3lpm4l4g60jf4nwzibi53yldbdbzb1svlqq060r";
+  };
+
+  nativeBuildInputs = [
+    gcc5
+  ];
+
+  propagatedBuildInputs = [
+    cudatoolkit
+    cudnn
+    linuxPackages.nvidia_x11
+    nccl
+    fastrlock
+    numpy
+    six
+    wheel
+  ];
+
+  CUDA_PATH = "${cudatoolkit}";
+  CFLAGS = "-I ${cudnn}/include -I ${nccl}/include";
+  LDFLAGS = "-L ${cudnn}/lib -L ${nccl}/lib";
+
+  # In python3, test was failed...
+  doCheck = !isPy3k;
+
+  meta = with stdenv.lib; {
+    description = "A NumPy-compatible matrix library accelerated by CUDA";
+    homepage = "https://cupy.chainer.org/";
+    license = licenses.mit;
+    platforms = [ "x86_64-linux" ];
+    maintainers = with maintainers; [ hyphon81 ];
+  };
+}
diff --git a/pkgs/development/python-modules/fastrlock/default.nix b/pkgs/development/python-modules/fastrlock/default.nix
new file mode 100644
index 00000000000..fb2c12b0db3
--- /dev/null
+++ b/pkgs/development/python-modules/fastrlock/default.nix
@@ -0,0 +1,19 @@
+{ stdenv, buildPythonPackage, fetchPypi }:
+
+buildPythonPackage rec {
+  name = "${pname}-${version}";
+  pname = "fastrlock";
+  version = "0.3";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "00mr9b15d539z89ng5nf89s2ryhk90xwx95jal77ma0wslixrk5d";
+  };
+
+  meta = with stdenv.lib; {
+    homepage = "https://github.com/scoder/fastrlock";
+    description = "A fast RLock implementation for CPython";
+    license = licenses.mit;
+    maintainers = with maintainers; [ hyphon81 ];
+  };
+}
diff --git a/pkgs/development/python-modules/filelock/default.nix b/pkgs/development/python-modules/filelock/default.nix
new file mode 100644
index 00000000000..38f1c594716
--- /dev/null
+++ b/pkgs/development/python-modules/filelock/default.nix
@@ -0,0 +1,19 @@
+{ stdenv, buildPythonPackage, fetchPypi }:
+
+buildPythonPackage rec {
+  name = "${pname}-${version}";
+  pname = "filelock";
+  version = "2.0.13";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "1n67dw7np5gsy5whynyk8c46pjlr353d6j9735p5gryaszkpjl6h";
+  };
+
+  meta = with stdenv.lib; {
+    homepage = "https://github.com/benediktschmitt/py-filelock";
+    description = "A platform independent file lock for Python";
+    license = licenses.unlicense;
+    maintainers = with maintainers; [ hyphon81 ];
+  };
+}  
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index dc415f624c8..9b8a10cbcdc 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -3555,6 +3555,10 @@ with pkgs;

   nbd = callPackage ../tools/networking/nbd { };

+  nccl = callPackage ../development/libraries/science/math/nccl {
+    cudatoolkit = cudatoolkit8;
+  };
+
   ndjbdns = callPackage ../tools/networking/ndjbdns { };

   ndppd = callPackage ../applications/networking/ndppd { };
diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix
index f425005c2fe..3cc29a7f2a7 100644
--- a/pkgs/top-level/python-packages.nix
+++ b/pkgs/top-level/python-packages.nix
@@ -1462,6 +1462,9 @@ in {
       substituteInPlace setup.py --replace "argparse" ""
     '';

+  chainer = callPackage ../development/python-modules/chainer {
+    cudaSupport = pkgs.config.cudaSupport or false;
+  };

   channels = callPackage ../development/python-modules/channels {};

@@ -1562,6 +1565,12 @@ in {

   cufflinks = callPackage ../development/python-modules/cufflinks { };

+  cupy = callPackage ../development/python-modules/cupy {
+    cudatoolkit = pkgs.cudatoolkit8;
+    cudnn = pkgs.cudnn6_cudatoolkit8;
+    nccl = pkgs.nccl;
+  };
+
   cx_Freeze = callPackage ../development/python-modules/cx_freeze {};

   cvxopt = buildPythonPackage rec {
@@ -8143,6 +8152,8 @@ in {

   fastimport = callPackage ../development/python-modules/fastimport { };

+  fastrlock = callPackage ../development/python-modules/fastrlock {};
+
   feedgen = callPackage ../development/python-modules/feedgen { };

   feedgenerator = callPackage ../development/python-modules/feedgenerator {
@@ -8261,6 +8272,8 @@ in {
     };
   };

+  filelock = callPackage ../development/python-modules/filelock {};
+
   fiona = callPackage ../development/python-modules/fiona { gdal = pkgs.gdal; };

   flake8 = callPackage ../development/python-modules/flake8 { };

前回のDerivationコードと大きく異なるところで言うと、metaのステートメントが増えています。
この部分は見た通り、パッケージのソフトウエアのライセンスやメンテナ等の情報を記入するところです。

さて、ここからいろいろなツッコミが入りまして修正を加えていくことになりました。
以下のようなツッコミをいただきました。

もらったReview

  • pkgs、python.pkgsは使うな。使用するパッケージは明記するべし。
  • GitHubからソースをダウンロードする場合はfetchFromGitHubが推奨される。
  • URLは""で囲むな。

このあたりはコーディング規約みたいな感じでしょうか。
ひょっとしたら、マニュアルを読み込めばちゃんと書いてあるのかも知れません。
まだまだ、全然読めてないので精進したいです。

  • cupyのビルド時のCUDA_PATH、CFLAGS、LDFLAGSは設定しなくても良いのでは?

はい、実際要りませんでした。
cupyビルド時にインストーラのpythonコードがPATHにあるライブラリとヘッダを探してくるので、
そのあたりはNixがうまいことやってくれたようです。

  • ncclの環境変数設定もこっちの方が良い。better-code.png

ごちゃごちゃしてたコードがスッキリしていくので非常にありがたいです。

  • buildPythonPackageにnameステートメントは必要ない。

これには正直驚きました。たとえばflaskなんかでもnameステートメントがあるので要らないとは思わなかったです。

Mergeへ

Reviewで指摘いただいた部分の修正をして、コードは以下のようになりました。

diff --git a/pkgs/development/libraries/science/math/nccl/default.nix b/pkgs/development/libraries/science/math/nccl/default.nix
new file mode 100644
index 00000000000..c4deccff5b7
--- /dev/null
+++ b/pkgs/development/libraries/science/math/nccl/default.nix
@@ -0,0 +1,41 @@
+{ stdenv, fetchFromGitHub
+, gcc5, eject, cudatoolkit
+}:
+
+stdenv.mkDerivation rec {
+  name = "cudatoolkit-${cudatoolkit.majorVersion}-nccl-${version}";
+  version = "1.3.4-1";
+
+  src = fetchFromGitHub {
+    owner = "NVIDIA";
+    repo = "nccl";
+    rev = "v${version}";
+    sha256 = "0fvnrfn572lc6i2a3xyhbifm53ivcrr46z6cqr3b0bwb1iq79m7q";
+  };
+
+  nativeBuildInputs = [
+    gcc5
+    eject
+  ];
+
+  propagatedBuildInputs = [
+    cudatoolkit
+  ];
+
+  makeFlags = [
+    "PREFIX=$(out)"
+    "CUDA_HOME=${cudatoolkit}"
+    "CUDA_LIB=${cudatoolkit.lib}/lib"
+  ];
+
+  meta = with stdenv.lib; {
+    description = ''
+      NVIDIA Collective Communications Library.
+      Multi-GPU and multi-node collective communication primitives.
+    '';
+    homepage = https://developer.nvidia.com/nccl;
+    license = licenses.bsd3;
+    platforms = [ "x86_64-linux" ];
+    maintainers = with maintainers; [ hyphon81 ];
+  };
+}
diff --git a/pkgs/development/python-modules/chainer/default.nix b/pkgs/development/python-modules/chainer/default.nix
new file mode 100644
index 00000000000..06a455176a2
--- /dev/null
+++ b/pkgs/development/python-modules/chainer/default.nix
@@ -0,0 +1,36 @@
+{ stdenv, lib, python
+, buildPythonPackage, fetchPypi, isPy3k
+, filelock, protobuf, numpy, pytest, mock
+, cupy, cudaSupport ? false
+}:
+
+buildPythonPackage rec {
+  pname = "chainer";
+  version = "3.2.0";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "0mbc8kwk7pvg03bf0j57a48gr6rsdg4lzmyj0dak8y2l4lmyskpw";
+  };
+
+  checkInputs = [
+    pytest
+    mock
+  ];
+
+  propagatedBuildInputs = [
+    filelock
+    protobuf
+    numpy
+  ] ++ lib.optionals cudaSupport [ cupy ];
+
+  # In python3, test was failed...
+  doCheck = !isPy3k;
+
+  meta = with stdenv.lib; {
+    description = "A flexible framework of neural networks for deep learning";
+    homepage = https://chainer.org/;
+    license = licenses.mit;
+    maintainers = with maintainers; [ hyphon81 ];
+  };
+}
diff --git a/pkgs/development/python-modules/cupy/default.nix b/pkgs/development/python-modules/cupy/default.nix
new file mode 100644
index 00000000000..6ac91c0aa25
--- /dev/null
+++ b/pkgs/development/python-modules/cupy/default.nix
@@ -0,0 +1,46 @@
+{ stdenv, python, buildPythonPackage
+, fetchPypi, isPy3k, linuxPackages, gcc5
+, fastrlock, numpy, six, wheel, pytest, mock
+, cudatoolkit, cudnn, nccl
+}:
+
+buildPythonPackage rec {
+  pname = "cupy";
+  version = "2.2.0";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "0si0ri8azxvxh3lpm4l4g60jf4nwzibi53yldbdbzb1svlqq060r";
+  };
+
+  checkInputs = [
+    pytest
+    mock
+  ];
+
+  nativeBuildInputs = [
+    gcc5
+  ];
+
+  propagatedBuildInputs = [
+    cudatoolkit
+    cudnn
+    linuxPackages.nvidia_x11
+    nccl
+    fastrlock
+    numpy
+    six
+    wheel
+  ];
+
+  # In python3, test was failed...
+  doCheck = !isPy3k;
+
+  meta = with stdenv.lib; {
+    description = "A NumPy-compatible matrix library accelerated by CUDA";
+    homepage = https://cupy.chainer.org/;
+    license = licenses.mit;
+    platforms = [ "x86_64-linux" ];
+    maintainers = with maintainers; [ hyphon81 ];
+  };
+}
diff --git a/pkgs/development/python-modules/fastrlock/default.nix b/pkgs/development/python-modules/fastrlock/default.nix
new file mode 100644
index 00000000000..848f01d6e16
--- /dev/null
+++ b/pkgs/development/python-modules/fastrlock/default.nix
@@ -0,0 +1,18 @@
+{ stdenv, buildPythonPackage, fetchPypi }:
+
+buildPythonPackage rec {
+  pname = "fastrlock";
+  version = "0.3";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "00mr9b15d539z89ng5nf89s2ryhk90xwx95jal77ma0wslixrk5d";
+  };
+
+  meta = with stdenv.lib; {
+    homepage = https://github.com/scoder/fastrlock;
+    description = "A fast RLock implementation for CPython";
+    license = licenses.mit;
+    maintainers = with maintainers; [ hyphon81 ];
+  };
+}
diff --git a/pkgs/development/python-modules/filelock/default.nix b/pkgs/development/python-modules/filelock/default.nix
new file mode 100644
index 00000000000..fec81d95bd8
--- /dev/null
+++ b/pkgs/development/python-modules/filelock/default.nix
@@ -0,0 +1,18 @@
+{ stdenv, buildPythonPackage, fetchPypi }:
+
+buildPythonPackage rec {
+  pname = "filelock";
+  version = "2.0.13";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "1n67dw7np5gsy5whynyk8c46pjlr353d6j9735p5gryaszkpjl6h";
+  };
+
+  meta = with stdenv.lib; {
+    homepage = https://github.com/benediktschmitt/py-filelock;
+    description = "A platform independent file lock for Python";
+    license = licenses.unlicense;
+    maintainers = with maintainers; [ hyphon81 ];
+  };
+}  
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index dc415f624c8..9b8a10cbcdc 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -3555,6 +3555,10 @@ with pkgs;

   nbd = callPackage ../tools/networking/nbd { };

+  nccl = callPackage ../development/libraries/science/math/nccl {
+    cudatoolkit = cudatoolkit8;
+  };
+
   ndjbdns = callPackage ../tools/networking/ndjbdns { };

   ndppd = callPackage ../applications/networking/ndppd { };
diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix
index f425005c2fe..3cc29a7f2a7 100644
--- a/pkgs/top-level/python-packages.nix
+++ b/pkgs/top-level/python-packages.nix
@@ -1462,6 +1462,9 @@ in {
       substituteInPlace setup.py --replace "argparse" ""
     '';

+  chainer = callPackage ../development/python-modules/chainer {
+    cudaSupport = pkgs.config.cudaSupport or false;
+  };

   channels = callPackage ../development/python-modules/channels {};

@@ -1562,6 +1565,12 @@ in {

   cufflinks = callPackage ../development/python-modules/cufflinks { };

+  cupy = callPackage ../development/python-modules/cupy {
+    cudatoolkit = pkgs.cudatoolkit8;
+    cudnn = pkgs.cudnn6_cudatoolkit8;
+    nccl = pkgs.nccl;
+  };
+
   cx_Freeze = callPackage ../development/python-modules/cx_freeze {};

   cvxopt = buildPythonPackage rec {
@@ -8143,6 +8152,8 @@ in {

   fastimport = callPackage ../development/python-modules/fastimport { };

+  fastrlock = callPackage ../development/python-modules/fastrlock {};
+
   feedgen = callPackage ../development/python-modules/feedgen { };

   feedgenerator = callPackage ../development/python-modules/feedgenerator {
@@ -8261,6 +8272,8 @@ in {
     };
   };

+  filelock = callPackage ../development/python-modules/filelock {};
+
   fiona = callPackage ../development/python-modules/fiona { gdal = pkgs.gdal; };

   flake8 = callPackage ../development/python-modules/flake8 { };

Pull Request自体は2018/12/28日に送ってその日のうちにReviewと修正、
2018/12/29にはMergeされたというくらいのスピードでした。

IRC Chat上でも色々話していて、そこにいた人がすぐにReviewしてくれたというのも良かったと思います。
またPull Requestとは別にChat上でcupyのビルドできるプラットフォームはlinux-x86_64だけなのかという話も上がったりしました。
(結局nixpkgsのcudatoolkit自体がlinux-x86_64のみに対応しているので、cupyもそうなることがわかりました。)
このようにnixpkgsはGitHubやIRC Chatでコミュニティが活発なので、Pull Requestでコミュニケーションを細かく取ることもできます。

nix-channel unstableへ

nixpkgsのリポジトリへマージされた後、nixpkgs-channelsのnixos-unstableへcommitが行われ、
この時点でnix-channelにunstableを追加していればパッケージをダウンロードできるようになります。
chainer-in-unstable.png
というわけで、無事、chainerのパッケージをダウンロードできる形にできました。

今回は以上です。

3
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1