Chapter 32  The bigarray library

The bigarray library implements large, multi-dimensional, numerical arrays. These arrays are called “big arrays” to distinguish them from the standard OCaml arrays described in Module Array. The main differences between “big arrays” and standard OCaml arrays are as follows:

Programs that use the bigarray library must be linked as follows:

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

For interactive use of the bigarray library, do:

        ocamlmktop -o mytop bigarray.cma
        ./mytop

or (if dynamic linking of C libraries is supported on your platform), start ocaml and type #load "bigarray.cma";;.

1  Module Bigarray: large, multi-dimensional, numerical arrays

2  Big arrays in the OCaml-C interface

C stub code that interface C or Fortran code with OCaml code, as described in chapter 19, can exploit big arrays as follows.

2.1  Include file

The include file <caml/bigarray.h> must be included in the C stub file. It declares the functions, constants and macros discussed below.

2.2  Accessing an OCaml bigarray from C or Fortran

If v is a OCaml value representing a big array, the expression Caml_ba_data_val(v) returns a pointer to the data part of the array. This pointer is of type void * and can be cast to the appropriate C type for the array (e.g. double [], char [][10], etc).

Various characteristics of the OCaml big array can be consulted from C as follows:

C expressionReturns
Caml_ba_array_val(v)->num_dimsnumber of dimensions
Caml_ba_array_val(v)->dim[i]i-th dimension
Caml_ba_array_val(v)->flags & BIGARRAY_KIND_MASKkind of array elements

The kind of array elements is one of the following constants:

ConstantElement kind
CAML_BA_FLOAT3232-bit single-precision floats
CAML_BA_FLOAT6464-bit double-precision floats
CAML_BA_SINT88-bit signed integers
CAML_BA_UINT88-bit unsigned integers
CAML_BA_SINT1616-bit signed integers
CAML_BA_UINT1616-bit unsigned integers
CAML_BA_INT3232-bit signed integers
CAML_BA_INT6464-bit signed integers
CAML_BA_CAML_INT31- or 63-bit signed integers
CAML_BA_NATIVE_INT32- or 64-bit (platform-native) integers

The following example shows the passing of a two-dimensional big array to a C function and a Fortran function.

    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 = Caml_ba_array_val(bigarray)->dim[0];
      int dimy = Caml_ba_array_val(bigarray)->dim[1];
      /* C passes scalar parameters by value */
      my_c_function(Caml_ba_data_val(bigarray), dimx, dimy);
      /* Fortran passes all parameters by reference */
      my_fortran_function_(Caml_ba_data_val(bigarray), &dimx, &dimy);
      return Val_unit;
    }

2.3  Wrapping a C or Fortran array as an OCaml big array

A pointer p to an already-allocated C or Fortran array can be wrapped and returned to OCaml as a big array using the caml_ba_alloc or caml_ba_alloc_dims functions.

The following example illustrates how statically-allocated C and Fortran arrays can be made available to OCaml.

    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 caml_ba_alloc(CAML_BA_NATIVE_INT | CAML_BA_C_LAYOUT,
                           2, my_c_array, dims);
    }

    value caml_get_fortran_array(value unit)
    {
      return caml_ba_alloc_dims(CAML_BA_FLOAT32 | CAML_BA_FORTRAN_LAYOUT,
                                2, my_fortran_array_, 300L, 400L);
    }