SlideShare una empresa de Scribd logo
1 de 17
桜庭 俊 @ 京大 誰得 Twitter: @chunjp FFTW/genfftハッキングガイドThe hitchhacker’s guide to FFTW/genfft
FFTWて何 MIT で開発されたFFT(高速フーリエ変換)のライブラリ 開発: MatteoFrigo & Steven G. Johnson その名も…… The Fastest Fourier Transform in the West (西洋最速のフーリエ変換)
ここが凄い Pen4, 2.8GHz Alpha, 833MHz 全てのCPUでベンダー提供のライブラリと拮抗(時に凌駕)するパフォーマンスを提供 From Proc. IEEE 93 (2), 216–231 (2005)
支えているのはOCaml! FFT専用コンパイラ “genfft” let reccooley_tukey sign n1 n2 input = let tmp1 =        array n2 (fun i2 ->  dft sign n1 (fun i1 -> input (i1 * n2 + i2))) in let tmp2 =         array n1 (fun i1 -> 	array n2 (fun i2 -> 	  exp n (sign * i1 * i2) @* tmp1 i2 i1)) in let tmp3 = array n1 (fun i1 -> dft sign n2 (tmp2 i1)) in     (funi -> tmp3 (imod n1) (i / n1)) 固定サイズの問題に対し 機械生成されたCコードを出力
生成コードの例 static void n1_5(const R *ri, const R *ii, R *ro, R *io, stride is, stride os, INT v, INT ivs, INT ovs) { … 	       { 		    E T2, T3, T5, T6; 		    T2 = ri[WS(is, 1)]; 		    T3 = ri[WS(is, 4)]; 		    T5 = ri[WS(is, 2)]; 		    T6 = ri[WS(is, 3)]; 		    { 			 E Tc, T4, T7, Td, Tf, Tg; Tc = ii[WS(is, 1)]; 			 Ts = T2 - T3; 			 T4 = T2 + T3; Tt = T5 - T6; 			 T7 = T5 + T6; 			 Td = ii[WS(is, 4)]; Tf = ii[WS(is, 2)];
今日のお題:genfftで遊ぶ なぜ遊ぶのか? そこにコンパイラがあるからだ! こんな時におすすめ! 金曜の夜に上司から「人生、宇宙すべての答えを月曜までに計算しておいて」と命令されたとき 卒論のアブストで広げてしまった風呂敷をたたむために高速な数値計算カーネルが必要なとき TopCoder Marathonや現実逃避のお供に
genfft構造 and dft sign n input =   let reccooley_tukey sign n1 n2 input =     let tmp1 =        array n2 (fun i2 ->  dft sign n1 (fun i1 -> input (i1 * n2 + i2))) in     let tmp2 = ..  0.0 * a + b b a+b 2a+2b 2a+2b a a b b 1 2 V T4, T5, Te, Tf, T7, T8; T4 = LD(&(xi[WS(is, 2)]), ivs, &(xi[0])); T5 = LD(&(xi[WS(is, 7)]), ivs, &(xi[WS(is, 1)])); Te = LD(&(xi[WS(is, 6)]), ivs, &(xi[0]));
命令セット(抜粋) type expr =   | Num of Number.number   | Plus of expr list   | Times of expr * expr   | Uminus of expr   | Load of Variable.variable   | Store of Variable.variable * expr Ifもloopも無い! 実際にはこれを直接書くことは少なく、もっぱらmodule Complexのval(@*) : expr -> expr -> expr val (@+) : expr -> expr -> expr val (@-) : expr -> expr -> exprなどを使う
fibを作る q0, q1, q0+q1, q1+(q0+q1), (q0+q1)+(q1+(q0+q1)), …   let q = load_array_c 2 input in let rec output =     function         0 -> q 0       | 1 -> q 1       | i -> output (i-1) @+ output (i-2)   in  (* 中略 *)  let odag = store_array_r n oloc output in   let annot = standard_optimizerodag in  let tree = Fcn (* 中略 *) ([Asch annot]))) in print_string (unparse tree ^ "") LoopはOcaml側で書く Complex.(@+)を利用 自動で最適化をしてくれる魔法の言葉 実態は最適化関数群を@@で繋いだもの C.unparse : C言語出力!
出力 /*  * This function contains 8 FP additions, 13 FP multiplications,  * (or, 1 additions, 6 multiplications, 7 fused multiply/add),  * 9 stack variables, 7 constants, and 12 memory accesses  */ void fib(const R * I, R * O) { DK(KP3_00000, +3.0000); DK(KP8_00000, +8.0000); DK(KP5_00000, +5.0000); DK(KP13_00000, +13.0000); DK(KP2_00000, +2.0000); DK(KP34_00000, +34.0000); DK(KP21_00000, +21.0000); { E T1; E T2; T1 = I[0]; T2 = I[1]; O[0] = T1; O[1] = T2; O[2] = T1 + T2; O[9] = FMA(KP21_00000, T1, KP34_00000 * T2); O[3] = FMA(KP2_00000, T2, T1); O[8] = FMA(KP13_00000, T1, KP21_00000 * T2); O[6] = FMA(KP5_00000, T1, KP8_00000 * T2); O[4] = FMA(KP2_00000, T1, KP3_00000 * T2); O[7] = FMA(KP8_00000, T1, KP13_00000 * T2); O[5] = FMA(KP3_00000, T1, KP5_00000 * T2); } } FMA=Fused Multiply-Add: ax+b型計算
まとめ FFTWのgenfftはソースの公開された数値計算用のミニコンパイラ ソースサイズが小さく、追跡が容易 いろいろな部分が差し替え可能 興味を持ったら触ってみてね!
以下、予備スライド
MinCamlやLLVMとの違い FFTWはFFTに特化 いくつかの特殊で危険な式簡略化を実装 oracle.mlなど 丸め誤差程度しか違わない数字はマージしてしまう アグレッシブに符号反転した定数を処理
遊び方提案 c.mlを参考にllvm.ml, java.ml, cuda.mlを作成 DWTなどを実装 あなたのタスクに最適なSchedulerを設計 微妙に作りかけで放置されているConvolution kernelを作る その他あなたの好きな計算を
みどころ (* I will regret this hack : *) (* NEWS: I did *)
ソースを読む上での注意点 Spotter又は-annotate / -dtypes必須 常に汝の横にPLDI’99を置け arrayはUtil.arrayで作成されint -> expr型 exprの表す数値は全てcomplex

Más contenido relacionado

La actualidad más candente

条件分岐とcmovとmaxps
条件分岐とcmovとmaxps条件分岐とcmovとmaxps
条件分岐とcmovとmaxps
MITSUNARI Shigeo
 
YATT::Lite - PSGI を直接サポートしたテンプレートエンジン at #plackcon
YATT::Lite - PSGI を直接サポートしたテンプレートエンジン at #plackconYATT::Lite - PSGI を直接サポートしたテンプレートエンジン at #plackcon
YATT::Lite - PSGI を直接サポートしたテンプレートエンジン at #plackcon
Hiroaki KOBAYASHI
 
20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン
yohhoy
 
関東GPGPU勉強会 LLVM meets GPU
関東GPGPU勉強会 LLVM meets GPU関東GPGPU勉強会 LLVM meets GPU
関東GPGPU勉強会 LLVM meets GPU
Takuro Iizuka
 
Wrapping a C++ library with Cython
Wrapping a C++ library with CythonWrapping a C++ library with Cython
Wrapping a C++ library with Cython
fuzzysphere
 
Continuation with Boost.Context
Continuation with Boost.ContextContinuation with Boost.Context
Continuation with Boost.Context
Akira Takahashi
 
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
Takeshi Yamamuro
 

La actualidad más candente (20)

V6でJIT・部分適用・継続
V6でJIT・部分適用・継続V6でJIT・部分適用・継続
V6でJIT・部分適用・継続
 
準同型暗号の実装とMontgomery, Karatsuba, FFT の性能
準同型暗号の実装とMontgomery, Karatsuba, FFT の性能準同型暗号の実装とMontgomery, Karatsuba, FFT の性能
準同型暗号の実装とMontgomery, Karatsuba, FFT の性能
 
コルーチンの使い方
コルーチンの使い方コルーチンの使い方
コルーチンの使い方
 
条件分岐とcmovとmaxps
条件分岐とcmovとmaxps条件分岐とcmovとmaxps
条件分岐とcmovとmaxps
 
YATT::Lite - PSGI を直接サポートしたテンプレートエンジン at #plackcon
YATT::Lite - PSGI を直接サポートしたテンプレートエンジン at #plackconYATT::Lite - PSGI を直接サポートしたテンプレートエンジン at #plackcon
YATT::Lite - PSGI を直接サポートしたテンプレートエンジン at #plackcon
 
フラグを愛でる
フラグを愛でるフラグを愛でる
フラグを愛でる
 
SSE4.2の文字列処理命令の紹介
SSE4.2の文字列処理命令の紹介SSE4.2の文字列処理命令の紹介
SSE4.2の文字列処理命令の紹介
 
20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン
 
Cython ことはじめ
Cython ことはじめCython ことはじめ
Cython ことはじめ
 
NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門
 
RubyKaigi2014: Just in Time compiler for CRuby
RubyKaigi2014: Just in Time compiler for CRubyRubyKaigi2014: Just in Time compiler for CRuby
RubyKaigi2014: Just in Time compiler for CRuby
 
関東GPGPU勉強会 LLVM meets GPU
関東GPGPU勉強会 LLVM meets GPU関東GPGPU勉強会 LLVM meets GPU
関東GPGPU勉強会 LLVM meets GPU
 
Wrapping a C++ library with Cython
Wrapping a C++ library with CythonWrapping a C++ library with Cython
Wrapping a C++ library with Cython
 
Cython intro prelerease
Cython intro prelereaseCython intro prelerease
Cython intro prelerease
 
llvm入門
llvm入門llvm入門
llvm入門
 
optimal Ate pairing
optimal Ate pairingoptimal Ate pairing
optimal Ate pairing
 
Continuation with Boost.Context
Continuation with Boost.ContextContinuation with Boost.Context
Continuation with Boost.Context
 
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
 
Rの高速化
Rの高速化Rの高速化
Rの高速化
 
プログラムを高速化する話
プログラムを高速化する話プログラムを高速化する話
プログラムを高速化する話
 

Destacado

OCamlでWebアプリケーションを作るn個の方法
OCamlでWebアプリケーションを作るn個の方法OCamlでWebアプリケーションを作るn個の方法
OCamlでWebアプリケーションを作るn個の方法
Hiroki Mizuno
 
Haskell Day2012 - 参照透過性とは何だったのか
Haskell Day2012 - 参照透過性とは何だったのかHaskell Day2012 - 参照透過性とは何だったのか
Haskell Day2012 - 参照透過性とは何だったのか
Kousuke Ruichi
 

Destacado (9)

64-bit SML# への壁
64-bit SML# への壁64-bit SML# への壁
64-bit SML# への壁
 
GLT#13 Naruhiko Ogasawara
GLT#13 Naruhiko OgasawaraGLT#13 Naruhiko Ogasawara
GLT#13 Naruhiko Ogasawara
 
プログラミングの基礎振り返りスライド1
プログラミングの基礎振り返りスライド1プログラミングの基礎振り返りスライド1
プログラミングの基礎振り返りスライド1
 
たのしい関数型
たのしい関数型たのしい関数型
たのしい関数型
 
OCamlでWebアプリケーションを作るn個の方法
OCamlでWebアプリケーションを作るn個の方法OCamlでWebアプリケーションを作るn個の方法
OCamlでWebアプリケーションを作るn個の方法
 
Haskell超入門 Part.1
Haskell超入門 Part.1Haskell超入門 Part.1
Haskell超入門 Part.1
 
Haskell Day2012 - 参照透過性とは何だったのか
Haskell Day2012 - 参照透過性とは何だったのかHaskell Day2012 - 参照透過性とは何だったのか
Haskell Day2012 - 参照透過性とは何だったのか
 
関数型プログラミング入門 with OCaml
関数型プログラミング入門 with OCaml関数型プログラミング入門 with OCaml
関数型プログラミング入門 with OCaml
 
磯野ー!関数型言語やろうぜー!
磯野ー!関数型言語やろうぜー!磯野ー!関数型言語やろうぜー!
磯野ー!関数型言語やろうぜー!
 

Similar a Fftw誰得ガイド

Can A Python Go Beyond The Python
Can A Python Go Beyond The PythonCan A Python Go Beyond The Python
Can A Python Go Beyond The Python
Yusuke Muraoka
 
HaskellではじめるCortex-M3組込みプログラミング
HaskellではじめるCortex-M3組込みプログラミングHaskellではじめるCortex-M3組込みプログラミング
HaskellではじめるCortex-M3組込みプログラミング
Kiwamu Okabe
 

Similar a Fftw誰得ガイド (20)

PBL1-v1-009j.pptx
PBL1-v1-009j.pptxPBL1-v1-009j.pptx
PBL1-v1-009j.pptx
 
HPC Phys-20201203
HPC Phys-20201203HPC Phys-20201203
HPC Phys-20201203
 
Intro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみたIntro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみた
 
x86とコンテキストスイッチ
x86とコンテキストスイッチx86とコンテキストスイッチ
x86とコンテキストスイッチ
 
テーマ「最適化 その2」
テーマ「最適化 その2」テーマ「最適化 その2」
テーマ「最適化 その2」
 
ラズパイでデバイスドライバを作ってみた。
ラズパイでデバイスドライバを作ってみた。ラズパイでデバイスドライバを作ってみた。
ラズパイでデバイスドライバを作ってみた。
 
テーマ「最適化」
テーマ「最適化」テーマ「最適化」
テーマ「最適化」
 
会津合宿2015Day3:D問題
会津合宿2015Day3:D問題会津合宿2015Day3:D問題
会津合宿2015Day3:D問題
 
Can A Python Go Beyond The Python
Can A Python Go Beyond The PythonCan A Python Go Beyond The Python
Can A Python Go Beyond The Python
 
Chainerの使い方と自然言語処理への応用
Chainerの使い方と自然言語処理への応用Chainerの使い方と自然言語処理への応用
Chainerの使い方と自然言語処理への応用
 
Yaminabe fortran
Yaminabe fortranYaminabe fortran
Yaminabe fortran
 
CMSI計算科学技術特論C (2015) feram と強誘電体②
CMSI計算科学技術特論C (2015)  feram と強誘電体②CMSI計算科学技術特論C (2015)  feram と強誘電体②
CMSI計算科学技術特論C (2015) feram と強誘電体②
 
Slide
SlideSlide
Slide
 
非静力学海洋モデルkinacoのGPUによる高速化
非静力学海洋モデルkinacoのGPUによる高速化非静力学海洋モデルkinacoのGPUによる高速化
非静力学海洋モデルkinacoのGPUによる高速化
 
Spmv9forpublic
Spmv9forpublicSpmv9forpublic
Spmv9forpublic
 
What is Metasepi?
What is Metasepi?What is Metasepi?
What is Metasepi?
 
マスターオブゴールーチンアンドチャネル スタートGo #1
マスターオブゴールーチンアンドチャネル   スタートGo #1マスターオブゴールーチンアンドチャネル   スタートGo #1
マスターオブゴールーチンアンドチャネル スタートGo #1
 
PBL1-v1-010j.pptx
PBL1-v1-010j.pptxPBL1-v1-010j.pptx
PBL1-v1-010j.pptx
 
Python physicalcomputing
Python physicalcomputingPython physicalcomputing
Python physicalcomputing
 
HaskellではじめるCortex-M3組込みプログラミング
HaskellではじめるCortex-M3組込みプログラミングHaskellではじめるCortex-M3組込みプログラミング
HaskellではじめるCortex-M3組込みプログラミング
 

Fftw誰得ガイド

  • 1. 桜庭 俊 @ 京大 誰得 Twitter: @chunjp FFTW/genfftハッキングガイドThe hitchhacker’s guide to FFTW/genfft
  • 2. FFTWて何 MIT で開発されたFFT(高速フーリエ変換)のライブラリ 開発: MatteoFrigo & Steven G. Johnson その名も…… The Fastest Fourier Transform in the West (西洋最速のフーリエ変換)
  • 3. ここが凄い Pen4, 2.8GHz Alpha, 833MHz 全てのCPUでベンダー提供のライブラリと拮抗(時に凌駕)するパフォーマンスを提供 From Proc. IEEE 93 (2), 216–231 (2005)
  • 4. 支えているのはOCaml! FFT専用コンパイラ “genfft” let reccooley_tukey sign n1 n2 input = let tmp1 = array n2 (fun i2 -> dft sign n1 (fun i1 -> input (i1 * n2 + i2))) in let tmp2 = array n1 (fun i1 -> array n2 (fun i2 -> exp n (sign * i1 * i2) @* tmp1 i2 i1)) in let tmp3 = array n1 (fun i1 -> dft sign n2 (tmp2 i1)) in (funi -> tmp3 (imod n1) (i / n1)) 固定サイズの問題に対し 機械生成されたCコードを出力
  • 5. 生成コードの例 static void n1_5(const R *ri, const R *ii, R *ro, R *io, stride is, stride os, INT v, INT ivs, INT ovs) { … { E T2, T3, T5, T6; T2 = ri[WS(is, 1)]; T3 = ri[WS(is, 4)]; T5 = ri[WS(is, 2)]; T6 = ri[WS(is, 3)]; { E Tc, T4, T7, Td, Tf, Tg; Tc = ii[WS(is, 1)]; Ts = T2 - T3; T4 = T2 + T3; Tt = T5 - T6; T7 = T5 + T6; Td = ii[WS(is, 4)]; Tf = ii[WS(is, 2)];
  • 6. 今日のお題:genfftで遊ぶ なぜ遊ぶのか? そこにコンパイラがあるからだ! こんな時におすすめ! 金曜の夜に上司から「人生、宇宙すべての答えを月曜までに計算しておいて」と命令されたとき 卒論のアブストで広げてしまった風呂敷をたたむために高速な数値計算カーネルが必要なとき TopCoder Marathonや現実逃避のお供に
  • 7. genfft構造 and dft sign n input = let reccooley_tukey sign n1 n2 input = let tmp1 = array n2 (fun i2 -> dft sign n1 (fun i1 -> input (i1 * n2 + i2))) in let tmp2 = .. 0.0 * a + b b a+b 2a+2b 2a+2b a a b b 1 2 V T4, T5, Te, Tf, T7, T8; T4 = LD(&(xi[WS(is, 2)]), ivs, &(xi[0])); T5 = LD(&(xi[WS(is, 7)]), ivs, &(xi[WS(is, 1)])); Te = LD(&(xi[WS(is, 6)]), ivs, &(xi[0]));
  • 8. 命令セット(抜粋) type expr = | Num of Number.number | Plus of expr list | Times of expr * expr | Uminus of expr | Load of Variable.variable | Store of Variable.variable * expr Ifもloopも無い! 実際にはこれを直接書くことは少なく、もっぱらmodule Complexのval(@*) : expr -> expr -> expr val (@+) : expr -> expr -> expr val (@-) : expr -> expr -> exprなどを使う
  • 9. fibを作る q0, q1, q0+q1, q1+(q0+q1), (q0+q1)+(q1+(q0+q1)), … let q = load_array_c 2 input in let rec output = function 0 -> q 0 | 1 -> q 1 | i -> output (i-1) @+ output (i-2) in (* 中略 *) let odag = store_array_r n oloc output in let annot = standard_optimizerodag in let tree = Fcn (* 中略 *) ([Asch annot]))) in print_string (unparse tree ^ "") LoopはOcaml側で書く Complex.(@+)を利用 自動で最適化をしてくれる魔法の言葉 実態は最適化関数群を@@で繋いだもの C.unparse : C言語出力!
  • 10. 出力 /* * This function contains 8 FP additions, 13 FP multiplications, * (or, 1 additions, 6 multiplications, 7 fused multiply/add), * 9 stack variables, 7 constants, and 12 memory accesses */ void fib(const R * I, R * O) { DK(KP3_00000, +3.0000); DK(KP8_00000, +8.0000); DK(KP5_00000, +5.0000); DK(KP13_00000, +13.0000); DK(KP2_00000, +2.0000); DK(KP34_00000, +34.0000); DK(KP21_00000, +21.0000); { E T1; E T2; T1 = I[0]; T2 = I[1]; O[0] = T1; O[1] = T2; O[2] = T1 + T2; O[9] = FMA(KP21_00000, T1, KP34_00000 * T2); O[3] = FMA(KP2_00000, T2, T1); O[8] = FMA(KP13_00000, T1, KP21_00000 * T2); O[6] = FMA(KP5_00000, T1, KP8_00000 * T2); O[4] = FMA(KP2_00000, T1, KP3_00000 * T2); O[7] = FMA(KP8_00000, T1, KP13_00000 * T2); O[5] = FMA(KP3_00000, T1, KP5_00000 * T2); } } FMA=Fused Multiply-Add: ax+b型計算
  • 12.
  • 14. MinCamlやLLVMとの違い FFTWはFFTに特化 いくつかの特殊で危険な式簡略化を実装 oracle.mlなど 丸め誤差程度しか違わない数字はマージしてしまう アグレッシブに符号反転した定数を処理
  • 15. 遊び方提案 c.mlを参考にllvm.ml, java.ml, cuda.mlを作成 DWTなどを実装 あなたのタスクに最適なSchedulerを設計 微妙に作りかけで放置されているConvolution kernelを作る その他あなたの好きな計算を
  • 16. みどころ (* I will regret this hack : *) (* NEWS: I did *)
  • 17. ソースを読む上での注意点 Spotter又は-annotate / -dtypes必須 常に汝の横にPLDI’99を置け arrayはUtil.arrayで作成されint -> expr型 exprの表す数値は全てcomplex