-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Are isbits-Unions isbits? #23567
Comments
The whole point of specializing this C function only for pointer arrays is that the compiler can do all the type checks instead of doing it at runtime so whether or not we make isbits-Union isbits the special case should be moved out of the C function. It was added as a C function only because calling In any case, it seems that you have to implement a separate branch for isbits-Union here since it needs a completely different fast path (two copies, one for content, one for tag) and that branch should be implemented in julia. Therefore, fixing this issue is independent with the value of |
Update: took a stab at making isbits Unions The alternative approach seems much more sane, implemented as the PR #23577. I tried to audit other places in Base where we're branching on function unsafe_convert(P::Type{Ptr{T}}, b::RefValue{T}) where T
if isbits(T)
return convert(P, pointer_from_objref(b))
elseif isleaftype(T)
return convert(P, pointer_from_objref(b.x))
else
# If the slot is not leaf type, it could be either isbits or not.
# If it is actually an isbits type and the type inference can infer that
# it can rebox the `b.x` if we simply call `pointer_from_objref(b.x)` on it.
# Instead, explicitly load the pointer from the `RefValue` so that the pointer
# is the same as the one rooted in the `RefValue` object.
return convert(P, pointerref(Ptr{Ptr{Void}}(pointer_from_objref(b)), 1, 0))
end
end There were also a few cases in deepcopy/serialize, but I thought we had handled those already in the |
I think it can share the |
So we'd have function unsafe_convert(P::Type{Ptr{T}}, b::RefValue{T}) where T
if isbits(T) || isbitsunion(T)
return convert(P, pointer_from_objref(b))
elseif isleaftype(T)
return convert(P, pointer_from_objref(b.x))
else
# If the slot is not leaf type, it could be either isbits or not.
# If it is actually an isbits type and the type inference can infer that
# it can rebox the `b.x` if we simply call `pointer_from_objref(b.x)` on it.
# Instead, explicitly load the pointer from the `RefValue` so that the pointer
# is the same as the one rooted in the `RefValue` object.
return convert(P, pointerref(Ptr{Ptr{Void}}(pointer_from_objref(b)), 1, 0))
end
end ? |
Yes |
We should probably work towards deprecating |
@vtjnash, I had a similar concern looking back over the original isbitsunion(u::Union) = isbitsunion(u.a) & isbitsunion(u.b)
isbitsunion(x) = isbits(x) Still probably not quite as performant as your |
So it looks like my revised definition above is about 22% faster, which is decent, but not quite as fast as I was expecting. So then I decided to just call the same function we call on the backend ( |
Noticed in the current master bug:
The issue is that we currently go thru the codepath in array.jl
but
isbits(Union{Float64, Void})
is false; so we hitjl_array_ptr_copy
. Now, I did had a hook injl_array_ptr_copy
to intercept isbits-Union arrays and handle them specially, the problem is it currently only works when you happen to be copying to the 1st element of the dest array. This is because we only passdest_p
, a pointer and not an index, tojl_array_ptr_copy
, so we don't actually know where to copy selector bytes from src to dest.There a couple of ways to address this:
isbits(Union{Float64, Void}) == true
, this would involve making sure we're careful in a # of places in Base where we're currently checkingisbits(T)
on arrays and doing optimizations (i.e.vcat
,unsafe_copy
,flipdim
). The biggest ? for me in doing this is how this propagates thru the rest of the system, in particular, inference.jl (which has quite a few calls toisbits(T)
.). Overall, I think it would be more correct, but it does seem a bit worrisome not quite knowing the full extent of this kind of change. I can certainly do more research here if we think it's the best way to try out first.jl_array_ptr_copy2
, which also takesind
arguments so we can correctly adjust when copying isbits-Union arrays.Ultimately, I think we should make isbits-Unions isbits, because we're essentially doing that everywhere in
src/
, so we might as well be consistent in Base.cc: @JeffBezanson, @vtjnash
The text was updated successfully, but these errors were encountered: