HPCメモ

HPC(High Performance Computing)に関連したりしなかったりすることのメモ書き

YubiKey

さて、cloud9にもだいぶ慣れてきたのですが、こう頻繁にAWSを使っているとMFA認証が煩わしくなってきました。

AWSのベストプラクティスとして推奨されているMFA認証ですが、スマホにインストールしたgoogle認証アプリを使っているものだから

  1. MFAでの認証画面が出る
  2. スマホを取り出す
  3. なんか通知が来てる
  4. twitter やらfacebookやらをつい見てしまう。
  5. ・・・あれ今何してたっけ?

という恐しい罠によくはまるんですよ・・・orz

AWS以外でMFAは使っていないので、以前はこの罠も月に1、2度くらいのものでしたが、さすがに1日1回はひっかかるようになってきたので こちらのハードウェアMFAデバイスを導入してみました。

aws.amazon.com

色々と並んでいますが、私が買ったのは左から2番目に表示されているyubico社製のYubiKeyという製品です。

AWSのページからはamazon.comの製品ページにリンクされていますが、リンク先にあるYubiKey4という製品は"Currently unavailable"となってました。 しかし、YubiKey自体は国内ではソフト技研さんが代理店として取り扱っているようで、amazon.co.jpでも普通に売ってました。

NFCが付いてたり、すごい小さいのがあったりと、色々バリエーション豊富なんですが、うちのスマホNFC非対応だし小さいと紛失する可能性が高くなるので*1旧バージョンらしきこちらの製品にしてみました。

AWSでの設定方法

こちらの公式ドキュメントに書いてある手順に従って進めていきます。

docs.aws.amazon.com

f:id:n_so5:20190401230922p:plain

一部和訳が進んだせいか、[My Security Credentials] が「マイセキュリティ資格情報」に進化してますが*2とりあえず進んでいって、一旦MFAの設定を削除すると、MFAデバイスをセットアップできるようになります。しかし、なんとサファリは非対応とのこと。

f:id:n_so5:20190401231423p:plain

Firefoxで同じページまで行くと、「U2F セキュリティキー」が選べるようになるのですが、今度はこの画面でYubiKeyをタップしても先に進めません。

トラブルシューティングのドキュメントへリンクが貼ってあったのでそちらを見てみると、firefoxは設定変更が必要な可能性が高いとのことでした。

docs.aws.amazon.com

こちらの設定変更を行なって、Firefoxを一度再起動すると、さきほどの画面でYubiKeyを挿した時点でキーのインジケータが点滅します。後はウィザードの指示どおりKeyをタップすると設定完了です。

この状態からgoogle chromeでマネジメントコンソールのページにアクセスすると、いつものユーザ名やパスワード入力画面の後で、こんな画面が表示されます。

f:id:n_so5:20190401233758p:plain

そして、ドヤ顔しながらKeyを軽く触わると、ログインできてマネジメントコンソールへ移ります。

しかし、safariで同じことをやろうとすると、

f:id:n_so5:20190401234836p:plain

うーむ残念。まぁこういう状況のようなので、そのうち使えるようになるでしょう。

applech2.com

それよりもモバイルブラウザが全滅なので、iPadからログインできなくなったのがちょっと痛いところです。

AWS consoleアプリを入れておけば、アクセスキー&シークレットアクセスキーでアクセスできるんですが、このアプリからではcloud9は使えないので私の用途には合いませんでしたorz

*1:たいして小さくもないRSA SecurIDのトークンでも1回紛失騒動を起こしたことがありまして・・・

*2:どうしてマイをつけちゃったんだw

モバイルディスプレイ用スタンド

去年導入したモバイルディスプレイに、こちらの記事で書いたように長ネジをネジ込んでスタンド代わりにしてました。

hpcmemo.hatenablog.com

最初は見た目のインパクトもあって楽しんでたものの、いかんせん後ろのデッドスペースが大きすぎますw

もともとVESAマウント用のネジ穴が本体に切られてるんだから、VESA規格のディスプレイスタンドに載せようかとも思ったんですが、 小さめのものでも数kgクラスのディスプレイ用に作られているものばかりのようで、11インチのサブディスプレイを載せるにはゴツすぎるものしか 見つけられませんでした。

カメラ用三脚なら小型のものもあるので

  • 120x120mmくらいのアルミかアクリル板を買う
  • VESA穴の位置に穴を開ける
  • 真ん中に適当に穴を開けて、三脚ネジのメスを埋め込む

といった工作を考えてたんですが、材料をアマゾンで物色してたらちょうど良い製品がありました。

記事作成中に確認しようと思って見に行ったら消えてましたが、私が買った時は商品説明に横幅115mmって書かれてたので、両端の溝同士で多少斜めにすればVESAマウンタの横幅(100mm)にはまるかなーと期待して買ってみました。

で、装着してみたらこの通りちょうど両端の穴同士で100mmだったようです。

f:id:n_so5:20190403115128j:plain

手元にあった卓上三脚に小型の自由雲台を追加して載せるとこんな感じです。 上からのアングルなので分かり難いかもしれませんが、机の上におくと自然な姿勢でちょっと見降ろした時に良い位置に来て使い勝手が良くなりました。

f:id:n_so5:20190403115504j:plain

AWS cloud9 メモ

これまで、自宅兼オフィスではMac mini、外出先はASUSのtransbook(surfaceっぽいwindows tablet)と2環境を使い分けてきました。

しかし、この構成だと外出先で電源とwifiを確保して、さー仕事するぞーと意気込んで git pull したのに mac側で作業した後で push してなくて何もできないという悲しい事態が稀によく起きます・・・orz

こういうミスが嫌だったので、一昔前はデスクトップマシンは使わず全ての作業をノートPCでやってたんですが、 最近はiPadやらラズパイやらと使う端末が増えることはあっても1台にまとめるのは到底無理な感じです。

というわけで、複数端末間の開発環境の統一のためにAWS Cloud9を導入してみました。

aws.amazon.com

網羅的な解説資料は既に色々なところにあるので、私が調べたり試したものをいくつかトピック毎にまとめておきます。

セットアップ方法

EC2を使う環境の場合は、ドキュメントの通りに作業すればほとんどひっかかるところは無いと思います(そもそも選択するオプションがほとんど無い)

唯一気をつけておく必要があるのは最初に入力する "Name" で、これがIDE起動後に表示されるファイルツリーのrootの名前になるのであまり長い名前をつけてると見難くなりますw f:id:n_so5:20190401140358p:plain

何が使えるのか?

こちらにインストール済のパッケージの一覧があります。

docs.aws.amazon.com

  • Amazon Linux AMI ウェブサイトの「Amazon Linux AMI 2018.03 パッケージ」にリストされているパッケージ。

なんて書かれてますが、こちらのパッケージリストには、

  • gcc-4.8.5
  • gcc44-4.4.6
  • gcc48-4.8.5
  • gcc64-6.4.1
  • gcc72-7.2.1

と色々書かれてて、イマイチよくわかりません。とりあえずログインして、調べてみましょう。

[ec2-user@ip-10-0-0-248 environment]$ gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-28)
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

[ec2-user@ip-10-0-0-248 environment]$ which gcc
/usr/bin/gcc
[ec2-user@ip-10-0-0-248 environment]$ ls -l `which gcc`
lrwxrwxrwx 1 root root 21 Feb 18 10:29 /usr/bin/gcc -> /etc/alternatives/gcc

おお、alternativesだ・・・どうやって使うんだっけ。*1

ぐぐりながら調べてみたところ、どうやらgccは4.8.5しか入っていないようです。

[ec2-user@ip-10-0-0-248 environment]$ alternatives --display gcc
gcc - status is auto.
 link currently points to /usr/bin/gcc48
/usr/bin/gcc48 - priority 482
 slave cc: /usr/bin/gcc48
 slave c89: /usr/bin/gcc48-c89
 slave c99: /usr/bin/gcc48-c99
 slave gcov: /usr/bin/gcov48
 slave gcc.1: /usr/share/man/man1/gcc48.1.gz
 slave gcov.1: /usr/share/man/man1/gcov48.1.gz
Current `best' version is /usr/bin/gcc48.
[ec2-user@ip-10-0-0-248 environment]$ alternatives --config gcc

There is 1 program that provides 'gcc'.

  Selection    Command
-----------------------------------------------
*+ 1           /usr/bin/gcc48

Enter to keep the current selection[+], or type selection number: 
failed to create /var/lib/alternatives/gcc.new: Permission denied

しかも、よくみたらgfortranが入っていません。AWSの人はFortran死すべし派だったのか?

yum install一発で4.8.5がインストールされるので必要になったらインストールしましょうか。

[ec2-user@ip-10-0-0-248 environment]$ sudo yum install -y gcc-gfortran
Loaded plugins: priorities, update-motd, upgrade-helper
amzn-main                                                                                                                                          | 2.1 kB  00:00:00     
amzn-updates                                                                                                                                       | 2.5 kB  00:00:00     
epel/x86_64/metalink                                                                                                                               | 6.7 kB  00:00:00     
epel                                                                                                                                               | 4.7 kB  00:00:00     
1060 packages excluded due to repository priority protections
Resolving Dependencies
--> Running transaction check
---> Package gcc-gfortran.noarch 0:4.8.5-1.22.amzn1 will be installed
--> Processing Dependency: gcc48-gfortran >= 4.8.5 for package: gcc-gfortran-4.8.5-1.22.amzn1.noarch
--> Running transaction check
---> Package gcc48-gfortran.x86_64 0:4.8.5-28.142.amzn1 will be installed
--> Processing Dependency: libgfortran.so.3()(64bit) for package: gcc48-gfortran-4.8.5-28.142.amzn1.x86_64
--> Running transaction check
---> Package libgfortran.x86_64 0:6.4.1-1.45.amzn1 will be installed
amzn-main/latest/filelists_db                                                                                                                      | 5.7 MB  00:00:01     
amzn-updates/latest/filelists_db                                                                                                                   | 7.3 MB  00:00:00     
epel/x86_64/filelists_db                                                                                                                           | 7.9 MB  00:00:00     
--> Processing Dependency: libquadmath.so.0(QUADMATH_1.0)(64bit) for package: libgfortran-6.4.1-1.45.amzn1.x86_64
--> Processing Dependency: /usr/lib64/libquadmath.so.0.0.0 for package: libgfortran-6.4.1-1.45.amzn1.x86_64
--> Processing Dependency: libquadmath.so.0()(64bit) for package: libgfortran-6.4.1-1.45.amzn1.x86_64
--> Running transaction check
---> Package libquadmath.x86_64 0:6.4.1-1.45.amzn1 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

==========================================================================================================================================================================
 Package                                   Arch                              Version                                        Repository                               Size
==========================================================================================================================================================================
Installing:
 gcc-gfortran                              noarch                            4.8.5-1.22.amzn1                               amzn-main                               3.8 k
Installing for dependencies:
 gcc48-gfortran                            x86_64                            4.8.5-28.142.amzn1                             amzn-updates                            8.0 M
 libgfortran                               x86_64                            6.4.1-1.45.amzn1                               amzn-main                               391 k
 libquadmath                               x86_64                            6.4.1-1.45.amzn1                               amzn-main                               197 k

Transaction Summary
==========================================================================================================================================================================
Install  1 Package (+3 Dependent packages)

Total download size: 8.5 M
Installed size: 20 M
Downloading packages:
(1/4): gcc-gfortran-4.8.5-1.22.amzn1.noarch.rpm                                                                                                    | 3.8 kB  00:00:00     
(2/4): libgfortran-6.4.1-1.45.amzn1.x86_64.rpm                                                                                                     | 391 kB  00:00:01     
(3/4): libquadmath-6.4.1-1.45.amzn1.x86_64.rpm                                                                                                     | 197 kB  00:00:00     
(4/4): gcc48-gfortran-4.8.5-28.142.amzn1.x86_64.rpm                                                                                                | 8.0 MB  00:00:02     
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Total                                                                                                                                     3.3 MB/s | 8.5 MB  00:00:02     
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : libquadmath-6.4.1-1.45.amzn1.x86_64                                                                                                                    1/4 
  Installing : libgfortran-6.4.1-1.45.amzn1.x86_64                                                                                                                    2/4 
  Installing : gcc48-gfortran-4.8.5-28.142.amzn1.x86_64                                                                                                               3/4 
  Installing : gcc-gfortran-4.8.5-1.22.amzn1.noarch                                                                                                                   4/4 
  Verifying  : gcc-gfortran-4.8.5-1.22.amzn1.noarch                                                                                                                   1/4 
  Verifying  : libgfortran-6.4.1-1.45.amzn1.x86_64                                                                                                                    2/4 
  Verifying  : gcc48-gfortran-4.8.5-28.142.amzn1.x86_64                                                                                                               3/4 
  Verifying  : libquadmath-6.4.1-1.45.amzn1.x86_64                                                                                                                    4/4 

Installed:
  gcc-gfortran.noarch 0:4.8.5-1.22.amzn1                                                                                                                                  

Dependency Installed:
  gcc48-gfortran.x86_64 0:4.8.5-28.142.amzn1                 libgfortran.x86_64 0:6.4.1-1.45.amzn1                 libquadmath.x86_64 0:6.4.1-1.45.amzn1                

Complete!
[ec2-user@ip-10-0-0-248 environment]$ gfortran --version
GNU Fortran (GCC) 4.8.5 20150623 (Red Hat 4.8.5-28)
Copyright (C) 2015 Free Software Foundation, Inc.

GNU Fortran comes with NO WARRANTY, to the extent permitted by law.
You may redistribute copies of GNU Fortran
under the terms of the GNU General Public License.
For more information about these matters, see the file named COPYING

しかし相変わらず、alternativeの方にはfortranは出力されない。

[ec2-user@ip-10-0-0-248 environment]$ alternatives --display gcc
gcc - status is auto.
 link currently points to /usr/bin/gcc48
/usr/bin/gcc48 - priority 482
 slave cc: /usr/bin/gcc48
 slave c89: /usr/bin/gcc48-c89
 slave c99: /usr/bin/gcc48-c99
 slave gcov: /usr/bin/gcov48
 slave gcc.1: /usr/share/man/man1/gcc48.1.gz
 slave gcov.1: /usr/share/man/man1/gcov48.1.gz
Current `best' version is /usr/bin/gcc48.
[ec2-user@ip-10-0-0-248 environment]$ alternatives --display gfortran
gfortran - status is auto.
 link currently points to /usr/bin/gfortran48
/usr/bin/gfortran48 - priority 482
 slave f95: /usr/bin/gfortran48
 slave gfortran.1: /usr/share/man/man1/gfortran48.1.gz
Current `best' version is /usr/bin/gfortran48.

これは、別バージョンのgccを入れた時にgccだけバージョンを変えて、gfortranを変え忘れるとはまるパターンですね・・・

nodeもv6.14.3とかいう挑戦的なバージョンですが、こっちはnvmが入っているのでltsの最新あたりまで上げときましょう。

[ec2-user@ip-10-0-0-248 WHEEL]$ nvm install lts/*
v10.15.3 is already installed.
Now using node v10.15.3 (npm v6.4.1)

で、この辺の初期化処理を自動化しようと思って色々と調べていたのですが、どうやらそういう仕組みは用意されていないようです。 こちらに初期化スクリプトというのがあって、これを使ってねってことかと思ったんですが、なぜかJavascriptです。

docs.aws.amazon.com

数時間ぐぐった結果こちらの記事で使われている例くらいしか見つけられなかったのですが、 これはひょっとするとcloud9独自の初期化処理用プラグイン的なものなんでしょうかね?

qiita.com

AWSのドキュメントによると

現時点では、IDE での初期化スクリプトへのコードの追加は実験的な機能であり、完全にはサポートされていません。初期化スクリプトにコードを追加するときは、ご自分の判断で行ってください。AWS Cloud9 には、この機能をいつでも変更する権利があります。

とのことなので、そのうちもっと分かりやすものが作られるのに期待しておきましょう。 *2

当面はパッケージの追加インストールくらいしかしないので、シェルスクリプトでも作ってgistあたりに置いておく運用が楽そうです。 *3

hibernate設定

環境作成時のウィザードで"Cost-saving setting"という内容で書かれているのですが、 inactive になってから、設定した時間が経過したらEC2のインスタンスを落としてくれるという設定があります。

ちょくちょくブラウザを開きっぱなしにして外出してしまう私としては、 大変ありがたい機能なんですが、どういう条件で inactive と判定してるのかよく分からなかったのでちょっと実験してみました。

実験方法

inactiveになって30分後にhibernateする設定(デフォルト設定)で、次の3パターンで放置し30分以上経過してから止まってたかどうかを確認します。 なお、ブラウザウィンドウは全て表示したままにしています。

  1. IDEを起動しているがterminal、ファイルともに開いていない状態
  2. IDEを起動してファイルを開いた状態
  3. IDEを起動してterminalを開きプロンプトが表示された状態
  4. IDEを起動してterminalを開き定期的に表示が更新されるコマンド(top)を実行した状態
  5. 何も起動せずに preview windowを押して8080ポートにアクセスしたままの状態
  6. immediate windowでwhile(true) console.log("hoge")しておいた場合

stopした時刻は、Cloud Trailには出てこないので(たぶんOS側でシャットダウンしてる)一晩放置してから、IDEのterminal経由で/var/log/messagesをチェックしてみました。

実験結果

全パターンシャットダウンされませんでした。

その後、ブラウザウィンドウを閉じて30分程度経過したところで、EC2コンソールをリロードしながら眺めていたらstopping->stopと遷移していったので、どうやらブラウザが開いてるとIDE上で何もしていなくてもactiveと判定されるようです。*4

というわけで、EC2側の実行状態には関係なくて、ブラウザとの接続が失われるとinactive状態と判定されるようです。

ここまで調べてから、ふとドキュメントを見ていたらしっかりとブラウザからの接続が全部無くなってからの時間ですよって書かれてました。 無駄にインスタンスを立ちあげてしまった・・・ orz

docs.aws.amazon.com

[Cost-saving setting (コスト削減のセットアップ)] で、environment の IDE に接続されているすべてのウェブブラウザインスタンスが閉じられてから、AWS Cloud9 で environment の Amazon EC2 インスタンスがシャットダウンされるまでの時間を選択します。または、デフォルトの選択のままにします。

PCをスリープにするか、ネットワーク接続が切れればinactiveとして扱ってもらえそうなので、たいていの場合は大丈夫そうですが、モバイルルータやテザリングでノートPCを使ってる人とかCellular版のiPadを使っている人は要注意ですね。

複数プロジェクト対応

1つのEnvironmentに複数のプロジェクト(というかgit repository)を配置することができますが、各種設定時に1つ注意が必要になります。

cloud9から立ち上げられたEC2インスタンスは$HOME直下に "environment"というディレクトリが作成されていて、ここがIDEのファイルブラウザ画面のrootになります。したがって、この下にディレクトリを掘ってgitリポジトリを複数作る(またはgit cloneしてくる)ことで複数プロジェクトを1つのEnvironmentに配置することができるのですが、ビルダーやランナー、あとコードフォーマッターなんかの起動時は、"$HOME/environment"がcurrentディレクトリになります。

code formatterにeslintを設定したのに動かなくって、AWS Developer Forumsで教えてもらいながら調べてたのですが、ローカルインストールされたコマンドを叩く場合は、次のように$fileの存在するディレクトリまで移動してからnpxを叩く必要があります。

cd `dirname $file`;npx eslint --fix `basename $file`

ビルダーやランナーの設定にnpmを使う場合も同様で、プロジェクトのディレクトリの下へ移動してからコマンドを実行する必要があります。 こちらは設定ファイルに "working_dir": "$file_path" という項目を追加しておけば、大丈夫です*5

ランナーの設定

デフォルトのランナーは大変お粗末な感じで、例えばC++ランナーだと次のような設定になっています。分割コンパイルはしない前提なのか、$fileをコンパイルして生成された実行ファイルを呼び出すだけのものです・・・

{
  "script": [
    "set -e",
    "if [ \"$debug\" == true ]; then ",
    "    g++ -ggdb3 -std=c++11 $file -o $file.o",
    "    chmod 755 \"$file.o\"",
    "    node $HOME/.c9/bin/c9gdbshim.js \"$file.o\" $args",
    "else",
    "    g++ -std=c++11 $file -o $file.o",
    "    chmod 755 $file.o",
    "    $file.o $args",
    "fi"
  ],
  "info": "Running $file",
  "debugger": "gdb",
  "$debugDefaultState": false,
  "selector": "^.*\\.(cpp|cc)$",
  "trackId": "Cplusplus"
}

プロジェクト全体でcmakeを使っているのであればcmake&&make&&make testみたいな感じで書き直しておきましょう。 あと、clean buildの設定も必要ですね。そもそもプロジェクト毎にcmakeを使うのかGNU auto toolsなのかはたまたmakefile直書きなのかと違うからこれに対応して・・・と考えると破綻しそうなので、私はこの設定を作り込むのは諦めました。

単にterminalを開いてビルドすれば良いだけなので・・・

起動中のインスタンスの確認

画面の右上にcloud9のアイコンがありますが、その隣のボタン(たぶんAWSのユーザ名の頭文字)をクリックするとドロップダウンリストが現れて、cloud9のダッシュボードと、EC2コンソールへのリンクが表示されます。また、cloud9のアイコンはdashboardへのリンクになっています。

f:id:n_so5:20190401141028p:plain

*1:スパコン関連はmodule使ってるとこが多いもんでこいつほとんど使ったこと無いんです

*2:そもそもドキュメントが不足してて何を書けば動くのやらさっぱり分かりませんorz

*3:私の場合はもとももドットファイルgithubで管理してたので、そこにシェルスクリプトを追加しました。

*4:1のケースだけ実験すれば十分だった・・・

*5:code formatterの設定では$fileは使えるけど$file_pathは使えないので一手間かけないといけないのです・・・

数値計算屋にはFortranは捨てなくても良いけどソフトウェアエンジニアリングを学んでほしい

twitterでこちらの記事をみかけたので、Fortran完全に理解したエンジニアの一人として便乗記事を書いときます。

qhapaq.hatenablog.com

ちなみに、私は学生時代からかれこれ20年近く数値計算屋をやってますが、メインの言語はC、C++Pythonときて今は主にJavascriptを使ってます。とはいえ、就職してからは基本的にチューニング屋なので、普通の数値計算屋さんの数倍は他人の(主にFortran)コードを読み書きしてきたと思っています。その中で日頃感じていたもやもやをこの機会にまとめてみました。

元記事には3つFortranを捨てるべき理由が挙げられていますが、個々の内容に対しては概ねその通りだと思います。(細かいところで異論は色々とあるんですが、そこは本筋ではないので省略します)

ところが、残念ながらFortranを捨てても何も解決しないのです。

私が今までに見た最も残念なC++のコードは、全ての処理がMainクラスのrunメソッドに書かれていて、main文からはそのメソッドが呼ばれているだけでした。 また、運良く(?)Fortranのコードを全て捨ててC++に移行したOpenFOAMみたいな例がありますが、ロジックの途中にコードのスニペットをincludeするとかいう凶悪な仕様になっていて、よりによってなんでそんなカプセル化しちゃったのか問いつめたいところです。

Rustにも言及されてましたが、プログラミング言語を変えたところでソフトウェアの品質が良くなるわけではないのです。

どうしてこうなった?

数値計算屋の中にはこんな形でキャリアが始まった方も多いのではないでしょうか

  1. 大学で非情報系の分野を専攻
  2. 研究室に配属されたらなんかコンピュータがいっぱいあった
  3. ソフトウェア遺産を読みつつ(もしくは先輩に教わりつつ)プログラミングを始める

こういう方々にとってはソフトウェアの開発は目的ではなくて研究のための手段なのです。ソフトウェアの品質に多少の難があっても研究の成果が得られていれば、良い方向に進んでいると判断されるし、「動いているコードになるべく手を入れない」というのは経験豊富なソフトウェアエンジニア以外には、とても素晴しいノウハウのように思えるものです。*1

そういった幾人もの研究者が、先代から受けついでいった秘伝のタレみたいなコードが数値計算の世界ではそこそこ生き残っているし、公開されて広く使われてたりもするので「Fortran死すべし!!」みたいな話になるのは理解できなくもないですが、別の言語で書いたところで、同じようなものを再生産するだけじゃないでしょうか。

Fortranを捨てることの是非はさておき、この不幸なサイクルを断ち切るために、数値計算屋を志す若者には次の3つを心に留めてほしいと思っています。

1. 関心の分離、KISS、DRY、YAGNIといったソフトウェアエンジニアリングの基本的な概念を知る

何かの目的があってプログラムを書き始めた時は、当初の機能が実現できたらあとは使うだけというように思えるものですが、使っているうちに何か新しい機能を追加したくなったり、OSやハードウェアの更新にともなって不具合がでてきたりと何だかんだで改修を迫られます。

その度に難解なコードを解読したり、複数の場所に同じ処理が書かれていて何箇所も同じような修正作業を繰り返す羽目になったりというような非生産的な苦行を繰返してきた先人達が、「この辺に気をつけておけば後々楽できる」といった観点で研究してきたものがソフトウェアエンジニアリングです。*2

あなただけがこの苦行から逃れられる確率は非常に低いので、先人の知恵にのっかりましょうw

2. デザインパターンを学ぶ

デザパタ自体を数値計算のプログラムに適用する機会はあまり無いかもしれませんが、色々なデザパタ本で紹介されている手法は、1で挙げたソフトウェアエンジニアリングの概念をJAVAC++で実装するためのものとも言えます。

抽象的な概念だけ聞いててもイマイチ分からんという人はこっち方面から勉強してみるのも良いと思います。

3. VCS、ビルドシステムやテストフレームワークといったツールを使う

多くのプログラマは、きりが良いところまでコードを書いたらビルド&テストをして実際に想定しているとおりに動作するか確認しつつ開発を進めていくと思います。

ソフトウェアエンジニアリングについて学んでいくと、たいていの場合コードが細ぎれになり、ビルド&テストのサイクルはどんどん短かくなります。 そうすると、これまで手作業でやっていたコンパイル -> 実行 -> 結果確認 というプロセスが邪魔になってきて、ふと気付いたらコンパイルすらせずに数十もの関数を書いていたなんて悪夢がおきます。

まっとうなビルドシステム(makeでも十分ですが移植性を考えるとautomakeやらcmakeやらも欲しい)であれば、コマンド一発でビルドしてテストすることも簡単ですし、そこにテストフレームワーク(googletestとか)を導入しておけば、単体テストなんかも楽に書けます。

VCS(Version Control System 要するにgitとか)は、開発プロセスに大量のセーブポイントを持ち込んでくれるものです。 数日かけてようやく完成させた機能が、まったく使いものにならないことが判明した時とか気軽に元の状態に戻すことができます。 逆に、お試し実装をポコポコと追加して、駄目だったら消すようなトライアンドエラーも簡単にできるようになるわけです。

特に性能面で「両方作って試してみるかー」みたいな話になりがちな数値計算屋にとっては、大変心強い味方です。 さらにgithubみたいなwebサービスを使っておけば、「手元のコードとスパコンのフロントエンドに置いてあるコードが違う」なんていう不慮の事故も防ぐことができます。(たまに外に出ていけないシステムがあってちょっと面倒ですが)

おわりに

長々と妄言を書いてきましたが、特定の数値計算ソフトウェアのプロジェクトや、特定の数値計算屋さんを非難するつもりで書いたものではありません。これから数値計算の世界に足を踏み入れる若い人が、過去の遺物に学んで負のスパイラルに陥いらないことを願って先輩風を吹かせただけの駄文ですので、ご笑覧いただければ幸いです。でもってこれを読んだ優秀な若手が育って、素晴しい開発プロジェクトを立ちあげた際には弊社にも何かお仕事を・・・

*1:まさにレガシーコード改善ガイドの冒頭に書かれているような感じで

*2:個人の感想です

travisCIでdockerを使ってsshクライアントのテストをする

node.js用のsshライブラリ(のラッパーライブラリ)を開発していて、こちらの方と全く同じ問題にぶつかりました。

kohkimakimoto.hatenablog.com

こちらの記事では、travisCIのテストが動いている環境でsshdを立ててアクセスしていますが、ローカルのテストで使いまわす時のことを考えて、dockerでsshdを立ち上げてそちらへアクセスするようにしてみました。

travisCIのテスト中にdockerを使う方法についてはこちら

docs.travis-ci.com

このドキュメントでは、dockerhubに公開されたイメージをbuildする前提で書かれていますが、Dockerfileをテスト対象コードのリポジトリに含めてそれを使う方針でやります。

まず、次のようなDockerfileを用意します。ここではcentOSのオフィシャルイメージを使っていますが、その辺はお好みで。

FROM centos:centos7
EXPOSE 22

# install sshd package
RUN yum -y install openssh-server initscripts

# generate hostkey
RUN /usr/sbin/sshd-keygen

# add non-root user and set password
RUN adduser testuser && echo "passw0rd" | passwd --stdin testuser
RUN mkdir -p /home/testuser/.ssh && chown testuser:testuser  /home/testuser/.ssh

CMD ["/usr/sbin/sshd", "-D"]

これをリポジトリ内の、testディレクトリに保存します。

続いて、.travis.ymlに次の記述を追加します。

services:
- docker
before_script:
- docker  build -t sshd ./test
- docker run -p 4567:22 -d sshd

docker buildの行で./testと書いているところは、実際にはDockerfileを配置したディレクトリを指定します。あと最後のdocker runの時に-dをつけてバックグラウンドに回すのをお忘れなく。

Amazonタイムセール&専門書フェア

先月からやってたIT語学専門書フェアが、アマゾンタイムセールの期間に食いこんだおかげで、50%off & 最大7.5%ポイント還元とお得になってますね。 まー、もともと50%オフなんてセールなんで、7.5%還元されてもおまけみたいなもんですが。

とはいえ、並み居る語学書の山をかきわけて、この一月ほどサンプルを読み漁ってタイムセールに備えてきたので、せっかくだから私がリストアップした本を並べておこうと思います。

まずは、機械学習関連

Pythonで動かして学ぶ! あたらしい機械学習の教科書

Pythonで動かして学ぶ! あたらしい機械学習の教科書

Pythonで学ぶあたらしい統計学の教科書 (AI & TECHNOLOGY)

Pythonで学ぶあたらしい統計学の教科書 (AI & TECHNOLOGY)

機械学習については、ずいぶん前にこの本を買ってたんですが、気付いたら第2版が出てたので、心を入れ変えて機械学習のお勉強をしようかと思っている私(要はど素人)が、このへんなら読めそうと思って選んだ3冊です。大外れだったらごめんなさいorz

アルゴリズム関連では、こちらの2冊を買いました。

アルゴリズムの基礎とデータ構造: 数理とCプログラム

アルゴリズムの基礎とデータ構造: 数理とCプログラム

これまたずいぶん前に買った、こちらの本(kindle版は無し)を2分冊にしたような構成で、これだけ分量も増えてりゃ分かり易いだろうし、最近計算幾何学関連のプログラムを書いてないんで、これでも読んでちょっと復習しようかくらいのノリで買ったものです。

計算幾何学入門―幾何アルゴリズムとその応用

計算幾何学入門―幾何アルゴリズムとその応用

ちなみにこちらのだと本、第一章で計算量理論とリスト、スタック、キュー、ヒープ、二分木、平衡二分探索木(赤黒木とか?)あたりまで扱ってるんですが、情報系の学生さんってこんなペースで授業受けてるんでしょうか・・・ あと、この本の著者が翻訳に参加されている、こちらの本も良さそうですね。網羅的すぎてたぶん読んでて迷子になるだろうと思ってパスしましたが。

アルゴリズムイントロダクション 第3版 総合版:世界標準MIT教科書

アルゴリズムイントロダクション 第3版 総合版:世界標準MIT教科書

アーキテクチャ関連では、定番のパタヘネ本と安藤先生のマイナビの連載をまとめた本がセール対象(ヘネパタ本は今回は入ってないっぽい)のようです。

コンピュータの構成と設計 第5版 上・下電子合本版

コンピュータの構成と設計 第5版 上・下電子合本版

コンピュータ設計の基礎

コンピュータ設計の基礎

高性能コンピュータ技術の基礎

高性能コンピュータ技術の基礎

私はこの辺は一通り読んでるのでスルーして、Amazonさんからお勧めされた、こちらの本を買ってみました。

低レベルプログラミング

低レベルプログラミング

低レベルというタイトルですが、system programming寄りの話のようなのでHPC屋的には物足りなさそうですが、Intelアーキテクチャで解説してる上に日本語訳されているというのも珍しいのでちょっと読んでみようかと思ってます。

モバイルモニタ導入

最近、モバイル環境を強化中なんですが、まずは手軽にできるところからということで、サブディスプレイを導入しました。

この手の用途では定番のGeChic on-Lapシリーズだと13インチモデルは約4万円。

ところが、こちらのcocoparなる会社(?)の製品だと約半額の2万円程度。しかも、HDMI2系統な上にVESAマウント対応の穴があるということで、こっちを買ってみました。

以前のモデルでは、amazonのレビューに「穴は空いてるけどネジが切られていない」とか書かれてましたが、改善されていたようです。*1 とりあえず、こんな感じでM4の長ネジを差し込んで超簡易スタンドのできあがり。

f:id:n_so5:20180710141552j:plain

肝心のディスプレイの性能ですが、とりあえず仕事中にサブモニタとして使ったり、Fire stick TVを挿してPrimeビデオで動画を見る程度なら特に問題は無さそうです。 背面の操作ボタンのところの加工精度が甘いのか、ちょっと振るとボタンが筐体と当たって音がしたり、ボタンによって出っ張り具合が違っていたりと、かなりチープな感じはしますが、そんなことより値段が安い方が良いという方には、お勧めできる製品です。

f:id:n_so5:20180612112557j:plain

あ、あと筐体の塗装がヤワなので、付属のスタンドと一緒に持ち運んでたら、背面にざっくりと傷がつきました・・・orz 多少傷がついたところで、動作に支障は無いので私は気にしませんが、気になる方はケースも付属しているGeChicの方が良いかもしれません。

*1:しかし旧モデルも併売してるっぽいので要注意