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
SwissDict #634
SwissDict #634
Conversation
src/swiss_dict.jl
Outdated
import Base: setindex!, sizehint!, empty!, isempty, length, copy, empty, | ||
getindex, getkey, haskey, iterate, @propagate_inbounds, ValueIterator, | ||
pop!, delete!, get, get!, isbitstype, in, hashindex, isbitsunion, | ||
isiterable, dict_with_eltype, KeySet, Callable, _tablesz, filter! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we always do this per file?
I thought we just did this at the top level file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's there in robin_dict.jl
. Nice suggestion, let me get to it and try to get it out from there as well. I'll remove this from here as well.
src/swiss_dict.jl
Outdated
copy(d::SwissDict) = SwissDict(d) | ||
empty(d::SwissDict, ::Type{K}, ::Type{V}) where {K, V} = SwissDict{K, V}() | ||
|
||
const AnyDict = SwissDict{Any,Any} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is never used and seems unuseful and confusing
src/swiss_dict.jl
Outdated
return dest | ||
end | ||
|
||
empty(a::AbstractDict, ::Type{K}, ::Type{V}) where {K, V} = SwissDict{K, V}() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we chanign the default definition of empty
for all AbstractDicts
?
That doesn't seem right
src/swiss_dict.jl
Outdated
|
||
#hashindex(key, sz) = (((hash(key)%Int) & (sz-1)) + 1)::Int | ||
|
||
##Simd utilities |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
##Simd utilities | |
##SIMD utilities |
Also fun, i haven't touched these llvmcall
for SIMD in ages.
src/swiss_dict.jl
Outdated
@inline function _prefetchr(p::Ptr) | ||
p = reinterpret(UInt, p) | ||
if UInt === UInt64 | ||
Core.Intrinsics.llvmcall(("declare void @llvm.prefetch(i8*, i32, i32, i32)", """ | ||
%ptr = inttoptr i64 %0 to i8* | ||
call void @llvm.prefetch(i8* %ptr, i32 0, i32 3, i32 1) | ||
ret void | ||
"""), Nothing, Tuple{UInt}, p) | ||
else | ||
Core.Intrinsics.llvmcall(("declare void @llvm.prefetch(i8*, i32, i32, i32)", """ | ||
%ptr = inttoptr i32 %0 to i8* | ||
call void @llvm.prefetch(i8* %ptr, i32 0, i32 3, i32 1) | ||
ret void | ||
"""), Nothing, Tuple{UInt}, p) | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we get rid of the if
by interpolating the type string in?
@inline function _prefetchr(p::Ptr) | |
p = reinterpret(UInt, p) | |
if UInt === UInt64 | |
Core.Intrinsics.llvmcall(("declare void @llvm.prefetch(i8*, i32, i32, i32)", """ | |
%ptr = inttoptr i64 %0 to i8* | |
call void @llvm.prefetch(i8* %ptr, i32 0, i32 3, i32 1) | |
ret void | |
"""), Nothing, Tuple{UInt}, p) | |
else | |
Core.Intrinsics.llvmcall(("declare void @llvm.prefetch(i8*, i32, i32, i32)", """ | |
%ptr = inttoptr i32 %0 to i8* | |
call void @llvm.prefetch(i8* %ptr, i32 0, i32 3, i32 1) | |
ret void | |
"""), Nothing, Tuple{UInt}, p) | |
end | |
end | |
@inline function _prefetchr(p::Ptr) | |
p = reinterpret(UInt, p) | |
int_t = Int === Int64 ? "i64" : "int_t" | |
Core.Intrinsics.llvmcall( | |
("declare void @llvm.prefetch(i8*, i32, i32, i32)", | |
""" | |
%ptr = inttoptr $int_t %0 to i8* | |
call void @llvm.prefetch(i8* %ptr, i32 0, i32 3, i32 1) | |
ret void | |
"""), | |
Nothing, Tuple{UInt}, p | |
) | |
end |
src/swiss_dict.jl
Outdated
|
||
@inline function _prefetchw(p::Ptr) | ||
p = reinterpret(UInt, p) | ||
if UInt === UInt64 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
similar to above, can we interpolate the type string in?
src/swiss_dict.jl
Outdated
end | ||
|
||
@propagate_inbounds function _slotget(slots::Vector{_u8x16}, i::Int) | ||
#@boundscheck 0 < i <= length(slots)*16 || throw(BoundsError(slots, 1 + (i-1)>>4) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this commented out?
test/runtests.jl
Outdated
"priority_queue", | ||
"fenwick", | ||
"priority_queue", | ||
"fenwick", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think maybe you did not intend to add this white-space?
Could you post a link to a reference on what are "Swiss dictionaries" ? It's difficult to find relevant results on search engines with these terms, also with "swiss map" ;-) |
@rfourquet |
@eulerkochy Thanks! |
src/swiss_dict.jl
Outdated
p = reinterpret(UInt, p) | ||
if UInt === UInt64 | ||
Core.Intrinsics.llvmcall(("declare void @llvm.prefetch(i8*, i32, i32, i32)", """ | ||
%ptr = inttoptr i64 %0 to i8* | ||
call void @llvm.prefetch(i8* %ptr, i32 0, i32 3, i32 1) | ||
ret void | ||
"""), Nothing, Tuple{UInt}, p) | ||
else | ||
Core.Intrinsics.llvmcall(("declare void @llvm.prefetch(i8*, i32, i32, i32)", """ | ||
%ptr = inttoptr i32 %0 to i8* | ||
call void @llvm.prefetch(i8* %ptr, i32 0, i32 3, i32 1) | ||
ret void | ||
"""), Nothing, Tuple{UInt}, p) | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p = reinterpret(UInt, p) | |
if UInt === UInt64 | |
Core.Intrinsics.llvmcall(("declare void @llvm.prefetch(i8*, i32, i32, i32)", """ | |
%ptr = inttoptr i64 %0 to i8* | |
call void @llvm.prefetch(i8* %ptr, i32 0, i32 3, i32 1) | |
ret void | |
"""), Nothing, Tuple{UInt}, p) | |
else | |
Core.Intrinsics.llvmcall(("declare void @llvm.prefetch(i8*, i32, i32, i32)", """ | |
%ptr = inttoptr i32 %0 to i8* | |
call void @llvm.prefetch(i8* %ptr, i32 0, i32 3, i32 1) | |
ret void | |
"""), Nothing, Tuple{UInt}, p) | |
end | |
ccall("llvm.prefetch", llvmcall, Cvoid, (Ref{Int8}, Int32, Int32, Int32), Ptr{Int8}(p), 0, 3, 1) | |
end |
Co-authored-by: Lyndon White <oxinabox@ucc.asn.au>
Co-authored-by: Lyndon White <oxinabox@ucc.asn.au>
|
h.nbfull += (iszero(index & 0x0f) & (so==0x00)) | ||
_slotset!(h.slots, tag, index) | ||
if index < h.idxfloor | ||
h.idxfloor = index |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need to fix the tests to make sure to cover this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't seem to find a test to cover this. It's quite hard to find a test case specifically for this. But, this serves the purpose of h.idxfloor
, so it isn't wrong.
SwissDict
Part of GSoC'20 work.
Initial code and tests.
Tests run and works.
As of now, the benchmarks aren't favorable.
I'll post the benchmarks once I finish the work on #517
Tasks remaining