UnsafeArrays provides stack-allocated pointer-based array views for Julia.
This package is mainly intended as a workaround for Julia issue #14955 (non-allocating array views). This issue is solved in Julia v1.5 and higher.
In Julia versions 1.4 and below, the Julia compiler is sometimes able to elide heap-allocation of views in some, but cannot always do so. If the view can't be elided, the relative cost of allocation and garbage collection of a views is usually still small, in single-threaded applications. But in in multi-threaded applications that use a large number of views, this cost can quickly become prohibitive and views must either be avoided (resulting in more lengthy and less readable code), or some form stack-allocated views must be used for decent scalability. UnsafeArrays provides such a solution. With Julia v1.5 and higher, using UnsafeArrays should not be necessary and is not likely to result in significant performance gains.
Starting with v1.5, Julia can allocate immutable objects that contain heap references on the stack, making UnsafeArrays.jl largely unnecessary. It may still be useful as a lightweight wrapper for memory allocated outside of Julia's memory management.
using Base.Threads, LinearAlgebra function colnorms!(dest::AbstractVector, A::AbstractMatrix) @threads for i in axes(A, 2) dest[i] = norm(view(A, :, i)) end dest end A = rand(50, 100000); dest = similar(A, size(A, 2)); colnorms!(dest, A)
The above will run fine on a single thread, but scales badly on multiple
threads. Use the
@uviews macro provided by UnsafeArrays to replace A with an
UnsafeArray within the scope of the macro. An
stack-allocated, and so are all views of it, e.g. within
using UnsafeArrays @uviews A begin colnorms!(dest, A) end
@uviews protects the original array
A from GC, so the above is safe as
long as the original array is not reallocated (via
resize!, etc.) while the
@uviews is active.
UnsafeArrays only supports bits types. If the element type of an array is not compatible, @uviews will simply use the original array.
UnsafeArrays also provides:
A non macro-variant
uview()to directly get an unsafe view (with optional sub-indexing) of an array.
UnsafeArrayitself, instances can be constructed from a data pointer and array size. The data type must be a bits type.
UnsafeArray directly, the user is responsible for
preserving the memory accessed from garbage collection.