AllocArrays

API Documentation for AllocArrays. See also the README at that link for more examples and notes.

Public API

Array types

AllocArrays.AllocArrayType
struct AllocArray{T,N,A<:AbstractArray{T,N}} <: AbstractArray{T,N}
    arr::A
end

Wrapper type which forwards most array methods to the inner array arr, but dispatches similar to special allocation methods.

AllocArrays.CheckedAllocArrayType
CheckedAllocArray(arr::AbstractArray)

"Slow but safe" version of AllocArray.

Keeps track of whether or not its memory is valid. All accesses to the array first check if the memory is still valid, and throw an InvalidMemoryException if not.

If the array has memory allocated via a BumperAllocator, when the BumperAllocator is reset via reset!, its memory will be marked invalid.

Uses locks to ensure concurrency safety to avoid races between deallocating memory on one task (with reset!) while accessing it on another task (e.g. getindex). However, this array is as unsafe as any other to write and read its contents simultaneously with multiple tasks. (i.e. locks are used only to ensure validity of the memory backing the array when the memory is accessed, not to remove data races when using the array as usual).

See also: AllocArray.

Allocators

AllocArrays.BumperAllocatorType
BumperAllocator(b::AllocBuffer)

Use with with_allocator to dispatch similar calls for AllocArrays and CheckedAllocArrays to allocate using the buffer b, an AllocBuffer provided by Bumper.jl.

Uses a lock to serialize allocations to the buffer b, which should allow safe concurrent usage.

Used with reset! to deallocate. Note it is not safe to deallocate while another task may be allocating, except with CheckedAllocArrays which will error appropriately.

See also: UncheckedBumperAllocator.

Example

using AllocArrays, Bumper

b = BumperAllocator(AllocBuffer(2^24)) # 16 MiB
input = AllocArray([1,2,3])
c = Channel(Inf)
with_allocator(b) do
    # ...code with may be multithreaded but which must not escape or return newly-allocated AllocArrays...
    @sync for i = 1:10
        Threads.@spawn put!(c, sum(input .+ i))
    end
    reset!(b) # called outside of threaded region
    close(c)
end
sum(collect(c))

# output
225
AllocArrays.reset!Function
reset!(B::UncheckedBumperAllocator)

Resets the UncheckedBumperAllocator, deallocating all of the arrays created by it.

This must only be used if those arrays will not be accessed again.

It is not safe to deallocate on one task while using the allocator to allocate on another task. Therefore this should only be called outside of threaded regions of code.

reset!(b::BumperAllocator)

Resets the BumperAllocator, deallocating all of the arrays created by it.

This must only be used if those arrays will not be accessed again. However, CheckedAllocArrays allocated by this allocator will be marked invalid, causing future accesses to them to error, as a safety feature. AllocArrays have no such safety feature, and access to them after reset! is unsafe.

It is also not safe to deallocate on one task while using the allocator to allocate on another task. Therefore this should only be called outside of threaded regions of code.

We also provide an unsafe option.

AllocArrays.UncheckedBumperAllocatorType
UncheckedBumperAllocator(b::AllocBuffer)

Use with with_allocator to dispatch similar calls for AllocArrays to allocate using the buffer b, an AllocBuffer provided by Bumper.jl.

Does not support CheckedAllocArray.

This provides a naive & direct interface to allocating on the buffer with no safety checks or locks.

This is unsafe to use if multiple tasks may be allocating simultaneously, and using BumperAllocator is recommended in general.

Used with reset! to deallocate.

See also: BumperAllocator.

Example

using AllocArrays, Bumper

input = AllocArray([1,2,3])
b = UncheckedBumperAllocator(AllocBuffer(2^24)) # 16 MiB
with_allocator(b) do
    # ...code with must not allocate AllocArrays on multiple tasks via `similar` nor escape or return newly-allocated AllocArrays...
    ret = sum(input .* 2)
    reset!(b)
    return ret
end

# output
12