Transcript n,x
最大マーキング問題を応用した
最適Binding-Time Analysis
数理第七研究室
村上 拓真
指導教官:胡 振江 助教授
発表の流れ
背景の紹介
Partial Evaluation
Binding-Time Analysis (BTA)
Maximum Marking Problem (MMP)
MMPの概要
効率的なアルゴリズム
MMPのBTAへの適用
まとめ
Partial Evaluationの役割
通常のプログラムの実行
Static
Input
Program
Dynamic
Input
Output
Partial Evaluationの役割 (cont.)
Partial Evaluationを使うと
Source
Program
Partial
Evaluator
Residual
Program
Residual
Program
Output
Static
Input
Dynamic
Input
Partial Evaluationの例
べき乗を計算するプログラム
3rd power of 5
3
Power
5
125
Partial Evaluationの例 (cont.)
Partial Evaluationを使うと
3乗するプログラム
Power
Partial
Evaluator
Residual
Program
Residual
Program
125
3
5
Partial Evaluationの例 (cont.)
実際のプログラム変換の様子
pow(n,x) {
if (n==0) then 1
else x * pow(n-1,x); }
n = 3 に固定する
pow3(x) {
x * x * x * 1; }
実際の応用例
プログラム最適化
汎用プログラム → 特殊化されたプログラム
例:将棋プログラム
汎用将棋プログラム
速度40%アップ
特殊化された将棋プログラム
(先手側でしか指せない)
実際の応用例 (cont.)
コンパイラの自動生成
インタプリタを使ってコンパイルする
インタプリタからコンパイラを作る
コンパイラ・コンパイラを作る
実際の応用例 (cont.)
FFTW (Fastest Fourier Transform in the West)
世界最高速クラスのフーリエ変換ライブラリ
インストール時にPartial Evaluation
汎用プログラムから実行環境にあわせた
最適プログラムを生成
高速性と移植性の両立
Partial Evaluationの方法
どの入力がStaticかを決める
Staticな入力だけで計算できる部分を調べる
Binding-Time Analysis
Staticな計算を行う
Dynamicな部分と組み合わせて結果を得る
Binding-Time Analysisとは?
Binding-Time: {Static, Dynamic}
変数とデータが“bind”されるタイミング
Static・・・
Partial Evaluationをする時
Dynamic・・・ Residual Programの実行時
入力のBinding-Time
プログラム全体のBiding-Time
Binding-Time Analysisの例
(n:Static, x:Dynamic)
pow(n,x) {
if (n==0) then 1;
else x * pow(n-1,x); }
Binding-Time Analysis (BTA)
pow(n,x) {
if (n==0) then 1;
else x * pow(n-1,x); }
Binding-Time Analysisの例 (cont.)
(n:Dynamic, x:Static)
pow(n,x) {
if (n==0) then 1;
else x * pow(n-1,x); }
Binding-Time Analysis (BTA)
pow(n,x) {
if (n==0) then 1;
else x * pow(n-1,x); }
Binding-Time Analysisの方法
いくつかの方法が提案されている
Abstract Interpretation
Constraint Solving
Type Inference
プログラムの「型」を利用する方式
プログラムの型
型・・・
型付け
G |- e:t
G ・・・
e ・・・
t ・・・
基本型(intなど)
関数型(int→intなど)
型環境({x:int,f:int→int,...})
式(x+f(y))
型(int)
型の推論規則
関数型の場合
仮定1
仮定2
G |- e1:t G |- e2:t
G |- e1 ( e2 ) :
結論
atoi:char* int
”5”:char*
⇒atoi(”5”):int
型の推論規則 (cont.)
if文の場合
仮定1
仮定2
仮定3
G |- e1:bool G |- e2:t G |- e3:t
G |- if e1 e2 e3:t
結論
if true
then 1
else “zero”
⇒型エラー
型推論と型チェック
型推論
G |- e:?
式の型を推論する
型チェック
G |- e:t ・・・?
式が指定された型であるかチェックする
型によるBTA
通常の型・・・ 基本型(intなど)
関数型(int→intなど)
型を拡張・・・ Staticデータの型(通常と同じ)
Dynamicデータの型(<int>など)
拡張された型の型推論 = BTA
型によるBTAの例
(n:Static, x:Dynamic)
pow(n,x) {
if (n==0) then 1;
else x * pow(n-1,x); }
Binding-Time Analysis (BTA)
pow(n,x) {
if (n==0) then 1;
else x * pow(n-1,x); }
推論規則に
よる制約
マークによる表現
pow(n,x) {
if (n==0) then 1;
else x * pow(n-1,x); }
型環境G
{n:int, x:<int>, pow’:int→<int>→<int>}
pow’(n,x) {
if (n==0) then <1>
else <~x * ~(pow’(n-1,x))>; }
BTAの付加する情報
型によるBTAの結果
元のプログラム+2種類のマーク
< >
~
・・・中身のDynamicに
・・・< >の効果を打ち消す
構文木
pow(n,x) {
if (n==0) then 1
else x * pow(n-1,x); }
if
=
n
1
*
0
x
pow
-
n
x
1
マーキングとしてのBTA
BTAの結果は、元の構文木+2種類のマーク
⇒木に対するマーキング問題
if
=
n
if
1
*
0
x
=
pow
n
n
1
*
0
x
x
1
pow’
-
赤:< >
青:~
n
x
1
マーキングとしてのBTA (cont.)
元のプログラム
if
if
=
if
=
n
1
n
*
0
x
n
1
*
0
x
x
1
n
n
1
*
0
x
pow’
-
pow’
-
=
pow’
-
x
n
x
1
1
型は正しいか?
より良いものは?
マーキングとしてのBTA (cont.)
どちらがより良いマーキングか?
if
=
n
if
1
*
0
x
=
pow’
-
赤:< >
青:~
n
n
1
*
0
x
x
1
pow’
-
n
x
1
BTAのまとめ
マーキング問題として解くことができる
2種類のマーク(< >、~)をつける
型チェックで正しいものだけを選ぶ
複数ある場合はできるだけ良いものを選ぶ
Maximum Marking Problem
Connected Tree Problem
連続したノードのうち、和が最大になるもの
-2
-2
5
-1
-1
-4
3
5
2
-1
-1
-4
3
2
1. 可能なマーキングをすべて列挙
2. 条件にあうものを取り出す
一般的な解法
3. 評価関数が最大になるものを選ぶ
(効率は悪い)
Maximum Marking Problem
一般的なマーキング問題を解くアルゴリズム
任意の再帰的データ型
任意の種類のマーク
ボトムアップな条件式
総和による評価関数
のマーキング問題を効率的に解く
効率のよいMMPのアルゴリズム
Maximum Marking Problemが
マークの種類
有限
条件式
ボトムアップ関数
評価関数
和
という条件を満たせば・・・
Optimization Theorem
Linear time algorithmが導出される
MMPのBTAへの適用
BTAのマーキングが
マークの種類
有限
条件式
ボトムアップ関数
評価関数
和
という条件を満たせば・・・
Optimization Theorem
Linear time algorithmが導出される
マークの種類
マークは< >、~の2種類
finite
Predicate
Predicateとして型チェックを用いる
構文木に関して再帰的に定義される
catamorphism
Predicate (cont.)
型チェックのCatamorphismによる記述
([ r ・fconst , rּ flambda , rּ fapp , rּ fcond ])
where fcond
r
= (conditional-case)
= (stage inference rule)
if
...
G |- e1:bool G |- e2:t G |- e3:t
G |- if e1 e2 e3:t
G |- <if e1 e2 e3> : <t>
e1
e2
Conditional-case
Bracket-case
e3
評価関数
Optimality of Solutions
マークごとに重みを与え、足しあわせる
マーク
重み
なし
<>
~
0
1
3
~はDynamicな計算を行う
評価関数 (cont.)
どちらがより良いマーキングか?
if
=
n
if
1
*
0
x
=
pow’
n
< >:1
~ :3
7
n
1
*
0
x
x
pow’
-
1
n
<
8
x
1
計算量
プログラム中の引数が最大(r-1)個とすると・・・
r
f: * * * *
f: * * <*> <*>
f: * <*> <*> <*>
f: * * <* *>
f: * <*> <* *>
...
O( (|Type| |Stage|)3 * |Mark| * n )
3r
= O( 2 n )
ソースプログラムを1度たどるだけで良い
O(2r)
アルゴリズムのまとめ
メリット
ソースプログラムのサイズに対してO(n)
一度に複数の型を解析できる
ステージ数の拡張が容易
デメリット
メモリの消費が多い
現在の評価関数は不十分
終わり
実際の応用例
繰り返し実験
f(x,y)を1 x 100、 1 y 100で計算
f(x,y)の計算
・・・5分
xについてPartial Evaluation ・・・10分
Residual Programの実行
・・・1分
5×100×100
=50000分
10×100+1×100×100 =11000分
構文木に対するマーク
Regarding Staging as Marking
if
=
n
if
1
*
0
x
=
pow’
n
Stage
Annotation
n
1
*
0
x
x
1
pow’
-
n
Mark
x
1
Division
Program Point + 変数のBinding-Time
int pow(int n,int x) { ...
(pow, ‘SD’)
Division (cont.)
(pow, ‘SD’)
int pow(int n,int x) {
if (n==0) return 1;
else return x * pow(n-1,x); }
(pow, ‘SD’)
int powSD(int n,int x) {
if (n==0) return 1;
else return x * powSD(n-1,x); }
Division (cont.)
int pp(int s,int d) {
if (d==0) return s;
else return pp(s,0); }
ppのdivisionは?
Monovariant Division
int pp(int s,int d) {
if (d==0) return s;
else return pp(s,0); }
Divisionを作る
(pp, ‘SD’)
Program Point : Binding-Time = 1 : 1
Monovariant Division (cont.)
int pp(int s,int d) {
if (d==0) return s;
else return pp(s,0); }
BTA
int ppSD(int s,int d) {
if (d==0) return s;
else return ppSD(s,0); }
Polyvariant Division
int pp(int s,int d) {
if (d==0) return s;
else return pp(s,0); }
Divisionを作る
(pp,{‘SD’,’SS’})
Program Point : Binding-Time = 1 : n
Polyvariant Division (cont.)
int pp(int s,int d) {
if (d==0) return s;
else return pp(s,0); }
BTA
int ppSD(int s,int d) {
if (d==0) return s;
else return ppSS(s,0); }
int ppSS(int s,int d) {
if (d==0) return s;
else return ppSS(s,0); }
Polyvariant Division (cont.)
int pp(int s,int d) {
if (d==0) return s;
else return pp(s,0); }
s=3でPartial Evaluation
int ppSD(int 3,int d) {
if (d==0) return 3;
else return ppSS(3,0); }
int ppSS(int 3,int 0) {
if (0==0) return 3;
else return ppSS(3,0); }
3
Polyvariant Division (cont.)
int pp(int s,int d) {
if (d==0) return s;
else return pp(s,0); }
s=3でPartial Evaluation
int ppSD(int 3,int d) {
if (d==0) return 3;
else return ppSS(3,0); }
int ppSS(int 3,int 0) {
if (0==0) return 3;
else return ppSS(3,0); }
3
3
Polyvariant Divisonの計算
f(x,y,z) のDivisionは・・・
‘SSS’
‘SSD’
‘SDS’
23
...
‘DDD’
関数fを23回解析!!
減らしたい
Partial Evaluationの簡単な例 (proc)
階乗関数
int pow (int n, int x) {
int i, result = 1;
for (i = 0; i < n; i++) result
*= x;
return result; }
n = 3 と固定する
int pow_3 (int x) { return x * x
r
f: * * * *
f: * * <*> <*>
f: * <*> <*> <*>
f: * * <* *>
f: * <*> <* *>
O(2r)
...
Online Partial Evaluation
Static Inputの値を利用できる
1-passのSpecialization
Source
Program
Online Partial
Evaluator
Static
Input
Residual
Program
Offline Partial Evaluation
Source
Program
Binding Time
Analysis (BTA)
Annotated
Program
Static
Input
Specializer
Division
(x:S, y:D)
Residual
Program
Offline Partial Evaluation (cont.)
2-pass (BTA + Specialization)
BTAではDivision (Static/Dynamicの区別)
のみしか分からない (値は分からない)
“cogen” Approach
cogen = COmpiler GENerator
Source
Program
Compiler
Generator
Generating
Extension
Generating
Extension
Residual
Program
Division
(x:S, y:D)
Static
Input
記法
in0
p
in1
を
out = [p][in0,in1]
と書く
out
Partial Evaluator pe
Partial Evaluationを行うプログラム pe
[[pe][p,in0]][in1]=[p][in0,in1]
を満たす
res = [pe][p,in0]
out = [res][in1]
= [[pe][p,in0]][in1]
= [p][in0,in1]
1st Futamura Projection
インタープリタを用いてコンパイルができる
out = [int][src,in]
= [[pe][int,src]]in
= [obj]in
obj = [pe][int,src]
2nd Futamura Projection
インタープリタからコンパイラを作る
Self-Applicationが必要
obj = [pe][int,src]
= [[pe][pe,int]]src
= [cmp]src
cmp = [pe][pe,int]
3rd Futamura Projection
コンパイラ・ジェネレータを作る
Self-Applicationが必要
cmp = [pe][pe,int]
= [[pe][pe,pe]]int
= [cogen]int
cogen = [pe][pe,pe]
Program Point
プログラム中の位置をProgram Pointと呼ぶ
たとえば
ブロック
関数名
ラベル名
など
(手続型言語)
(関数型言語)
(アセンブラ)
Specialized Program Point
Program Point + Static Value を記録
int pow (int n, int x) {
if (n == 0) return 1;
else
return x * pow(n-1, x); }
を(n=3)でPartial Evaluationすると...
Specialized Program Point (cont.)
int pow_3 (int x) { return x * pow_2(x); }
int pow_2 (int x) { return x * pow_1(x); }
int pow_1 (int x) { return x * pow_0(x); }
int pow_0 (int x) { return 1; }
という4つのSpecialized Program Pointになる。
Specialized Program Point (cont.)
int pow (int n, int x) {
if (n == 0) return 1;
else
return x * pow(n-1, x); }
を(x=3)でPartial Evaluationすると、
int pow_3 (int n) {
if (n == 0) return 1;
else
return 3 * pow_3(n-1); }
Unfolding
Program Pointを展開する
int pow_3 (int x) { return x * pow_2(x); }
int pow_2 (int x) { return x * pow_1(x); }
int pow_1 (int x) { return x * pow_0(x); }
int pow_0 (int x) { return 1; }
int pow_3 (int x) { return x * x * x * 1; }
Infinite Unfolding
Dynamic Conditional
int pow_3 (int n) {
if (n == 0) return 1;
else
return 3 * pow_3(n-1); }
infinite unfolding
Unfolding Strategies
Unfoldingをしない
Static callについてだけUnfoldする
引数がすべてStaticであるfunction call
Dynamic Conditionalの下にあるもの以外を
Unfoldする
Dynamic ConditionalをProgram Pointとすると
よさそう
Code Duplication
int triple (int n) { return n * n * n; }
int main () { ...... triple(d1 + d2) ...... }
Unfolding
int main () {
...... (d1 + d2) * (d1 + d2) * (d1 + d2) ...... }
Code (Computation) Duplication
Code Duplication (cont.)
int triple (int n) { return n * n * n; }
int main () { ...... triple(d1 + d2) ...... }
Unfolding
int main () { int d3 = (d1 + d2);
...... d3 * d3 * d3 ...... }
関数型でのlet-insertionにあたる
pow n x = if n == 0 then 1
else x * pow (n-1) x
Program Point
pp1 s d = if d == 0 then s
else pp2 s 0
ProgramPoint Division
pp1
pp2
発表の流れ
Partial Evaluationの紹介
Binding-Time Analysisの紹介
今回のアルゴリズムの概要
Maximum Marking Problemの紹介
アルゴリズムの詳細
アルゴリズムの計算量
まとめと課題
Partial Evaluationとは
プログラムへの入力のうち、すでに分かって
いるものだけを使ってプログラムをある程度
実行する
[pin1][in2] = [p][in1,in2]
pよりも高速に実行できるpin1を作り出したい
Partial Evaluator
Partial Evaluationを行うプログラム pe
[pe][p,in1] = pin1
[[pe][p,in1]][in2]
= [pin1][in2]
= [p][in1,in2]
Partial Evaluationの例
インタプリタからコンパイラを作る
コンパイラの入力 —データ
インタプリタの入力 —プログラムとデータ
pgm = [pe][int,src]
[pgm][dat] =[[pe][int,src]][dat]
=[int][src,dat]
•€
][¶ωΫке۴۷طضصشسੜ
[[
《〔}「》[
Staging Problem
n-th power of x
pow’ n x
pow n x
if
if
=
n
=
1
0
*
x
n
ap
ap
pow
x
0
<>
<>
1
*
~
~
x
ap
n
ap
1
int <int> <int>
pow’
x
-
n
1
Search-Based Algorithm [SL02]
if
=
n
0
if
<>
<>
<>
<>
<>
1
*
=
1
*
x
~
n
0
x
~
ap
ap
pow’
ap
x
n
ap
pow’
1
: int int <int>
n
: type error
x
1
Search-Based Algorithm (cont.)
Search Space: Stage Annotated Tree
Pruning: Type Information
Based on Heuristics
Unclear Points
Computation Complexity
Optimality of Solution
What is the “optimal” solution?
Pruning may cut off the optimal solution
Our Algorithm
Regarding Staging as Marking
if
=
n
if
<>
<>
1
*
0
=
n
~
~
x
ap
ap
Stage
Annotation
pow’
1
0
*
x
ap
pow’
1
Mark
x
-
n
x
-
n
ap
1
Our Algorithm (cont.)
Original Tree
if
if
=
if
=
n
n
1
0
=
1
0
x
*
x
ap
pow’
x
x
ap
x
pow’
x
n
n
ap
1
1
Which is valid?
n
0
*
ap
ap
ap
pow’
n
*
1
1
Which is better?
Maximum Marking Problem [Sas02]
Select connected
elements
-2
5
-1
-1
-4
3
-2
5
2
-1
-1
-4
3
2
1. Generate Possible Markings
2. Select Valid Markings
3. Maximize Weights of Markings
General Algorithm
Maximum Marking Problem (cont.)
General Algorithm
Marks
finite
Predicate
finite catamorphism
Weight Function catamorphism
Optimization Theorem
Linear algorithm
Maximum Marking Problem (cont.)
Solve Staging by using MMP algorithm
MMP
Our Staging
Marks
Predicate
Weight Function
{None, <>, ~, lift}
Type Judgment
Sum of Weights of Marks
Optimization Theorem automatically derives
Linear algorithm
Type Judgment
Validity of Solutions
G |-s e1:t G |-s e2:t
G |-s e1 e2:
t
Induction – Catamorphism
Type Space is Finite
t
Weight Function
Optimality of Solutions
Summing up all weights of marks
Mark
Weight
None
<>
lift
~
0
1
2
3
no mark
dynamic
static dynamic
static
Weight Function (cont.)
if
=
n
if
1
0
*
x
=
ap
ap
None
<>
lift
~
0
1
2
3
Weight
pow’
0
*
x
x
ap
ap
n
7
n
1
pow’
1
n
<
9
x
1
Efficiency
r
f: * * * *
f: * * <*> <*>
f: * <*> <*> <*>
f: * * <* *>
f: * <*> <* *>
...
O( (|Type| |Stage|)3 * |Mark| * n )
r
= O( 2 n )
Linear under fixed type space
O(2r)
Polyvariance
pow1:int int <int>
pow:int int int
pow2:int <int> <int>
pow3:int <int int>
...
Dynamic Programming – Memoization
Once Staging, All Stagings are Solved
Multi-Staging
Easy Extension
Stage = {0,1}
|Stage| must be finite
Stage = {0,1,2,3,...}
Extension of Marks
<<x>>, lift(~x), ...
Higher Order Functions
Staging could be nested
f: * * * *
***
Nested
Staging
* * <*>
* <*> <*>
* <* *>
<*> <* *>
...
Inter-Procedural Weight Function
Better Optimality
Size of subtree
?
Conclusion
Solve Staging as Marking Problem
Efficient Algorithm
Explicit Definition of Optimality
Current Work
Improvement of Weight Function
The End
Thank you for listening.
Working Slide
l
l
n
x
if
=
n
*
1
0
x
ap
ap
x
-
pow
n
1
Working Slide 2
l
l
n
x
if
=
n
if
*
1
0
=
x
n
ap
ap
n
0
x
ap
ap
x
1
x
-
pow
-
pow
*
1
n
1
BTA on MetaML
Static constructs: normal ML expressions
3 + 5 : int
Dynamic constructs: meta-brackets
<3+5> : <int>
Dynamic computations: escape
< ~x + ~y > : <int>
Key Point
Type system has binding time information
Type inference infers not only types but also
binding time information
Search-based Staging (1)
Tim Sheard & Nathan Linger : ASIA-PEPM’02
Input:source program, desirable staged type
fun pow n x = if n=0 then 1
else x*pow (n-1) x;
pow1 at int -> <int> -> <int>
Output:MetaML program of specified type
fun pow1 n x = if n = 0 then <1>
else < ~x * ~(pow1 (n-1) x) >;
Search-based Staging (2)
Searching by heuristics
Problems remained:
Computation complexity estimation
Optimality of solutions
Staging as Marking
Original syntax tree + new nodes
Original syntax tree + marks
Multi-Marking Problem
Linear Algorithm by Isao Sasano et al.
Mark whole tree and type check
Type check with constructing tree
○
○
×
×
△
○
Syntax Tree
λx=>if x then x else not x
4 kinds of nodes
λ
x
•Constant, Variable
if
x
x
•λabstraction
ap
•application
not
x
•if expression
Staged Type Checking
Original Node
I
I: int
(conditional)
B
I
B: bool
I
Staging by Marking
<I>
<I>
<>
<>
<>
error
<>
<>
Time Complexity
r
r
f:
*
*
|Type| = O(2 )
*
*
O( (|Type| |Stage|)3 * |Mark| * n )
r
= O( 2 n )
Linear under fixed type space
Optimality
Summing up weights of marks
M a rk
W e ig h t
N one
0
N o m a rk
B ra
1
<>
E sc
3
~
L ift
2
lift
Working Example
Our System:
stage pow’ = pow at int -> <int -> int>
fn n => <fn x =>
~(if (n=0) then lift 1
else <x*(~(pow’ (n-1)) x)>)>
MetaML:
pow’ 3 => <(fn a => a * a * a * 1)>
Future work
escape performs syntactic substitution:
not evaluation
f n =
<if ~n = 0 then 0
else ~(f <~n - 1>)>
escape: sometimes causes infinite
unfolding
run:
always does 1-level unfolding
Example 5: Connected tree problem
Select connected
elements
-2
5
-1
-1
-4
3
-2
5
2
-1
-1
-4
3
maximize the sum of selected elements
O(2^n)
O(n)
2