-
Notifications
You must be signed in to change notification settings - Fork 8
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
Type instability of surfpt_nearby
for abstract Shape
#19
Comments
surfpt_nearby
for abstract Shape
I think now I found the source of this instability. I will spend a few more hours to examine this finding to make sure it is really the source of the instability, and will report back here. |
So it turned out that this instability was related with #6, where we introduced the extra In the above unstable So, to remove the above type instability, we need to embed the information of abstract type Shape{N,L,D} end and define (Another possibility is to define |
It turns out that this issue hasn't been fully resolved yet. Strangely, I still get type instability in the return type of Maybe a Julia bug? Filed an issue at JuliaLang/julia#23210. |
According to JuliaLang/julia#23210, when a function is called with abstract arguments, Julia seems to give up type inference if the function has more than four method definitions. The comments in function abstract_call_gf_by_type(f::ANY, atype::ANY, sv::InferenceState)
tm = _topmod(sv)
# don't consider more than N methods. this trades off between
# compiler performance and generated code performance.
# typically, considering many methods means spending lots of time
# obtaining poor type information.
# It is important for N to be >= the number of methods in the error()
# function, so we can still know that error() is always Bottom.
# here I picked 4. From this comment, I figured that I shouldn't abuse calling a function with abstract arguments. So, as for surfpt_nearby(x::AbstractVector, o::Shape{N}) where {N} = surfpt_nearby(SVector{N}(x), o)
normal(x::AbstractVector, o::Shape) = surfpt_nearby(x, o)[2] with more concrete versions: surfpt_nearby(x::AbstractVector, b::Box{N}) where {N} = surfpt_nearby(SVector{N}(x), b)
surfpt_nearby(x::AbstractVector, s::Cylinder{N}) where {N} = surfpt_nearby(SVector{N}(x), s)
surfpt_nearby(x::AbstractVector, b::Ellipsoid{N}) where {N} = surfpt_nearby(SVector{N}(x), b)
surfpt_nearby(x::AbstractVector, s::Sphere{N}) where {N} = surfpt_nearby(SVector{N}(x), s)
normal(x::AbstractVector, b::Box) = surfpt_nearby(x, b)[2]
normal(x::AbstractVector, s::Cylinder) = surfpt_nearby(x, s)[2]
normal(x::AbstractVector, b::Ellipsoid) = surfpt_nearby(x, b)[2]
normal(x::AbstractVector, s::Sphere) = surfpt_nearby(x, s)[2] I verified that this trick works even if I add more concrete subtypes of Unfortunately, the same trick doesn't work for Base.in(x::AbstractVector, o::Shape{N}) where {N} = SVector{N}(x) in o with Base.in(x::AbstractVector, b::Box{N}) where {N} = in(SVector{N}(x), b)
Base.in(x::AbstractVector, s::Cylinder{N}) where {N} = in(SVector{N}(x), s)
Base.in(x::AbstractVector, b::Ellipsoid{N}) where {N} = in(SVector{N}(x), b)
Base.in(x::AbstractVector, s::Sphere{N}) where {N} = in(SVector{N}(x), s) does not make calling Why does |
Closed via #26. |
Currently
surfpt_nearby
is type-stable for every concrete subtype ofShape{N}
and returnsNTuple{2,SVector{N,Float64}}
. However, whensurfpt_nearby
is called with an abstractShape{N}
object, it is type-unstable. For example, consider the following code:The above
test
function is type-unstable, because the second arguments
ofsurfpt_nearby
is an element ofVector{Shape{3}}
and thus typedShape{3}
:This makes sense. When
surfpt_nearby
is called with an abstractShape
object, the following method defined inGeometryPrimitives.jl
is called:Because the specific type of
o
is not known, the compiler cannot further infer the return type in this case.To resolve this type instability, I tried to change the above method definition using return type annotation:
I thought this would remove the type instability, because now the compiler would know the return type of the above method. Strangely, the type instability remains:
I'm not sure which method of
surfpt_nearby
is being called here. To me, the only method with a matching argument types is the one defined inGeometryPrimitives.jl
, which is now annotated with a return type. Still, the compiler fails to pick up this annotated return type.In fact, if we call
surfpt_nearby
with a regularVector
instead of anSVector
in the first argumentp
, the return type annotation works as intended andtest
becomes type-stable:I don't understand why the return type annotation does not kick in for
SVector
p
. How can we resolve this problem? Any suggestions?The text was updated successfully, but these errors were encountered: