Ruby科学データ処理ツールの開発 NArrayとPwrake

92
Ruby科学データ処理ツールの開発 NArrayPwrake 田中昌宏 筑波大学 計算科学研究センター 2011-7-4 1 東大本郷

Transcript of Ruby科学データ処理ツールの開発 NArrayとPwrake

Page 1: Ruby科学データ処理ツールの開発 NArrayとPwrake

Ruby科学データ処理ツールの開発NArrayとPwrake

田中昌宏

筑波大学計算科学研究センター

2011-7-4 1東大本郷

Page 2: Ruby科学データ処理ツールの開発 NArrayとPwrake

内容

• 多次元数値配列 NArray

– リリース版

–開発版

• プロットツール

• 並列分散ワークフローシステム Pwrake

2011-7-4 2東大本郷

Page 3: Ruby科学データ処理ツールの開発 NArrayとPwrake

注意書き

• これまで考えたことの、まとまりのない話

• HPC的とか、学術的な話ではありません

• Ruby言語、Rubyオブジェクトの内部構造(C言語)に関しての知識が前提

2011-7-4 3東大本郷

Page 4: Ruby科学データ処理ツールの開発 NArrayとPwrake

開発動機

• データ解析のためのツール

• 自分が必要だと思う機能を入れたい

• フリーがいい

2011-7-4 4東大本郷

Page 5: Ruby科学データ処理ツールの開発 NArrayとPwrake

• IDL (Interactive Data Language)

• Yorick

• Python Numeric

• あまり知らないもの

– MATLAB, Octave, Scilab

– R

– PDL

2011-7-4 東大本郷 5

NArrayの手本

Page 6: Ruby科学データ処理ツールの開発 NArrayとPwrake

IDL

• 1970年代からあるらしい• 商用 (Linux版1ライセンス25万円, 年間保守7万円)• 機能

– 便利な多次元配列– 数値計算ライブラリが豊富– 可視化・グラフィックライブラリが豊富– プラットホーム非依存のGUI– 天文データ計算ライブラリが公開

• 言語仕様が古い– フラットネームスペース– 変数スコープ

• ローカルまたはcommon宣言で共有

– あとづけオブジェクト指向

2011-7-4 6東大本郷

Page 7: Ruby科学データ処理ツールの開発 NArrayとPwrake

IDLで作ったツール

2011-7-4 東大本郷 7

Cross-platform GUIの作成が容易

Page 8: Ruby科学データ処理ツールの開発 NArrayとPwrake

Yorick

• フリーソフト

• C言語に似た言語

• 独特の多次元配列操作記法

–ベクトルの外積: x*y(-,)

–行列積: A(,+)*B(+,)

• あまり性能はよくなかった

• あまり使われていない

2011-7-4 8東大本郷

Page 9: Ruby科学データ処理ツールの開発 NArrayとPwrake

NumPy

• Numeric → NumArray → NumPyと変遷

• 最近

–初期にに比べていろいろ改善

–グラフィックライブラリもできた: matplotlib

– コミュニティが増えた

–実際に幅広く使われている

• 天文データ

2011-7-4 9東大本郷

Page 10: Ruby科学データ処理ツールの開発 NArrayとPwrake

• プログラムが書ける – Ruby

• インタラクティブ – irb

• データ配列操作 – NArray

• 数値計算ライブラリ – Lapack, FFTW, GSL

等のwrapper

• グラフ表示機能 – ?

2011-7-4 東大本郷 10

Scientific Ruby に必要なもの

Page 11: Ruby科学データ処理ツールの開発 NArrayとPwrake

• 多次元数値配列

– Numerical N-dimensional Array

• http://narray.rubyforge.org

• http://github.com/masa16/narray

2011-7-4 東大本郷 11

Ruby/NArray

Page 12: Ruby科学データ処理ツールの開発 NArrayとPwrake

• 0.3.0 – 1999

• 0.5.0 – 2000

• 0.5.9p9 – 2010 (リリース版)

–次 0.6.0 ?

• 0.7.1 – 2007 (開発版1)

• 0.9? – 2011 (開発版2)

2011-7-4 東大本郷 12

NArrayバージョン

Page 13: Ruby科学データ処理ツールの開発 NArrayとPwrake

• rank

–次元数

• shape

–配列の「形」

• type

–要素の型

• memory block

–データを格納するメモリーブロック

2011-7-4 東大本郷 13

NArray 構成要素 (基本部分)

Page 14: Ruby科学データ処理ツールの開発 NArrayとPwrake

• Ruby Array :

– VALUE *ptr; →

• NArray

– void *ptr; →

– or

2011-7-4 東大本郷 14

メモリーブロック

struct RVALUE {…

}

double[0] double[1] double[2] double[3] …

int[0] int[1] int[2] int[3] …

value[0] value[1] value[2] value[3] …

Page 15: Ruby科学データ処理ツールの開発 NArrayとPwrake

• 整数

– BYTE (8bit)

– SINT (16bit)

– INT (32bit)

• 浮動小数点数

– SFLOAT (32bit)

– DFLOAT (64bit)

• 複素数

– SCOMPLEX (64bit)

– DCOMPLEX (128bit)

• Rubyオブジェクト

– ROBJECT

2011-7-4 東大本郷 15

NArray(リリース版)のデータ型(ビルトイン)

Page 16: Ruby科学データ処理ツールの開発 NArrayとPwrake

• shape = [4]– 1次元配列

• shape = [4,4]– 2次元配列

• shape = [4,4,4]– 3次元配列

2011-7-4 東大本郷 16

配列の形:shape

a[0,0] a[1,0] a[2,0] a[3,0]

a[0,1] a[1,1] a[2,1] a[3,1]

a[0,2] a[1,2] a[2,2] a[3,2]

a[0,3] a[1,3] a[2,3] a[3,3]

a[0] a[1] a[2] a[3]

a[0,0,0] a[1,0,0] a[2,0,0] a[3,0,0]

a[0,1,0] a[1,1,0] a[2,1,0] a[3,1,0]

a[0,2,0] a[1,2,0] a[2,2,0] a[3,2,0]

a[0,3,0] a[1,3,0] a[2,3,0] a[3,3,0]

Page 17: Ruby科学データ処理ツールの開発 NArrayとPwrake

• a[i,j]

• 左の次元(i)が早く回る

– Fortran-order 、または

– Row-major order

• 多次元配列を1次元でアクセスshape=[m,n]のとき、

a[i,j] == a[i+j*m]

• Rubyの配列:

a[j][i]

2011-7-4 東大本郷 17

多次元データの順序

データが連続する順番

a[0,0] a[1,0] a[2,0] a[3,0]

a[0,1] a[1,1] a[2,1] a[3,1]

a[0,2] a[1,2] a[2,2] a[3,2]

a[0,3] a[1,3] a[2,3] a[3,3]

Page 18: Ruby科学データ処理ツールの開発 NArrayとPwrake

NArray.float(3,2)

=> NArray.float(3,2):

[ [ 0.0, 0.0, 0.0 ],

[ 0.0, 0.0, 0.0 ] ]

NArray.float(3,2).indgen!

=> NArray.float(3,2):

[ [ 0.0, 1.0, 2.0 ],

[ 3.0, 4.0, 5.0 ] ]

NArray[[1,2,3],[4,5,6]]

=> NArray.int(3,2):

[ [ 1, 2, 3 ],

[ 4, 5, 6 ] ]

NArray[1..10]

=> NArray.int(10):

[ 1, 2, 3, 4, 5, 6, 7, 8,

9, 10 ]

2011-7-4 東大本郷 18

NArrayの生成

Page 19: Ruby科学データ処理ツールの開発 NArrayとPwrake

• a[1]

–要素参照

• a[1..2]

–範囲参照

• a[[1,3]]

– インデックス配列参照

2011-7-4 東大本郷 19

配列のスライス

a[0] a[1] a[2] a[3]

a[0] a[1] a[2] a[3]

a[0] a[1] a[2] a[3]

Page 20: Ruby科学データ処理ツールの開発 NArrayとPwrake

部分代入

a = NArray[[0,1],[2,3]]

a[1,true] = [11,22]

=> NArray[[0,11],[2,22]]

a[1,true] = 99

=> NArray[[0,99],[2,99]]

• できれば記号を使いたい

a[1,*] = 99

2011-7-4 20東大本郷

Page 21: Ruby科学データ処理ツールの開発 NArrayとPwrake

• 演算は要素ごと (element-wise)

• 演算

– 四則演算• +, -, *, /, %, **

– 統計・ソート• min, max, sum, mean, stddev, rms, rmsdev, median, sort

– 数学関数演算• NMath module

2011-7-4 東大本郷 21

NArrayの演算

a * b = a[0]*b[0] a[1]*b[1] a[2]*b[2] a[3]*b[3]

Page 22: Ruby科学データ処理ツールの開発 NArrayとPwrake

coerce

• a + b

• レシーバ a が b の型を知らない

• coerce で型変換してから演算

a,b = b.coerce(a,b)

• a が Numeric → NArrayScalar

• NArray同士では、coerce は使わない–巨大な配列の場合、型変換のコストが大きい

–行列が絡むと、さらにややこしい

2011-7-4 22東大本郷

Page 23: Ruby科学データ処理ツールの開発 NArrayとPwrake

upcast

• NArrayの演算は、(基本的に)同じ型同士

• 型が異なる場合:UPCASTテーブルに基づいて型変換する

• DFLOAT + SFLOAT の場合、後者を DFLOAT に変換してから演算

• a = NArray.sfloat(n) のとき、

• 0.5 * a が返す型は?

–配列の型を優先:単精度で返す

2011-7-4 23東大本郷

Page 24: Ruby科学データ処理ツールの開発 NArrayとPwrake

サイズ1の繰り返しルール

• 2つの配列が絡む場合

–演算やスライス代入

• ある次元のサイズが、n対1の場合、

• サイズ1の次元で、データがn回繰り返す

• 例: a = [1,2,3,4]

– a[0..2] = 1 → a[0..2] = [1,1,1]

– a * 2 → a * [2,2,2,2]

2011-7-4 24東大本郷

Page 25: Ruby科学データ処理ツールの開発 NArrayとPwrake

繰り返しルールの応用:クロス演算

• x = [[1,2,3]] (shape=[n,1])

• y = [[4],[5]] (shape=[1,m])

• x * y = [[4,8,12],[5,10,15]]

• 例: 原点からの距離のグリッドデータを作る場合• NMath.sqrt( x**2 + y**2 )

↑ ここの’+’で2次元に展開

x[0,0] x[1,0] x[2,0]

y[0,0] x[0,0]*y[0,0] x[1,0]*y[0,0] x[2,0]*y[0,0]

y[0,1] x[0,0]*y[0,1] x[1,0]*y[0,1] x[2,0]*y[0,1]

2011-7-4 25東大本郷

Page 26: Ruby科学データ処理ツールの開発 NArrayとPwrake

条件演算

• 0 or 1 を含むバイト型NArrayを返すa.eq(b) # ==が使えない…

ne, gt(>), lt(<), ge(>=), le(<=)

• whereメソッド: 非ゼロのインデックスを返す

(a.gt b).where

– 多次元の場合は、1次元のインデックス

• ゼロ未満の部分に0を代入– a[(a.lt 0).where] = 0

– a[a.lt 0] = 0

2011-7-4 26東大本郷

Page 27: Ruby科学データ処理ツールの開発 NArrayとPwrake

マンデルブロ(普通の計算方法)

def mandel_pix(cr, ci)

limit = 30

c = Complex(cr,ci)

z = Complex(0.0,0.0)

for i in 1..limit

z = z**2 + c # 漸化式return i if z.abs>2 # 条件式

end

return limit

end

-2.0-1.0i -1.9-1.0i … 1.0-1.0i

-2.0-0.9i -1.9-0.9i 1.0-0.9i

… …

-2.0+1.0i -1.9+1.0i … 1.0+1.0i

実部→

虚部↓

複素数配列

1. 要素ごとに漸化式ループ

2. 配列についてループ

2011-7-4 27東大本郷

Page 28: Ruby科学データ処理ツールの開発 NArrayとPwrake

マンデルブロ(NArrayでの計算方法)def mandel_narray(c)

limit = 30

w,h = c.shape

z = NArray.dcomplex(w,h)

a = NArray.int(w,h)

idx = NArray.int(w,h).indgen!

for i in 1..limit

z = z**2 + c # 漸化式 (配列ループ)idx_t,idx_f = (z.abs>2).where2 # 条件式a[idx[idx_t]] = i

idx = idx[idx_f]

z = z[idx_f]

c = c[idx_f]

end

a[idx] = limit

return a

end

i=6

i=12

i=30

i=18NArrayの使い方のコツ:1. ループの順序を入れ替える2. 条件分岐にwhere を使う

for ループの途中経過:(白い部分が計算途中)

2011-7-4 28東大本郷

Page 29: Ruby科学データ処理ツールの開発 NArrayとPwrake

• Float Array with 106 elements

• Ruby 1.9.2 :

(0...n).map{|i| a[i]*b[i]}

– elapsed time : 180 ms

• NArray with Ruby 1.9.2 :

a*b

– elapsed time : 6.4 ms

• NArray is ~ 28 times faster

2011-7-4 東大本郷 29

NArray speed

Page 30: Ruby科学データ処理ツールの開発 NArrayとPwrake

0

10

20

30

40

50

60

0.E+00 2.E+05 4.E+05 6.E+05 8.E+05 1.E+06

Spe

ed

up

fact

or

data size

Speedup by NArray

2011-7-4 東大本郷 30

マンデルブロの計算速度

Page 31: Ruby科学データ処理ツールの開発 NArrayとPwrake

Benchmark (2005年)

•CPU: Pentium 4 Prescott, 2.8GHz•OS: Linux 2.6.14-1.1644_FC4

elapsed time (sec)

2011-7-4 東大本郷 31

array add

array mul

matrix dot

matrix solve

10^6 elm * 100 times

500x500 elm * 3 tiems

Ruby 1.8.2

NArray 0.5.8

1.56 1.52 2.10 6.54

Python 2.4.1

numarray1.5.0

5.08 5.06 2.10 3.05

Python 2.4.1

Numeric 23.7-2

5.58 5.61 5.34 6.15

Octave 2.1.72 (i686-pc-linux-gnu)

1.43 1.39 2.12 2.96

Page 32: Ruby科学データ処理ツールの開発 NArrayとPwrake

バイナリデータとして

• NArrayのメモリーデータを Stringと相互変換

• NArray → String

– narray.to_s

• String → NArray

– NArray.to_na( string, NArray::DFLOAT, nx, ny )

• バイトオーダ変換メソッド

– hton, ntoh, vtoh, htov

2011-7-4 32東大本郷

Page 33: Ruby科学データ処理ツールの開発 NArrayとPwrake

NArray開発状況

• リリース版:

– 0.5.9.9 最新版

• 開発版

– 0.7.0.1 非互換の変更(2007年)

– 0.9 ? 0.7 からさらに仕様変更

2011-7-4 33東大本郷

Page 34: Ruby科学データ処理ツールの開発 NArrayとPwrake

次版の開発動機

• すでにNumPyより大きく出遅れている

• 配列の基本機能として、NumPyで可能なことはすべて可能にしたい

• +αの機能

• 周辺機能(行列演算、FFT等)は追々。。。

2011-7-4 34東大本郷

Page 35: Ruby科学データ処理ツールの開発 NArrayとPwrake

開発版の変更点

• 次元順序の変更

• 64bit対応

• データ型が追加可能

• 配列スライスのとき、コピーを作らない

• NMatrix, NVectorは廃止

–行列積の記法以外にメリットがない

– クラス変換とかcoerceで複雑になる

– dot メソッドで代用

2011-7-4 35東大本郷

Page 36: Ruby科学データ処理ツールの開発 NArrayとPwrake

開発版の新機能

• inplace演算

• ビット配列

• 構造体データ型

• mmap

2011-7-4 36東大本郷

Page 37: Ruby科学データ処理ツールの開発 NArrayとPwrake

• リリース版:

– a[i,j]

– 左の次元(i)がはやく回る

– 画像や科学データはこちら

• Rubyのネスト配列と逆:

– a[j][i]

• 開発版: Rubyと同じ順序に変更

– a[j,i]

– 説明が省けて混乱しにくい

– フラグによって、オブジェクトごとに次元順序が変えられる

2011-7-4 東大本郷 37

次元の順序データが連続する順番

a[0,0] a[1,0] a[2,0] a[3,0]

a[0,1] a[1,1] a[2,1] a[3,1]

a[0,2] a[1,2] a[2,2] a[3,2]

a[0,3] a[1,3] a[2,3] a[3,3]

Page 38: Ruby科学データ処理ツールの開発 NArrayとPwrake

64bit対応

• リリース版

–データ位置のデータ型: int32_t

–配列サイズ: 最大2GB

• 開発版

– NArrayに Int64 型を追加

–データ位置のデータ型: sizt_t

– where が返すデータ型:

• 配列サイズによって、Int32 または Int64

2011-7-4 38東大本郷

Page 39: Ruby科学データ処理ツールの開発 NArrayとPwrake

データ型

• リリース版– NArrayクラスの内部属性

– NArray#typecodeで型コードを返す

– NArray::DFLOAT :型コード定数

– データ型は固定で、追加不可能

• 開発版– NArrayクラスのサブクラス

– クラス名: NArray::DFloat など• 前は Num::DFloatだった。まだ悩み中…

– データ型の追加が可能

2011-7-4 39東大本郷

Page 40: Ruby科学データ処理ツールの開発 NArrayとPwrake

データ型一覧

• 既存の型

– NArray::Int8

– NArray::Int16

– NArray::Int32

– NArray::DFloat

– NArray::SFloat

– NArray::DComplex

– NArray::SComplex

– NArray::RObject

• 新規の型

– NArray::Int64

– NArray::UInt8

– NArray::UInt16

– NArray::UInt32

– NArray::UInt64

– NArray::Bit

– NArray::NStruct

2011-7-4 40東大本郷

Page 41: Ruby科学データ処理ツールの開発 NArrayとPwrake

型変換

• 演算によって、どの型に変換するか決めたい

– float * int => float * float

– float ** int => float ** int

• coerce は、演算ごとに設定できない

• NArrayでは、UPCASTを導入

2011-7-4 41東大本郷

Page 42: Ruby科学データ処理ツールの開発 NArrayとPwrake

UPCAST

• 例a = NArray::Int32[1,2,3]

b = NArray::DFloat[4,5,6]

c = a + b

• 演算の擬似コードtp = NArray::UPCAST[a.class][b.class]

• tpは DFloat

c = tp.add(a,b)

• a が DFloatにキャストされる

• ハッシュ UPCAST は、追加・変更可能

2011-7-4 42東大本郷

2次元ハッシュ

Page 43: Ruby科学データ処理ツールの開発 NArrayとPwrake

NumPy配列スライス

• 「元の配列の一部分を指す配列」が作られる

• データがコピーされない

• スライス配列の値を変えると、元の配列も変わる

a =

b = a[1::2,1::2] =

b [0,0] = 99a[1,1] #=> 99

2011-7-4 43東大本郷

Page 44: Ruby科学データ処理ツールの開発 NArrayとPwrake

NumPyオブジェクト

typedef struct PyArrayObject {

char *data;

int nd;

npy_intp *dimensions; /* shapeと同じ */

npy_intp *strides;

char *data

strides[1]

strides[0]

2011-7-4 44東大本郷

Page 45: Ruby科学データ処理ツールの開発 NArrayとPwrake

リリース版NArray配列スライス

• 値をコピーした新しい配列が作られる

• スライス配列を書き換えても、元の配列の内容は変更されない

a =

b = a[1..2,1..2] = b [0,0] = 99a[1,1] #=> 0

2011-7-4 45東大本郷

Page 46: Ruby科学データ処理ツールの開発 NArrayとPwrake

配列スライス

• NumPy式

–スライス配列を書き換える

–スライスだけなら高速

–オブジェクトの構造が複雑

• NArray式

–オブジェクトの構造が簡単

2011-7-4 46東大本郷

Page 47: Ruby科学データ処理ツールの開発 NArrayとPwrake

• NumPyの参照方式に変更

• NArrayでは、インデックスも指定可能

• a[1..2]

–範囲参照

• a[[1,3]]

– インデックス配列参照

2011-7-4 東大本郷 47

開発版NArrayの配列スライス

a[0] a[1] a[2] a[3]

a[0] a[1] a[2] a[3]

Page 48: Ruby科学データ処理ツールの開発 NArrayとPwrake

開発版NArray構造体(抜粋)

{

unsigned char ndim;

size_t size;

size_t *shape;

VALUE data;

size_t offset;

stridx_t *stridx;

VALUE data

stride[1]

stride[0]

offset

2011-7-4 48東大本郷

Page 49: Ruby科学データ処理ツールの開発 NArrayとPwrake

stridx

• 最下位ビットが1:

– 1ビット下位にシフトした数を stride とみなす

stride = stridx>>1 = 4

• 最下位ビットが0:

–ポインタとみなし、index配列を指す

*stridx = index = [1,2,4,7]

2011-7-4 49東大本郷

Page 50: Ruby科学データ処理ツールの開発 NArrayとPwrake

stridx実装

• インデックスを持つと、実装が複雑に

• ループも遅い

• 本当に必要か?

• まだ悩み中

2011-7-4 50東大本郷

Page 51: Ruby科学データ処理ツールの開発 NArrayとPwrake

inplace

• 元の配列に結果を上書き

– メモリーを確保しなくて済むので、高速

• リリース版– a.mul!(b).add!(c)

–演算子が使えない

– メソッドを作る必要がある

2011-7-4 51東大本郷

Page 52: Ruby科学データ処理ツールの開発 NArrayとPwrake

inplace

• 開発版– inplaceフラグが付いたオブジェクトに上書き

– Numpyにはない機能

• フラグの伝播– a.inplace * b + c # すべて a に上書き

• 左側でも上書き– a + b * c.inplace # すべて c に上書き

• 両側ともinplaceのときは、左側に上書き– a.inplace * b + c.inplace * d

2011-7-4 52東大本郷

Page 53: Ruby科学データ処理ツールの開発 NArrayとPwrake

inplace (contd.)

• NMathでも上書き– NMath.sin(a.inplace)

• スライス配列でも上書き– a[1..2,1..2].inplace + 1

=> a[1..2,1..2] += 1 と同じだが、配列は作らない

2011-7-4 53東大本郷

Page 54: Ruby科学データ処理ツールの開発 NArrayとPwrake

ビット配列

• 0 or 1 の配列

• 1要素が 1ビット

–バイト配列と比べて、サイズが1/8になる

• 条件演算の結果として使う

– and / or が高速(のはず)

• 多次元スライスも可能

2011-7-4 54東大本郷

Page 55: Ruby科学データ処理ツールの開発 NArrayとPwrake

構造体データ型

Foo = NArray::NStruct.new() do

int8 :byte

float64 :float, [2,2]

dcomplex :compl

end

z = Foo.new([2,3])

z.fill([2,[[1,2],[3,4]],0.123])

z.field(:float)

z[1,1..2].field(:float)

2011-7-4 55東大本郷

Page 56: Ruby科学データ処理ツールの開発 NArrayとPwrake

mmap

• メモリーをファイルにマップ– メモリーに全データをロードできない場合に需要あり

• 環境の違いを吸収– UNIX系→ mmap

– Windows → MapViewOfFile

• 前は ByteDataクラスというメモリークラスを作って、そのサブクラスにした

• 今は、NArrayでメモリー管理

2011-7-4 56東大本郷

Page 57: Ruby科学データ処理ツールの開発 NArrayとPwrake

メモリー参照の問題

• 他のオブジェクトのメモリーを参照–ポインタが変わらなければ問題はなさそう

• 今はそうしている

–ポインタが変わる場合• 配列のサイズを可変にしたい

• データを push したいとか需要あり

• realloc

• 他のオブジェクトでポインタを使っている間に、ポインタが変わらないような、ロックの仕組みが必要

• Rubyとしての枠組みはないですよね

2011-7-4 57東大本郷

Page 58: Ruby科学データ処理ツールの開発 NArrayとPwrake

NArrayへの協力

• Prince lab https://github.com/princelab/narray/wiki

–チュートリアル英語版

2011-7-4 58東大本郷

Page 59: Ruby科学データ処理ツールの開発 NArrayとPwrake

プロットツールについて余談

2011-7-4 59東大本郷

Page 60: Ruby科学データ処理ツールの開発 NArrayとPwrake

matplotlib

• Pythonプロットツール

• MATLABのコマンド体系がベース

• これが出てから、Numpyが広まったような気がする

• Rubyにもプロットツールがほしい

2011-7-4 60東大本郷

Page 61: Ruby科学データ処理ツールの開発 NArrayとPwrake

既存のRubyプロットツール

• Ruby/PGPLOT– PGPLOTライブラリのラッパー

• Ruby/DCL– DCLのラッパー

• どちらもFORTRANライブラリで、古い

• GNUPLOT みたいに

plot x,y

と書くだけで、プロットしたい

2011-7-4 61東大本郷

Page 62: Ruby科学データ処理ツールの開発 NArrayとPwrake

作りかけのプロットライブラリ

• グラフィックバックエンド

– X11 とWin32 と Postscript に対応

• 2次元プロットはできた

• 「プロット機能」と「装飾機能」を分離したい

– CSS みたいな

• 今だと Cairo とWPF に対応しなきゃ?

• 自分でできる気がしない

2011-7-4 62東大本郷

Page 63: Ruby科学データ処理ツールの開発 NArrayとPwrake

• プログラムが書ける – Ruby

• インタラクティブ – irb

• データ配列操作 – NArray

• 数値計算ライブラリ – FFTW, Lapack, GSL

• グラフ表示機能 – ?

2011-7-4 東大本郷 63

Scientific Ruby

Page 64: Ruby科学データ処理ツールの開発 NArrayとPwrake

並列分散ワークフローシステムPwrake(プレイク)

http://github.com/masa16/pwrake

2011-7-4 64東大本郷

Page 65: Ruby科学データ処理ツールの開発 NArrayとPwrake

Pwrake開発動機

• Gfarm開発者の建部チームに所属

• 研究テーマ

– Gfarmを使った天文アプリケーションの性能調査

2011-7-4 東大本郷 65

Page 66: Ruby科学データ処理ツールの開発 NArrayとPwrake

Gfarm 広域分散ファイルシステム

• 各ノードのストレージを統合

• 統一したディレクトリ空間

• 広域でファイルを共有

• http://datafarm.apgrid.org/

LocalStorageLocalStorage

LocalStorageLocalStorage

LocalStorageLocalStorage

Internet Gfarm File System

/

/dir1

file1file1 file2file2

/dir2

file3file3 file4file4

Computer nodes

LocalStorageLocalStorage

LocalStorageLocalStorage

LocalStorageLocalStorage

66東大本郷2011-7-4

Page 67: Ruby科学データ処理ツールの開発 NArrayとPwrake

ローカリティを考慮したタスク実行

• Gfarmでは、計算ノードがとストレージノードを兼ねる

• ファイルが存在するノードで処理すれば、性能が向上

• タスク実行は、ワークフローシステムが行う

2011-7-4 東大本郷 67

LocalStorageLocalStorage

LocalStorageLocalStorage

LocalStorageLocalStorage

file1file1 file2file2 file3file3

LocalStorageLocalStoragefile4file4

Task forFile 1

Task forFile 1

Task forFile 3

Task forFile 3

Slow

Fast

Page 68: Ruby科学データ処理ツールの開発 NArrayとPwrake

ワークフローツール

• GXP–東大田浦さんらが開発したツール

– Python で記述

– クラスターの各ノードで、一斉にコマンド実行

• GXP make : GNU make の機能–始めは GXP make を使用

–ローカリティを考慮した機能がない

–拡張しようにも、Python なのでよくわからない

• Rakeを拡張しよう

2011-7-4 東大本郷 68

Page 69: Ruby科学データ処理ツールの開発 NArrayとPwrake

Rakefileにおけるタスク記述

file “prog” => [“a.o”, “b.o”] do

sh “cc –o prog a.o b.o”

end

タスク定義タスク定義(Rubyメソッド)

Ruby コードブロックRuby コードブロックタスクのアクションをRuby言語で記述

依存関係自身のタスク名 依存タスク名

依存関係自身のタスク名 =>依存タスク名

東大本郷2011-7-4 69

Page 70: Ruby科学データ処理ツールの開発 NArrayとPwrake

Rakeを拡張しよう

• Rake の並列実行

multitask “out” => [“in1”, “in2”, “in3”]

• in1..in3 についてスレッドを起動して、タスクを並列実行

• タスクの数だけスレッドを立ち上げる

–並列度を制御できない

• 当初の目標:

–並列度制御、リモート実行機能

2011-7-4 東大本郷 70

Page 71: Ruby科学データ処理ツールの開発 NArrayとPwrake

最初のPwrake

• multitask => pw_multitask– スレッドプールを作り、指定の並列数でタスクを実行

• Sshクラス– sshコマンドでリモート接続

• sh => t.rsh– Rake::Task クラスのメソッド– 実行ノードを知る必要があるため

• これでは互換性がない– Pwrake用に書いたRakefileが、Rakeで動かない– Rake用に書いたRakefileが、Pwrakeで並列に走らない

2011-7-4 東大本郷 71

Page 72: Ruby科学データ処理ツールの開発 NArrayとPwrake

改良したPwrake

• タスク並列性

– Drake を参考にした

• 毎回タスクの依存性を辿って、キューに入れる

– Drake は、1回の探索でタスク1個取得

– Pwrake は、1回の探索で実行可能なタスク全て取得

• shにおける接続情報の取得

– Thread.current[:connection] で接続先を渡す

• Rakeで動くRakefileが、Pwrakeで並列分散実行

2011-7-4 東大本郷 72

Page 73: Ruby科学データ処理ツールの開発 NArrayとPwrake

Pwrake ホストキュー

PwMultitask classPwMultitask class

PrerequisitePrerequisiteTasks

SSH connectionSSH connection

Task1

Task2

Task3

HostQueueHostQueue

Queuefor host1

Queuefor host1

Thread pool Thread pool for remote executions

worker thread1worker thread1

worker thread2worker thread2

worker thread3worker thread3

remote host1

remote host1

remote host2

remote host2

remote host3

remote host3

enqueue dequeue

東大本郷

Queuefor host2

Queuefor host2

Queuefor host3

Queuefor host3

pushpush poppop

入力ファイル保存ノードのキューに入れる

自分ノードのキューが空のとき、他のキューから盗む

2011-7-4 73

Page 74: Ruby科学データ処理ツールの開発 NArrayとPwrake

ワークフロー記述言語としてのRakefile

• 科学ワークフローは、Makefileのルールに収まらないことが多い

• Rakefileは、Rubyの内部DSLなので、プログラムが書ける

2011-7-4 東大本郷 74

Page 75: Ruby科学データ処理ツールの開発 NArrayとPwrake

依存関係がファイルに書かれている場合

• File dependency is given as a list written in a file:$ cat depend_list

dif_1_2.fits image1.fits image2.fits

dif_1_3.fits image1.fits image3.fits

dif_2_3.fits image2.fits image3.fits

...

image1

dif_1_2

image2 image3

dif_1_3 dif_2_3

2011-7-4 75東大本郷

Page 76: Ruby科学データ処理ツールの開発 NArrayとPwrake

Dependency is given as a file list

• Make:–依存関係を記述したファイルから、Makefile を作成するプログラムが必要

• Rake: ファイルを読み、タスクを定義open("depend_list") { |f|

f.readlines.each { |line|

name, file1, file2 = line.split

file name => [file1,file2] do |t|

sh “prog #{t.prerequisites.join(' ')} #{t.name}"

end

}

}

2011-7-4 76東大本郷

Page 77: Ruby科学データ処理ツールの開発 NArrayとPwrake

• タスクを実行した結果により、それ以降のファイル・タスクが定義できる

2011-7-4 東大本郷 77

動的なワークフローの生成

TaskTask

file3file1 file2

Task Task

FileFile

Page 78: Ruby科学データ処理ツールの開発 NArrayとPwrake

• make実行中にMakefileを生成

• Makefile だけではワークフローを定義できない

Makefileの動的生成

MakefileMakefile.sub: prerequisite

awk –f hoge.awk $< > $@

target: Makefile.sub

make -f $<

Makefile.subtarget1: source1

target2: source2

create

invoke

2011-7-4 78東大本郷

Page 79: Ruby科学データ処理ツールの開発 NArrayとPwrake

Rakeにおける動的タスク生成(失敗)

task :A do

task :B do

puts “B”

end

end

task :default => :A

• task A の実行中にtask B を生成

• しかし task B は実行されない

– task B が生成される前

に、すでに依存関係が決定

2011-7-4 79東大本郷

Page 80: Ruby科学データ処理ツールの開発 NArrayとPwrake

Rakeにおける動的タスク生成(成功)

task :A do

b = task :B do

puts “B”

end

b.invoke

end

task :default => :A

• 変数 b に、Taskオブジェクトを格納

• invoke メソッドにより、明示的に実行

• Rake により、動的なワークフローが実現

2011-7-4 80東大本郷

Page 81: Ruby科学データ処理ツールの開発 NArrayとPwrake

• Montage– software for producing a custom mosaic image

from multiple shots of images.

– http://montage.ipac.caltech.edu/

天文データ処理の例

2011-7-4 81東大本郷

Page 82: Ruby科学データ処理ツールの開発 NArrayとPwrake

Montage Workflow• 処理内容:

–座標変換

–明るさ補正

–足し合わせ

• 1 image : 1 process

82東大本郷2011-7-4

mProjectPP

mDiff

mBgModel

mBackground

mAddmFitplane

m1

= a'1x+b'

1y+c'

1

m2

= a'2x+b'2y+c'

2

a1x+b

1y+c

1=0 a

2x+b

2y+c

2=0

Final image

Input images

Page 83: Ruby科学データ処理ツールの開発 NArrayとPwrake

Montageワークフローのグラフflow

Inputfiles

Outputfile

2011-7-4 83東大本郷

Page 84: Ruby科学データ処理ツールの開発 NArrayとPwrake

Montage Workflow 性能評価

• ワークフローをRakefileとして記述

mProjectPP

mDiff

mBgModel

mBackground

mAddmFitplane

m1

= a'1x+b'

1y+c'

1

m2

= a'2x+b'2y+c'

2

a1x+b

1y+c

1=0 a

2x+b

2y+c

2=0

Final image

Input images

84東大本郷2011-7-4

Page 85: Ruby科学データ処理ツールの開発 NArrayとPwrake

Montage Workflow の実行時間

1 node4 cores

2 nodes8 cores

4 nodes16 cores

8 nodes32 cores

1-site

2 sites16 nodes48 cores

東大本郷 85

筑波大の計算機クラスタ

筑波大+産総研の計算機クラスタ

2011-7-4

Page 86: Ruby科学データ処理ツールの開発 NArrayとPwrake

Montage Workflow の実行時間

1 node4 cores

2 nodes8 cores

4 nodes16 cores

8 nodes32 cores

1-site

2 sites16 nodes48 cores

NFS並列度を上げても処理時間が減らない

東大本郷 862011-7-4

Page 87: Ruby科学データ処理ツールの開発 NArrayとPwrake

Montage Workflow の実行時間

1 node4 cores

2 nodes8 cores

4 nodes16 cores

8 nodes32 cores

1-site

2 sites16 nodes48 cores

東大本郷 87

Gfarm

スケーラブル

Gfarm1拠点で

スケーラブル

ファイルやジョブの配置により約20%性能向上

2011-7-4

Page 88: Ruby科学データ処理ツールの開発 NArrayとPwrake

Montage Workflow の実行時間

1 node4 cores

2 nodes8 cores

4 nodes16 cores

8 nodes32 cores

1-site

2 sites16 nodes48 cores

東大本郷

GfarmはNFS 倍の性能向上

GfarmはNFSの約10倍の性能向上

2011-7-4 88

Page 89: Ruby科学データ処理ツールの開発 NArrayとPwrake

Montage Workflow の実行時間

1 node4 cores

2 nodes8 cores

4 nodes16 cores

8 nodes32 cores

1-site

2 sites16 nodes48 cores

Gfarm2拠点でもスケーラブル

東大本郷 892011-7-4

Page 90: Ruby科学データ処理ツールの開発 NArrayとPwrake

Pwrake今後の予定

• 大規模なワークフローの実行– 100万並列

–自律分散システム

• 障害対策–障害情報の取得

– タスクの再試行

–故障ノードの判別

• 可用性–実行状況の可視化、プロファイリング

2011-7-4 90東大本郷

Page 91: Ruby科学データ処理ツールの開発 NArrayとPwrake

クラスタクラスタ

Pwrakeプロセス

計算プロセス

計算プロセス

計算プロセス

計算プロセス

クラスタクラスタ

Pwrakeプロセス

計算プロセス 計算

プロセス計算プロセス

計算プロセス

Pwrakeプロセス

Pwrakeプロセス

現状 将来接続ごとにThreadが起動

DAGを渡して自律処理

階層的自律分散システム

Page 92: Ruby科学データ処理ツールの開発 NArrayとPwrake

Pwrakeまとめ

• ワークフロー記述言語として、Rakeを採用

• 並列分散ワークフロー処理システムPwarkeを開発

– URL: http://github.com/masa16/pwrake

• 分散ファイルシステムGfarmを用いることにより、スケーラブルな性能向上を達成

2011-7-4 92東大本郷