Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrate Bigarray documentation #1779

Merged
merged 1 commit into from May 14, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions Changes
Expand Up @@ -398,6 +398,9 @@ OCaml 4.07
- GPR#1765: manual, ellipsis in code examples
(Florian Angeletti, review and suggestion by Gabriel Scherer)

- GPR#1779: integrate the Bigarray documentation into the main manual.
(Perry E. Metzger, review by Florian Angeletti and Xavier Clerc)

### Compiler distribution build system

- MPR#5219, GPR#1680: use 'install' instead of 'cp' in install scripts
Expand Down
105 changes: 105 additions & 0 deletions manual/manual/cmds/intf-c.etex
Expand Up @@ -2011,6 +2011,111 @@ word is reserved for storing the custom operations; the other
\var{used} and \var{max} are used to control the speed of garbage
collection, as described for "caml_alloc_custom".

\section{Advanced topic: Big arrays and the OCaml-C interface}
\label{s:C-Bigarrays}

This section explains how C stub code that interfaces C or Fortran
code with OCaml code can use big arrays.

\subsection{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.

\subsection{Accessing an OCaml bigarray from C or Fortran}

If \var{v} is a OCaml "value" representing a big array, the expression
"Caml_ba_data_val("\var{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:
\begin{tableau}{|l|l|}{C expression}{Returns}
\entree{"Caml_ba_array_val("\var{v}")->num_dims"}{number of dimensions}
\entree{"Caml_ba_array_val("\var{v}")->dim["\var{i}"]"}{\var{i}-th dimension}
\entree{"Caml_ba_array_val("\var{v}")->flags & BIGARRAY_KIND_MASK"}{kind of array elements}
\end{tableau}
The kind of array elements is one of the following constants:
\begin{tableau}{|l|l|}{Constant}{Element kind}
\entree{"CAML_BA_FLOAT32"}{32-bit single-precision floats}
\entree{"CAML_BA_FLOAT64"}{64-bit double-precision floats}
\entree{"CAML_BA_SINT8"}{8-bit signed integers}
\entree{"CAML_BA_UINT8"}{8-bit unsigned integers}
\entree{"CAML_BA_SINT16"}{16-bit signed integers}
\entree{"CAML_BA_UINT16"}{16-bit unsigned integers}
\entree{"CAML_BA_INT32"}{32-bit signed integers}
\entree{"CAML_BA_INT64"}{64-bit signed integers}
\entree{"CAML_BA_CAML_INT"}{31- or 63-bit signed integers}
\entree{"CAML_BA_NATIVE_INT"}{32- or 64-bit (platform-native) integers}
\end{tableau}
%
The following example shows the passing of a two-dimensional big array
to a C function and a Fortran function.
\begin{verbatim}
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;
}
\end{verbatim}

\subsection{Wrapping a C or Fortran array as an OCaml big array}

A pointer \var{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.
\begin{itemize}
\item
"caml_ba_alloc("\var{kind} "|" \var{layout}, \var{numdims}, \var{p}, \var{dims}")"

Return an OCaml big array wrapping the data pointed to by \var{p}.
\var{kind} is the kind of array elements (one of the "CAML_BA_"
kind constants above). \var{layout} is "CAML_BA_C_LAYOUT" for an
array with C layout and "CAML_BA_FORTRAN_LAYOUT" for an array with
Fortran layout. \var{numdims} is the number of dimensions in the
array. \var{dims} is an array of \var{numdims} long integers, giving
the sizes of the array in each dimension.

\item
"caml_ba_alloc_dims("\var{kind} "|" \var{layout}, \var{numdims},
\var{p}, "(long) "\nth{dim}{1}, "(long) "\nth{dim}{2}, \ldots, "(long) "\nth{dim}{numdims}")"

Same as "caml_ba_alloc", 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.
\end{itemize}
%
The following example illustrates how statically-allocated C and
Fortran arrays can be made available to OCaml.
\begin{verbatim}
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);
}
\end{verbatim}

\section{Advanced topic: cheaper C call}
\label{s:C-cheaper-call}

Expand Down
171 changes: 20 additions & 151 deletions manual/manual/library/libbigarray.etex
Expand Up @@ -2,167 +2,36 @@
\pdfchapterfold{-1}{The bigarray library}
%HEVEA\cutname{libbigarray.html}

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
The "bigarray" library has now been integrated into OCaml's standard
library.

The "bigarray" functionality may now be found in the standard library
\ifouthtml
\ahref{libref/Array.html}{Module \texttt{Array}}.
\ahref{libref/Bigarray.html}{\texttt{Bigarray} module},
\else
section~\ref{Array}.
\texttt{Bigarray} module,
\fi
The main differences between ``big arrays'' and standard OCaml arrays
are as follows:
\begin{itemize}
\item Big arrays are not limited in size, unlike OCaml arrays
("float array" are limited to 2097151 elements on a 32-bit platform,
other "array" types to 4194303 elements).
\item 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.
\item 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
``small'' 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.
\item 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.
\item Big arrays support interesting high-level operations that normal
arrays do not provide efficiently, such as extracting sub-arrays and
``slicing'' a multi-dimensional array along certain dimensions, all
without any copying.
\end{itemize}
%
Programs that use the "bigarray" library must be linked as follows:
except for the "map_file" function which is now
part of the \hyperref[c:unix]{Unix library}. The documentation has
been integrated into the documentation for the standard library.

The legacy "bigarray" library bundled with the compiler is a
compatibility library with exactly the same interface as before,
i.e. with "map_file" included.

We strongly recommend that you port your code to use the standard
library version instead, as the changes required are minimal.

If you choose to use the compatibility library, you must link your
programs as follows:
\begin{alltt}
ocamlc \var{other options} bigarray.cma \var{other files}
ocamlopt \var{other options} bigarray.cmxa \var{other files}
\end{alltt}
For interactive use of the "bigarray" library, do:
For interactive use of the "bigarray" compatibility library, do:
\begin{alltt}
ocamlmktop -o mytop bigarray.cma
./mytop
\end{alltt}
or (if dynamic linking of C libraries is supported on your platform),
start "ocaml" and type "#load \"bigarray.cma\";;".

\ifouthtml
\section{Module {\tt Bigarray}: large, multi-dimensional, numerical arrays}
\begin{links}
\item \ahref{libref/Bigarray.html}{Module \texttt{Bigarray}}
\end{links}

\else
\input{Bigarray.tex}
\fi

\section{Big arrays in the OCaml-C interface}

C stub code that interface C or Fortran code with OCaml code, as
described in chapter~\ref{c:intf-c}, can exploit big arrays as
follows.

\subsection{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.

\subsection{Accessing an OCaml bigarray from C or Fortran}

If \var{v} is a OCaml "value" representing a big array, the expression
"Caml_ba_data_val("\var{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:
\begin{tableau}{|l|l|}{C expression}{Returns}
\entree{"Caml_ba_array_val("\var{v}")->num_dims"}{number of dimensions}
\entree{"Caml_ba_array_val("\var{v}")->dim["\var{i}"]"}{\var{i}-th dimension}
\entree{"Caml_ba_array_val("\var{v}")->flags & BIGARRAY_KIND_MASK"}{kind of array elements}
\end{tableau}
The kind of array elements is one of the following constants:
\begin{tableau}{|l|l|}{Constant}{Element kind}
\entree{"CAML_BA_FLOAT32"}{32-bit single-precision floats}
\entree{"CAML_BA_FLOAT64"}{64-bit double-precision floats}
\entree{"CAML_BA_SINT8"}{8-bit signed integers}
\entree{"CAML_BA_UINT8"}{8-bit unsigned integers}
\entree{"CAML_BA_SINT16"}{16-bit signed integers}
\entree{"CAML_BA_UINT16"}{16-bit unsigned integers}
\entree{"CAML_BA_INT32"}{32-bit signed integers}
\entree{"CAML_BA_INT64"}{64-bit signed integers}
\entree{"CAML_BA_CAML_INT"}{31- or 63-bit signed integers}
\entree{"CAML_BA_NATIVE_INT"}{32- or 64-bit (platform-native) integers}
\end{tableau}
%
The following example shows the passing of a two-dimensional big array
to a C function and a Fortran function.
\begin{verbatim}
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;
}
\end{verbatim}

\subsection{Wrapping a C or Fortran array as an OCaml big array}

A pointer \var{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.
\begin{itemize}
\item
"caml_ba_alloc("\var{kind} "|" \var{layout}, \var{numdims}, \var{p}, \var{dims}")"

Return an OCaml big array wrapping the data pointed to by \var{p}.
\var{kind} is the kind of array elements (one of the "CAML_BA_"
kind constants above). \var{layout} is "CAML_BA_C_LAYOUT" for an
array with C layout and "CAML_BA_FORTRAN_LAYOUT" for an array with
Fortran layout. \var{numdims} is the number of dimensions in the
array. \var{dims} is an array of \var{numdims} long integers, giving
the sizes of the array in each dimension.

\item
"caml_ba_alloc_dims("\var{kind} "|" \var{layout}, \var{numdims},
\var{p}, "(long) "\nth{dim}{1}, "(long) "\nth{dim}{2}, \ldots, "(long) "\nth{dim}{numdims}")"

Same as "caml_ba_alloc", 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.
\end{itemize}
%
The following example illustrates how statically-allocated C and
Fortran arrays can be made available to OCaml.
\begin{verbatim}
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);
}
\end{verbatim}


1 change: 1 addition & 0 deletions manual/manual/library/libunix.etex
@@ -1,6 +1,7 @@
\chapter{The unix library: Unix system calls}
\pdfchapterfold{-1}{The unix library: Unix system calls}
%HEVEA\cutname{libunix.html}
\label{c:unix}

The "unix" library makes many Unix
system calls and system-related library functions available to
Expand Down
5 changes: 4 additions & 1 deletion manual/manual/library/stdlib.etex
Expand Up @@ -58,7 +58,8 @@ the above 4 modules \\
"Lazy" & p.~\pageref{Lazy} & delayed evaluation \\
"Weak" & p.~\pageref{Weak} & references that don't prevent objects
from being garbage-collected \\
"Ephemeron" & p.~\pageref{Ephemeron} & ephemerons and weak hash tables
"Ephemeron" & p.~\pageref{Ephemeron} & ephemerons and weak hash tables \\
"Bigarray" & p.~\pageref{Bigarray} & large, multi-dimensional, numerical arrays
\end{tabular}
\subsubsection*{Arithmetic:}
\begin{tabular}{lll}
Expand Down Expand Up @@ -103,6 +104,7 @@ be called from C \\
\item \ahref{libref/Arg.html}{Module \texttt{Arg}: parsing of command line arguments}
\item \ahref{libref/Array.html}{Module \texttt{Array}: array operations}
\item \ahref{libref/ArrayLabels.html}{Module \texttt{ArrayLabels}: array operations (with labels)}
\item \ahref{libref/Bigarray.html}{Module \texttt{Bigarray}: large, multi-dimensional, numerical arrays}
\item \ahref{libref/Buffer.html}{Module \texttt{Buffer}: extensible buffers}
\item \ahref{libref/Bytes.html}{Module \texttt{Bytes}: byte sequences}
\item \ahref{libref/BytesLabels.html}{Module \texttt{BytesLabels}: byte sequences (with labels)}
Expand Down Expand Up @@ -151,6 +153,7 @@ be called from C \\
\input{Arg.tex}
\input{Array.tex}
\input{ArrayLabels.tex}
\input{Bigarray.tex}
\input{Buffer.tex}
\input{Bytes.tex}
\input{BytesLabels.tex}
Expand Down
37 changes: 33 additions & 4 deletions stdlib/bigarray.mli
Expand Up @@ -16,13 +16,42 @@
(** Large, multi-dimensional, numerical arrays.

This module implements multi-dimensional arrays of integers and
floating-point numbers, thereafter referred to as 'big arrays'.
floating-point numbers, thereafter referred to as 'big arrays',
to distinguish them from the standard OCaml arrays described in
{!module:Array}.

The implementation allows efficient sharing of large numerical
arrays between OCaml code and C or Fortran numerical libraries.

Concerning the naming conventions, users of this module are encouraged
to do [open Bigarray] in their source, then refer to array types and
operations via short dot notation, e.g. [Array1.t] or [Array2.sub].
The main differences between 'big arrays' and standard OCaml
arrays are as follows:
- Big arrays are not limited in size, unlike OCaml arrays.
(Normal float arrays are limited to 2,097,151 elements on a 32-bit
platform, and normal arrays of other types to 4,194,303 elements.)
- Big arrays are multi-dimensional. Any number of dimensions
between 0 and 16 is supported. In contrast, OCaml arrays
are mono-dimensional and require encoding multi-dimensional
arrays as arrays of arrays.
- Big arrays can only contain integers and floating-point numbers,
while OCaml arrays can contain arbitrary OCaml data types.
- Big arrays provide more space-efficient storage of
integer and floating-point elements than normal OCaml arrays, in
particular because they support 'small' 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.
- 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.
- Big arrays support interesting high-level operations that normal
arrays do not provide efficiently, such as extracting sub-arrays
and 'slicing' a multi-dimensional array along certain dimensions,
all without any copying.

Users of this module are encouraged to do [open Bigarray] in their
source, then refer to array types and operations via short dot
notation, e.g. [Array1.t] or [Array2.sub].

Big arrays support all the OCaml ad-hoc polymorphic operations:
- comparisons ([=], [<>], [<=], etc, as well as {!Pervasives.compare});
Expand Down