Skip to content
2017年2月1日 / masterq

僕の職歴1

なんとなく書きはじめてみます。ところどころごまかしてあるのは、守秘義務らしきものを回避しています。たぶんこのレベルなら大丈夫かな?

某社に入社したのは2001年ぐらいでしょうか。そのころ社内のプロジェクトでx86を組込みシステムに使おうとしていました。で、僕が新人時代に担当したのは

  • BIOS
  • 某Option BIOS
  • bootloader

と起動まわりでした。(その当時僕はもー本当にRuby厨で、C言語まともに書いたことなし、アセンブラもさっぱりな状況でした。よくソフト部門配属になったもんです。)

とりあえずまずはじめに某オープソースプロジェクトのbootloaderをパクって某社要求を満たすような機能をみようみまねで実装しはじめました。で、おそらく皆さんハマると思うreal modeとprotect modeの移行やその逆でのバグに当然悩まされることになりました。何年かまともに動作していたように見えたのですが、潜在バグが上記移行コードに潜んでいて、某Iさんに多大なるご迷惑をかけました。。。すいません。

その後、当該のbootloaderを組込みストレージから起動するためにOption BIOSを書きました。当然full real modeで某ASICのデバドラを書く工数も頭もないので、先輩KさんにC言語で書いてもらったアルゴをごにょごにょっとしてOption BIOS化しました。あの頃の僕の頭の中にはメモリマップドI/Oでデバイスというモノが全く思い描けてませんでした。(今もデバドラをイチから書いたことはないのですが。。。ヘタレです。。。)

bootloaderがそこそこ軌道にのった後は、機種毎抽象化のためのしくみを作った後は特になんもしてないです。機種を担当していただいている方々に毎度毎度多大なるご迷惑をかけている毎日です。

あ、そうそう。bootloaderでもう一つ面白い話題があって、某公開鍵暗号をbootloaderに組み込んだことがありました。某オープンソースプロジェクトからコードをパチってdecryptだけをねじこんだような思い出があります。でも、このイカレた試みはもう実機には搭載されていません。。。ちょっと残念ではあります。

2016年12月24日 / masterq

AtomではじめるVerilogプログラミング

この記事は Atom Advent Calendar 2016 の24日目の記事みたいです。

はじめに

こんばんは。元気ですか?僕は仕事やら論文やらの進捗がわるくて体調が悪化しています。そんなこんなで家族とはなれてスタバでThinkPadと向き合うクリスマスイブ。。。がんばっていきましょう。

えー皆様普段Verilogを読み書きするのにどんなエディタをお使いでしょうか。Vivado。そうですよね。そうなんです。でも前回の記事で解説したように、IceStormを使ってHDL合成する場合、どんなエディタを使えば良いでしょうか。

もちろんEmacsやVimを使うこともできますが、ここは1つ流行のAtomエディタを使ってみましょう。この記事では当該エディタをインストールする環境としてDebian GNU/Linuxを仮定していますが、WindowsでもMac OS Xでも同様に使えるはずだと思います。

環境整備

なにはともあれFPGAボードが必要です。この記事ではiCEstickを使います。Mouserから買えますが、2600円と安いので送料がかかってしまいます。なんかの発注ついでに買いましょう。

ice_1

次はソフトウェア環境を整備しましょう。まずAtomエディタをインストールしましょう。

$ wget -O atom.deb https://atom.io/download/deb
$ sudo dpkg -i atom.deb

その後いくつかAtom内から使われるDebianパッケージをインストールします。

$ sudo apt-get install gtkwave iverilog

iverilogはVerilogのシミュレータで、gtkwaveはシミュレーション後の波形を見るためのツールです。前者はVerilogの構文チェックにも使われます。

さらにAtomを起動して”Ctrl-,”を入力して設定タブを出していくつかパッケージをインストールしましょう。まずはVerilog関連のパッケージであるlanguage-verilogとlinter-verilogをインストールします。

verilog-atom

次にPlatformIOという統合開発環境を使うために、platformio-ide-terminalとplatformio-ideパッケージをインストールしましょう。

platformio-atom

上記のパッケージのインストールに完了すると以下のようにAtomの再起動が要求されます。

platformio-reboot

“Reload now”を選んで、Atomを再起動させましょう。すると以下のようにPlatformIOのWelcomeタブが表示されます。これで環境整備は完了です。

platformio

とりあえずプロジェクトを作ってみる

新しいプロジェクトを作ってみましょう。Welcomeタブから”New Project”ボタンを押下してみます。

platformio-new

プロジェクトの設定ウィンドウが出るので、以下のようにiCEstickボードを選択します。

setting-lattice

次に適当なディレクトリをプロジェクトディレクトリとして”led”というディレクトリを作って選択します。

setting-other

led

これでプロジェクトの設定ができました。”Process”ボタンを押下しましょう。

process

ここでなんやかんやツールチェーンを読み込むのでしばらく待ちましょう。その後以下のようなエラーが表示されてしまうでしょう。

error

これはまだプロジェクトディレクトリに何も設定されていないためです。びっくりせずにとりあえず×ボタンでエラーメッセージウィンドウを消しましょう。

ledプロジェクトのsrcディレクトリにファイルを追加しましょう。1つ目は”led.pcf”ファイルで、以下のようにポートの番号を列挙します。

set_io D1 99
set_io clk 21

次にVerilogでLチカを書きましょう。ledプロジェクトのsrcディレクトリに”led.v”ファイルを追加して、以下のようにコードを書いていみます。

module led #(parameter N = 29)(input clk, output D1);
  reg [N-1:0] cont;
  reg rstn = 0;

  always @(posedge clk)
    rstn <= 1;

  always @(posedge clk)
    if (!rstn)
      cont <= 0;
    else
      cont <= cont + 1;

  assign D1 = cont[N-6];
endmodule

iCEstickをPCのUSBポートに挿した上で、プロジェクトをアップロードしてみましょう。左ペインの右矢印ボタンを押下します。

upload

するとiCEstickボードのD1 LEDがチカチカしたら成功です!

より本格的なプロジェクト

もっとちゃんとしたプロジェクトの例を見てましょう。まずはサンプルプロジェクトをgit cloneしましょう。

$ git clone https://github.com/platformio/platform-lattice_ice40.git

その後、当該プロジェクトのplatform-lattice_ice40/examples/counter/ディクトリをplatformioのプロジェクトとしてオープンします。

platformio_open

open_counter

すると以下のようなcounterプロジェクトが登録されているはずです。

proj_counter

それではやはりiCEstickをPCのUSBポートに挿した上で、プロジェクトをアップロードしてみましょう。

upload_counter

すると以下のようにiCEstickのLEDにカウントアップされるはずです。

mov_counter

さらにターミナルを開いて、platformio run –target sim と入力してみましょう。
terminal

するとなんとシュミレーション結果の波形が表示されるではないですか。ちゃんとLEDがカウントアップされているタイミングが見えますね。

gtkwave

シミュレーションを実行するにはテストベンチファイル(counter/src/counter_tb.v)とgtkwaveの設定ファイル(counter/src/counter_tb.gtkw)を作る必要がありますが、そこさえ作りこんでしまえば後は快適にGUIから操作できそうです。

さいごに

IceStormやiverilog、gtkwaveコマンドを使えば、これのような開発環境はこれまでも使用することはできました。しかしAtomとPlatformIOをIDEとして使うことで、統合開発環境として使うことができ、ぐっと使いやすいと感じるのではないでしょうか。

2016年12月1日 / masterq

とあるHaskellアプリでプレゼンする方法

この記事はHaskell Advent Calendar 2016の一日目の記事みたいです。

こんばんは。12月ですね。週末に車で旅行に行くことになっているので雪がふらないとうれしいです。なぜならウチの車、雪がつもったときの装備が貧弱だからです!

ところで、近年は草の根の勉強会がたくさん開催されています。そんな勉強会で発表される機会のある方も多いと思うんです。問題はどんなプレゼンツール使うか悩むことではないでしょうか?また、プレゼン資料を作るのにやけに時間を食ったりしないでしょうか?今日はそんなときのために便利かもしれないHaskell製のツールCarettahのご紹介です。

あと重要なことを忘れてました。本記事はLinuxユーザ向けです。WindowsやMac OS XではCarettahは使えません。これは、このアプリケーションがWiiリモコンに対応するためにcwiidというライブラリに依存していて、当該ライブラリがLinuxでしか使えないためです。

インストール手順

まずはCarettahが依存しているライブラリ群をインストールしましょう。Debian系のディストリビューションをお使いであれば以下のようにすればインストール完了するはずです。

$ sudo apt-get install libcwiid-dev fonts-noto-cjk haskell-platform libghc-gtk-dev gtk2hs-buildtools

フォントが必要なのはCarettahアプリの中でnotoフォントの使用をハードコーディングして参照しているためです。このアプリはめっさやる気がなく、「使えりゃいいだろ」思想で作られているので、そこらへんはお察っしください。。。もっとも、notoフォントはインストールしなくてもそれっぽく文字が出るらしいです。余力があったらここらへんを設定できるようにしたいところです。

これでcabalも使えるようになったので、さっそくCarettahをインストールしてみましょう。

$ cabal update
$ cabal install carettah
$ which carettah
/home/user/.cabal/bin/carettah
$ carettah

carettah version 0.5.1
Usage: carettah [OPTION...] FILE
  -w                --wiimote                 use wiimote
  -o[FILE]          --output-filename[=FILE]  output PDF_FILE
  -t[TIME(minute)]  --time[=TIME(minute)]     set presentation time with minutes
  -i                --info                    show slide infomation
  -n                --new-slide               create a new slide file and open it

やったねーですぞ。

基本的な使い方

まず最初にプレゼンスライドの雛形を作ってみましょう。どこか適当なディレクトリで”-n”オプション付きでCarettahを起動してみます。

$ mkdir new_slide
$ cd new_slide
$ carettah -n new_slide.md

すると、以下のようなウィンドウが開かないでしょうか。

new_slide

このウィンドウはまさに雛形です。「Presentation Title」と「Your Name」を書き換えれば、スライドの表紙ができそうです。

起動したcarettahプロセスはそのままにしておいて、別のコンソールを開いて”new_slide.md”ファイルの中身をちょっと見てみましょう。

$ vi new_slide.md
# Presentation Title
![background](debian.png)

Your Name
--snip--

すると、この”new_slide.md”ファイルを以下のように変えれば、スライドの表紙が変わるはず。。。ですよね。

$ vi new_slide.md
# Carettahでプレゼンしよう
![background](debian.png)

名無 権兵衛
--snip--

さっそくCarettahのウィンドウに戻って確認しましょう。Carettahのウィンドウで”r”キーを押下するとその時点での”new_slide.md”ファイルの内容が表示されているスライドに反映されます。

new_slide

やりました! これで堂々と名無 権兵衛としてプレゼンできそうです。

ところで、表紙だけではプレゼンできません。なにか中身は書けないのでしょうか?もちろんこの雛形には次のページがあります。Carettahウィンドウ上で”j”キーを押下してみましょう。

new_slide

次のページに進んで箇条書きが表示されました。このページも”new_slide.md”ファイルで記述されていて、それは以下のような形式です。

$ vi new_slide.md
--snip--
# Slide Title
* item1
* item2
* item3

![inline](turtle.png)

Haskellアプリでプレゼンするなら当然ソースコードもはりつけたくなるでしょう。”new_slide.md”ファイルの最後に以下のように新しいページを追加してみましょう。

$ vi new_slide.md
--snip--
# ソースコードの例

```haskell
qsort []     = []
qsort (p:xs) = qsort lt ++ [p] ++ qsort gteq
                 where
                   lt   = [x | x = p]
```

ファイルを保存したらCarettahウィンドウでまた”r”キーを押下してみましょう。さらに”j”キーを押下して新しいページを表示してみましょう。以下のようにハイライトされたHaskellコードが表示されるはずです。

code

つまるところ、markdownで文書を書くとCarettahはそれっぽくスライドとして表示してくれます。markdownと違うのは “![background](pngファイル名)” でスライドの背景画像を選択でき、”![inline](pngファイル名)” でスライドの該当位置に画像を貼り付けられる点だけです。(本当はまっとうなmarkdownを食えなかったりしますが見なかったことにしてくださ い。。。)

だいたいCarettahがどんなアプリなのかわかりました。一旦休憩しましょう。”q”キーを押下するとCarettahアプリケーションは終了します。もし同じ”new_slide.md”ファイルの内容をプレゼンテーションしたい場合には以下のように”-n”オプションなしでCarettahを起動するだけです。

$ carettah new_slide.md

ここでCarettahウィンドウで使えるキーの機能をまとめておきます。

  • “f”: Carettahウィンドウをフルスクリーンに
  • “F”: Carettahウィンドウを(フルスクリーンではない)通常のウィンドウに
  • “q”: アプリケーションを終了する
  • “j”: 次のページのスライドを表示する
  • “k”: 前のページのスライドを表示する
  • “g”: スライドの先頭ページを表示する
  • “G”: スライドの最後のページを表示する
  • “r”: markdownファイルを読み直してスライドを更新する

Wiiリモコンを使ってみよう

k0000157211

もしWiiiリモコンを持っていたら、Carettahを当該リモコンでリモートコントロールできます。広い会場で大きなパフォーマンスをしながらプレゼンするにはリモコンが必要ですよね。そして一家に一台はWiiリモコンはあるものです。

Wiiリモコンを用意したら以下のように”-w”オプション付きでCarettahを起動してください。

$ carettah -w new_slide.md
Put Wiimote in discoverable mode now (press 1+2)...

言われたまんまなのですが、ここでWiiリモコンの”1″ボタンと”2″ボタンを同時に押下してください。するとコンソールには以下のように表示さえて、先程と同じスライドが表示されるはずです。

found!

この時認識されたWiiリモコンの4つのLEDの内、右端と左端のLEDが点灯し、中央の2つのLEDは消灯しているはずです。これで準備は整いました。

前章で紹介したキー操作とほとんど同じことがWiiリモコンからできます。

  • Aボタン: 次のページのスライドを表示する
  • Bボタン: 前のページのスライドを表示する
  • 十字キー上ボタン: スライドの先頭ページを表示する
  • 十字キー下ボタン: スライドの最後のページを表示する
  • プラスボタン: Carettahウィンドウをフルスクリーンに
  • マイナスボタン: Carettahウィンドウを(フルスクリーンではない)通常のウィンドウに
  • ホームボタン: markdownファイルを読み直してスライドを更新する

プレゼン時間の設定

さあスライドもできたし操作方法もわかりました。さっそくプレゼンの練習をしてみましょう。

ところでプレゼンには時間が決まってますよね。ライトニングトークなら5分。通常の発表だと30分ぐらいでしょうか。学会でしゃべるときなどは60分にも及ぶかもしれません。そんなときペース配分に困ったりしないでしょうか?

そんな状況のためにCarettahにはプレゼンのペース配分をサポートする機能があります。例えば30分の発表をしたいのであれば”-t30″オプション付きでCarettahを起動しましょう。”-t”と”30″の間にスペースを入れないでください。

$ git clone git@github.com:master-q/carettah.git
$ cd carettah/sample
$ carettah -t30 sample.md

いつものようにCarettahが起動します。じーっと待っていると下側に黒い”>”がだんだん右側につらなって表示されないでしょうか。また、スライドのページを進めると下にいる亀が左から右に向かって進むと思います。

module

上図において亀と”>”はそれぞれ以下を表わしています。

  • 亀の位置は、現在表示しているスライドのページ数
  • “>”の先頭位置は、経過時間

そのため”>”に亀が追い抜かれたら、プレゼンを巻きで進める必要があります。理想的には亀と”>”が同じ位置になるようなペースで話をするのが良さそうです。

PDF化

やれやれ。プレゼンは終わりました。プレゼン資料を後日見たい方もいるかもしれないので、slideshareあたりに資料をアップロードしましょう。

しかしCarettahのファイルはmarkdownのテキストファイルです。slideshareにはPDF形式に変換する必要があります。もちろんCarettahにはmarkdownのファイルをPDF化するオプションがあります。

$ carettah -o new_slide.md
$ file output.pdf
output.pdf: PDF document, version 1.5

この”output.pdf”をslideshareにアップロードすれば良さそうですね。

そもそもなんでこんなツール作ったの?

むかーしむかーし2011年。スタートHaskellというイベントが当時ニフティにいた小川さんの主動の元に開かれたことがありました。その最初の会にはなんと100人を超える人が集りました! 僕はそこでLTすることになっていました。僕は「あまりHaskellに向いていないアプリ例があると聴衆の興味を引けるんじゃないか。たとえばGUIでなにか、、、そうだ! そもそもプレゼンツールをHaskellで作ってそのプレゼンツールでLTすれば面白いんじゃないか」と考えて1日で基本設計をして4日で詳細設計をでっちあげたのでした。なのでCarettahのコードはそれはそれはひどいものだと思います。

それ以降、僕が講演する際のスライドは全てこのCarettahを使って作って、プレゼンしています。それらのスライドはここから見ることができ、またそのmarkdownファイルはここから入手できます。

最後にどうしても触れたいことなのですが、Carettahの使い勝手はRabbitというRuby製のプレゼンツールから強く影響を受けています。Carettahを作る前はこのRabbitを使って作っていました。今のCarettahはRabbitの持っている多くの機能(テーマなど)を持っていません。それには(実装がめんどうだなどの)理由がたくさんありますが、一番の理由は僕が以下のような手順でプレゼン資料を作るからです。

  1. プレゼンで話す内容を箇条書きにする => これがスライドのページタイトルになる
  2. 1つ1つのスライドのページで話したいことを箇条書きにする => これがページの箇条書きになる
  3. 必要なら図をLibreOfficeDiaで描いてMakefileでpngにする
  4. 最後にプレゼンの雰囲気を作るためにFlickrから画像をひろってきてスライドの背景に差し込む

このようなスライドの作成方法をCarettahは上手くサポートしてくれます。その意味ではRabbitの1ユーザであった僕の使い勝手だけに特化させたプレゼンツールがCarettahであるとも言えます。僕のプレゼン形式のベースを作ってくださったRabbitの作者である須藤 功平さんに感謝いたします。

2016年11月20日 / masterq

第1回FPGAスタートアップセミナーで「完全オープンソースHDL合成とForthマシン実装」というLTをした話

第1回FPGAスタートアップセミナーで、FPGAもVerilogもまったくわからないのにLTしてしゃべってきました。なんでソフト屋がFPGAネタでLTしたのでしょう?そこには熱い思いがあるからです!

ところが残念なことに準備が間に合わなくてスライドを作らずにWebページと動画見るだけでLTしてきちゃいました。これだとセミナーに参加していなかった方にはまったく伝わらないので、どんな話をしたのか書こうと思います。

まずは以下の動画を見てください。

謎技術!しょぼいlatticeのFPGAであるiCE40という石の上でForth言語マシンが動作してLinuxからシリアルで繋いだ上でForth言語のREPLが動いてプログラミングできちゃってます。しかもソフトウェアによるインタープリタじゃない証拠に、動画の最後には、シリアルコンソールから打ち込んだスクリプトがメガヘルツオーダーの綺麗な矩形波を描けることを示しています。このForthマシンについてより詳しい情報は http://www.excamera.com/sphinx/article-j1a-swapforth.html にまとまっています。ちなみにこのForthマシンを動かせるボードはなんと22ドルで入手できます。

このForthマシン自体も素晴しいのですが、本プレゼンテーションでスポットをあてたいのはこのロジックを合成したHDL合成ツールです。その名はIceStorm。なんと完全にオープンソースのHDL合成ツールなんです。このツールを使うとVerilogによる回路設計をiCE40に実際に書き込んで動作させるところまでを全てオープンソースのツールを使って実現できるんです。

さらに、このIceStormはZ3というソルバを使うことで、Verilogのコードに対してFormal Verificationをすることもできるらしいです。moduleの同値性を静的検査したり、Verilogコード中の表明や仮定を静的検査したりできるらしいです。これ一人で作ったとは。。。

このIceStormのまわりには既にエコシステムが広がりつつあります。いくつか例を挙げてみます。

まず、IceStormの作者がiCE40の上で動作するRISC-V CPUの実装であるPicoRV32を作っています。こんなしょぼいFPGAの上で32bit MCUを作れちゃうものなんですね。。。でもVerilog実装はデカいmoduleがいくつかあるだけで、エスパーじゃないと読めなそうです。。。このPicoRV32はiCE40HX8Kが載ったボードなら動くと思います。43ドルだそうです。

また、lattice以外にMaker達がiCE40を搭載したボードをリリースしています。中でも以下の動画で紹介しているGo Boardは無茶苦茶多機能です。VGAポートまでついてて、PONGゲームを遊べちゃいます。

さらに、多数のMCUボードの開発環境として有名なPlatformIOIceStormを使ったiCE40をプラットフォームとしてサポートしています。えっと。君ほんとうはC言語を使った組み込み開発環境だったはずなのに、なんでVerilog開発環境になっちゃってるの。。。

さらにさらに、icestudioというツールを使うと下図のようにGUIを使って回路設計をしてIceStormを使って合成できます。通常の回路プリミティブの他にVerilogのmoduleを直に書けるボックスも使えます。例えばこのファイルをicestudioで開いて、iCEstickボードに書き込むとLEDがくるくる回転すると思います。

gui

ところで、なぜ無料でメーカ製のHDL合成器が使えるにもかかわらず、私はIceStormというオープンソースのHDL合成器をおすすめしちゃってるのでしょうか?

今までオープンハードという名の元にいくつものHDLで記述されたIPが提案されてきました。でも実際それらをHDL合成するのは不自由なメーカ製のツール群でした。それらのバージョンによる不具合に悩まされた人も多いかと思います。想像してみてください。もしHDL合成器がオープンソースで開発されていて、当該合成器に不足した機能や不具合があったら、(自分の力さえあれば)その開発へ参加できるとしたら。もうメーカ製ツールの言いなりにならなくて済むかもしれません。(逆に言いわけができなくなるかもしれませんが…) そんな夢がIceStormで実現しつつあるのです。

20世紀のC言語コンパイラを思い出してみてください。当時はメーカ製C言語コンパイラは高価でした。また互換性に問題があることもありました。そこに降臨したのはGCCでした。GCCは誰でも自由に使うことができ、十分な移植性を獲得しました。それでも当時、GCCに対する組み込みベンダーの視線は今よりもっと冷やかなものでした。「GCCで製品開発するなんてバカげてる」そんな意見をたくさん耳にしました。しかしEGCSなど多くの人々の努力によって次第にゲームのルールは書き換えられていきます。そして2016年の今、多くの人が最初に使うC言語コンパイラはGCCになりました。デファクトスタンダードになったのです。ルールはひっくりかえりました。そしてGCCの上ではLinuxをはじめとする多くのオープンソース製品が花をひらき、安価なクラウドサービスやArduinoのようなアマチュアのための開発環境など多くの文化が産まれました。

今日、大規模なHDL開発のためにはメーカ製のツールが必須です。それでもいつの日か、HDLの世界にも自由なオープンソースの空気が流れてくることを信じて、IceStormを少しだけ使ってみませんか?

2016年11月1日 / masterq

替え歌: セマンティックあげるよ

すんごい昔の日記からほりおこしました。当時はHaskellに解を求めていたようです。もっと愛をこめたいです。。。

おいでC言語好きさC++君の素直さ隠さないで
意味付けしたくて型付けしたくて誰もみんなウズウズしてる
職業プログラマのフリしてあきらめちゃ
設計の謎など解けないよ
もっとワイルドにもっとたくましく生きてごらん

セマンティックあげるよセマンティックあげるよ
ホントの意図見せてくれたら
セマンティックあげるよセマンティックあげるよ
トキメクバイナリに
キラキラ光った
Foreign.Storableをあげるよ

2016年10月6日 / masterq

あげます&なんかください。その1

こんにちは。秋もふかまる中いかがおすごしでしょうか。え。ぼくですか。家がちらかってます。すごいことになってます。もう色々なデバイスでお風呂に入れるんじゃないかとさえ思います。

そこで、ぼくがいらなくなったデバイスや書籍を無料でおゆずりするバーゲンを開催しようと思います。

おゆずり可能な物件

P8X32A Propeller QuickStart (Rev.B) 売り切れ

IMG_20161006_065745

https://www.parallax.com/product/40000

Propellerという組み込み向けマルチコアアーキティクチャのMCUが載った試作ボードです。こんな小さいチップに8コア(Cogと呼びます)のってます。Cogは高速なローカルメモリを持っていて、その他にグローバルメモリも持っています。通常はアプリケーションをSPINという言語で書きグローバルメモリ上でインタープリタ実行するのですが並行処理させたい部分はインラインアセンブラで書いて局所的にCogの上で実行させます。現在Propeller2が開発中のはずですが、それが出荷されるまでは面白いボードだと思います。

ちなみに一度も使ってないので、動くかはわかりません。

NUCLEO-F303RE

IMG_20161006_065715

https://developer.mbed.org/platforms/ST-Nucleo-F303RE/

どこにでもあるふつーのmbedが動くボードです。一度も動かしてないので動くかわかりません。

なんかの本1 売り切れ

IMG_20161006_065649

なんかの本です。

なんかの本2

IMG_20161006_065636

なんかの本です。

なんかの本3

IMG_20161006_065619

なんかの本です。

なんかの本4

IMG_20161006_065704

なんかの本です。

おゆずりする条件

  • 東京/横浜近郊の喫茶店などでお会いして物件を手渡しで受け取れる方
  • ぼくと1時間程度世間話ができる方
  • (できれば) なにか面白いモノと交換していただける方

連絡先

以下いずれかにご連絡ください:

  • Email: kiwamu@debian.or.jp
  • Twitter: https://twitter.com/masterq_mogumog/
  • Facebook: https://www.facebook.com/kiwamu
2015年12月18日 / masterq

AWSに36コア環境作ってR言語プログラミング

この記事はR Advent Calendar 2015, HashiCorp Advent Calendar 2015, AWS Advent Calendar 2015の19日目です。

ある日のこと

  • ボス: 「オレの書いたR言語スクリプトの実行に時間がかかってしょうがないんだ…」
  • 僕: 「それならAWSできっと解決できますよ!」

僕の考えた最強のR言語プログラミング環境

bigpicture

そこで上図のような環境を作ってみました。R言語プログラミングでのユースケースはスクリプトのバッチ実行とEmacs上でのインタラクティブなプログラミングが挙げられるでしょう。そこでこれらのユースケースをローカルPCで実行するRプログラムではなく、AWS上でリモートに実行できるようにしました。今日ではローカルPCはノートパソコンのような非力な計算資源しか使えないことが多いですが、AWS上であれば最大36コア(c4.8xlarge)までスケールアップすることができます。この環境を”Kick-R”と呼ぶことにします。Kick-RのソースコードはGitHubで公開しています。

Kick-Rのやることは単純です。VMインスタンスの種であるUbuntuのAMIをPackerを使って開いて、R言語関連の環境をインストールし、新たなAMIとしてAWS上に保存します。このR言語環境が追加されたUbuntuAMIをここでは”R AMI”と呼ぶことにします。さらにR AMIをTerraformを使って起動し、ssh接続可能にします。これでどこからでもR環境入りのVMインスタンスにsshログインできるようになりました。このAWS上で起動したR言語実行環境を含むVMインスタンスを”Rインスタンス”と呼ぶことにします。このR環境が不要になったら、R AMIとRインスタンスをいつでもAWS上から削除することができます。使わない時はRインスタンスを削除することでAWSの課金を最小限にすることができます。R AMIは残したままでも課金されることはありません。

一度AWS上にRインスタンスが立ち上がってしまえば、sshを使ってローカルPCからRインスタンスにバッチジョブを投げることもできますし、EmacsのESSモードを使ってEmacsを使ったインタラクティブプログラミングをもAWS上でssh経由のリモート実行することができます。その使い方は後の章で説明します。

ベンチマーク

よくある以下のようなRプログラムを考えましょう。

library(foreach)
library(doParallel)
library(randomForest)
library(kernlab)

data(spam)
cores <- detectCores()
cl <- makeCluster(cores)
registerDoParallel(cl)

system.time(fit.rf <- foreach(ntree = rep(40, 36), .combine = combine,
.export = “spam”, .packages = “randomForest”) %dopar% {
randomForest(type ~ ., data = spam, ntree = ntree)
})

stopCluster(cl)

このスクリプトを:

  • ThinkPad X220で実行すると25.0秒かかるところ…
  • AWS上で実行すると10.5秒で済みます

より実践的なRプログラム(すいません、そのソースコードは社外秘です…)を実行させると以下のようなベンチマーク結果になります。

  • ThinkPad X220上: 555秒
  • AWS上: 84秒

利用シーンと使い方

セットアップ

この作業はKick-Rを使う前に一度だけ実行すれば済みます。まずKick-Rのために必要なパッケージをインストールしてください。

$ sudo apt-get install git make bundler unzip

次にPackerとTerraformをインストールしましょう。

$ cd /usr/local/bin
$ wget https://releases.hashicorp.com/packer/0.8.6/packer_0.8.6_linux_amd64.zip
$ wget https://releases.hashicorp.com/terraform/0.6.7/terraform_0.6.7_linux_amd64.zip
$ sudo unzip -x packer_0.8.6_linux_amd64.zip
$ sudo unzip -x terraform_0.6.7_linux_amd64.zip

AWS鍵を環境変数で指定します。${HOME}/.bashrc などに書いておくと良いでしょう。

$ export AWS_ACCESS_KEY_ID=XXXXXXXXXXXXXXXXXXXX
$ export AWS_SECRET_ACCESS_KEY=YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY

Kick-RのソースコードをGitHubから入手します。

$ git clone https://github.com/centillion-tech/kick-r.git
$ cd kick-r

最後に自分の.emacsファイルでtrampを有効にしておきます。

$ vi ${HOME}/.emacs
(require 'tramp)

これで準備が整いました。以後はこの”kick-r”ディレクトリで作業することにします。

出社

朝会社に出社しました。今日も元気にRプログラミングをはじめましょう。プログラミングの前に重い計算をするためにRインスタンスをAWS上に起動しておきます。チェックアウトした”kick-r”ディレクトリで単にmakeコマンドを実行すればRインスタンスは起動します。ログインに必要なsshの設定はmake ssh-configコマンドで設定します。

$ make
$ make ssh-config > ~/.ssh/config
$ ssh kick-r
ubuntu@ip-10-189-135-202:~$ R --version | head -1
R version 3.0.2 (2013-09-25) -- "Frisbee Sailing"

ちゃんとRインスタンスはAWS上で起動して、少し古いですがR環境も使えるようですね。

インタラクティブプログラミング

Emacs ESSモードを使ってインタラクティブにRスクリプトをデザインしましょう。まずはEmacs上でRを起動します。

emacs-r-1

次にAWS上のRインスタンスへのsshセッションを開始します。”/ssh:kick-r:”と入力しましょう。

emacs-r-2

はじめてsshセッションを作るときには下図のように聞かれるかもしれませんが、yesと答えれば大丈夫です。人生はyesマンでだいたい問題ありません。

emacs-r-3

これでRのプロンプトがEmacs上で表示されました。Emacs上で起動したRはAWS上のRインスタンスで起動していて、ローカルPCとリモートで接続されています。

emacs-r-4

それではこのRプロンプトからグラフを描画してみましょう。

> x <- 1:10
> y <- 1:10
> plot(x, y)

emacs-r-graph

sshを経由してAWS上でRが実行されているにもかかわらず、plot関数はグラフをローカルのPCに表示することができました。これは ${HOME}/.ssh/config にXを転送するように設定されているためです。

バッチ実行

Rスクリプトが完成したら、Emacsで実行するよりRコマンドを直接たたいてバッチ実行した方が便利かもしれません。以下のようにCSVの内容をグラフ描画するようなプログラムをAWS上のRインスタンスで実行してみましょう。makeコマンドのjobターゲットのR変数にはRスクリプトの在処を絶対パスで指定してください。

$ ls examples/batch_job/
plot.R  plot_tfidf.csv
$ cat examples/batch_job/plot.R
data <- read.csv('plot_tfidf.csv', header=T, sep=",")
pdf("plot_result.pdf")
plot(data)
dev.off()
$ cat examples/batch_job/plot_tfidf.csv
  "a",    "b"
0.688, 0.1930
0.701, 0.7370
0.705, 0.6860
0.732, 0.0174
0.341, 0.1390
$ make job R=`pwd`/examples/batch_job/plot.R
$ ls examples/batch_job/
plot.R  plot_result.pdf  plot_tfidf.csv

plot.Rスクリプトはplot_tfidf.csvファイルを読み込んで、その内容をplot_result.pdfに描画します。このとき、このplot.RスクリプトはAWS上のRインスタンスで実行されいるにもかかわらず、plot_tfidf.csvとplot_result.pdfファイルをRインスタンスへ送受信する手間は不要でした。これはKick-Rが裏でこれらのファイルの送受信を自動的に行なってくれるためです。このおかげでRスクリプトをAWS上でバッチ実行する使い勝手はローカルPCでバッチ実行するのと同様にスムーズです。

退社

今日はがんばりました。もう帰ってもよいでしょう。帰る前に余計な課金を避けるためにRインスタンスを落としてしまいましょう。

$ make distclean

これでR AMIとRインスタンスはきれいさっぱりAWS上から削除されました。寝ている間の課金を防止できて、お財布にやさしい生活がおくれます。

もし、R AMIファイルだけは削除せず残しておきたい場合にはdistcleanのかわりにcleanターゲットを使うこともできます。R AMIを作るのには時間がかかるので、この方が明日の朝にすぐRインスタンスを起動できるでしょう。

$ make clean

蛇足

Japan.R 2015で発表するはずだったスライドもあります。将来的にはスケールアップだけでなくクラスタを使ったスケールアウトも検討したいところですが、そのニーズがまだないために対応していません。