File: libbigarray.html

package info (click to toggle)
ocaml-doc 4.05-1
  • links: PTS, VCS
  • area: non-free
  • in suites: buster
  • size: 13,700 kB
  • sloc: sh: 37; makefile: 14
file content (155 lines) | stat: -rw-r--r-- 10,731 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<meta name="generator" content="hevea 2.18">
<link rel="stylesheet" type="text/css" href="manual.css">
<title>Chapter&#XA0;32&#XA0;&#XA0;The bigarray library</title>
</head>
<body>
<a href="libdynlink.html"><img src="previous_motif.gif" alt="Previous"></a>
<a href="index.html"><img src="contents_motif.gif" alt="Up"></a>
<a href="manual047.html"><img src="next_motif.gif" alt="Next"></a>
<hr>
<h1 class="chapter" id="sec538">Chapter&#XA0;32&#XA0;&#XA0;The bigarray library</h1>
<ul>
<li><a href="libbigarray.html#sec539">32.1&#XA0;&#XA0;Module <span class="c003">Bigarray</span>: large, multi-dimensional, numerical arrays</a>
</li><li><a href="libbigarray.html#sec540">32.2&#XA0;&#XA0;Big arrays in the OCaml-C interface</a>
</li></ul>
<p>The <span class="c003">bigarray</span> library implements large, multi-dimensional, numerical
arrays. These arrays are called &#X201C;big arrays&#X201D; to distinguish them
from the standard OCaml arrays described in
<a href="libref/Array.html">Module <span class="c003">Array</span></a>.
The main differences between &#X201C;big arrays&#X201D; and standard OCaml arrays
are as follows:
</p><ul class="itemize"><li class="li-itemize">
Big arrays are not limited in size, unlike OCaml arrays
(<span class="c003">float array</span> are limited to 2097151 elements on a 32-bit platform,
other <span class="c003">array</span> types to 4194303 elements).
</li><li class="li-itemize">Big arrays are multi-dimensional. Any number of dimensions
between 1 and 16 is supported. In contrast, OCaml arrays are
mono-dimensional and require encoding multi-dimensional arrays as
arrays of arrays.
</li><li class="li-itemize">Big arrays can only contain integers and floating-point
numbers, while OCaml arrays can contain arbitrary OCaml data types.
However, big arrays provide more space-efficient storage of integer
and floating-point elements, in particular because they support
&#X201C;small&#X201D; types such as single-precision floats and 8 and 16-bit
integers, in addition to the standard OCaml types of double-precision
floats and 32 and 64-bit integers.
</li><li class="li-itemize">The memory layout of big arrays is entirely compatible with that
of arrays in C and Fortran, allowing large arrays to be passed back
and forth between OCaml code and C / Fortran code with no data copying
at all.
</li><li class="li-itemize">Big arrays support interesting high-level operations that normal
arrays do not provide efficiently, such as extracting sub-arrays and
&#X201C;slicing&#X201D; a multi-dimensional array along certain dimensions, all
without any copying.
</li></ul><p>
Programs that use the <span class="c003">bigarray</span> library must be linked as follows:
</p><pre>
        ocamlc <span class="c009">other options</span> bigarray.cma <span class="c009">other files</span>
        ocamlopt <span class="c009">other options</span> bigarray.cmxa <span class="c009">other files</span>
</pre><p>
For interactive use of the <span class="c003">bigarray</span> library, do:
</p><pre>
        ocamlmktop -o mytop bigarray.cma
        ./mytop
</pre><p>
or (if dynamic linking of C libraries is supported on your platform),
start <span class="c003">ocaml</span> and type <span class="c003">#load "bigarray.cma";;</span>.</p>
<h2 class="section" id="sec539">32.1&#XA0;&#XA0;Module <span class="c003">Bigarray</span>: large, multi-dimensional, numerical arrays</h2>
<ul class="ftoc2"><li class="li-links">
<a href="libref/Bigarray.html">Module <span class="c003">Bigarray</span></a>
</li></ul>
<h2 class="section" id="sec540">32.2&#XA0;&#XA0;Big arrays in the OCaml-C interface</h2>
<p>C stub code that interface C or Fortran code with OCaml code, as
described in chapter&#XA0;<a href="intfc.html#c%3Aintf-c">19</a>, can exploit big arrays as
follows.</p>
<h3 class="subsection" id="sec541">32.2.1&#XA0;&#XA0;Include file</h3>
<p>The include file <span class="c003">&lt;caml/bigarray.h&gt;</span> must be included in the C stub
file. It declares the functions, constants and macros discussed
below.</p>
<h3 class="subsection" id="sec542">32.2.2&#XA0;&#XA0;Accessing an OCaml bigarray from C or Fortran</h3>
<p>If <span class="c009">v</span> is a OCaml <span class="c003">value</span> representing a big array, the expression
<span class="c003">Caml_ba_data_val(</span><span class="c009">v</span><span class="c003">)</span> returns a pointer to the data part of the array.
This pointer is of type <span class="c003">void *</span> and can be cast to the appropriate C
type for the array (e.g. <span class="c003">double []</span>, <span class="c003">char [][10]</span>, etc).</p><p>Various characteristics of the OCaml big array can be consulted from C
as follows:
</p><div class="center"><table class="c000 cellpadding1" border=1><tr><td class="c014"><span class="c013">C expression</span></td><td class="c014"><span class="c013">Returns</span> </td></tr>
<tr><td class="c016">
<span class="c003">Caml_ba_array_val(</span><span class="c009">v</span><span class="c003">)-&gt;num_dims</span></td><td class="c016">number of dimensions </td></tr>
<tr><td class="c016"><span class="c003">Caml_ba_array_val(</span><span class="c009">v</span><span class="c003">)-&gt;dim[</span><span class="c009">i</span><span class="c003">]</span></td><td class="c016"><span class="c009">i</span>-th dimension </td></tr>
<tr><td class="c016"><span class="c003">Caml_ba_array_val(</span><span class="c009">v</span><span class="c003">)-&gt;flags &amp; BIGARRAY_KIND_MASK</span></td><td class="c016">kind of array elements </td></tr>
</table></div><p>
The kind of array elements is one of the following constants:
</p><div class="center"><table class="c000 cellpadding1" border=1><tr><td class="c014"><span class="c013">Constant</span></td><td class="c014"><span class="c013">Element kind</span> </td></tr>
<tr><td class="c016">
<span class="c003">CAML_BA_FLOAT32</span></td><td class="c016">32-bit single-precision floats </td></tr>
<tr><td class="c016"><span class="c003">CAML_BA_FLOAT64</span></td><td class="c016">64-bit double-precision floats </td></tr>
<tr><td class="c016"><span class="c003">CAML_BA_SINT8</span></td><td class="c016">8-bit signed integers </td></tr>
<tr><td class="c016"><span class="c003">CAML_BA_UINT8</span></td><td class="c016">8-bit unsigned integers </td></tr>
<tr><td class="c016"><span class="c003">CAML_BA_SINT16</span></td><td class="c016">16-bit signed integers </td></tr>
<tr><td class="c016"><span class="c003">CAML_BA_UINT16</span></td><td class="c016">16-bit unsigned integers </td></tr>
<tr><td class="c016"><span class="c003">CAML_BA_INT32</span></td><td class="c016">32-bit signed integers </td></tr>
<tr><td class="c016"><span class="c003">CAML_BA_INT64</span></td><td class="c016">64-bit signed integers </td></tr>
<tr><td class="c016"><span class="c003">CAML_BA_CAML_INT</span></td><td class="c016">31- or 63-bit signed integers </td></tr>
<tr><td class="c016"><span class="c003">CAML_BA_NATIVE_INT</span></td><td class="c016">32- or 64-bit (platform-native) integers </td></tr>
</table></div><p>
The following example shows the passing of a two-dimensional big array
to a C function and a Fortran function.
</p><pre>    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)-&gt;dim[0];
      int dimy = Caml_ba_array_val(bigarray)-&gt;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), &amp;dimx, &amp;dimy);
      return Val_unit;
    }
</pre>
<h3 class="subsection" id="sec543">32.2.3&#XA0;&#XA0;Wrapping a C or Fortran array as an OCaml big array</h3>
<p>A pointer <span class="c009">p</span> to an already-allocated C or Fortran array can be
wrapped and returned to OCaml as a big array using the <span class="c003">caml_ba_alloc</span>
or <span class="c003">caml_ba_alloc_dims</span> functions.
</p><ul class="itemize"><li class="li-itemize">
<span class="c003">caml_ba_alloc(</span><span class="c009">kind</span> <span class="c003">|</span> <span class="c009">layout</span>, <span class="c009">numdims</span>, <span class="c009">p</span>, <span class="c009">dims</span><span class="c003">)</span><p>Return an OCaml big array wrapping the data pointed to by <span class="c009">p</span>.
<span class="c009">kind</span> is the kind of array elements (one of the <span class="c003">CAML_BA_</span>
kind constants above). <span class="c009">layout</span> is <span class="c003">CAML_BA_C_LAYOUT</span> for an
array with C layout and <span class="c003">CAML_BA_FORTRAN_LAYOUT</span> for an array with
Fortran layout. <span class="c009">numdims</span> is the number of dimensions in the
array. <span class="c009">dims</span> is an array of <span class="c009">numdims</span> long integers, giving
the sizes of the array in each dimension.</p></li><li class="li-itemize"><span class="c003">caml_ba_alloc_dims(</span><span class="c009">kind</span> <span class="c003">|</span> <span class="c009">layout</span>, <span class="c009">numdims</span>,
<span class="c009">p</span>, <span class="c003">(long) </span><span class="c009">dim</span><sub>1</sub>, <span class="c003">(long) </span><span class="c009">dim</span><sub>2</sub>, &#X2026;, <span class="c003">(long) </span><span class="c009">dim</span><sub><span class="c009">numdims</span></sub><span class="c003">)</span><p>Same as <span class="c003">caml_ba_alloc</span>, but the sizes of the array in each dimension
are listed as extra arguments in the function call, rather than being
passed as an array.
</p></li></ul><p>
The following example illustrates how statically-allocated C and
Fortran arrays can be made available to OCaml.
</p><pre>    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);
    }
</pre>
<hr>
<a href="libdynlink.html"><img src="previous_motif.gif" alt="Previous"></a>
<a href="index.html"><img src="contents_motif.gif" alt="Up"></a>
<a href="manual047.html"><img src="next_motif.gif" alt="Next"></a>
</body>
</html>