Chapter 29 The bigarray library

このページは最後に更新されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

last mod. 2008-09-25 (木) 18:02:31

The Objective Caml system release 3.10

bigarray ライブラリは、大規模で、多次元で、数値のみを扱うことのできる配列を実装しています。これらの配列は、標準の Caml の Array モジュールで提供されるものと区別するために "big array" と呼ばれます。big array とCaml 標準の配列との大きな違いは以下のものです。

  • big array は、Caml の配列と異なりサイズに制限がありません。(Caml の配列は32ビットの環境で、float の配列は 2097151個の要素まで、その他の型の配列の場合には4194303個の要素までに制限されています)

  • big array は多次元配列です。1次元から16次元までの任意の次元をサポートしています。それに対して Caml の配列は単一の次元に限られ、多次元配列は配列の配列としてエンコードする必要があります。

  • Caml の配列は Caml の任意のデータ型をその中に含むことができますが、big array は整数と浮動小数点数しか含むことができません。しかし、big array はより効率よく整数と浮動小数点数を含むことができます。その理由は、big array は標準の Caml の倍精度浮動小数型や32ビット・64ビットの整数型に加えて、8ビットや16ビット整数のような"小さい"型サポートしているからです。

  • big array のメモリレイアウトは、C や Fortran のものと完全に互換性があるので、 Caml のコードと C や Fortran のコードとの間で大きな配列のデータをまったくコピーすることなくやりとりすることができます。

  • big array は、コピーをまったくせずに部分配列を取り出したり多次元配列からある次元のものだけを切り出してきたりといった、通常の配列では効率よく提供できない便利でおもしろい操作をサポートしています。

bigarray ライブラリを使用するプログラムは次のようにリンクしてください。

       ocamlc other options bigarray.cma other files
       ocamlopt other options bigarray.cmxa other files

インタラクティブモードで str ライブラリを使うには以下のようにします。

       ocamlmktop -o mytop bigarray.cma
       ./mytop

あるいは(あなたのプラットフォームが C ライブラリのダイナミックリンクをサポートする場合には)、ocaml を起動して #load "bigarray.cma";; と入力してください。

Module Bigarray: large, multi-dimensional, numerical arrays

  • Module Bigarray

Big arrays in the Caml-C interface

C や Fortran のコードと Caml のコードを結びつける(18章で述べられています) C のスタブコードは、次のようにして big array を利用することができます。

Include file

C スタブファイルには必ず <caml/bigarray.h> をインクルードしなくてはいけ ません。これは、以下で述べる関数と定数とマクロを宣言します。

Accessing a Caml bigarray from C or Fortran

もし v が big array を表す Caml の値だとすると、Data_bigarray_val(v) と いう式は配列のデータ部分へのポインタを返します。このポインタは void 型 で、適切な C の型にキャストすることができます。(例えば double [], char [][10], などなど)

Caml の big array の様々な情報は、C で次のように得ることができます。

C の式返る値
Bigarray_val(v)->num_dims次元の数
Bigarray_val(v)->dim[i]i番目の次元
Bigarray_val(v)->flags & BIGARRAY_KIND_MASK配列の要素の種類

配列の要素の種類は、次の定数のうちのどれかです。

定数要素の種類
BIGARRAY_FLOAT3232ビットの単精度浮動小数点数
BIGARRAY_FLOAT6464ビットの倍精度浮動小数点数
BIGARRAY_SINT88ビット符号付き整数
BIGARRAY_UINT88ビット符号なし整数
BIGARRAY_SINT1616ビット符号付き整数
BIGARRAY_UINT1616ビット符号なし整数
BIGARRAY_INT3232ビット符号付き整数
BIGARRAY_INT6464ビット符号付き整数
BIGARRAY_CAML_INT31ビットか63ビットの符号付き整数
BIGARRAY_NATIVE_INT32ビットか64ビットの(プラットフォームネイティブな)整数

以下は、2次元の big array を C と Fortran の関数に渡す例です。

   extern void my_c_function(double * data, int dimx, int dimy);
   extern void my_fortran_function_(double * data, int * dimx, int * dimy);

   value caml_stub(value bigarray)
   {
     int dimx = Bigarray_val(bigarray)->dim[0];
     int dimy = Bigarray_val(bigarray)->dim[1];
     /* C passes scalar parameters by value */
     my_c_function(Data_bigarray_val(bigarray), dimx, dimy);
     /* Fortran passes all parameters by reference */
     my_fortran_function_(Data_bigarray_val(bigarray), &dimx, &dimy);
     return Val_unit;
   }

Wrapping a C or Fortran array as a Caml big array

既にメモリ領域が割り当てられた C や Fortran の配列へのポインタ p は、 alloc_bigarray や alloc_bigarray_dims 関数を使って Caml の世界に持って 帰ることができます。

  • alloc_bigarray(kind | layout, numdims,p, dims)

p で示されるデータをラップして Caml の big array として返します。 kind は配列の要素の種類です(上で述べた BIGARRAY_ のうちのひとつ)。 layout には、C の配列なのか(BIGARRAY_C_LAYOUT)、Fortran の配列なのか (BIGARRAY_FORTRAN_LAYOUT)を指定します。numdims は配列の次元の数です。 dmis は numdims の長さの整数の配列で、それぞれの配列のサイズを表します。

  • alloc_bigarray_dims(kind | layout, numdims, p, (long) dim1, (long) dim2, …, (long) dimnumdims)

alloc_bigarray と同じですが、それぞれの次元の配列のサイズを配列として 渡すのではなく、関数呼び出しの引数に直接追加されています。

以下は、静的に割り当てられた C と Fortran の配列をどうやって Caml から扱えるようにするかを表した例です。

   extern long my_c_array[100][200];
   extern float my_fortran_array_[300][400];

   value caml_get_c_array(value unit)
   {
     long dims[2];
     dims[0] = 100; dims[1] = 200;
     return alloc_bigarray(BIGARRAY_NATIVE_INT | BIGARRAY_C_LAYOUT,
                           2, my_c_array, dims);
   }

   value caml_get_fortran_array(value unit)
   {
     return alloc_bigarray_dims(BIGARRAY_FLOAT32 | BIGARRAY_FORTRAN_LAYOUT,
                                2, my_fortran_array_, 300L, 400L);
   }

新規 編集 添付