Migrating from v0.2 to v0.3
Overview
v0.3 is a breaking release that simplifies the API:
acquire!now returnsArray(wasSubArray/ReshapedArray)unsafe_*functions removed (no deprecation period)acquire_view!added for explicit view access
On Julia 1.11+, Array became a mutable struct, enabling zero-allocation wrapper reuse via setfield! — the same guarantee views had. With Array now zero-alloc too, it's the natural default.
API Changes at a Glance
Return type changes
| Function | v0.2 return type | v0.3 return type |
|---|---|---|
acquire!(pool, T, dims...) | SubArray / ReshapedArray | Array{T,N} |
zeros!(pool, T, dims...) | SubArray / ReshapedArray | Array{T,N} |
ones!(pool, T, dims...) | SubArray / ReshapedArray | Array{T,N} |
similar!(pool, x) | SubArray / ReshapedArray | Array{T,N} |
acquire!(pool, Bit, dims...) | BitVector / BitArray{N} | BitVector / BitArray{N} (unchanged) |
trues!(pool, dims...) | BitArray{N} | BitArray{N} (unchanged) |
falses!(pool, dims...) | BitArray{N} | BitArray{N} (unchanged) |
reshape!(pool, A, dims...) | Array{T,N} | Array{T,N} (unchanged) |
Removed functions
| v0.2 (removed) | v0.3 replacement |
|---|---|
unsafe_acquire!(pool, T, dims...) | acquire!(pool, T, dims...) |
unsafe_zeros!(pool, T, dims...) | zeros!(pool, T, dims...) |
unsafe_ones!(pool, T, dims...) | ones!(pool, T, dims...) |
unsafe_similar!(pool, x) | similar!(pool, x) |
New functions
| Function | Returns | Description |
|---|---|---|
acquire_view!(pool, T, dims...) | SubArray / ReshapedArray | Old acquire! behavior (explicit opt-in) |
acquire_array!(pool, T, dims...) | Array{T,N} | Alias for acquire! (symmetric naming) |
Search-and-Replace Guide
For most codebases, a simple find-and-replace handles the migration:
unsafe_acquire! → acquire! (or just delete "unsafe_" prefix)
unsafe_zeros! → zeros!
unsafe_ones! → ones!
unsafe_similar! → similar!If you were using acquire! specifically for its view return type, switch to acquire_view!:
acquire!(pool, T, dims...) → acquire_view!(pool, T, dims...)Code Examples
Basic migration
# ── v0.2 ──────────────────────────────────────────
v = acquire!(pool, Float64, 100) # SubArray{Float64,1}
a = unsafe_acquire!(pool, Float64, 100) # Array{Float64,1}
z = unsafe_zeros!(pool, Float64, 10, 10) # Array{Float64,2}
# ── v0.3 ──────────────────────────────────────────
a = acquire!(pool, Float64, 100) # Array{Float64,1} ← now Array!
v = acquire_view!(pool, Float64, 100) # SubArray{Float64,1} ← explicit opt-in
z = zeros!(pool, Float64, 10, 10) # Array{Float64,2} ← always Array nowIf you relied on view types
Code that depended on acquire! returning SubArray needs updating:
# ── v0.2 ──────────────────────────────────────────
v = acquire!(pool, Float64, 100)
@assert v isa SubArray # ← was true
# ── v0.3 ──────────────────────────────────────────
v = acquire_view!(pool, Float64, 100)
@assert v isa SubArray # ← still true with acquire_view!
# Or embrace the new default:
a = acquire!(pool, Float64, 100)
@assert a isa Array # ← true in v0.3Type assertions in tests
If your tests asserted view types, update them:
# ── v0.2 ──────────────────────────────────────────
@test v isa SubArray
# ── v0.3 ──────────────────────────────────────────
@test v isa Array # for acquire!
@test v isa SubArray # for acquire_view! (1D)
@test v isa Base.ReshapedArray # for acquire_view! (N-D)Why Array is Better as Default
| Property | Array | SubArray/ReshapedArray |
|---|---|---|
FFI/ccall (Ptr{T}) | Works directly | Needs parent() conversion |
::Array{T,N} constraints | Satisfies directly | Type error |
| BLAS/LAPACK | Compatible | Compatible |
| Zero-alloc reuse (1.11+) | Yes (setfield!) | Yes (always was) |
| User expectation | Natural | Surprising ("why SubArray?") |
Special Cases
Bit arrays — no change
acquire!(pool, Bit, ...) still returns BitVector/BitArray{N}, not Array{Bool}. The Bit sentinel is unchanged:
mask = acquire!(pool, Bit, 1000) # BitVector in both v0.2 and v0.3
bits = trues!(pool, 10, 10) # BitArray{2} in both versionsCUDA — no behavioral change
On CUDA, both acquire! and acquire_view! return CuArray. There is no view/array distinction on GPU:
using CUDA
a = acquire!(pool, Float32, 100) # CuArray{Float32,1}
v = acquire_view!(pool, Float32, 100) # CuArray{Float32,1} (same)Julia 1.10 LTS
v0.3 still supports Julia 1.10, but the zero-allocation Array reuse via setfield! only works on Julia 1.11+. On 1.10, acquire! returns a freshly constructed Array wrapper (the underlying buffer is still reused — only the wrapper allocates ~40 bytes).
FAQ
Q: Will my v0.2 code break immediately? Yes — if you used any unsafe_* function, it will be an UndefVarError at runtime. The search-and-replace above fixes this in seconds.
Q: Do I need acquire_view! at all? Most users don't. acquire_view! exists for the rare case where you need a SubArray reference into the pool's backing storage (e.g., for custom memory layouts or view-specific dispatch).
Q: Is there a performance difference between acquire! and acquire_view!? Both are zero-allocation on Julia 1.11+. The only difference is the returned wrapper type.