月別アーカイブ: 2013年6月

Windows HPC Serverを使ってみる

なぜ「Windows HPC Serverによる分散処理計算」か?

保険数理におけるEmbedded Value計算・リスク量計算などにおいては、大量のシナリオ・センシティビティによるプロジェクションが求められます。
1台のPCでは計算速度に限界があるので、複数台PCによる分散処理計算が必要となってきます。

複数台PCによる分散処理計算の方法の一つとして、Windows HPC Serverがあります。
その他、Hadoopなどの選択肢もあるようです。

Windows HPC Serverによる分散処理環境の構成

ヘッドノード+ノード(複数)による構成になります。この他、ファイルを保存するファイルサーバを用意することもあります。

ヘッドノード
ジョブ/タスクの管理を行うPC
ノード
計算を行うPC

Windows HPC Serverが行うこと

Windows HPC Serverは、ジョブ/タスクの管理を行ってくれます。
タスクを各ノードに割り振ったり、ジョブ/タスクが失敗したときにそれを通知してくれます。

ジョブ
一かたまりの仕事。ジョブ単位でWindows HPC Serverに「投げる」ことになります。1つのジョブは複数のタスクから構成されます。
例)ある保険種類のプロジェクションの1000シナリオの計算
タスク
ジョブを小さく分けたもの。タスク単位で各ノードPCに割り振られます。
例)ある保険種類のプロジェクションの1000シナリオのうち、各1シナリオの計算

Windows HPC Server 環境構築

  1. Windows Azure(Microsoftのクラウドサービス)を使用する方法

    Windows Azure上に、Windows HPC Serverがインストールされた状態で仮想PCを構築することができます。

    以下の資料の前半部に沿うことで、Windows Azure上に環境を構築することができます。
    (Run the Sample SOA Application の代わりに、以下で作成したアプリケーションを実行できる)

  2. 実PCで運用する方法

    複数台PCを購入し、それらにWindows HPC Packを導入します。個人ではちょっと現実的ではないですね。。

分散処理アプリケーションの作成

サンプル分散処理アプリケーション

100行の数値をインプットとし、各行の数値の2乗平均和を取得するアプリケーションを作成します。
ジョブを「各行の数値を2乗すること×100」とし、分散処理実行させます。その後、結果を取得しクライアント側で平均をとります。

サンプル分散処理アプリケーションの構成

以下のようにプログラムを分割して構成しています。

  • SampleClient.exe…クライアントアプリケーション。これを起動して計算を開始します。
  • HPCLib.DLL …分散処理用のライブラリ
  • HPCNode.exe …ノードから実行される実行ファイル

SampleClient.exeの部分を変更することで、好きな計算を分散処理により行うことができます。

サンプル分散処理アプリケーションのビルド

  • 筆者はVisual Studio 2010 Professionalですが、2012やExpress版でも実行可能と思います。
  • 参考資料にある以下SDKのインストールが必要となります。
    • HPC Pack 2008 R2 Client Utilities Redistributable Package with Service Pack 4
    • Microsoft HPC Pack 2008 R2 SDK with Service Pack 4

分散処理アプリケーションの流れ

準備

各ノードPCからも読み書きができる共有フォルダを作成しておきます。

計算の流れ

  1. SampleClient.exeを実行します。
  2. 共有フォルダ内に一時フォルダを作成し、必要なデータをコピーします。この中に各ノードPCから実行するためのHPCNode.exeも含めます。
  3. Windows HPC ServerにHPCNode.exeを実行するジョブを送信します。
  4. Windows HPC Serverから指示を受けた各ノードPCがHPCNode.exeを実行する。実行結果はファイルとして共有フォルダに保存します。
  5. Windows HPC Serverからジョブが終了したという指示を受け取ります。
  6. 各ノードPCの実行結果を読み込み、集計して結果を出力します。
  7. 一時フォルダを削除します。

他にも、SOA(サービス志向アーキテクチャ)という方法で分散処理を行うこともできます。しかし、学習すべき事項が増えるため、今回はその方法をとっていません。

分散処理アプリケーションのポイント

通常のアプリケーションでは1つのPC内で計算されるため、通常どおりプログラムを書くことで、メモリ内で情報を受け渡すことができます。しかし、分散処理アプリケーションでは、別のPCで実行するため、情報を共有/受け渡すために配慮が必要となります。

このサンプルでは、以下のような工夫を行っています。

データの受け渡し

インプットデータ等の受け渡しには共有フォルダを使っています。
計算したデータの受け渡しには、「シリアライズ」というデータをファイルとして保存する機能を利用しています。「シリアライズ」により計算結果を表すクラスをファイルに保存し、逆(デリシアライズ)によって読み込みます。

ノードからの計算メソッドの実行

ノード用実行ファイルがクライアントのクラスを利用するため、普通に組むとノード用実行ファイルがクライアントに依存することになり、ライブラリとして切り出しにくくなります。ですので、実行すべきクラス・メソッドを文字列で渡し、「リフレクション」という機能を使って実行しています。

「リフレクション」を使うと、クラスが定義された実行ファイル・ライブラリをロードし、クラス・メソッド名を文字列で指定することでメソッドを実行することができます。

サンプルプログラム

HPCSampleCalculationRev4.zip

勉強会用に作成したppt

Windows HPC Server 20130621.pptx

参考資料

Windows HPC Serverで分散処理を行うアプリケーションを作成するのに必要なSDK

Azureで分散処理を行うために必要なSDK

SOAアプリケーションを作成して分散処理を行うためのドキュメント

SOAアプリケーションを扱わない場合でも、Windows HPC Serverの仕組みを理解するのには役立ちます。

ANTLRのお勉強

DSLを作りたいので、ANTLRのお勉強をしています。
ANTLRのサイトではどのドキュメントから読んでいけば良いのかわかりにくい部分があるので、整理してみました。
使いこなしているわけではないので、誤り等はご容赦下さい。

ANTLR 概要

ANTLRとは?

ANTLRはパーサジェネレータと呼ばれるもので、「言語設計者が定義した文法から、言語の文法に従って記述されたコードを解析するパーサを生成する」ツールです。
DSL(ドメイン特化言語=特定の目的のためのミニ言語)を作成するための重要なツールになります。
Javaをメインの言語として開発されています。

ANTLRでは、以下を行うことができます。

  • 字句解析・構文解析の文法ファイルからの字句解析器・構文解析器の生成
    文法ファイルを記述すると、そこから字句解析器・構文解析器クラスを生成してくれます。
  • 木文法からの抽象構文木の走査器の生成
    木文法と呼ばれるものを記述すると、抽象構文木(DSLコードを解析し木構造にしたもの)の走査器クラスを生成してくれます。

ANTLRの凄いところ

  • 字句解析器・構文解析器・走査器は、Javaがメインですが、C#やC++等のコードとしても出力できます。
  • コードにエラーがある場合、ある程度わかりやすくエラーを出力してくれます(たぶん)。
  • StringTemplateというテンプレートエンジンと統合されているため、DSLからのコード生成ができます。
  • ANTLRWorksというGUIで、文法の作成・デバッグをサポートしてくれます。

エラー出力なども含めて字句解析器・構文解析器・走査器を手で記述すると、気の遠くなるような作業になりそうですが、ANTLRでそれらを省力化することができます。

DSL開発者は何をすればいい?

DSL開発者は、ANTLRを使ってDSLの開発を行うときには、以下のことをすれば良いです。

  • DSLの文法を定義する
  • ANTLRを使って、文法から字句解析器・構文解析器・走査器のクラスを出力する。
  • 字句解析器・構文解析器・走査器を呼び出すメソッドを作成し、コンパイルする。

以上で、DSLプログラムが開発できたことになるので、DSLコードを記述してプログラムを走らせると、DSLコードを解析して思いのままのことができます。(たぶん)

ANTLRを使ってみる

JavaでANTLRを使ってみる

下の方に記述した参考文献のGetting Startedのリンクに沿って、ファイルを入手し設定して行くのが良いと思います。 私はJavaでANTLRを使っていないので、説明は省略します。

C#でANTLRを使ってみる

下の方に記述した参考文献のGetting Started C#のリンクに沿って、ファイルを入手し設定して行くのが良いと思います。

ANTLRの実行は、以下の2つのフェーズに分かれるのですが、

  1. grammerファイルから、ANTLRによりlexer, parserクラスを作成する
  2. メインファイルから、作成したlexer, parserクラスを呼び出し、DSLコードを解析する

以下のようにいくつか方法があります。

  1. コマンドラインからlexer, parserクラスを作成し、Visual Studioにそれらのクラスを追加し実行する
  2. ANTLRWorksを用いてlexer, parserクラスを作成し、Visual Studioにそれらのクラスを追加し実行する
  3. Visual Studio機能拡張を用いて両方を同時に行う

Visual Studio機能拡張は楽なのですが、設定方法にひと手間必要だったり、デバッグがややしづらかったりします。ANTLRWorksも、C#用の出力をする場合にはdebugが行いにくいなどの微妙な点があるため、一長一短です。
私は現在のところ2.の方法を用いています。

ポイント

つまづくポイントや、ドキュメントからはなかなかわかりにくいことを書きます。

[C#]Visual Studio 機能拡張を使ったときにコンパイルができない

ANTLR Language Support v1.0.11で確認。
「呼び出しのターゲットが例外をスローしました。」なるエラーが出てコンパイルできない。
これは、以下にあるように、Antlr\Tool\Templates\messages\languagesのen.stgをコピーして名前をja.stgに変更すればOK。
Something Wrong in Antlr3CSharpReleases 3.4?
http://antlr.1301665.n2.nabble.com/Something-Wrong-in-Antlr3CSharpReleases-3-4-td6895968.html

[C#]エラーを出力しない!

ANTLR3.Runtime v3.4.1.9004で確認。
Parserを作成してDSLコードを解析しようとしたときに、No viable alternativeなどのエラーを出力してくれません。これでは、入力したDSLコードがあっているかわからないので、使い物になりません。
http://stackoverflow.com/questions/8525009/antlr-not-emitting-error-messages-on-invalid-input
にあるとおり、
lexer.TraceDestination = Console.Out;
parser.TraceDestination = Console.Out; を追加すると出力してくれます。

文法の種類って何があるの?

ANTLRの文法には、以下の種類がある。

  • lexer grammer(lexer grammer で始まる)字句解析器
  • parser grammer(parser grammer で始まる)構文解析器
  • tree grammer(tree grammer で始まる)木文法-抽象構文木の走査を行うもの
  • combined grammer(grammer で始まる)字句解析器+構文解析器

通常は、combined grammer(とtree grammer)を使えば良いはず。

走査のやり方

コード解析できるだけでは意味が無く、解析したコードをもとにクラスを出力したり、抽象構文木を走査して適宜画面出力したり、といったことが必要になる。
主に以下の2種類の方法で走査を行うことができる。

後者の方がひと手間増えるが、走査を抽象構文木の作成と走査の2つのパーツに分けることができ、スケーラブルな方法といえる。

1.構文解析時にアクションを用いて走査等を行う方法
2.構文解析により抽象構文木(AST)を作成し、木文法により走査を行う方法

参考文献

Getting Started

まずは、以下のGetting Startedから読むのが良さそう
http://www.antlr.org/wiki/display/ANTLR3/FAQ+-+Getting+Started

次に、Getting Startedで紹介されているTutorialsや例を読んでいくと良さそう。
http://www.antlr.org/wiki/display/ANTLR3/Five+minute+introduction+to+ANTLR+3
http://www.antlr.org/wiki/display/ANTLR3/Quick+Starter+on+Parser+Grammars+-+No+Past+Experience+Required
http://www.ociweb.com/jnb/jnbJun2008.html
http://www.antlr.org/wiki/display/ANTLR3/Parsing+XML
http://www.antlr.org/wiki/display/ANTLR3/Fig+-+Generic+configuration+language+interpreter

また、以下のページの下部にExampleがある。
http://www.antlr.org/download.html

お金があれば、ANTLRv3の参考書を買ってみるのも良いかも。
http://www.pragmaticprogrammer.com/titles/tpantlr/index.html
全部を読むのはきついが、以下の章はとても参考になった。

  • chapter3の電卓計算をするような言語の解析
  • chapter8.2のC-言語(簡易版C言語)の解析

Getting Started C#

C#で始めるには、以下から読んでいくと良いと思います。
http://www.antlr.org/wiki/display/ANTLR3/Antlr+3+CSharp+Target
http://www.antlr.org/wiki/display/ANTLR3/Antlr3CSharpReleases
Antlr3CSharpReleasesのVisual Studio and the ANTLR C# Targetのリンクから、Visual Studio機能拡張を入手できます。

その他役に立ちそうなドキュメント

http://www.antlr.org/wiki/display/ANTLR3/ANTLR+Cheat+Sheet
http://www.antlr.org/wiki/display/ANTLR3/ANTLR+v3+documentation
http://www.antlr.org/wiki/display/ANTLR3/ANTLR+v3+printable+documentation
http://www.stringtemplate.org/

その他役に立ちそうなドキュメント C#

http://stackoverflow.com/questions/4396080/antlr-3-3-c-sharp-tutorials
http://www.manuelabadia.com/blog/CategoryView,category,ANTLR.aspx
http://www.lextm.com/search/label/ANTLR
http://www.codeproject.com/Articles/18880/State-of-the-Art-Expression-Evaluation
http://d.hatena.ne.jp/runicalp/searchdiary?word=*[ANTLR]

日本語のドキュメント

cx5software C++でANTLRを使う
http://cx5software.com/article_antlr/
ここが一番わかりやすいか。
Unlimited Island ANTLRを使ってみる
http://www.limy.org/program/java/antlr/step1.html
http://www.limy.org/program/java/antlr/step2.html
竹本 浩のページ antlr
http://www.pwv.co.jp/~take/TakeWiki/index.php?FrontPage#q1c6f434
cloverrose ANTLR
https://sites.google.com/site/cloverplusrose/gou-wen-jie-xi
zp’s note ANTLRかわいいよANTLR
http://d.hatena.ne.jp/zpx/20110502/1304416560

DSL関連書籍

一緒に読むと理解が深まりそう。というか本を1回読んだだけではわからなくて、本⇔ANTLRを行ったり来たりして理解が深まってくる感じ。
言語実装パターン ―コンパイラ技術によるテキスト処理から言語実装まで
http://www.amazon.co.jp/dp/4873115329
ドメイン特化言語 パターンで学ぶDSLのベストプラクティス46項目
http://www.amazon.co.jp/dp/4864010471
2週間でできる! スクリプト言語の作り方
http://www.amazon.co.jp/dp/4774149748

保険数理計算のためのSQLServer

現状、Accessで行っている保険数理業務をSQLServerにアップグレードし、より効率的・保守性の高い環境を構築するためのメモを記述する。

想定する業務

  • 保険数理用の契約データや異動データをデータベースにより編集・集計する業務
  • システムからテキストが定期的に送付され、それをデータベースに搬入して処理を行う。
  • 月/四半期/年といった単位での定例処理およびtemporaryな分析を行う。
  • リアルタイムの処理・同時更新などは考慮しなくてよい。

SQLServer化のメリット・デメリット

メリット

  • 処理をSQL文で管理するため、読みやすく保守性が高い
    Accessでは、処理の内容を確認するのが非常に面倒(クエリを一つ一つ開けて読んでいく必要がある)
    Accessでは、SQL文を勝手に汚く変更されてしまう
  • 処理を記述するSQLとデータの分離ができるため、保守性が高い
    Accessでは、クエリを少し修正するのにもmdbファイルごとコピーが必要なことがある
    2GB以上のデータを扱えるようになる
  • 自動化が可能となる
  • 一度作成したデータベースについて分析がしやすい
    クエリをコピー・変更して実行すれば良い
    Accessでは、特に複数mdbにまたがる場合など煩雑な作業になる

デメリット

  • 学習コストがかかる
  • いくつかの関数が違う、型について厳しい、VBAが使えない(代替手段はある)。関数まわりは少し微妙。

SQLServerでの業務構築(一例)

いくつかのポイント

  • SQLServer用PCにSQLServerをインストール・設定する。
    ユーザーPCには、SQLServer Management Studioをインストール・設定する。
  • 1かたまりの作業について1データベースとする
  • 処理の内容はSQL文を記述したテキストファイルで管理する。
  • 編集・集計の1ステップごとに、テーブルを作成する。
    ただし、小さな変更のステップがいくつかある場合などは、ビューを作成する。
  • ファイルのインポートはBULK INSERTで行う
    BULK INSERT (Transact-SQL) (bcpでも良い)
    http://msdn.microsoft.com/ja-jp/library/ms188365.aspx

テーブルの編集

テーブルの編集は、以下の方法で行う。変更・追加する項目が多い場合は1を推奨。

1.ALTER Tableで列を追加し、Update句で値を入力する
ALTER TABLE (Transact-SQL)
http://msdn.microsoft.com/ja-jp/library/ms190273.aspx#add
UPDATE (Transact-SQL)
http://msdn.microsoft.com/ja-jp/library/ms177523.aspx#UpdateExamples

2.ビューを作成し、Select [列定義] As [列名]を用いて項目を追加する
SQLServerではAccessと違い、Select文で定義した変数をそのSQL文内で使用できないので注意が必要

関数

テーブルの編集において複雑な変換などが必要な場合、以下のように関数を用いる。
簡単な場合は1、一定以上複雑な場合は2が良いかなぁ。。

1.CASE-WHEN文により条件分岐する
2.CLR関数を使用する。VB.NETもしくはC#で記述することが可能。
3.ユーザー定義関数(スカラー値関数)を使用する

出力

出力はsqlcmdで行う。
sqlcmd ユーティリティ
http://msdn.microsoft.com/ja-jp/library/ms162773.aspx
バッチファイルにsqlcmd文を記述して連続実行を行う。sqlcmdでは-vオプションで変数を指定することができるので、それを利用してSQL文を共通で利用することができる。

その他、Accessからの移行で注意する点

  • SQLServerは型について厳しい。数値型をそのまま結合して文字列にすることはできないため、型変換を適切に行う。
  • 文字列の結合は’+’で行う
  • 文字列は”で囲う。(Accessでは””)
  • 文字列から数値の変換…Convert([型名],[列名])を使う。
  • 数値から文字列の変換…Format([列名],[書式指定])が書式を指定できて便利。
  • Mid関数の代わりにSubstring関数を使う。LeftやRightは使用可能。
    IIF関数やFormat関数はSQL Server 2012以前では使用できないかも。

SQLServerその他メモ

書式設定

FORMAT (Transact-SQL)
http://msdn.microsoft.com/ja-jp/library/hh213505.aspx
標準の数値書式指定文字列
http://msdn.microsoft.com/ja-jp/library/dwhawy9k%28v=vs.100%29.aspx

型について

CASE-WHEN文による条件分岐

CASE-WHEN文による条件分岐は結構強力。
CASE (Transact-SQL)
http://msdn.microsoft.com/ja-jp/library/ms181765.aspx

参考書籍

SQL Server 2012の教科書 開発編
http://www.amazon.co.jp/dp/4883378403
Microsoft自習書 SQL Server 2012
http://www.microsoft.com/ja-jp/sqlserver/2012/technology/self-learning.aspx