本当は怖い情報科学

とあるHPC屋の趣味&実益ブログ

Travis CIのテストをローカルで走らせる

Travis CIは、Githubリポジトリにあるコードの継続的インテグレーションをサポートしてくれるツールです。 公開リポジトリであれば無料で利用できるため、プロジェクトで利用されていると思います。

.travis.yml というファイルをリポジトリに置くことによって Travis CIの挙動を制御することができますが、テスト動作をテストするためにはリポジトリへ push を行う必要があるため、 細かい挙動の調整を繰り返し行うのは時間のかかる作業です。

そこで、loci というソフトウェアを使って、ローカルにセットアップしたVagrantとDockerを使って Travis CIの挙動をローカルで再現する環境を作ってみました。

全体の構成

今回は、私の作業環境であるMacbook上での作業です。その上にVagrantを使ってUbuntuの仮想環境を構築し、その仮想環境の中でさらにDockerを動かしてTravis相当のCIを走らせます。

VagrantとDockerを設定する

まず、Virtualboxを用いてVagrant環境を構築します。Virtualbox, Vagrantが何かということと、それらのインストール方法は他に譲ります。

まず、Travis CIのコンテナ環境と同じUbuntu Trustyのboxイメージをダウンロードしてきます。適当な場所に作業ディレクトリを作って作業します

$ vagrant box add travis https://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box

次に、その boxを使って仮想マシンを作成します

$ vagrant init ubuntu/trusty64

# Vagrantの仮想マシンにログイン
$ vagrant ssh

Go言語とLociの導入

作成した仮想マシン上にGo言語の環境を構築してからLockをインストールします。Go言語の1.7以降が必要ですが、Ubuntuのパッケージに含まれているのは古いバージョンなので、手動で導入することにします。下記のWebサイトに従ってインストールを行いました。

How to Install Go 1.8 on Ubuntu 16.04 & 14.04 | TecAdmin

ここでは、Go言語自体のインストールパスを GOROOT 、goプログラムのパスを GOPATHとしています。

次に、仮想マシン上にLociをインストールします。これは、githubの説明に従って go get を走らせるだけです。

$ go get github.com/jkawamoto/lock

動作を確認しておきましょう。

$ ${GOPATH}/bin/lock --version
Loci version 0.5.2

Dockerの導入

UbuntuのパッケージにあるDockerではなく、Docker-CEを自分で導入します。

Get Docker CE for Ubuntu | Docker Documentation

起動用シェルスクリプトの構築

以下のように起動スクリプトを作成しました。VagrantをインストールしたディレクトリをVAGRANT_PATHとして、以下のように起動します。また、VAGRANT_PATHの1つ上のディレクトリがプロジェクトのディレクトリであることを仮定しています。

$ env VAGRANT_PATH=~/.mpienv/vagrant bash run-local-travis.sh

ポイントとしては、

  • vagrant sshでSSHの設定を取り出してSSH接続をおこなうこと
  • DOCKER_API_VERSION変数を設定すること
  • Dockerの構築に使うイメージをubuntu/trustyにすること(Lociのデフォルトだと Ubuntu 16を使おうとするので、パッケージ等がTravisと異なるためにエラーになるケースが有る)

といったあたりです。

gist.github.com

HPDC'17

HPDC'17が開催されています(私は参加していません)。

Programを眺めた感じ、個人的には以下の論文が面白そうです。

  • “CuMF_SGD: Parallelized Stochastic Gradient Descent for Matrix Factorization on GPUs” Xie, Tan, Fong, Liang
  • LetGo: A Lightweight Continuous Framework for HPC Applications Under Failures Fang, Guan, Debardeleben, Pattabiraman, Ripeanu
  • “Towards a More Complete Understanding of SDC Propagation” Calhoun, Snir, Olson, Gropp
  • “Diagnosing Machine Learning Pipelines with Fine-grained Lineage” Zhang, Sparks, Franklin
  • “COS: A Parallel Performance Model for Dynamic Variations in Processor Speed, Memory Speed, and Thread Concurrency” Li, Leon, Cameron
  • “Explaining Wide Area Data Transfer Performance” Liu, Balaprakash, Kettimuthu, Foster
  • “Machine and Application Aware Partitioning for Adaptive Mesh Refinement Applications” Fernando, Sundar, Duplyakin

MPI環境の切り替えをするmpienvというツールを作った

背景

多くの場合、スパコンやクラスタ上には複数のMPIがインストールされています。ユーザーは、これらを適切に切り替えて使わなければなりません。普通のユーザーであれば、普段使うMPIは一種類で固定であるケースが多いので、.bashrc等の設定ファイルに設定を書いておけば問題ありません。

ライブラリなどの開発をする場合、複数のMPIでテストを行う必要があるので、MPIを切り替えて使うことになります。基本的にはPATHLD_LIBRARY_PATHを切り替えればOKなのですが、プログラムをコンパイルしたときのMPIと、実行するときのMPIは合致していなければいけません。これらが食い違うと、正しく並列プログラムを実行できません。

基本的には2つの環境変数を切り替えるだけですので、シェルスクリプトでも書けば一瞬ですし、環境によっては実際に既に用意されていることも多いです。プラットフォーム固有の切り替えコマンドがある場合もあります(例えばCray系システムのmoduleコマンドなど)。

解決すべき問題

このような、複数のMPIの利用にはいくつか問題があります。

  • システムにどのようなMPIが用意されているのか忘れる
  • あるプログラムをどのMPIでコンパイルしたのか忘れる
  • MPIの切り替えを手動でやろうとして忘れる
  • 自分でインストールしたMPIの存在を忘れる

のような問題です。

さらに、PythonからMPIを使うライブラリであるmpi4pyを用いると、さらなる問題が発生します。mpi4pyはインストール時に使ったMPIにリンクされるため、PATHLD_LIBRARY_PATHを切り替えるだけでは駄目だということです。切替時には、mpi4pyを一旦アンインストールし、MPIを切り替えたあとに再度mpi4pyをインストールする必要があるということです。

pyenvなどのツールを使ってPython実装ごと切り替えるという手もありますが、それはかなり面倒ですし、どちらにしろpyenvによる切り替えを忘れると謎のエラーで苦しむ事になります。

解決策

これらを解決するために、mpienvというツールを作りました。これは、Pythonにおけるpyenvだと思っていただければ、ほぼ正しいです。

github.com

詳細はREADMEを見ていただきたいと思いますが、基本的にできることは以下です。

  • システムにインストールされているMPIを一覧・管理する
  • MPIを切り替える
  • mpi4pyも同時に切り替える
  • 開発中の機能
    • MPIを自動でインストールする
    • バイナリを指定した時に、それに適したMPI実装を自動で選ぶ
    • pyenvのように、ディレクトリごとに使うMPIを切り替える

などのことができます。手前味噌ですが、複数MPIを切り替えてのテストやデバッグが劇的に楽になりました。まだまだ開発中ですが、適当なタイミングで利用方法の説明を書きたいと思います。

【広告】