# Bigarray tutorial or examples?

**URL:** <https://discuss.ocaml.org/t/bigarray-tutorial-or-examples/1325>\
**Category:** Learning\
**Created:** [December 21, 2017, 7:01pm UTC](https://discuss.ocaml.org/t/bigarray-tutorial-or-examples/1325 "2017-12-21T19:01:32Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![mars0i](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/mars0i/32/1058_2.png) [@mars0i](https://discuss.ocaml.org/u/mars0i)\
**Post date:** [December 21, 2017, 7:01pm UTC](https://discuss.ocaml.org/t/bigarray-tutorial-or-examples/1325/1 "2017-12-21T19:01:32Z")

</div>

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`](https://caml.inria.fr/pub/docs/manual-ocaml/libbigarray.html) 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.

---

<div class="post-metadata">

**Author:** ![jeffsco](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/jeffsco/32/45_2.png) [@jeffsco](https://discuss.ocaml.org/u/jeffsco)\
**Post date:** [December 21, 2017, 7:21pm UTC](https://discuss.ocaml.org/t/bigarray-tutorial-or-examples/1325/2 "2017-12-21T19:21:59Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![mars0i](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/mars0i/32/1058_2.png) [@mars0i](https://discuss.ocaml.org/u/mars0i)\
**Post date:** [December 21, 2017, 9:50pm UTC](https://discuss.ocaml.org/t/bigarray-tutorial-or-examples/1325/3 "2017-12-21T21:50:01Z")

</div>

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).)

---

<div class="post-metadata">

**Author:** ![mars0i](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/mars0i/32/1058_2.png) [@mars0i](https://discuss.ocaml.org/u/mars0i)\
**Post date:** [December 22, 2017, 3:50am UTC](https://discuss.ocaml.org/t/bigarray-tutorial-or-examples/1325/4 "2017-12-22T03:50:26Z")

</div>

One thing that confused me is that I initially tried to make an integer array, and discovered that normal `int`s are neither `Bigarray.int32` nor `Bigarray.int64`. So I assumed that `float`s 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 “;;”.)

---

<div class="post-metadata">

**Author:** ![jeffsco](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/jeffsco/32/45_2.png) [@jeffsco](https://discuss.ocaml.org/u/jeffsco)\
**Post date:** [December 22, 2017, 5:32am UTC](https://discuss.ocaml.org/t/bigarray-tutorial-or-examples/1325/5 "2017-12-22T05:32:28Z")

</div>

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.)

---

<div class="post-metadata">

**Author:** ![mars0i](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/mars0i/32/1058_2.png) [@mars0i](https://discuss.ocaml.org/u/mars0i)\
**Post date:** [December 23, 2017, 4:33am UTC](https://discuss.ocaml.org/t/bigarray-tutorial-or-examples/1325/6 "2017-12-23T04:33:12Z")

</div>

@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:

> [@jeffsco](#):
>
> It’s true, on my 64-bit machine, the store/retrieve type for a 32-bit int array is int32:
> 
> ```auto
> # 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 =
> &lt;abstr&gt;
> 
> ```
> 
> 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.)

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

```ocaml
# 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:

```ocaml
# 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:

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

```

---

<div class="post-metadata">

**Author:** ![octachron](https://avatars.discourse-cdn.com/v4/letter/o/49beb7/32.png) [@octachron](https://discuss.ocaml.org/u/octachron)\
**Post date:** [December 23, 2017, 8:42am UTC](https://discuss.ocaml.org/t/bigarray-tutorial-or-examples/1325/7 "2017-12-23T08:42:39Z")

</div>

> 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:

```OCaml
let x = 5n

```

---

<div class="post-metadata">

**Author:** ![mk270](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/mk270/32/689_2.png) [@mk270](https://discuss.ocaml.org/u/mk270)\
**Post date:** [December 23, 2017, 12:51pm UTC](https://discuss.ocaml.org/t/bigarray-tutorial-or-examples/1325/8 "2017-12-23T12:51:30Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![jeffsco](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/jeffsco/32/45_2.png) [@jeffsco](https://discuss.ocaml.org/u/jeffsco)\
**Post date:** [December 24, 2017, 12:34am UTC](https://discuss.ocaml.org/t/bigarray-tutorial-or-examples/1325/9 "2017-12-24T00:34:59Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![zeroexcuses](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/zeroexcuses/32/1692_2.png) [@zeroexcuses](https://discuss.ocaml.org/u/zeroexcuses)\
**Post date:** [June 26, 2023, 8:49am UTC](https://discuss.ocaml.org/t/bigarray-tutorial-or-examples/1325/10 "2023-06-26T08:49:32Z")

</div>

I was just googling for bigarray tutorials, and landed here. Has the situation improved for bigarray documentation ?

---

<div class="post-metadata">

**Author:** ![zoj613](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/zoj613/32/5253_2.png) [@zoj613](https://discuss.ocaml.org/u/zoj613)\
**Post date:** [May 19, 2024, 12:18am UTC](https://discuss.ocaml.org/t/bigarray-tutorial-or-examples/1325/11 "2024-05-19T00:18:41Z")

</div>

Has there been any since the last post of this thread? I am finding myself struggling to use this module properly and get the desired results and would love to use some tutorial as a guide. Maybe It’s because I don’t have a good understanding of the type system yet. For example, I want to create a Generalized array using a string that represents the data type of the array elements and the number of dimensions. I tried

```ocaml
module B = Bigarray
  let of_datatype dims = function
    | "float64" -> B.Genarray.create B.float64 B.c_layout dims
    | "float32" -> B.Genarray.create B.float32 B.c_layout dims
    | "int8" -> B.Genarray.create B.int8_signed B.c_layout dims
    ...

```

But this wont type check since the output array can have different types. I can’t think of a way to create an array on the fly using the string information about the element type. This string is read from a json file. Any ideas how this can be done?

---

<div class="post-metadata">

**Author:** ![Chet\_Murthy](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/chet_murthy/32/1501_2.png) [@Chet\_Murthy](https://discuss.ocaml.org/u/Chet_Murthy)\
**Post date:** [May 19, 2024, 1:45am UTC](https://discuss.ocaml.org/t/bigarray-tutorial-or-examples/1325/12 "2024-05-19T01:45:04Z")

</div>

One supposes there’s only one way, and that’s to make yourself a constructor data-type with a branch for each different type of bigarray you plan to use ? Which means that you’ll end up having to do the tag-check each time you use that bigarray-wrapped-in-a-constructor, and that’ll slow things down. But this would be the same if you were trying to do it with `array`, right? I mean, this is part of the way OCaml is: you can’t just dump things with different types into the same bag and expect code to typecheck.

---

<div class="post-metadata">

**Author:** ![zoj613](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/zoj613/32/5253_2.png) [@zoj613](https://discuss.ocaml.org/u/zoj613)\
**Post date:** [May 19, 2024, 6:15pm UTC](https://discuss.ocaml.org/t/bigarray-tutorial-or-examples/1325/13 "2024-05-19T18:15:42Z")

</div>

I decided to wrap the output in polymorphic variant constructors. It’s not a very ergonomic solution but at least the function type checks. Thanks!
