Bigarray tutorial or examples?

I’d be interested in a tutorial on elementary use of the mysterious Bigarray–or even simple examples of use. The OCaml manual chapter on Bigarray and the ocamldoc pages are pretty opaque.

I don’t actually want to interface with C or Fortran or anything else. (Other folks have done that part.)

At this point, I would just like to be able to create a Genarray or Array2 with values that I have specified. This is non-trivial! Too much mysterious type information is required, and I don’t know how to provide it.

3 Likes

Here is a small bit of code to get started:

# let my_big_array =
    Bigarray.Array2.create Bigarray.float32 Bigarray.c_layout 20 20;;
val my_big_array :
  (float, Bigarray.float32_elt, Bigarray.c_layout) Bigarray.Array2.t =
  <abstr>
# my_big_array.{12,12};;
- : float = 0.
# my_big_array.{12,12} <- 1.5;;
- : unit = ()
# my_big_array.{12,12};;
- : float = 1.5

my_big_array is a two-dimensional array of 32-bit floats with C layout.

3 Likes

Thanks! That might be all I need to get started.

In the long run, it might be useful if someone made available a more thorough introduction to Bigarray somewhere.

(I had also checked the two books I have, RWO (just some passing references), and Développement d’applications avec Objective Caml from 2000 (nothing–maybe Bigarray was developed later).)

1 Like

One thing that confused me is that I initially tried to make an integer array, and discovered that normal ints are neither Bigarray.int32 nor Bigarray.int64. So I assumed that floats would not be Bigarray.float32 or Bigarray.float64. Yet I can assign them into either kind of float Array2.

(I must be very tired. I just tried to end a sentence with “;;”.)

In the type returned by Bigarray.Array2.create

(float, Bigarray.float32_elt, Bigarray.c_layout) Bigarray.Array2.t

The first type float is the type used to store and retrieve values from the array. If you look at the type returned for a float64 array you’ll see that it is also float:

# let my_second_big_array =
    Bigarray.Array2.create Bigarray.float64 Bigarray.c_layout 20 20;;
val my_second_big_array :
  (float, Bigarray.float64_elt, Bigarray.c_layout) Bigarray.Array2.t =
  <abstr>

It’s true, on my 64-bit machine, the store/retrieve type for a 32-bit int array is int32:

# let my_third_big_array =
    Bigarray.Array2.create Bigarray.int32 Bigarray.c_layout 20 20;;
val my_third_big_array :
  (int32, Bigarray.int32_elt, Bigarray.c_layout) Bigarray.Array2.t =
  <abstr>

Presumably this is so the code will also work on a 32-bit machine. (On a 32-bit machine a plain OCaml int has 31 bits.)

1 Like

@jeffsco, thanks for explaining the meaning of the first type in the tuple. And I guess the second one is the internal type of the array. That’s very helpful. It was the hint that allowed me to get a little bit further.

I don’t think the problem with storing ints into an Array2 has anything to do with the machine type:

My machine should be 64 bits, but I’ll try both 64-bit and 32-bit integers just to be sure:

# let int32_array = Bigarray.Array2.create Bigarray.int32 Bigarray.c_layout 20 20;;
val int32_array :
  (int32, Bigarray.int32_elt, Bigarray.c_layout) Bigarray.Array2.t = <abstr>

# Bigarray.Array2.set int32_array 0 0 22;;
Error: This expression has type int but an expression was expected of type
         int32

# let int64_array = Bigarray.Array2.create Bigarray.int64 Bigarray.c_layout 20 20;;
val int64_array :
  (int64, Bigarray.int64_elt, Bigarray.c_layout) Bigarray.Array2.t = <abstr>

# Bigarray.Array2.set int64_array 0 0 22;;
Error: This expression has type int but an expression was expected of type
         int64

So I can’t put an int in either kind of Array2.

Then I discovered that there is an Int64 module with an of_int function:

# Bigarray.Array2.set int64_array 0 0 (Int64.of_int 22);;
- : unit = ()
# Bigarray.Array2.get int64_array 0 0;;
- : int64 = 22L
# Bigarray.Array2.set int64_array 0 0 23L;;
- : unit = ()
# Bigarray.Array2.get int64_array 0 0;;
- : int64 = 23L

So number+L is the simple syntax for 64-bit ints. For 32-bit ints one uses lowercase “L”, it appears:

# Int32.of_int 22;;
- : int32 = 22l
# Bigarray.Array2.set int32_array 0 0 22l;;
- : unit = ()
# Bigarray.Array2.get int32_array 0 0;;
- : int32 = 22l

So number+L is the simple syntax for 64-bit ints. For 32-bit ints one uses lowercase “L”, it appears

There is also +n for untagged native-size integers:

let x = 5n
1 Like

The problem here is that we still don’t have a surfaceable Bigarray tutorial merged into the official docs or website, we just have another search result.

1 Like

My observation is just that on a 64-bit machine it would be most convenient to use a plain int as the store/retrieve type for a 32-bit integer bigarray. int32’s are a little cumbersome and are boxed. I would assume using int32 is for compatibility with 32-bit machines where you can’t use a plain int. They’re not big enough to hold 32 bits.