GSLを使うC言語プログラムをRから実行

WinXP+cygwin 環境で、GSL(GNU Scientific Library)を使うC言語プログラムをRから実行するための環境設定とテストの手順。

1. RからC言語のプログラムを実行する
2. GSLをCのプログラムで利用する
3. GSLを使うCのプログラムをRから実行する

という内容。cygwin の devel 環境は入っているのが前提。入ってないなら、そもそも cygwin ではなく、MinGW とか使うほうが簡単らしい。環境は cygwin ver. 1.7.1 + R ver. 2.9.2。


1. RからC言語のプログラムを実行する

cygwin のホームにRから起動するC言語のソースファイル /home/username/mysum.c を 準備する。

void mysum(double *a, double *b, double *c)
{
  double sum;
  sum =  *a + *b;
  *c = sum;
}

}の後に改行が必要。ないとコンパイル時に「warning: no newline at end of file」というエラーになる。

cc1.exe と libgcc.a があるディレクトリを探す。私の場合は以下3ヵ所にありました。

/usr/lib/gcc/i686-pc-cygwin/3.4.4
/usr/lib/gcc/i686-pc-cygwin/4.3.4
/usr/lib/gcc/i686-pc-mingw32/3.4.4

cygwin 上でパスを通す。

> export PATH=$PATH:/usr/lib/gcc/i686-pc-cygwin/3.4.4

次に、-mno-cygwin オプションをつけて作ったソースをコンパイルする。

> gcc-3 -shared -o mysum.dll mysum.c -mno-cygwin -L/usr/lib/gcc/i686-pc-cygwin/3.4.4 -lgcc

これで mysum.dll が作られる。

コンパイラはデフォルトの gccではなく gcc-3 にする。gcc つまり gcc-4 だと「The -mno-cygwin flag has been removed; use a mingw-targeted cross-compiler」というエラーになる。

その場で R を起動し、作成したdllをdyn.loadで読み込む

> R
dyn.load("mysum.dll")

R上でC言語関数の読み出し専用の関数を準備し実行。

mysum <- function(a,b) {
  .C("mysum",            # Cルーチン名
      arg1=as.double(a), # Cルーチン第1引数の型指定
      arg2=as.double(b), # Cルーチン第2引数
      arg3=double(1)     # Cルーチン第3引数
     )
}
(z <- mysum(1.234,2.345))


$arg1
[1] 1.234
$arg2
[1] 2.345
$arg3
[1] 3.579

が出力されればOK

2. GSLをCのプログラムで利用する

cygwin を入れた時点でGSLのライブラリは入っているようす。コンパイルの必要は特にありません。/usr/lib に、libgsl.a, libgsl.la, libgslcblas.a, libgslcblas.la があることを確認しておく。

http://www.ai-gakkai.or.jp/jsai/journal/toolbox/04/#FOURTH からサンプルをDLし、解凍。rand.cとeigen.cをコンパイル&実行する。

> gcc -o rand.exe rand.c -lgsl
> ./rand.exe
An instance = 0.999742

> gcc -o eigen.exe eigen.c -lgsl -lgslcblas
> ./eigen.exe
eigenvalue = 4.01673
eigenvector =
0.0379945
0.999278
eigenvalue = 0.888063
eigenvector =
0.999278
-0.0379945

こちらのコンパイルは、ステップ1のときとは違い、gcc-3 だけではなく gcc のほうでも通りました。Rがらみのコンパイルをするときはgcc-3のほうが安全なようです。

3. GSLを使うCのプログラムをRから実行する

mysum.c のときと同じく、以下 mybess.c を準備

#include <stdio.h>
#include <gsl/gsl_sf_bessel.h>
void mybess(double *x, double *y)
{
  *y = gsl_sf_bessel_J0 (*x);
}

gsl/gsl_sf_bessel.h がある場所を確認する。私の場合は、/usr/include/ つまり C:\cygwin\usr\include\ にありました。で、そのオプションをつけてコンパイル。

> gcc-3 -shared -o mybess.dll mybess.c -mno-cygwin -I/usr/include -L/usr/lib/gcc/i686-pc-cygwin/3.4.4 -lgcc -lgsl -lgslcblas

warning が出ます。

In file included from /usr/include/gsl/gsl_sf_bessel.h:25,
from mybess.c:2:
/usr/include/stdlib.h:104: warning: `warning' attribute directive ignored
/usr/include/stdlib.h:109: warning: `warning' attribute directive ignored

DLLはできている模様。あとは、R で呼び出し関数を作って実行・・・なのですが以下まだうまくいきません。クラッシュする様子。

> R
dyn.load("mybess.dll")
mybess = function(x) {
  .C("mybessel", as.double(x), result = double(1))$result
}
mybess(5)
-0.1775968

参考URL
Rから他言語利用
RからGSL(WinXP用)
Windows で GSLをビルドとインストール(Cygwin を使用)

  1. mトラックバックがありません。