2009-10-06[n年前へ]
■無料配布MathematicaカーネルとNET Framework実装IronRubyでグリッド・Matheatica計算環境は5分で作れる 
今日も、「無料配布のMathematicaカーネルと(やはり同じく無料で使うことができる).NET Framework上で動作するRubyであるIronRuby」を使って色々なことをしてみよう、という話の続きです。もちろん、さらにパワーアップした可能性を追求してみたいと思います。
数式処理環境であるMathematicaには、オプション製品としてgridMathematicaという製品があります。Mathematicaでグリッド・コンピューティングを実現する、というようなネーミングの製品ではありますが、実際にはMathematicaで並列(パラレル)計算を実現するための拡張オプションです。価格は・・・眼の球が10cmくらいは前に突き出てしまうほどのお値段になっています。
さて、「無料配布のMathematicaカーネルと(やはり同じく無料で使うことができる).NET Framework上で動作するRubyであるIronRuby」を使えば、色々なことができるわけです。そこで、今日はgridMathematicaが可能にするようなことを、誰でも入手可能なツールで実現してみることに挑戦してみようと思います。
本来ならば、分散処理環境をRubyで実装したdRubyなどを使いたいところですが、いくつかの理由から、今日は(IronRubyで動作する)ごくごく普通のRubyライブラリを使って、Mathematicaカーネルをネットワーク上で並列計算させることができるコードを書いてみることにします。
まずは、(無料配布されている)Mathematicaカーネルを扱うサーバ・アプリを書いてみます。といっても、単にこれだけのコードです。
class Mathematica
require 'Wolfram.NETLink'
include Wolfram::NETLink
def initialize()
end
def open
@kernelLink=MathLinkFactory.CreateKernelLink()
@kernelLink.WaitAndDiscardAnswer()
end
def do(command)
@kernelLink.EvaluateToInputForm(command, 0)
end
def close
@kernelLink.EvaluateToInputForm('MVClose[]', 0)
end
end
require 'webrick'
include WEBrick
m=Mathematica.new
m.open
s=HTTPServer.new(:Port=>ARGV[0].to_i,
:DocumentRoot=>'',
:RequestTimeout=>600,
:MaxClients=>1)
s.mount_proc("/restart") {m.close;m.open}
s.mount_proc("/shutdown") {s.shutdown}
s.mount_proc("/"){|req,res|
res.body='use /evaluate/command'
if /evaluate\/(.+)$/=~req.path
res.body=m.do($1)
end
}
trap("INT"){m.close;s.shutdown}
s.start
これは、例題のため、多くの処理をはしょっていますが、例題の範囲ではきちんと動作するコードです。ひとことで言えば、URIを介して渡されたコマンドを実行した結果を返すWEBサーバアプリです。
ちなみに、このスクリプトを mathematicaServer.rb と名付ければ、
ir.exe mathematicaServer.rb 80という具合で、ポート80番でコマンドを待ち受けるWEBサーバが起動します。あるいは、
ir.exe mathematicaServer.rb 81とすれば、ポート81番でコマンドを待ち受けるWEBサーバが起動します。複数台のPC上で実行しても構いませんし、あるいは、(テスト用として)一台のPC上で複数のサーバを実行しても構いません。もちろん、多数台のPC上でサーバー群を立ち上げる方が高性能になるのは言うまでもありません。
さて、ここまで来たら、後はそれらのサーバ群に"Mathematica"による並列計算をさせるスクリプトを書いてみることにしましょう。たとえば、こんな感じです。
require 'pp'
require 'net/http'
Net::HTTP.version_1_2
result=[]
threads = []
command='2+2'
uri=['localhost','localhost']
port=[80,81]
2.times do |i|
threads.push(
Thread.new do
Net::HTTP.start(uri[i],port[i]){ |http|
r=http.get('/evaluate/'+command);
result<<r.body;}
end
)
end
threads.each do |t| t.join end
pp result
このスクリプトをmathematicaController.rbとでも名付け、
ir.exe mathematicaController.rbという風に起動してやります。もちろん、この並列計算を行わせるコントローラ側はIronRubyである必要はありませんから、
ruby mathematicaController.rbでも構いませんし、計算サーバ群は結局のところ単なるWEBサーバ群なのですから、Rubyプログラムである必要もありません。
このスクリプトの内容はとても簡単です。上の例であれば、ローカルPC上で動いている、2つのMathematicaカーネルを使ったサーバに対して、"2+2"という計算をパラレル(並列)に投げて、その結果を受け取りまとめているわけです。その結果、
["4","4"]という計算結果が最終的には手に入ることになります。httpを使い、また、コマンドのをエンコード処理を行わずGETで投げつけていますが、それはあくまで簡単なテスト用であるためです。
Mathematicaという最高の開発環境を使い、並列計算も可能にし、さらに、そういったプログラムを自分で書くことができる・・・なんて、とても楽しそうではありませんか?この「無料配布のMathematicaカーネルと(やはり同じく無料で使うことができる).NET Framework上で動作するRubyであるIronRubyを使って、遊んでみよう」というシリーズ!?の可能性はまだまだ広がりそうです。
さまざまなデータに対し透過的にアクセスが可能で、並列計算もとても簡単にできたなら、色々なことができそうだ、と思えますよね?無料配布のMathematicaカーネルとNET Framework実装IronRubyでグリッド・Matheaticaコンピューティングのプログラムは、実際のところ5分程度で作ることができます。
無料配布のMathematicaカーネルなのに、それが実に多くのことができることに驚かされます。少し時間ができたとき、こんなプログラムを作って遊んでみるのはいかがでしょうか。