Skip to content

Commit 1b8fa4d

Browse files
committed
Initial commit
0 parents  commit 1b8fa4d

File tree

7 files changed

+248
-0
lines changed

7 files changed

+248
-0
lines changed

.github/workflows/CI.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: CI
2+
on:
3+
- push
4+
- pull_request
5+
jobs:
6+
test:
7+
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }}
8+
runs-on: ${{ matrix.os }}
9+
strategy:
10+
fail-fast: false
11+
matrix:
12+
version:
13+
- '1.1'
14+
- '1.2'
15+
- '1.3'
16+
- '1.4'
17+
- '1.5'
18+
- 'nightly'
19+
os:
20+
- ubuntu-latest
21+
# - macos-latest
22+
# - windows-latest
23+
arch:
24+
- x64
25+
steps:
26+
- uses: actions/checkout@v2
27+
- uses: julia-actions/setup-julia@latest
28+
with:
29+
version: ${{ matrix.version }}
30+
arch: ${{ matrix.arch }}
31+
- uses: julia-actions/julia-buildpkg@latest
32+
- uses: julia-actions/julia-runtest@latest

.github/workflows/TagBot.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
name: TagBot
2+
on:
3+
schedule:
4+
- cron: 0 * * * *
5+
jobs:
6+
TagBot:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- uses: JuliaRegistries/TagBot@v1
10+
with:
11+
token: ${{ secrets.GITHUB_TOKEN }}
12+
ssh: ${{ secrets.TAGBOT_DEPLOY_KEY }}

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2019 Analytech Solutions
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Project.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
name = "AlignedArrays"
2+
uuid = "1603b9d5-f456-4bc7-93d8-0a6ecb110267"
3+
authors = ["Keith Rutkowski <[email protected]>"]
4+
version = "0.1.0"
5+
6+
[deps]
7+
Mmap = "a63ad114-7e13-5084-954f-fe012c677804"
8+
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
9+
10+
[compat]
11+
julia = "^1.3"

README.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# AlignedArrays.jl
2+
3+
[![Build Status](https://github.com/analytech-solutions/AlignedArrays.jl/workflows/CI/badge.svg)](https://github.com/analytech-solutions/AlignedArrays.jl/actions)
4+
5+
Array wrappers for working with aligned memory allocations suitable for efficient GPU and RDMA transfers.
6+
7+
8+
# Usage
9+
10+
AlignedArrays.jl is still in early development, and currently only works for Linux systems.
11+
Basic usage follows that of standard Array, Vector, Matrix types, but with the added parameter depicting the alignment of the array's memory.
12+
Use `AlignedArray`, `AlignedVector`, or `AlignedMatrix` to specify memory alignment as a type parameter.
13+
We provide `PageAlignedArray`, `PageAlignedArray`, and `PageAlignedArray` for convenience when allocations using the system's page-alignment is desired.
14+
15+
```jl
16+
julia> using AlignedArrays
17+
18+
julia> x = Vector{Int32}(undef, 5)
19+
5-element Array{Int32,1}:
20+
1897413280
21+
32662
22+
1826880912
23+
32662
24+
1730212208
25+
26+
julia> y = PageAlignedVector{Int32}(undef, 5)
27+
5-element Array{Int32,1}:
28+
0
29+
0
30+
0
31+
0
32+
0
33+
34+
julia> z = AlignedVector{Int32, 1024}(undef, 5)
35+
5-element Array{Int32,1}:
36+
-1
37+
-1
38+
-1
39+
-1
40+
-1
41+
42+
julia> typeof(y)
43+
AlignedArray{Int32,1,4096}
44+
45+
julia> typeof(z)
46+
AlignedArray{Int32,1,1024}
47+
48+
julia> pointer(x)
49+
Ptr{Int32} @0x00007f966a213850
50+
51+
julia> pointer(y)
52+
Ptr{Int32} @0x00000000029cf000
53+
54+
julia> pointer(z)
55+
Ptr{Int32} @0x00000000029fd800
56+
57+
julia> y .= x
58+
5-element Array{Int32,1}:
59+
1897413280
60+
32662
61+
1826880912
62+
32662
63+
1730212208
64+
65+
julia> for i in y
66+
println(i)
67+
end
68+
1897413280
69+
32662
70+
1826880912
71+
32662
72+
1730212208
73+
74+
```
75+

src/AlignedArrays.jl

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
module AlignedArrays
2+
import Mmap
3+
4+
5+
export AlignedArray, AlignedVector, AlignedMatrix, AlignedVecOrMat
6+
export PageAlignedArray, PageAlignedVector, PageAlignedMatrix, PageAlignedVecOrMat
7+
8+
9+
const PAGESIZE = Mmap.PAGESIZE
10+
11+
12+
struct AlignedArray{T, N, A} <: DenseArray{T, N}
13+
parent::Array{T, N}
14+
addr::Ref{Ptr{Cvoid}}
15+
16+
function AlignedArray{T, N, A}(::UndefInitializer, dims::NTuple{N, Integer}) where {T, N, A}
17+
ispow2(A) || error("Alignment must be a power of two")
18+
isconcretetype(T) || error("Element type must be a concrete type")
19+
20+
size = isempty(dims) ? 0 : reduce(*, dims)
21+
@static if Sys.islinux()
22+
addr = Ref(C_NULL)
23+
ccall(:posix_memalign, Cint, (Ptr{Ptr{Cvoid}}, Csize_t, Csize_t), addr, A, size) == 0 || error("Failed to allocate aligned memory")
24+
else
25+
error("Operating system not yet supported")
26+
end
27+
28+
a = new{T, N, A}(unsafe_wrap(Array{T, N}, reinterpret(Ptr{T}, addr[]), dims, own = false), addr)
29+
finalizer(a.addr) do x
30+
@static if Sys.islinux()
31+
ccall(:free, Cvoid, (Ptr{Cvoid},), x[])
32+
end
33+
end
34+
return a
35+
end
36+
end
37+
38+
AlignedArray{T, N, A}(u::UndefInitializer, dims::Integer...) where {T, N, A} = AlignedArray{T, N, A}(u, dims)
39+
40+
const AlignedVector{T, A} = AlignedArray{T, 1, A}
41+
const AlignedMatrix{T, A} = AlignedArray{T, 2, A}
42+
const AlignedVecOrMat{T, A} = Union{AlignedVector{T, A}, AlignedMatrix{T, A}}
43+
44+
const PageAlignedArray{T, N} = AlignedArray{T, N, PAGESIZE}
45+
const PageAlignedVector{T} = AlignedVector{T, PAGESIZE}
46+
const PageAlignedMatrix{T} = AlignedMatrix{T, PAGESIZE}
47+
const PageAlignedVecOrMat{T} = AlignedVecOrMat{T, PAGESIZE}
48+
49+
50+
Base.parent(a::AlignedArray) = a.parent
51+
52+
Base.pointer(a::AlignedArray) = pointer(parent(a))
53+
54+
Base.size(a::AlignedArray) = size(parent(a))
55+
Base.length(a::AlignedArray) = length(parent(a))
56+
Base.axes(a::AlignedArray) = axes(parent(a))
57+
58+
Base.IndexStyle(::Type{A}) where {T, N, A<:AlignedArray{T, N}} = IndexStyle(Array{T, N})
59+
Base.getindex(a::AlignedArray, args...) = getindex(parent(a), args...)
60+
Base.setindex!(a::AlignedArray, args...) = setindex!(parent(a), args...)
61+
Base.iterate(a::AlignedArray, args...) = iterate(parent(a), args...)
62+
63+
Base.similar(a::AlignedArray, args...) = similar(parent(a), args...)
64+
65+
Base.show(io::IO, m::MIME"text/plain", a::AlignedArray) = show(io, m, parent(a))
66+
end

test/runtests.jl

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using Test: @testset, @test, @test_throws, @test_broken
2+
using AlignedArrays
3+
4+
5+
@testset "AlignedArrays" begin
6+
@testset "AlignedArrays" begin
7+
a = AlignedVector{Int, 256}(undef, 3)
8+
@test eltype(a) === Int
9+
@test length(a) === 3
10+
@test reinterpret(Int, pointer(a)) % 256 == 0
11+
12+
a[1] = 1234
13+
@test a[1] == 1234
14+
a .= zeros(Int, 3)
15+
@test a[1] == a[2] == a[3] == 0
16+
end
17+
18+
19+
@testset "PageAlignedArrays" begin
20+
a = PageAlignedVector{Int}(undef, 3)
21+
@test eltype(a) === Int
22+
@test length(a) === 3
23+
@test reinterpret(Int, pointer(a)) % AlignedArrays.PAGESIZE == 0
24+
25+
a[1] = 1234
26+
@test a[1] == 1234
27+
a .= zeros(Int, 3)
28+
@test a[1] == a[2] == a[3] == 0
29+
end
30+
end
31+

0 commit comments

Comments
 (0)