すべてをRacketに取り込もう! ~Racket FFI と Package システムの使い方~
-
Upload
kazuhiro-hishinuma -
Category
Technology
-
view
1.706 -
download
6
description
Transcript of すべてをRacketに取り込もう! ~Racket FFI と Package システムの使い方~
すべてをRacketに取り込もう!~Racket FFIと Packageシステムの使い方~
菱沼 和弘 (@kazh98)
明治大学理工学部情報科学科 数理最適化研究室URL: http://www.mo.cs.meiji.ac.jp/kaz/
K. Hishinuma すべてを Racket に取り込もう! 1 / 35
Let’s Introduction
数学徒の苦悩
マスハラという言葉をご存知ですか?
K. Hishinuma すべてを Racket に取り込もう! 2 / 35
Let’s Introduction
[複名/U] マスハラ (mathematical harassment)
U :数学徒,
V ⊂ U :精神的苦痛を感じている数学徒,
T : U → U,数学的を用いた言動.
T がマスハラである.
⇐⇒def
∃x ∈ U : Tx ∈ V.
※このスライドもマスハラかもしれない
K. Hishinuma すべてを Racket に取り込もう! 3 / 35
Let’s Introduction
例. 水面上のマスハラ
「ちょっとそれ証明してよ」「本当にそれ定義から言えるの?」「・・・(板書への無言の視線)」
K. Hishinuma すべてを Racket に取り込もう! 4 / 35
Let’s Introduction
しかし!
CS系数学徒には、知られざる水面下のマスハラもあるのです!!!
K. Hishinuma すべてを Racket に取り込もう! 5 / 35
Let’s Introduction
例. 水面下のマスハラ
「数値計算ならFORTRAN使わなきゃ」「FORTRANに良いライブラリがあるよ~」README: Available for Fortran77
K. Hishinuma すべてを Racket に取り込もう! 6 / 35
Let’s Introduction
FORTRAN地獄
いつまでそんな太古の言語を使っているんだ!!
K. Hishinuma すべてを Racket に取り込もう! 7 / 35
Let’s Introduction
備考
Fortran (1957–)
Lisp (1958–)
……やばい、そんなに違いない
K. Hishinuma すべてを Racket に取り込もう! 8 / 35
Let’s Introduction
ということで、
///////////////過去の遺産人類の叡智を、1年未来の言語から呼びだそう!!
Lispで書くことに幸せを感じる人間もいるのです
K. Hishinuma すべてを Racket に取り込もう! 9 / 35
Racket Foreign Interface
Racket FFI
C言語向けのライブラリをRacketから叩ける機能。baseパッケージにより標準提供。
FFI機能の利用� �(require ffi/unsafe ffi/unsafe/define)
(require ffi/vector) ; 配列型を扱う場合� �
K. Hishinuma すべてを Racket に取り込もう! 10 / 35
Racket Foreign Interface
ということは?
FORTRANライブラリ→Cインターフェイス
→Racket FFI
で、Racketから呼び出せる!!!
K. Hishinuma すべてを Racket に取り込もう! 11 / 35
Racket Foreign Interface
BLASのRacketインターフェイスを書いてみた
成果物は、Github:
https://github.com/kazh98/blas
で公開しています。
※Lv1呼び出しのみ完成
K. Hishinuma すべてを Racket に取り込もう! 12 / 35
Racket Foreign Interface
ライブラリのロード
ライブラリのロードには、ffi-lib関数を用いる。ffi-lib関数� �(ffi-lib "ライブラリ名" #:fail 失敗時手続き)
ライブラリ名 ロードするライブラリの名前 (e.g. libc)
失敗時手続き ロード失敗時に呼び出される thunk
戻り値 FFIオブジェクトを返す。これを define-ffi-definer構文で捕捉すると、FFI定義子が手に入る。� �
K. Hishinuma すべてを Racket に取り込もう! 13 / 35
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
Racket Foreign Interface
インターフェイス定義
FFI定義子 define-cblasを使って、ライブラリ関数へのインターフェイスを定義する。C言語のプロトタイプ宣言に相当。
define-cblas構文� �(define-cblas 名前 型)
名前 ライブラリからインターフェイスを張る関数名型 ライブラリから張られる関数の型
(_fun 引数型 1 引数型 2 ... -> 戻り値型)� �K. Hishinuma すべてを Racket に取り込もう! 15 / 35
Racket Foreign Interface
インターフェイス定義型
C言語 Racketint _int
unsigned int _uint
double _double*
size_t _size
intptr_t _intptr
void* _pointer
char* _string
C言語 Racketint32_t* _s32vector
int64_t* _s64vector
double* _f64vector
呼び出し時には、スカラ型は対応する Racketの値を、配列型は対応する SRFI-4のベクタを用いればよい。
K. Hishinuma すべてを Racket に取り込もう! 16 / 35
Racket Foreign Interface
例. インターフェイス定義
C言語プロトタイプ宣言 (cblas.h)� �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
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
Package Management
再利用可能のために
Racket新機能のPackageシステムで、標準に準拠した 1ライブラリを書こう!
1http://pkgs.racket-lang.org/で公開できるK. Hishinuma すべてを Racket に取り込もう! 19 / 35
Package Management
ライブラリ作成の手順
1 ファイルの配置とprovide2 info.rktの作成3 Githubで公開
K. Hishinuma すべてを Racket に取り込もう! 20 / 35
Package Management
ファイルの配置
(require [パッケージ名]/[ライブラリ名])
で読み込まれるライブラリを、/[パッケージ名]/[ライブラリ名].rkt
に配置する。今回の例� �/math/blas.rkt
/math/cblas.rkt� �K. Hishinuma すべてを Racket に取り込もう! 21 / 35
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
Package Management
みなさま
お気づきでしょうか・・・悲劇に向かって直進してきたことを。
K. Hishinuma すべてを Racket に取り込もう! 23 / 35
Package Management
なんということをしてくれたのでしょう
K. Hishinuma すべてを Racket に取り込もう! 24 / 35
Package Management
なんということをしてくれたのでしょう!
K. Hishinuma すべてを Racket に取り込もう! 25 / 35
Package Management
なんということをしてくれたのでしょう!!
K. Hishinuma すべてを Racket に取り込もう! 26 / 35
Package Management
契約プログラミングへの冒涜
FFIが、関数契約生成子->と同じ名前->を使うので、契約付きprovideなど2
ができない!!
2see, http://www.mo.cs.meiji.ac.jp/kaz/km-iterK. Hishinuma すべてを Racket に取り込もう! 27 / 35
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
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
Package Management
対策
FFIインターフェイス定義のみを、別ファイルに隔離する。blas.rkt (requireされる)ライブラリcblas.rkt FFI定義の隔離先
K. Hishinuma すべてを Racket に取り込もう! 30 / 35
Package Management
info.rkt
Packageのルートに、info.rktを配置する。info.rkt� �#lang setup/infotab
(define collection ’multi)
(define version "バージョン番号")
(define deps ’(依存関係))
バージョン番号 数字とピリオド区切りの文字列依存関係 依存するパッケージ名を表す文字列のリスト� �
K. Hishinuma すべてを Racket に取り込もう! 31 / 35
Package Management
Githubで公開
あとは、作ったものをGithubで公開すればOK!
% raco pkg install github://github.com/
ユーザ名/リポジトリ名/master
とか叩けば、ライブラリをインストールできる。
K. Hishinuma すべてを Racket に取り込もう! 32 / 35
あとがき
BLAS Interface for Racket の使用例閉球C := {x ∈ Rn : ∥x− c∥ ≤ r}への距離射影
PC(x) :=
{x+ ∥c−x∥−r
∥c−x∥ (c− x) (∥x− c∥ > r)
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
あとがき
参考文献
[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-Manniterationsの数値実験.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
あとがき
Thanks for your listening.
K. Hishinuma すべてを Racket に取り込もう! 35 / 35