すべてをRacketに取り込もう! ~Racket FFI と Package システムの使い方~

2,337 views
2,112 views

Published on

すべてをRacketに取り込もう! ~Racket FFI と Package システムの使い方~
Lisp Meet Up presented by Shibuya.lisp #14 発表資料

Published in: Technology
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,337
On SlideShare
0
From Embeds
0
Number of Embeds
465
Actions
Shares
0
Downloads
4
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

すべてをRacketに取り込もう! ~Racket FFI と Package システムの使い方~

  1. 1. すべてを Racket に取り込もう! ∼Racket FFI と Package システムの使い方∼ 菱沼 和弘 (@kazh98) 明治大学理工学部情報科学科 数理最適化研究室 URL: http://www.mo.cs.meiji.ac.jp/kaz/ K. Hishinuma すべてを Racket に取り込もう! 1 / 35
  2. 2. Let’s Introduction 数学徒の苦悩 マスハラという言葉を ご存知ですか? K. Hishinuma すべてを Racket に取り込もう! 2 / 35
  3. 3. Let’s Introduction [複名/U] マスハラ (mathematical harassment) U : 数学徒, V ⊂ U : 精神的苦痛を感じている数学徒, T : U → U, 数学的を用いた言動. T がマスハラである. ⇐⇒ ∃x ∈ U : T x ∈ V. def ※このスライドもマスハラかもしれない K. Hishinuma すべてを Racket に取り込もう! 3 / 35
  4. 4. Let’s Introduction 例. 水面上のマスハラ 「ちょっとそれ証明してよ」 「本当にそれ定義から言えるの?」 「・・・(板書への無言の視線)」 K. Hishinuma すべてを Racket に取り込もう! 4 / 35
  5. 5. Let’s Introduction しかし! CS系数学徒には、 知られざる水面下のマスハラ もあるのです!!! K. Hishinuma すべてを Racket に取り込もう! 5 / 35
  6. 6. Let’s Introduction 例. 水面下のマスハラ 「数値計算なら FORTRAN 使わなきゃ」 「FORTRAN に良いライブラリがあるよ∼」 README: Available for Fortran77 K. Hishinuma すべてを Racket に取り込もう! 6 / 35
  7. 7. Let’s Introduction FORTRAN 地獄 いつまでそんな太古の言語を 使っているんだ!! K. Hishinuma すべてを Racket に取り込もう! 7 / 35
  8. 8. Let’s Introduction 備考 Fortran (1957–) Lisp (1958–) ……やばい、そんなに違いない K. Hishinuma すべてを Racket に取り込もう! 8 / 35
  9. 9. Let’s Introduction ということで、 /////////////// 過去の遺産人類の叡智を、 1 年未来の言語から 呼びだそう!! Lisp で書くことに 幸せを感じる人間もいるのです K. Hishinuma すべてを Racket に取り込もう! 9 / 35
  10. 10. Racket Foreign Interface Racket FFI C 言語向けのライブラリを Racket から叩ける機能。 base パッケージにより標準提供。 FFI 機能の利用 (require ffi/unsafe ffi/unsafe/define) (require ffi/vector) ; 配列型を扱う場合 K. Hishinuma すべてを Racket に取り込もう! 10 / 35
  11. 11. Racket Foreign Interface ということは? FORTRAN ライブラリ → C インターフェイス → Racket FFI で、Racket から呼び出せる!!! K. Hishinuma すべてを Racket に取り込もう! 11 / 35
  12. 12. Racket Foreign Interface BLAS の Racket インターフェイスを書いてみた 成果物は、Github: https://github.com/kazh98/blas で公開しています。 ※ Lv1 呼び出しのみ完成 K. Hishinuma すべてを Racket に取り込もう! 12 / 35
  13. 13. Racket Foreign Interface ライブラリのロード ライブラリのロードには、ffi-lib 関数を用いる。 ffi-lib 関数 (ffi-lib ライブラリ名 #:fail 失敗時手続き) ライブラリ名 ロードするライブラリの名前 (e.g. libc) 失敗時手続き ロード失敗時に呼び出される thunk 戻り値 FFI オブジェクトを返す。 これを define-ffi-definer 構文で捕捉すると、 FFI 定義子が手に入る。 K. Hishinuma すべてを Racket に取り込もう! 13 / 35
  14. 14. Racket Foreign Interface 例. ライブラリのロード (define-ffi-definer define-cblas (ffi-lib libcblas #:fail (lambda () (ffi-lib libgslcblas)))) ライブラリ名 libcblas,libgslcblas を順に探す。 以後、define-cblas 構文が、FFI 定義子となる。 K. Hishinuma すべてを Racket に取り込もう! 14 / 35
  15. 15. Racket Foreign Interface インターフェイス定義 FFI 定義子 define-cblas を使って、 ライブラリ関数へのインターフェイスを定義する。 C 言語のプロトタイプ宣言に相当。 define-cblas 構文 (define-cblas 名前 型) 名前 ライブラリからインターフェイスを張る関数名 型 ライブラリから張られる関数の型 (_fun 引数型 1 引数型 2 ... - 戻り値型) K. Hishinuma すべてを Racket に取り込もう! 15 / 35
  16. 16. Racket Foreign Interface インターフェイス定義型 C 言語 int unsigned int double size_t intptr_t void* char* Racket _int _uint _double* _size _intptr _pointer _string C 言語 int32_t* int64_t* double* Racket _s32vector _s64vector _f64vector 呼び出し時には、スカラ型は対応する Racket の値を、 配列型は対応する SRFI-4 のベクタを用いればよい。 K. Hishinuma すべてを Racket に取り込もう! 16 / 35
  17. 17. Racket Foreign Interface 例. インターフェイス定義 言語プロトタイプ宣言 (cblas.h) C double cblas_dnrm2(const int N, const double *X, const int incX); ↓ Racket インターフェイス定義 (define-cblas cblas_dnrm2 (_fun _int _f64vector _int - _double)) これで、cblas_dnrm2 が普通の関数同様に呼び出せる。 K. Hishinuma すべてを Racket に取り込もう! 17 / 35
  18. 18. Racket Foreign Interface FFI 完成 (require math/cblas ffi/vector) (cblas_dnrm2 2 (f64vector 3.0 4.0) 1) ;= 5.0 K. Hishinuma すべてを Racket に取り込もう! 18 / 35
  19. 19. Package Management 再利用可能のために Racket 新機能の Package システムで、 標準に準拠した 1 ライブラリを書こう! 1 http://pkgs.racket-lang.org/ で公開できる K. Hishinuma すべてを Racket に取り込もう! 19 / 35
  20. 20. Package Management ライブラリ作成の手順 1 2 3 ファイルの配置と provide info.rkt の作成 Github で公開 K. Hishinuma すべてを Racket に取り込もう! 20 / 35
  21. 21. Package Management ファイルの配置 (require [パッケージ名]/[ライブラリ名]) で読み込まれるライブラリを、 /[パッケージ名]/[ライブラリ名].rkt に配置する。 今回の例 /math/blas.rkt /math/cblas.rkt K. Hishinuma すべてを Racket に取り込もう! 21 / 35
  22. 22. Package Management provide の宣言 provide 構文を用いて、 外部参照可能な関数を指定する。 今回の例 (provide cblas_dswap cblas_dscal cblas_dcopy cblas_daxpy cblas_ddot cblas_dnrm2 cblas_dasum cblas_idamax) ※ FFI インターフェイスは、Racket 上では単なる手続きなので、 それらと同様にしてよい。 K. Hishinuma すべてを Racket に取り込もう! 22 / 35
  23. 23. Package Management みなさま お気づきでしょうか・・・ 悲劇に向かって 直進してきたことを。 K. Hishinuma すべてを Racket に取り込もう! 23 / 35
  24. 24. Package Management なんということをしてくれたのでしょう K. Hishinuma すべてを Racket に取り込もう! 24 / 35
  25. 25. Package Management なんということをしてくれたのでしょう! K. Hishinuma すべてを Racket に取り込もう! 25 / 35
  26. 26. Package Management なんということをしてくれたのでしょう!! K. Hishinuma すべてを Racket に取り込もう! 26 / 35
  27. 27. Package Management 契約プログラミングへの冒涜 FFI が、関数契約生成子-と 同じ名前-を使うので、 契約付き provide など 2 ができない!! 2 see, http://www.mo.cs.meiji.ac.jp/kaz/km-iter K. Hishinuma すべてを Racket に取り込もう! 27 / 35
  28. 28. Package Management エラーになる例 (provide cblas_dswap cblas_dscal cblas_dcopy (contract-out (SWAP (- f64vector? f64vector? void?)) (SCAL (- real? f64vector? void?)) (COPY (- f64vector? f64vector? void?)))) K. Hishinuma すべてを Racket に取り込もう! 28 / 35
  29. 29. Package Management 公式見解 Eli Barzilay: The Racket Foreign Interface It’s unfortunate that this literal has the same name as - from racket/contract, but it’s a different binding. unfortunate か、それなら仕方ない。 ……では済まないでしょ!!! K. Hishinuma すべてを Racket に取り込もう! 29 / 35
  30. 30. Package Management 対策 FFI インターフェイス定義のみを、 別ファイルに隔離する。 blas.rkt (require される) ライブラリ cblas.rkt FFI 定義の隔離先 K. Hishinuma すべてを Racket に取り込もう! 30 / 35
  31. 31. Package Management info.rkt Package のルートに、info.rkt を配置する。 info.rkt #lang setup/infotab (define collection ’multi) (define version バージョン番号) (define deps ’(依存関係)) バージョン番号 数字とピリオド区切りの文字列 依存関係 依存するパッケージ名を表す文字列のリスト K. Hishinuma すべてを Racket に取り込もう! 31 / 35
  32. 32. Package Management Github で公開 あとは、 作ったものを Github で公開すれば OK ! % raco pkg install github://github.com/ ユーザ名/リポジトリ名/master とか叩けば、 ライブラリをインストールできる。 K. Hishinuma すべてを Racket に取り込もう! 32 / 35
  33. 33. あとがき BLAS Interface for Racket の使用例 閉球 C := {x ∈ Rn : ∥x − c∥ ≤ r} への距離射影 { x + ∥c−x∥−r (c − x) (∥x − c∥ r) ∥c−x∥ PC (x) := . x (Otherwise) (require math/blas) (define (PROJ C R X) (let ((T (make-vect (vect-length C))) (U 0.)) (COPY C T) (AXPY -1 X T) (set! U (NRM2 T)) (when ( U R) (AXPY (/ (- U R) U) T X)) X)) K. Hishinuma すべてを Racket に取り込もう! 33 / 35
  34. 34. あとがき 参考文献 [1] E. Barzilay: The Racket Foreign Interface. URI: http://docs.racket-lang.org/foreign/ [2] J. McCarthy: Package Management in Racket. URI: http://docs.racket-lang.org/pkg/ [3] K. Hishinuma: Racket(Scheme) による Krasnosel’skii-Mann iterations の数値実験. URI: http://www.mo.cs.meiji.ac.jp/kaz/km-iter [4] K. Hishinuma: K. Hishinuma: BLAS Interface for Racket. URI: http://www.mo.cs.meiji.ac.jp/kaz/blas K. Hishinuma すべてを Racket に取り込もう! 34 / 35
  35. 35. あとがき Thanks for your listening. K. Hishinuma すべてを Racket に取り込もう! 35 / 35

×