Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cut RNTuple allocation by 40% #281

Merged
merged 3 commits into from
Oct 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions src/RNTuple/bootstrap.jl
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,27 @@
return rnt
end

function decompress_bytes(compbytes, NTarget)
function decompress_bytes(compbytes::Vector{UInt8}, NTarget::Integer)
if length(compbytes) >= NTarget
return compbytes

Check warning on line 47 in src/RNTuple/bootstrap.jl

View check run for this annotation

Codecov / codecov/patch

src/RNTuple/bootstrap.jl#L45-L47

Added lines #L45 - L47 were not covered by tests
else
uncomp_data = Vector{UInt8}(undef, NTarget)
decompress_bytes!(uncomp_data, compbytes, NTarget)
return uncomp_data

Check warning on line 51 in src/RNTuple/bootstrap.jl

View check run for this annotation

Codecov / codecov/patch

src/RNTuple/bootstrap.jl#L49-L51

Added lines #L49 - L51 were not covered by tests
end
end

function decompress_bytes!(uncomp_data, compbytes, NTarget::Integer)
resize!(uncomp_data, NTarget)

Check warning on line 56 in src/RNTuple/bootstrap.jl

View check run for this annotation

Codecov / codecov/patch

src/RNTuple/bootstrap.jl#L55-L56

Added lines #L55 - L56 were not covered by tests
# not compressed
length(compbytes) >= NTarget && return compbytes
if length(compbytes) >= NTarget
copyto!(uncomp_data, compbytes)
return uncomp_data

Check warning on line 60 in src/RNTuple/bootstrap.jl

View check run for this annotation

Codecov / codecov/patch

src/RNTuple/bootstrap.jl#L58-L60

Added lines #L58 - L60 were not covered by tests
end

# compressed
io = IOBuffer(compbytes)
fufilled = 0
uncomp_data = Vector{UInt8}(undef, NTarget)
while fufilled < NTarget # careful with 0/1-based index when thinking about offsets
compression_header = unpack(io, CompressionHeader)
cname, _, compbytes, uncompbytes = unpack(compression_header)
Expand Down
39 changes: 25 additions & 14 deletions src/RNTuple/footer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,14 @@
meta_data_links::Vector{EnvLink}
end

function _read_locator(io, locator, uncomp_size)
function _read_locator(io, locator, uncomp_size::Integer)

Check warning on line 57 in src/RNTuple/footer.jl

View check run for this annotation

Codecov / codecov/patch

src/RNTuple/footer.jl#L57

Added line #L57 was not covered by tests
decompress_bytes(read_seek_nb(io, locator.offset, locator.num_bytes), uncomp_size)
end

function _read_locator!(dst::Vector{UInt8}, io, locator, uncomp_size::Integer)
decompress_bytes!(dst, read_seek_nb(io, locator.offset, locator.num_bytes), uncomp_size)

Check warning on line 62 in src/RNTuple/footer.jl

View check run for this annotation

Codecov / codecov/patch

src/RNTuple/footer.jl#L61-L62

Added lines #L61 - L62 were not covered by tests
end

@memoize LRU(maxsize = 200) function _read_envlink(io, link::EnvLink)
_read_locator(io, link.locator, link.uncomp_size)
end
Expand All @@ -68,8 +72,7 @@
end

# https://discourse.julialang.org/t/simd-gather-result-in-slow-down/95161/2
function split2_reinterpret(src::Vector{UInt8})
dst = similar(src)
function split2_reinterpret!(dst, src::Vector{UInt8})

Check warning on line 75 in src/RNTuple/footer.jl

View check run for this annotation

Codecov / codecov/patch

src/RNTuple/footer.jl#L75

Added line #L75 was not covered by tests
count = length(src) ÷ 2
res = reinterpret(UInt16, dst)
@inbounds for i = 1:count
Expand All @@ -78,8 +81,7 @@
end
return dst
end
function split4_reinterpret(src::Vector{UInt8})
dst = similar(src)
function split4_reinterpret!(dst, src::Vector{UInt8})

Check warning on line 84 in src/RNTuple/footer.jl

View check run for this annotation

Codecov / codecov/patch

src/RNTuple/footer.jl#L84

Added line #L84 was not covered by tests
count = length(src) ÷ 4
res = reinterpret(UInt32, dst)
@inbounds for i = 1:count
Expand All @@ -88,8 +90,7 @@
end
return dst
end
function split8_reinterpret(src::Vector{UInt8})
dst = similar(src)
function split8_reinterpret!(dst, src::Vector{UInt8})

Check warning on line 93 in src/RNTuple/footer.jl

View check run for this annotation

Codecov / codecov/patch

src/RNTuple/footer.jl#L93

Added line #L93 was not covered by tests
count = length(src) ÷ 8
res = reinterpret(UInt64, dst)
@inbounds for i = 1:count
Expand All @@ -111,24 +112,34 @@

"""
function read_pagedesc(io, pagedescs::Vector{PageDescription}, nbits::Integer; split=false)
res = map(pagedescs) do pagedesc
output_L = div(sum((p.num_elements for p in pagedescs))*nbits, 8, RoundUp)
res = Vector{UInt8}(undef, output_L)

Check warning on line 116 in src/RNTuple/footer.jl

View check run for this annotation

Codecov / codecov/patch

src/RNTuple/footer.jl#L115-L116

Added lines #L115 - L116 were not covered by tests

# a page max size is 64KB
tmp = Vector{UInt8}(undef, 65536)

Check warning on line 119 in src/RNTuple/footer.jl

View check run for this annotation

Codecov / codecov/patch

src/RNTuple/footer.jl#L119

Added line #L119 was not covered by tests

tip = 1
for i in eachindex(pagedescs)
pagedesc = pagedescs[i]

Check warning on line 123 in src/RNTuple/footer.jl

View check run for this annotation

Codecov / codecov/patch

src/RNTuple/footer.jl#L121-L123

Added lines #L121 - L123 were not covered by tests
# when nbits == 1 for bits, need RoundUp
uncomp_size = div(pagedesc.num_elements * nbits, 8, RoundUp)
tmp = _read_locator(io, pagedesc.locator, uncomp_size)
dst = @view res[tip:tip+uncomp_size-1]
_read_locator!(tmp, io, pagedesc.locator, uncomp_size)

Check warning on line 127 in src/RNTuple/footer.jl

View check run for this annotation

Codecov / codecov/patch

src/RNTuple/footer.jl#L126-L127

Added lines #L126 - L127 were not covered by tests
if !split
tmp
dst .= tmp

Check warning on line 129 in src/RNTuple/footer.jl

View check run for this annotation

Codecov / codecov/patch

src/RNTuple/footer.jl#L129

Added line #L129 was not covered by tests
elseif split
if nbits == 16
split2_reinterpret(tmp)
split2_reinterpret!(dst, tmp)

Check warning on line 132 in src/RNTuple/footer.jl

View check run for this annotation

Codecov / codecov/patch

src/RNTuple/footer.jl#L132

Added line #L132 was not covered by tests
elseif nbits == 32
split4_reinterpret(tmp)
split4_reinterpret!(dst, tmp)

Check warning on line 134 in src/RNTuple/footer.jl

View check run for this annotation

Codecov / codecov/patch

src/RNTuple/footer.jl#L134

Added line #L134 was not covered by tests
elseif nbits == 64
split8_reinterpret(tmp)
split8_reinterpret!(dst, tmp)

Check warning on line 136 in src/RNTuple/footer.jl

View check run for this annotation

Codecov / codecov/patch

src/RNTuple/footer.jl#L136

Added line #L136 was not covered by tests
end
end
tip += uncomp_size

Check warning on line 139 in src/RNTuple/footer.jl

View check run for this annotation

Codecov / codecov/patch

src/RNTuple/footer.jl#L139

Added line #L139 was not covered by tests
end

return reduce(vcat, res)::Vector{UInt8}
return res::Vector{UInt8}

Check warning on line 142 in src/RNTuple/footer.jl

View check run for this annotation

Codecov / codecov/patch

src/RNTuple/footer.jl#L142

Added line #L142 was not covered by tests
end

struct PageLink end
Expand Down
Loading