-
Notifications
You must be signed in to change notification settings - Fork 20
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 stability of NamedArrays #58
Comments
It would, but you have to give a little more context and pointers, because I have no idea what you mean, and the error message is sort-of difficult to parse for me. |
That's not an error message. The problem is that the compiler is not able to infer the return type of the |
Here you have more detailed examples:
and here is a consequence of this:
|
I can see there is a problem, now. So the constructor needs to be changed, then? I don't really understand why the compiler can't figure out the return type of the constructor (my guess is that it would be the type of the constructor, what other type would it be constructing? But apparently things are not that simple). |
The problem is the presence of type parameters. The compiler should be able to find out that the result is a |
Ah thanks, so I should end a constructor with a call to a parent constructor with explicit type parameters, then? I'll try that. (I must say I am still not over the syntax change to the |
If I run f(n)::NTuple{n,Int} = tuple(fill(1, n)...)
@code_warntype f(1)
Variables:
#self# <optimized out>
n::Int64
Body:
begin
return (Core.typeassert)((Base.convert)((Core.apply_type)(Main.NTuple, n::Int64, Main.Int)::Type{Tuple{Vararg{Int64,_}}} where _, (Core._apply)(Main.tuple, $(Expr(:invoke, MethodInstance for fill!(::Array{Int64,1}, ::Int64), :(Base.fill!), :($(Expr(:foreigncall, :(:jl_alloc_array_1d), Array{Int64,1}, svec(Any, Int64), Array{Int64,1}, 0, :(n), 0))), 1)))::Tuple{Vararg{Int64,N} where N})::Tuple{Vararg{Int64,N}} where N, (Core.apply_type)(Main.NTuple, n::Int64, Main.Int)::Type{Tuple{Vararg{Int64,_}}} where _)::Tuple{Vararg{Int64,N}} where N
end::Tuple{Vararg{Int64,N}} where N the |
In that example, the code cannot be type-stable since as you note |
I've tried to stabilize the type in the constructor, see cb253ad. The culprit seems to be But I have two places ensuring Calling I am kind-of debugged-out right now. I might consider to move the defaults for the 1-arg call of |
The problem isn't
I don't think default keyword arguments can affect inferred: they're just like arguments passed manually. So the problem is always inside the function. Are there any other issues? FWIW, I think some of the changes you have made are not really required. In particular, specifying the type parameters isn't useful when they are simply computed by calling |
Thanks again, I ended up in the black hole of trying to figure out what constructor is called, and I am reached a dead end (is that possible in a black hole? I suppose not. There is only the way forward). I commented-out all final constructor calls, and println'ed the entry point of every constructor, and I get an error that a non-existent constructor is called with an amount of arguments for which there is no code. And no result of printlns. The type assertions are attempts to convince the compiler of the type, but apparently still are incomplete. I'll see if your suge=gestions work, now. |
Tried to follow your suggestions in a9bd5ff, but I still get type problem |
Hmm. It appears the type assertion that commit removes is actually needed, and must be more precise: with Note that the best way to ensure this does not regress is to add |
Allright, it was slightly more difficult than that, but in the end it turned out to be If this now works for you guys, I can merge in master and eventually update the version in METADATA. |
Great! Maybe @bkamins can confirm, but yes, a new release would certainly improve performance for all users, and notably FreqTables. |
Great work! Thank you. I have checked the fix-58 branch.
|
Those are probably what you need for freqtables. OK, I'll have a dig at them. |
Thanks! |
Also add @inferred in loads of assignments in the tests, to make sure Julia's type inferrence works for us
The I have trouble finding out which code actually runs issuing a statement like It looks like in |
Yes, that must be the function which is called by Note that in 0.7 the |
I have checked it earlier (unfortunately as you say - this is a bit of digging) and in the end indeed Probably it is best to follow @nalimilan recommendation in the implementation. |
Hi, OK, well, I'll have a quick dig at it then, but maybe concentrate on the type-stability of some other functions as well, and then release this for 0.6. Further fixes (like the |
I don't seem to be able to able to convince Julia what the resulting type of |
No, I think that's solvable, just like
I think for both cases, an approach which could help would use two steps:
I admit that's a bit complex. The key here is to ensure that the helper function are themselves type-stable and that the compiler is able to guess their return types from their input types. Another solution would be to use a generated function. It could work with an organization more similar to the current code, but generated functions are not completely trivial to write either. |
(Truly, I didn't close this issue, Github did that for me.) Thanks for the detailed proposal. I can see why the type-compiler (is this called "inference"?) has problems deducing the Your proposal would take me couple of days to process, I suppose, but I'll have another dig at it. |
Hello @nalimilan I don't get anywhere with type programming, see c299c71 . Even the simplest functionality seems to require a |
Small progress in 891fa55, but can't get |
When working on nalimilan/FreqTables.jl#19 we hit a problem of type inference of
NamedArrays
. Would it be possible to fix it?Inference fails even the simplest constructor:
similar problems propagate to other operations (broadcasting, summing over margins, ...).
The text was updated successfully, but these errors were encountered: