Massiv is a library, that allows creation and manipulation of arrays
in parallel and sequentially. Depending on the representation
(
r), an
Array r ix e will have
certain properties that are unique to that particular representation,
but all of them will share the same trait, that an array is simply a
mapping from an index (
ix) of an arbitrary dimension
to an element (
e) of some value. Which means that some
representations describe classic arrays and are backed by a contiguous
chunk of memory reserved for the elements (or pointers to elements),
namely arrays with
Manifest representations:
- B - The most basic type of array that can hold any type of
element in a boxed form, i.e. each element is a pointer to the actual
value, therefore it is also the slowest representation. Elements are
kept in a Weak Head Normal Form (WHNF).
- BN - Similar to B, it is also a boxed type, except
its elements are always kept in a Normal Form (NF). This property is
very useful for parallel processing, i.e. when calling compute
you do want all of your elements to be fully evaluated.
- BL - Similar to B, it is also a boxed type, but
lazy. Its elements are not evaluated when array is computed.
- S - Is a type of array that is backed by pinned memory,
therefore pointers to those arrays can be passed to FFI calls, because
Garbage Collector (GC) is guaranteed not to move it. Elements must be
an instance of Storable class. It is just as efficient as
P and U arrays, except it is subject to
fragmentation.
- U - Unboxed representation. Elements must be an instance of
Unbox class.
- P - Array that can hold Haskell primitives, such as
Int, Word, Double, etc. Any element must be an
instance of Prim class.
There are also array representations that only describe how values for
its elements can be computed or loaded into memory, as such, they are
represented by functions and do not impose the memory overhead, that
is normally associated with arrays. They are needed for proper fusion
and parallelization of computation.
- D - delayed array that is a mere function from an index to
an element. Also known as Pull array. Crucial representation
for fusing computation. Use computeAs in order to load array
into Manifest representation.
- DL - delayed load array representation that describes how
an array can be loaded. Also known as Push array. Useful for
fusing various array combining functions. Use computeAs in
order to load array into Manifest representation.
- DS - delayed stream vector representation that describes
how to handle a vector with possibility of unknown length. Useful for
filtering and unfolding. Use computeAs in order to load such
vector into Manifest representation.
- DI - delayed interleaved array. Same as D, but
performs better with unbalanced computation, when evaluation of one
element takes much longer than of its neighbor.
- DW - delayed windowed array. This peculiar representation
allows for very fast Stencil computation.
Other Array types:
- L - this type isn't particularly useful on its own, but
because it has unique ability to be converted to and from nested lists
in constant time, it provides a perfect intermediary for conversion of
nested lists into manifest arrays.
Most of the
Manifest arrays are capable of in-place mutation.
Check out
Data.Massiv.Array.Mutable module for available
functionality.
Many of the function names exported by this package will clash with
the ones from
Prelude, hence it can be more convenient to
import like this:
import Prelude as P
import Data.Massiv.Array as A