2009年11月16日月曜日

次世代スーパーコンピュータが必要な理由

このブログ記事をはてなブックマークに追加

先日の事業仕分けによる次世代スーパーコンピュータ(次世代スパコン)の予算見直しで事実上の「凍結」との結論が出たことで、多くの人々から次世代スパコンについて注目が集まることになったが、情報不足のためか、一部誤解があるようだ。そこで、自分の知っている範囲で次世代スパコンについて記したいと思う。もし自分の知識が至らず間違っている場合は指摘して頂けると有り難い。

次世代スーパーコンピュータ

次世代スパコンは富士通のCPU、"Vinus" SPARC64 VIIIfxか、その後継CPUで構成する公算が高いが、このCPUはスカラ型だ。もともと、NECと日立がベクトル型のCPUを開発する予定であったが、撤退によりベクトル型とスカラ型の混成システムから、スカラ型のみのシステムに変更された。因みに、この富士通のCPU "Vinus"は現時点で世界最高速のCPUであり、国産で高速なCPUを開発できるのかという疑問も払拭できている。

ところで、この撤退により次世代スーパーコンピュータ開発について危惧する声が出たのだが、実のところ次世代スパコン開発に関わるユーザや開発者の一部では、開発がしやすくなったとして喜んでいたりする。もともとの混成システムでは、実用的に使う場合、ベクタ部はベクタ部のみの利用、スカラ部ではスカラ部のみの利用でしかパフォーマンスが出せず、これでベクタ部とスカラ部を一台に入れる意味があるのかというもっともな疑問が出ていたようだ。また、次世代スーパーコンピュータ開発実施本部のプロジェクトリーダーである渡辺氏がNEC出身であることからのあらぬ疑いもされずに済むようになったと思う。

NECと日立が撤退した理由として、百数十億円の負担が重荷になったと答えている。しかし、実際はそんな負担額では済まなかったというのが関係者間での通説だ。つまり、それ以上の巨額の開発資金を企業は自腹で負担しなくてはならなかったのだ。では何故そのような負担をしてまでも次世代スパコンに参加したかったのか。それは「世界一高速なコンピュータを作りました」という事実が企業にとって非常に大きな宣伝になるから。世間一般ではそれで世界一の技術があると見なしてくれるのだ。それに、売り上げももちろん重要だが、技術者の士気も上がることのメリットが大きい。技術者の士気はなかなか目に見えにくいものだが、そういう技術者の士気があってこそ、今日の技術立国日本に成長したのだと思う。そして、国や理研側としては実際にかかる費用よりかなり割安に開発できるのだからある意味Win-Winの関係という訳だ。

因みにスパコン開発のために必要な総費用は1,154億円(現在ではNECと日立の撤退により若干増えて1,230億円)は7年間の総費用であり、それにこの金額はスパコンで利用するアプリケーション開発や研究、センターの建設などすべてを含めた費用であり、ハードウェア作製の資金はこの中の一部が担っている。これを考えると決して高い予算ではないように思う。

次世代スパコンについてもっと詳しく知りたい場合は、理化学研究所 次世代スーパーコンピュータ開発実地本部が参考になる。

研究者からみたスーパーコンピューティング

スパコンを利用する研究者からしてみれば世界トップレベルの速いコンピュータ(CPUだけではなくメモリやネットワークのレイテンシを含む)がちゃんと利用できればそれでいいのだが、それにはまず国がちゃんと音頭を取ってくれないとそんな素敵なコンピュータは使えないわけで、国がやるなら日本のためにということで、前述の次世代スーパーコンピュータということになる。

で、本当に重要なのは次世代スパコンを使った実際の研究であり、そのためにグランドチャレンジ・アプリケーションの研究開発などのプロジェクトがある。これは、ライフサイエンス分野ナノテクノロジー分野が対象で非常に大きな役割を果たすと思われる。これらに加えて産学の研究者・技術者へのインフラとしての意味合いも強い。共同利用を積極的に推進しているのだ。

実はこれには訳があって、前回の地球シミュレータ運用の際に、アプリケーション開発が難しい、特定分野に偏っている、申請が通りにくいなどの問題点が指摘されたので、よりよく研究に利用してもらうにはどうしたら良いかという視点からこのような方針になったようなのだ。そして、すでに複数の大学や研究機関との連携をとりつつある。

という訳で、今後代替措置もなくスパコンが使えなくなったりすると産学の基礎研究、応用研究に大きなダメージが出ることは間違いないと思う。

予算「凍結」について

ここでは政治が云々、政党が云々というつもりはない。どのようにすればスーパーコンピューティングの重要性を理解してもらえるか考えてみる。

今回の事業仕分けによる次世代スパコン「凍結」の際、以下のような意見が出た。

「世界一を目指す理由は何か。2位ではだめなのか」
「一時的にトップを取る意味はどれくらいあるか」
「一番だから良いわけではない」

実際にこう思っている一般の方々もいると思う。それに対して、前述の理研のページで一般の方にも分かる説明が出ている。

トップの座にいられるのは、わずか数年なんですね。

個々の研究者や科学を理解している人たちも早速ブログやTwitterで多くの意見を出している。このような議論は積極的に行うべきだと思うし、多くの人の目に触れれば触れるほど認知度は上がってくるはずだ。また、今回の事業仕分けについて文科省でも意見を募集しているので、ここで意見を述べるのも効果があるかもしれない。

さらに、一部の議員の方にも次世代スパコンについては理解してもらっているようで、民主党の藤末健三議員のブログTwitter木俣佳丈議員のブログでも言及されている。

以上をまとめると、技術力の維持と科学の発展のために次世代スパコンは必要であり、このような理由を積極的にアピールして一般の方々にそれを知ってもらうことが大事なのだと思う。

続きを読む...

2009年11月1日日曜日

Google Wave: 「てめーはおれを怒らせた」ボットを作ってみた

このブログ記事をはてなブックマークに追加

「てめーはおれを怒らせた」ボットといきなり言われても何のことだか分からないと思うけど、要はユーザの発言に含まれる特定の文字に反応して動作するGoogle Waveのボット billowlet@appspot.com を作成したのだ。

追記(2010/3/7): Google Wave Robots API v2がリリースされたので、新しいAPIでボットを書き直してみた。古いAPIは今後使用できなくなるようなので、今のうちに新しいAPIに移行した方が良いと思う。


先日、Google Waveの開発者用アカウントをGoogleからもらえたので早速何か作ってみることにした。どうせならGoogle App Engineを利用したかったので簡単に作れそうなボット(bot)を作成してみたわけだ。因みに元ネタのジョジョの奇妙な冒険とは言い回しが似ているというだけで内容とは関係ないので悪しからず。

このボットはユーザの発言内容に含まれる特定の文字に反応して動作し、ネコみたいな喋り方にさせられたり、英語や中国語で喋らされたり、笑いっぱなしにさせられたり、どもらされたりと、ユーザの発言がいろいろ変化する。因みに、「ごめんなさい」もしくは「ゆるして」と言うことで、動作を取り消すことができる。画像は実際の使用例だ。

ボットのアカウントはbillowlet@appspot.comで、使い方はGoogle WaveのContactsパネル内にある+ボタンでこのアカウントを追加するだけだ。そして、このボットアカウントをWaveに参加させればよい。因みに、ボットに使われている仔猫のアイコンについてはフリー素材ROKOの画像を利用させてもらった。

以下に「てめーはおれを怒らせた」ボットのデモのリンクを張っておくが、こちらはWave Sandboxアカウント所持者のみが利用できる。

「てめーはおれを怒らせた」ボット デモ

実際に使ってみて、このGoogle Waveはとても面白いWebアプリケーションだと思った。今回のアプリケーション作成でも将来性を強く感じることができたので、これから多くの人が使うことでどのように発展していくのか楽しみだ。

以下にGoogle App Engine上のソースコードを示しておく。ところで、stringモジュールのtranslate関数がunicodeに対してちゃんと動作しないのは何とかならないものかな。

追記(2009/11/23):

開発者用アカウント(Sandbox)では正常に動作するボットの発言が、Previewアカウントでは表示されないので調べてみたら、どうやらGAEにおけるGoogle Wave APIのバグのようだ。現在、GAEでCreateBlip/CreateChildを使うと正常に動作しない。今のところ対策はないようなので、修正されるまで待つしかないようだ。因みにそれ以外のAPIは動作するようで、ボットの発言はないが自分の発言はちゃんとボットによって変更されて表示される。

追記(2009/11/24):

Google Wave APIのバグが直って、Previewアカウントでも正常に動作するようになったみたい。しかし、今度はしばらくするとボットが反応しなくなるバグがあるようだ。プレビュー版だし不具合が出るのは仕方がないな。未知のバグを見つけたらできるだけ報告するようにしよう。

追記(2009/11/27):

ボットが反応しなくなるバグが直ったようだ。これでボットの開発については問題なくなったかな。

追記(2010/1/31):

最近、ボットのアイコンや名前が表示されないと思っていたら、ボットのプロフィールが表示されないバグがあるみたい。

billowlet.py

#!/usr/bin/env python # -*- coding: utf-8 -*- import re, string, urllib, urllib2, random from google.appengine.ext import db from waveapi import events from waveapi import model from waveapi import robot from waveapi import document from waveapi import simplejson HIRAGANA = u"あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよわをん" KATAKANA = u"アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨワヲン" class UserData(db.Model): user = db.StringProperty(multiline=False) status = db.StringProperty(multiline=False) def OnParticipantsChanged(properties, context): added = properties["participantsAdded"] for participant in added: if participant != "billowlet@appspot.com": Notify(context, participant) def OnRobotAdded(properties, context): root_wavelet = context.GetRootWavelet() root_wavelet.CreateBlip().GetDocument().SetText(u"おれはbillowlet。よろしくな。") def Translate(text, from_lang, to_lang): url = "http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=%s&langpair=%s%%7C%s" % (urllib.quote(text.encode("utf-8")), from_lang, to_lang) data = simplejson.loads(urllib2.urlopen(url).read()) return data["responseData"]["translatedText"] def BeCat(text): text = re.sub(u"。", u"にゃ。", text) text = re.sub(u"?|\?", u"にゃぁ?", text) text = re.sub(u"!|\!", u"にゃっ!", text) text = re.sub(u"な", u"にゃ", text) if text[-1] not in (u"。", u"?", u"?", u"!", u"!"): text += u"にゃ" return text def DotMarks(text): from_kana = u"かきくけこさしすせそたちつてとはひふへほカキクケコサシスセソタチツテトハヒフヘホ" to_kana = u"がぎぐげござじずぜぞだぢづでどばびぶべぼガギグゲゴザジズゼゾダヂヅデドバビブベボ" for f, t in zip(from_kana, to_kana): text = text.replace(f, t) return text def Laugh(text, ch): for i in range(len(text), 0, -1): text = text[:i] + ch + text[i:] return text.replace(u"。", u"").replace(u"、", u"") + ch * random.randint(3, 10) def Kana(idx): return HIRAGANA[idx] + u"|" + KATAKANA[idx] def OnBlipCreated(properties, context): blip = context.GetBlipById(properties["blipId"]) doc = blip.GetDocument() user = blip.GetCreator() data = UserData.all().filter("user =", user).fetch(1) if data: status = data[0].status else: status = None text = doc.GetText().strip() if status and re.match(u"ごめんなさい|ゆるして", text): blip.CreateChild().GetDocument().SetText(u"ゆるしてやる。やれやれだぜ。") if data: data[0].delete() angry = range(len(HIRAGANA)) random.shuffle(angry) if status: if status == u"ネコになれ。": text = BeCat(text) doc.SetText(text) elif status == u"英国紳士になれ。": text = Translate(text, "ja", "en") doc.SetText(text) elif status == u"台湾に住め。": text = Translate(text, "ja", "zh-TW") doc.SetText(text) elif status == u"インチキ日本人になれ。": text = Translate(Translate(text, "ja", "en"), "en", "ja") doc.SetText(text) elif status == u"大事なことは2回言え。": doc.SetText(text + text + u"\n大事なことなので2回言いました。") elif status == u"笑え。": doc.SetText(Laugh(text, u"w")) elif status == u"濁れ。": doc.SetText(DotMarks(text)) elif status == u"逆さまになれ。": doc.SetText(text[::-1]) elif status == u"どもれ。": doc.SetText((text[0] + u"、") * 3 + text) elif status == u"うざくなれ。": doc.SetText(Laugh(text, u"っ")) else: userdata = UserData() if re.search(Kana(angry[0]), text): status = u"ネコになれ。" elif re.search(Kana(angry[1]), text): status = u"英国紳士になれ。" elif re.search(Kana(angry[2]), text): status = u"台湾に住め。" elif re.search(Kana(angry[3]), text): status = u"インチキ日本人になれ。" elif re.search(Kana(angry[4]), text): status = u"大事なことは2回言え。" elif re.search(Kana(angry[5]), text): status = u"笑え。" elif re.search(Kana(angry[6]), text): status = u"濁れ。" elif re.search(Kana(angry[7]), text): status = u"逆さまになれ。" elif re.search(Kana(angry[8]), text): status = u"どもれ。" elif re.search(Kana(angry[9]), text): status = u"うざくなれ。" if status: blip.CreateChild().GetDocument().SetText(u"てめーはおれを怒らせた。%s" % status) userdata.user = user userdata.status = status userdata.put() def Notify(context, participant): root_wavelet = context.GetRootWavelet() root_wavelet.CreateBlip().GetDocument().SetText(u"%s、おれを怒らせるなよ。" % participant.split("@")[0]) def main(): myRobot = robot.Robot("billowlet", image_url="http://billowlet.appspot.com/assets/icon.gif", version="1", profile_url="http://billowlet.appspot.com/") myRobot.RegisterHandler(events.WAVELET_PARTICIPANTS_CHANGED, OnParticipantsChanged) myRobot.RegisterHandler(events.BLIP_SUBMITTED, OnBlipCreated) myRobot.RegisterHandler(events.WAVELET_SELF_ADDED, OnRobotAdded) myRobot.Run() if __name__ == "__main__": main()

app.yaml

application: billowlet version: 1 runtime: python api_version: 1 handlers: - url: /_wave/.* script: billowlet.py - url: /assets static_dir: assets

続きを読む...