# MemViews.jl - practical, simple, low-level views into Memory

**URL:** https://discourse.julialang.org/t/memviews-jl-practical-simple-low-level-views-into-memory/116043
**Category:** Package Announcements
**Created:** [June 22, 2024, 10:28am UTC](https://discourse.julialang.org/t/memviews-jl-practical-simple-low-level-views-into-memory/116043 "2024-06-22T10:28:04Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![jakobnissen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jakobnissen/32/13477_2.png) [@jakobnissen](https://discourse.julialang.org/u/jakobnissen)
#### Post date: [June 22, 2024, 10:28am UTC](https://discourse.julialang.org/t/memviews-jl-practical-simple-low-level-views-into-memory/116043/1 "2024-06-22T10:28:04Z")

</div>

# ANN: MemViews.jl - low-level view into Memory{T}

MemViews.jl is a small package that introduces two new types:

- `MemView` is a view into `Memory{T}`
- `MemKind(T::Type)` is a trait signalling if `T` can be represented as memory.

MemViews.jl requires Julia the last Julia 1.11 release branch or master (it does not work on Julia 1.11-beta2).  
It is currently [undergoing registration](https://github.com/JuliaRegistries/General/pull/109566).

The `MemView` type has the following important features compared to `SubArray`:

- It has a concrete, simple memory layout, because it is not generic over the underlying `AbstractArray` or index type.  
This makes it much easier to reason about low-level considerations such as whether you can take a pointer to the view, and what stride it has, and what dimensionality it has, and whether it uses one-based indexing, and much else.  
Practically speaking, this makes it easier to write correct code.
- The `MemKind` trait makes it easier to write specialized implementations for dense, memory backed arrays. In contrast, it’s difficult to select the correct subtypes of `SubArray` (or `AbstractArray`) that are dense and memory-backed.
- Mutability or immutability is statically encoded into the type as either `MemView{T, :mutable}` or `MemView{T, :immutable}`. This makes it more difficult to e.g. accidentally mutate a string, even in code where you regularly manipulate strings with pointers or `ccall`s.

Please see the documentation for more information:

- [Basic usage](https://biojulia.dev/MemViews.jl/dev/#MemViews.jl)
- [Writing interfaces with MemKind](https://biojulia.dev/MemViews.jl/dev/interfaces/)
- [An argument for MemViews in Base](https://biojulia.dev/MemViews.jl/dev/base/)

Also, see [the related Julia issue](https://github.com/JuliaLang/julia/issues/54581)

I’ve already been dogfooding MemViews.jl by developing the upcoming [XAMAuxData.jl](https://github.com/BioJulia/XAMAuxData.jl) and [PairwiseMappingFormat.jl](https://github.com/BioJulia/PairwiseMappingFormat.jl) and I must say it’s been quite nice to use, API-wise.

I’d like to express my appreciation for the work of @Oscar_Smith and @jameson , whose work on the underlying Julia types `Memory` and `MemoryRef` has made this package possible.

**Please give feedback on the package’s design etc**

## Example

```julia
julia> MemView([1, 2, 3]) |> typeof
MutableMemView{Int64} (alias for MemView{Int64, :mutable})

julia> MemView(view(codeunits("abc"), Base.OneTo(0x02))) |> typeof
ImmutableMemView{UInt8} (alias for MemView{UInt8, :immutable})

julia> immutable = MemView("abc");

julia> unsafe_copyto!(immutable, MemView([0x01, 0x02, 0x03]))
ERROR: MethodError: no method matching unsafe_copyto!(::ImmutableMemView{UInt8}, ::MutableMemView{UInt8})

```

---

<div class="post-metadata">

### Author: ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)
#### Post date: [June 22, 2024, 2:20pm UTC](https://discourse.julialang.org/t/memviews-jl-practical-simple-low-level-views-into-memory/116043/2 "2024-06-22T14:20:40Z")

</div>

For some low-level IO package applications, I have long been struggling with exactly this:

> [@jakobnissen](#):
>
> In contrast, it’s difficult to select the correct subtypes of `SubArray` (or `AbstractArray`) that are dense and memory-backed.

So I immediately tried this:

```julia
julia> a = ImmutableMemView([1, 2, 3])
3-element ImmutableMemView{Int64}:
 1
 2
 3

julia> reinterpret(Int32, a)
6-element reinterpret(Int32, ::ImmutableMemView{Int64}):

```

this currently doesn’t have special implementation, but what I want essentially is for this to return a `ImmutableMemView{Int32}` – this would solve the problem of “difficult to pre-select correct types”

---

<div class="post-metadata">

### Author: ![jakobnissen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jakobnissen/32/13477_2.png) [@jakobnissen](https://discourse.julialang.org/u/jakobnissen)
#### Post date: [June 22, 2024, 3:04pm UTC](https://discourse.julialang.org/t/memviews-jl-practical-simple-low-level-views-into-memory/116043/3 "2024-06-22T15:04:17Z")

</div>

See [the Limitations section of the README](https://github.com/BioJulia/MemViews.jl?tab=readme-ov-file#limitations) and also [this Discourse thread](https://discourse.julialang.org/t/memory-aliasing-rules-and-reinterpret/109875)

I also tried to make that work, but couldn’t. The reason is that it’s not possible to construct a `MemoryRef{B}` from a `MemoryRef{A}`.  
It can be done incurring an allocation by making a new `Memory` object that aliases the old one, and then taking a view of that.  
However, the docs of `unsafe_wrap` states:

> Unlike unsafe\_load and unsafe\_store!, the programmer is responsible also  
> for ensuring that the underlying data is not accessed through two arrays of different element type, similar to the strict aliasing rule in C.

I believe it might be UB to create a `MemView{A}` object pointing to `Memory{B}. The [proposed docs on UB in Julia](https://github.com/JuliaLang/julia/pull/54099) states that it’s UB to cause:

> Violations of TBAA guarantees (e.g. using `unsafe_wrap`)

---

<div class="post-metadata">

### Author: ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)
#### Post date: [June 22, 2024, 3:19pm UTC](https://discourse.julialang.org/t/memviews-jl-practical-simple-low-level-views-into-memory/116043/4 "2024-06-22T15:19:16Z")

</div>

yeah. that would be UB

---

<div class="post-metadata">

### Author: ![camilogarciabotero](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/camilogarciabotero/32/35000_2.png) [@camilogarciabotero](https://discourse.julialang.org/u/camilogarciabotero)
#### Post date: [June 22, 2024, 5:12pm UTC](https://discourse.julialang.org/t/memviews-jl-practical-simple-low-level-views-into-memory/116043/5 "2024-06-22T17:12:21Z")

</div>

> [@jakobnissen](#):
>
> [XAMAuxData.jl](https://github.com/BioJulia/XAMAuxData.jl) and [PairwiseMappingFormat.jl](https://github.com/BioJulia/PairwiseMappingFormat.jl)

Are those links placeholders? they seem to be broken.

Fantastic work @jakobnissen! Thanks for all your efforts to make BioJulia even better.

---

<div class="post-metadata">

### Author: ![jakobnissen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jakobnissen/32/13477_2.png) [@jakobnissen](https://discourse.julialang.org/u/jakobnissen)
#### Post date: [June 22, 2024, 5:32pm UTC](https://discourse.julialang.org/t/memviews-jl-practical-simple-low-level-views-into-memory/116043/6 "2024-06-22T17:32:35Z")

</div>

Thanks for the kind words!  
The repos were private. I’ve now made them public as they are almost complete.
