carray-0.1.0.0: A C-compatible array library.Source codeContentsIndex
Data.Array.CArray.Base
Portabilitynon-portable
Stabilityexperimental
Maintainerjed@59A2.org
Description

This module provides both the immutable CArray and mutable IOCArray. The underlying storage is exactly the same - pinned memory on the GC'd heap. Elements are stored according to the class Storable. You can obtain a pointer to the array contents to manipulate elements from languages like C.

CArray is 16-byte aligned by default. If you create a CArray with unsafeForeignPtrToCArray then it may not be aligned. This will be an issue if you intend to use SIMD instructions.

CArray is similar to Data.Array.Unboxed.UArray but slower if you stay within Haskell. CArray can handle more types and can be used by external libraries.

IOCArray is equivalent to Data.Array.Storable.StorableArray and similar to Data.Array.IO.IOUArray but slower. IOCArray has O(1) versions of unsafeFreeze and unsafeThaw when converting to/from CArray.

Synopsis
data CArray i e = CArray !i !i Int !ForeignPtr e
data IOCArray i e = IOCArray !i !i Int !ForeignPtr e
withCArray :: CArray i e -> (Ptr e -> IO a) -> IO a
withIOCArray :: IOCArray i e -> (Ptr e -> IO a) -> IO a
touchIOCArray :: IOCArray i e -> IO ()
unsafeForeignPtrToCArray :: Ix i => ForeignPtr e -> (i, i) -> IO (CArray i e)
unsafeForeignPtrToIOCArray :: Ix i => ForeignPtr e -> (i, i) -> IO (IOCArray i e)
copy :: (Ix i, Storable e) => CArray i e -> IO (CArray i e)
freezeIOCArray :: (Ix i, Storable e) => IOCArray i e -> IO (CArray i e)
unsafeFreezeIOCArray :: Ix i => IOCArray i e -> IO (CArray i e)
thawIOCArray :: (Ix i, Storable e) => CArray i e -> IO (IOCArray i e)
unsafeThawIOCArray :: Ix i => CArray i e -> IO (IOCArray i e)
zeroElem :: Storable a => a -> a
unsafeArrayCArray :: (MArray IOCArray e IO, Storable e, Ix i) => (i, i) -> [(Int, e)] -> e -> IO (CArray i e)
unsafeReplaceCArray :: (MArray IOCArray e IO, Storable e, Ix i) => CArray i e -> [(Int, e)] -> IO (CArray i e)
unsafeAccumCArray :: (MArray IOCArray e IO, Storable e, Ix i) => (e -> e' -> e) -> CArray i e -> [(Int, e')] -> IO (CArray i e)
unsafeAccumArrayCArray :: (MArray IOCArray e IO, Storable e, Ix i) => (e -> e' -> e) -> e -> (i, i) -> [(Int, e')] -> IO (CArray i e)
eqCArray :: (IArray CArray e, Ix i, Eq e) => CArray i e -> CArray i e -> Bool
cmpCArray :: (IArray CArray e, Ix i, Ord e) => CArray i e -> CArray i e -> Ordering
cmpIntCArray :: (IArray CArray e, Ord e) => CArray Int e -> CArray Int e -> Ordering
reshape :: (Ix i, Ix j) => (j, j) -> CArray i e -> CArray j e
flatten :: Ix i => CArray i e -> CArray Int e
rank :: (Shapable i, Ix i, IArray a e) => a i e -> Int
shape :: (Shapable i, Ix i, IArray a e) => a i e -> [Int]
shapeToStride :: [Int] -> [Int]
size :: (Ix i, IArray a e) => a i e -> Int
ixmapWithIndP :: (Ix i, Ix i', IArray a e, IArray a' e') => (i', i') -> (i' -> i) -> (i -> e -> i' -> e') -> a i e -> a' i' e'
ixmapWithInd :: (Ix i, Ix i', IArray a e, IArray a e') => (i', i') -> (i' -> i) -> (i -> e -> i' -> e') -> a i e -> a i' e'
ixmapWithP :: (Ix i, Ix i', IArray a e, IArray a' e') => (i', i') -> (i' -> i) -> (e -> e') -> a i e -> a' i' e'
ixmapWith :: (Ix i, Ix i', IArray a e, IArray a e') => (i', i') -> (i' -> i) -> (e -> e') -> a i e -> a i' e'
ixmapP :: (Ix i, Ix i', IArray a e, IArray a' e) => (i', i') -> (i' -> i) -> a i e -> a' i' e
sliceStrideWithP :: (Ix i, Shapable i, Ix i', IArray a e, IArray a' e') => (i', i') -> (i, i, i) -> (e -> e') -> a i e -> a' i' e'
sliceStrideWith :: (Ix i, Shapable i, Ix i', IArray a e, IArray a e') => (i', i') -> (i, i, i) -> (e -> e') -> a i e -> a i' e'
sliceStrideP :: (Ix i, Shapable i, Ix i', IArray a e, IArray a' e) => (i', i') -> (i, i, i) -> a i e -> a' i' e
sliceStride :: (Ix i, Shapable i, Ix i', IArray a e) => (i', i') -> (i, i, i) -> a i e -> a i' e
sliceWithP :: (Ix i, Shapable i, Ix i', IArray a e, IArray a' e') => (i', i') -> (i, i) -> (e -> e') -> a i e -> a' i' e'
sliceWith :: (Ix i, Shapable i, Ix i', IArray a e, IArray a e') => (i', i') -> (i, i) -> (e -> e') -> a i e -> a i' e'
sliceP :: (Ix i, Shapable i, Ix i', IArray a e, IArray a' e) => (i', i') -> (i, i) -> a i e -> a' i' e
slice :: (Ix i, Shapable i, Ix i', IArray a e) => (i', i') -> (i, i) -> a i e -> a i' e
mapCArrayInPlace :: (Ix i, IArray CArray e, Storable e) => (e -> e) -> CArray i e -> CArray i e
indexes :: (Ix i, Shapable i, IArray a e) => a i e -> i -> [Int]
offsets :: (Ix a, Shapable a) => (a, a) -> a -> [Int]
normp :: (Ix i, RealFloat e', Abs e e', IArray a e) => e' -> a i e -> e'
norm2 :: (Ix i, Floating e', Abs e e', IArray a e) => a i e -> e'
normSup :: (Ix i, Num e', Ord e', Abs e e', IArray a e) => a i e -> e'
liftArrayP :: (Ix i, IArray a e, IArray a1 e1) => (e -> e1) -> a i e -> a1 i e1
liftArray :: (Ix i, IArray a e, IArray a e1) => (e -> e1) -> a i e -> a i e1
liftArray2P :: (Ix i, IArray a e, IArray a1 e1, IArray a2 e2) => (e -> e1 -> e2) -> a i e -> a1 i e1 -> a2 i e2
liftArray2 :: (Ix i, IArray a e, IArray a e1, IArray a e2) => (e -> e1 -> e2) -> a i e -> a i e1 -> a i e2
liftArray3P :: (Ix i, IArray a e, IArray a1 e1, IArray a2 e2, IArray a3 e3) => (e -> e1 -> e2 -> e3) -> a i e -> a1 i e1 -> a2 i e2 -> a3 i e3
liftArray3 :: (Ix i, IArray a e, IArray a e1, IArray a e2, IArray a e3) => (e -> e1 -> e2 -> e3) -> a i e -> a i e1 -> a i e2 -> a i e3
class Shapable i where
sRank :: i -> Int
sShape :: i -> i -> [Int]
sBounds :: [Int] -> (i, i)
class Abs a b | a -> b where
abs_ :: a -> b
unsafeInlinePerformIO :: IO a -> a
mallocForeignPtrArrayAligned :: Storable a => Int -> IO (ForeignPtr a)
mallocForeignPtrBytesAligned :: Int -> IO (ForeignPtr a)
createCArray :: (Ix i, Storable e) => (i, i) -> (Ptr e -> IO ()) -> IO (CArray i e)
unsafeCreateCArray :: (Ix i, Storable e) => (i, i) -> (Ptr e -> IO ()) -> CArray i e
Documentation
data CArray i e Source
The immutable array type.
Constructors
CArray !i !i Int !ForeignPtr e
show/hide Instances
Typeable2 CArray
Storable e => IArray CArray e
(Ix ix, Eq e, IArray CArray e) => Eq (CArray ix e)
(Data i, Typeable e) => Data (CArray i e)
(Ix ix, Ord e, IArray CArray e) => Ord (CArray ix e)
(Ix ix, Show ix, Show e, IArray CArray e) => Show (CArray ix e)
data IOCArray i e Source
Absolutely equivalent representation, but used for the mutable interface.
Constructors
IOCArray !i !i Int !ForeignPtr e
show/hide Instances
withCArray :: CArray i e -> (Ptr e -> IO a) -> IO aSource
The pointer to the array contents is obtained by withCArray. The idea is similar to ForeignPtr (used internally here). The pointer should be used only during execution of the IO action retured by the function passed as argument to withCArray.
withIOCArray :: IOCArray i e -> (Ptr e -> IO a) -> IO aSource
touchIOCArray :: IOCArray i e -> IO ()Source
If you want to use it afterwards, ensure that you touchCArray after the last use of the pointer, so the array is not freed too early.
unsafeForeignPtrToCArray :: Ix i => ForeignPtr e -> (i, i) -> IO (CArray i e)Source
Construct a CArray from an arbitrary ForeignPtr. It is the caller's responsibility to ensure that the ForeignPtr points to an area of memory sufficient for the specified bounds.
unsafeForeignPtrToIOCArray :: Ix i => ForeignPtr e -> (i, i) -> IO (IOCArray i e)Source
copy :: (Ix i, Storable e) => CArray i e -> IO (CArray i e)Source
freezeIOCArray :: (Ix i, Storable e) => IOCArray i e -> IO (CArray i e)Source
unsafeFreezeIOCArray :: Ix i => IOCArray i e -> IO (CArray i e)Source
thawIOCArray :: (Ix i, Storable e) => CArray i e -> IO (IOCArray i e)Source
unsafeThawIOCArray :: Ix i => CArray i e -> IO (IOCArray i e)Source
zeroElem :: Storable a => a -> aSource
Hackish way to get the zero element for a Storable type.
unsafeArrayCArray :: (MArray IOCArray e IO, Storable e, Ix i) => (i, i) -> [(Int, e)] -> e -> IO (CArray i e)Source
unsafeReplaceCArray :: (MArray IOCArray e IO, Storable e, Ix i) => CArray i e -> [(Int, e)] -> IO (CArray i e)Source
unsafeAccumCArray :: (MArray IOCArray e IO, Storable e, Ix i) => (e -> e' -> e) -> CArray i e -> [(Int, e')] -> IO (CArray i e)Source
unsafeAccumArrayCArray :: (MArray IOCArray e IO, Storable e, Ix i) => (e -> e' -> e) -> e -> (i, i) -> [(Int, e')] -> IO (CArray i e)Source
eqCArray :: (IArray CArray e, Ix i, Eq e) => CArray i e -> CArray i e -> BoolSource
cmpCArray :: (IArray CArray e, Ix i, Ord e) => CArray i e -> CArray i e -> OrderingSource
cmpIntCArray :: (IArray CArray e, Ord e) => CArray Int e -> CArray Int e -> OrderingSource
reshape :: (Ix i, Ix j) => (j, j) -> CArray i e -> CArray j eSource
O(1) reshape an array. The number of elements in the new shape must not exceed the number in the old shape. The elements are in C-style ordering.
flatten :: Ix i => CArray i e -> CArray Int eSource
O(1) make a rank 1 array from an arbitrary shape. It has the property that 'reshape (0, size a - 1) a == flatten a'.
rank :: (Shapable i, Ix i, IArray a e) => a i e -> IntSource
Determine the rank of an array.
shape :: (Shapable i, Ix i, IArray a e) => a i e -> [Int]Source
Canonical representation of the shape. The following properties hold: 'length . shape = rank' 'product . shape = size'
shapeToStride :: [Int] -> [Int]Source
How much the offset changes when you move one element in the given direction. Since arrays are in row-major order, 'last . shapeToStride = const 1'
size :: (Ix i, IArray a e) => a i e -> IntSource
Number of elements in the Array.
ixmapWithIndP :: (Ix i, Ix i', IArray a e, IArray a' e') => (i', i') -> (i' -> i) -> (i -> e -> i' -> e') -> a i e -> a' i' e'Source
Generic slice and map. This takes the new range, the inverse map on indices, and function to produce the next element. It is the most general operation in its class.
ixmapWithInd :: (Ix i, Ix i', IArray a e, IArray a e') => (i', i') -> (i' -> i) -> (i -> e -> i' -> e') -> a i e -> a i' e'Source
Less polymorphic version.
ixmapWithP :: (Ix i, Ix i', IArray a e, IArray a' e') => (i', i') -> (i' -> i) -> (e -> e') -> a i e -> a' i' e'Source
Perform an operation on the elements, independent of their location.
ixmapWith :: (Ix i, Ix i', IArray a e, IArray a e') => (i', i') -> (i' -> i) -> (e -> e') -> a i e -> a i' e'Source
Less polymorphic version.
ixmapP :: (Ix i, Ix i', IArray a e, IArray a' e) => (i', i') -> (i' -> i) -> a i e -> a' i' eSource
More polymorphic version of ixmap.
sliceStrideWithP :: (Ix i, Shapable i, Ix i', IArray a e, IArray a' e') => (i', i') -> (i, i, i) -> (e -> e') -> a i e -> a' i' e'Source
More friendly sub-arrays with element mapping.
sliceStrideWith :: (Ix i, Shapable i, Ix i', IArray a e, IArray a e') => (i', i') -> (i, i, i) -> (e -> e') -> a i e -> a i' e'Source
Less polymorphic version.
sliceStrideP :: (Ix i, Shapable i, Ix i', IArray a e, IArray a' e) => (i', i') -> (i, i, i) -> a i e -> a' i' eSource
Strided sub-array without element mapping.
sliceStride :: (Ix i, Shapable i, Ix i', IArray a e) => (i', i') -> (i, i, i) -> a i e -> a i' eSource
Less polymorphic version.
sliceWithP :: (Ix i, Shapable i, Ix i', IArray a e, IArray a' e') => (i', i') -> (i, i) -> (e -> e') -> a i e -> a' i' e'Source
Contiguous sub-array with element mapping.
sliceWith :: (Ix i, Shapable i, Ix i', IArray a e, IArray a e') => (i', i') -> (i, i) -> (e -> e') -> a i e -> a i' e'Source
Less polymorphic version.
sliceP :: (Ix i, Shapable i, Ix i', IArray a e, IArray a' e) => (i', i') -> (i, i) -> a i e -> a' i' eSource
Contiguous sub-array without element mapping.
slice :: (Ix i, Shapable i, Ix i', IArray a e) => (i', i') -> (i, i) -> a i e -> a i' eSource
Less polymorphic version.
mapCArrayInPlace :: (Ix i, IArray CArray e, Storable e) => (e -> e) -> CArray i e -> CArray i eSource
In-place map on CArray. Note that this is IN PLACE so you should not retain any reference to the original. It flagrantly breaks referential transparency!
indexes :: (Ix i, Shapable i, IArray a e) => a i e -> i -> [Int]Source
offsets :: (Ix a, Shapable a) => (a, a) -> a -> [Int]Source
normp :: (Ix i, RealFloat e', Abs e e', IArray a e) => e' -> a i e -> e'Source
p-norm on the array taken as a vector
norm2 :: (Ix i, Floating e', Abs e e', IArray a e) => a i e -> e'Source
2-norm on the array taken as a vector (Frobenius norm for matrices)
normSup :: (Ix i, Num e', Ord e', Abs e e', IArray a e) => a i e -> e'Source
Sup norm on the array taken as a vector
liftArrayP :: (Ix i, IArray a e, IArray a1 e1) => (e -> e1) -> a i e -> a1 i e1Source
Polymorphic version of amap.
liftArray :: (Ix i, IArray a e, IArray a e1) => (e -> e1) -> a i e -> a i e1Source
Equivalent to amap. Here for consistency only.
liftArray2P :: (Ix i, IArray a e, IArray a1 e1, IArray a2 e2) => (e -> e1 -> e2) -> a i e -> a1 i e1 -> a2 i e2Source
Polymorphic 2-array lift.
liftArray2 :: (Ix i, IArray a e, IArray a e1, IArray a e2) => (e -> e1 -> e2) -> a i e -> a i e1 -> a i e2Source
Less polymorphic version.
liftArray3P :: (Ix i, IArray a e, IArray a1 e1, IArray a2 e2, IArray a3 e3) => (e -> e1 -> e2 -> e3) -> a i e -> a1 i e1 -> a2 i e2 -> a3 i e3Source
Polymorphic 3-array lift.
liftArray3 :: (Ix i, IArray a e, IArray a e1, IArray a e2, IArray a e3) => (e -> e1 -> e2 -> e3) -> a i e -> a i e1 -> a i e2 -> a i e3Source
Less polymorphic version.
class Shapable i whereSource
We need this type class to distinguish between different tuples of Ix. There are Shapable instances for homogenous Int tuples, but may Haddock doesn't see them.
Methods
sRank :: i -> IntSource
sShape :: i -> i -> [Int]Source
sBounds :: [Int] -> (i, i)Source
show/hide Instances
class Abs a b | a -> b whereSource
Hack so that norms have a sensible type.
Methods
abs_ :: a -> bSource
show/hide Instances
unsafeInlinePerformIO :: IO a -> aSource

This variant of unsafePerformIO is quite mind-bogglingly unsafe. It unstitches the dependency chain that holds the IO monad together and breaks all your ordinary intuitions about IO, sequencing and side effects. Avoid it unless you really know what you are doing.

It is only safe for operations which are genuinely pure (not just externally pure) for example reading from an immutable foreign data structure. In particular, you should do no memory allocation inside an unsafeInlinePerformIO block. This is because an allocation is a constant and is likely to be floated out and shared. More generally, any part of any IO action that does not depend on a function argument is likely to be floated to the top level and have its result shared.

It is more efficient because in addition to the checks that unsafeDupablePerformIO omits, we also inline. Additionally we do not pretend that the body is lazy which allows the strictness analyser to see the strictness in the body. In turn this allows some re-ordering of operations and any corresponding side-effects.

With GHC it compiles to essentially no code and it exposes the body to further inlining.

mallocForeignPtrArrayAligned :: Storable a => Int -> IO (ForeignPtr a)Source
Allocate an array which is 16-byte aligned. Essential for SIMD instructions.
mallocForeignPtrBytesAligned :: Int -> IO (ForeignPtr a)Source
Allocate memory which is 16-byte aligned. This is essential for SIMD instructions. We know that mallocPlainForeignPtrBytes will give word-aligned memory, so we pad enough to be able to return the desired amount of memory after aligning our pointer.
createCArray :: (Ix i, Storable e) => (i, i) -> (Ptr e -> IO ()) -> IO (CArray i e)Source
Make a new CArray with an IO action.
unsafeCreateCArray :: (Ix i, Storable e) => (i, i) -> (Ptr e -> IO ()) -> CArray i eSource
Produced by Haddock version 2.1.0