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

type-inference workq #15300

Merged
merged 7 commits into from
Mar 4, 2016
Merged

type-inference workq #15300

merged 7 commits into from
Mar 4, 2016

Conversation

vtjnash
Copy link
Sponsor Member

@vtjnash vtjnash commented Mar 1, 2016

This changes type inference to use a queue. Benefits thereof include:

  1. Much faster (inference.ji ran in over 90s –> now runs is less than 30s)
  2. Much less stack (old version used ~3-10GB. new version uses < 1GB)
  3. Fewer bugs (fixes type inference bug for multi-cycle functions #9770)
  4. works with very-linear-mode
  5. described in a detailed blog post (http://juliacomputing.com/blog/2016/04/04/inference-convergence.html)
  6. likely can be backport to v0.4 without breaking changes

TODO:

  • squash commits
  • merge VarInfo and InferenceState?

@Keno
Copy link
Member

Keno commented Mar 1, 2016

Amazing 💯 !

@Keno
Copy link
Member

Keno commented Mar 1, 2016

For things like this, it would be good to also have a compile-time benchmark suite (cc @jrevels).

@@ -7,7 +7,7 @@ endof(t::Tuple) = length(t)
size(t::Tuple, d) = d==1 ? length(t) : throw(ArgumentError("invalid tuple dimension $d"))
getindex(t::Tuple, i::Int) = getfield(t, i)
getindex(t::Tuple, i::Real) = getfield(t, convert(Int, i))
getindex(t::Tuple, r::AbstractArray) = tuple([t[ri] for ri in r]...)
getindex(t::Tuple, r::AbstractArray) = tuple(Any[t[ri] for ri in r]...)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this necessary?

@JeffBezanson
Copy link
Sponsor Member

Awesome!! 👍

@@ -291,11 +291,9 @@ function code_typed(f::ANY, types::ANY=Tuple; optimize=true)
for x in _methods(f,types,-1)
linfo = func_for_method_checked(x, types)
if optimize
(tree, ty) = Core.Inference.typeinf(linfo, x[1], x[2], linfo,
true, true)
(tree, ty) = Core.Inference.typeinf(linfo, x[1], x[2], true)
Copy link
Sponsor Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recently made the exact same change to the signature of typeinf on jb/linear. That's encouraging :)

Copy link
Sponsor Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

having a parameter that was always true has confused me for quite some time

(::Type{Matrix})(m::Integer, n::Integer) = Array{Any}(m, n)
(::Type{Matrix})() = Array{Any}(0, 0)
(::Type{Array{T}}){T}(m::Integer) = Array{T,1}(Int(m))
(::Type{Array{T}}){T}(m::Integer, n::Integer) = Array{T,1}(Int(m), Int(n))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Array{T,2}

@timholy
Copy link
Sponsor Member

timholy commented Mar 1, 2016

image

(As in, "the best thing since")

@pkofod
Copy link
Contributor

pkofod commented Mar 1, 2016

Sounds great!

@vtjnash vtjnash force-pushed the jn/typeinfq branch 3 times, most recently from 5d1bf6a to ff1e1e6 Compare March 2, 2016 03:53
note: directly inferring linfo in pure_eval_call is unnecessary since abstract_call_gf_by_type would add this edge anyways
and it can be harmful since there was no logic here to prevent unbounded recursion in the type signature

fixes #9770
since in the common case, the call graph is a simple DAG,
and it is faster / more efficient to infer immediately rather than building
the edges graph and repeating method lookup process after the backedge finishes
@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Mar 2, 2016

since CI was killing this before it could finish, i layered several optimizations on top of the original design. now CI is happy and it should be good to merge.

@yuyichao
Copy link
Contributor

yuyichao commented Mar 2, 2016

since CI was killing this before it could finish, i layered several optimizations on top of the original design.

Were there any regression without the optimizations you add?

@tkelman
Copy link
Contributor

tkelman commented Mar 2, 2016

judging by the timeouts, yes. I saw some tests slower, some faster when running an earlier version of this locally

@tkelman tkelman closed this Mar 2, 2016
@tkelman tkelman reopened this Mar 2, 2016
@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Mar 2, 2016

yes, i think CI is right up against its memory limit, and some tests cause it to start swapping heavily. these optimizations are faster, but mostly they retain a lot less temporary memory during inference.

@Keno
Copy link
Member

Keno commented Mar 2, 2016

Observed the following on this branch after the latest updates:

ERROR: BoundsError: attempt to access ()
  at index [2]
 in getindex(::Tuple{}, ::Int64) at ./tuple.jl:8
 in typeinf_frame(::Core.Inference.InferenceState) at ./inference.jl:1836
 in typeinf_loop(::Core.Inference.InferenceState) at ./inference.jl:1680
 in typeinf_edge(::LambdaInfo, ::Any, ::SimpleVector, ::Bool, ::Bool, ::Bool, ::Void) at ./inference.jl:1637
 in typeinf_ext(::LambdaInfo, ::Bool) at ./inference.jl:1655
 in run_interface(::Base.Terminals.TTYTerminal, ::Base.LineEdit.ModalInterface) at ./LineEdit.jl:1611
 [inlined code] from ./LineEdit.jl:18
 in RunDebugREPL(::ASTInterpreter.Interpreter) at /home/ubuntu/.julia/v0.5/ASTInterpreter/src/ASTInterpreter.jl:853
 in eval(::Module, ::Any) at ./boot.jl:267

the interaction here is rather complex, but recursing on a frame already in typeinf_frame
causes the state upon return to that function to be a bit convoluted.
detecting frame.inferred at that point and aborting was also correct,
but requires a bit of code duplication at each abstract_interpret call
to check and return quickly.

making the processing state part of inworkq rather than stuck' should be a bit more robust
against future edits to this code
@JeffBezanson
Copy link
Sponsor Member

I would like to see comments clearly explaining the roles of typeinf_edge, typeinf_loop, and typeinf_frame.

I see the code for limiting the number of exception handlers is commented out. Are we sure it's no longer needed? If so then the code should be removed. There is also a commented-out piece in typeinf_loop.

@JeffBezanson
Copy link
Sponsor Member

Ok, this seems to be ready to go. My only comments (above) are very minor and can be addressed post-merge.

JeffBezanson added a commit that referenced this pull request Mar 4, 2016
@JeffBezanson JeffBezanson merged commit 7facd20 into master Mar 4, 2016
@Keno Keno mentioned this pull request Mar 5, 2016
@tkelman tkelman deleted the jn/typeinfq branch March 5, 2016 05:00
@schmrlng
Copy link
Contributor

schmrlng commented Mar 7, 2016

The results of a git bisect indicate that this pull request is responsible for an LLVM ERROR when trying to use PyCall:

   _       _ _(_)_     |  A fresh approach to technical computing
  (_)     | (_) (_)    |  Documentation: http://docs.julialang.org
   _ _   _| |_  __ _   |  Type "?help" for help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 0.5.0-dev+2960 (2016-03-02 06:55 UTC)
 _/ |\__'_|_|_|\__'_|  |  Commit 8f4238a (4 days old master)
|__/                   |  x86_64-linux-gnu


julia> versioninfo()
Julia Version 0.5.0-dev+2960
Commit 8f4238a (2016-03-02 06:55 UTC)
Platform Info:
  System: Linux (x86_64-linux-gnu)
  CPU: Intel(R) Core(TM) i7-5960X CPU @ 3.00GHz
  WORD_SIZE: 64
  BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Haswell)
  LAPACK: libopenblas64_
  LIBM: libopenlibm
  LLVM: libLLVM-3.7.1

julia> Pkg.status("PyCall")
 - PyCall                        1.4.0

julia> using PyCall
INFO: Recompiling stale cache file /home/schmrlng/.julia/lib/v0.5/PyCall.ji for module PyCall.
INFO: Recompiling stale cache file /home/schmrlng/.julia/lib/v0.5/Compat.ji for module Compat.
LLVM ERROR: Program used external function 'julia_getindex_24827' which could not be resolved!

> git bisect bad
8f4238a3d5d1c066cf679c2b8485a930be2476ce is the first bad commit
commit 8f4238a3d5d1c066cf679c2b8485a930be2476ce
Author: Jameson Nash <vtjnash@gmail.com>
Date:   Sun Feb 21 16:21:14 2016 -0500

    do type-inference using a work queue

    note: directly inferring linfo in pure_eval_call is unnecessary since abstract_call_gf_by_type would add this edge anyways
    and it can be harmful since there was no logic here to prevent unbounded recursion in the type signature

    fixes #9770

:040000 040000 541c80bcd982ef89fe6e4400ad31bad1e1e18a59 5f6e7971b1b52381b7087ffe577dc89061934b91 M        base
:040000 040000 4bdf31060b659942f3ca153dd22f717f7806374d 6697c40e8f018f5a693dbf9d117a00751e62c2ff M        src
:040000 040000 4ab513a676c3b1117efcb7c0393bebac0254c84d 54291a6b791fc24f9006d178013a78138688a91b M        test

I'm a bit out of my depth here as gdb doesn't catch any signals from the error. Does anyone have any insight on why this is occurring, or have advice on how to further debug this issue?

@yuyichao
Copy link
Contributor

yuyichao commented Mar 7, 2016

Catch the llvm error with br llvm::report_fatal_error. I could reproduce this locally too.

The error happens when generating native code for

Core.Inference.convert(Core.Inference.#convert, Type{Any}, Type{Union{Int64, PyCall.PyGetSetDef}})
#0  0x00007fc2c0f6f0e0 in llvm::report_fatal_error(llvm::Twine const&, bool) ()
   from /home/yuyichao/projects/julia/gc/array-card/usr/bin/../lib/libjulia.so
#1  0x00007fc2c085fe06 in llvm::RuntimeDyldImpl::resolveExternalSymbols() ()
   from /home/yuyichao/projects/julia/gc/array-card/usr/bin/../lib/libjulia.so
#2  0x00007fc2c085fe34 in llvm::RuntimeDyldImpl::resolveRelocations() ()
   from /home/yuyichao/projects/julia/gc/array-card/usr/bin/../lib/libjulia.so
#3  0x00007fc2c04088b8 in llvm::orc::ObjectLinkingLayer<(anonymous namespace)::DebugObjectRegistrar>::ConcreteLinkedObjectSet<llvm::RTDyldMemoryManager*, std::unique_ptr<llvm::orc::LambdaResolver<(anonymous namespace)::JuliaOJIT::addModule(llvm::Module*)::<lambda(const string&)>, (anonymous namespace)::JuliaOJIT::addModule(llvm::Module*)::<lambda(const string&)> >, std::default_delete<llvm::orc::LambdaResolver<(anonymous namespace)::JuliaOJIT::addModule(llvm::Module*)::<lambda(const string&)>, (anonymous namespace)::JuliaOJIT::addModule(llvm::Module*)::<lambda(const string&)> > > > >::Finalize (this=0x20a5ba0)
    at /usr/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h:126
#4  llvm::orc::ObjectLinkingLayer<(anonymous namespace)::DebugObjectRegistrar>::<lambda()>::operator() (__closure=0x2639330)
    at /usr/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h:247
#5  std::_Function_handler<long unsigned int(), llvm::orc::ObjectLinkingLayer<NotifyLoadedFtor>::findSymbolIn(llvm::orc::ObjectLinkingLayerBase::ObjSetHandleT, llvm::StringRef, bool) [with NotifyLoadedFtor = (anonymous namespace)::DebugObjectRegistrar; llvm::orc::ObjectLinkingLayerBase::ObjSetHandleT = std::_List_iterator<std::unique_ptr<llvm::orc::ObjectLinkingLayerBase::LinkedObjectSet> >]::<lambda()> >::_M_invoke(const std::_Any_data &) (__functor=...)
    at /usr/include/c++/5.3.0/functional:1857
#6  0x00007fc2c04087f3 in std::function<unsigned long ()>::operator()() const (
    this=0x7ffc935f80c8) at /usr/include/c++/5.3.0/functional:2267
#7  llvm::orc::JITSymbol::getAddress (this=0x7ffc935f80c0)
    at /usr/include/llvm/ExecutionEngine/Orc/JITSymbol.h:62
#8  (anonymous namespace)::JuliaOJIT::getFunctionAddress (this=<optimized out>, 
    Name="julia_convert_22968")
    at /home/yuyichao/projects/julia/gc/array-card/src/jitlayers.cpp:381
#9  0x00007fc2c0429395 in getAddressForOrCompileFunction (llvmf=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/codegen.cpp:1059
#10 0x00007fc2c042985d in jl_generate_fptr (li=li@entry=0x7fc0bdac8380)
    at /home/yuyichao/projects/julia/gc/array-card/src/codegen.cpp:1100
#11 0x00007fc2c03be49a in jl_call_method_internal (nargs=3, args=0x7ffc935f8530, 
    meth=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/julia_internal.h:66
#12 jl_apply_generic (args=0x7ffc935f8530, nargs=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/gf.c:1855
#13 0x00007fc2baf70234 in julia_type_annotate_628 () at inference.jl:2130
#14 0x00007fc2baf70b48 in jlcall_type_annotate_628 ()
   from /home/yuyichao/projects/julia/gc/array-card/usr/lib/julia/sys.so
#15 0x00007fc2c03be38f in jl_call_method_internal (nargs=6, args=0x7ffc935f8890, 
---Type <return> to continue, or q <return> to quit---
    meth=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/julia_internal.h:69
#16 jl_apply_generic (args=0x7ffc935f8890, nargs=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/gf.c:1855
#17 0x00007fc2baf5a18f in julia_finish_284 () at inference.jl:1982
#18 0x00007fc2baf5d83b in julia_typeinf_frame_202 () at inference.jl:1928
#19 0x00007fc2baf5ea44 in julia_typeinf_loop_201 () at inference.jl:1681
#20 0x00007fc2baf5f0bc in jlcall_typeinf_loop_201 ()
   from /home/yuyichao/projects/julia/gc/array-card/usr/lib/julia/sys.so
#21 0x00007fc2c03be38f in jl_call_method_internal (nargs=2, args=0x7ffc935f9690, 
    meth=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/julia_internal.h:69
#22 jl_apply_generic (args=0x7ffc935f9690, nargs=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/gf.c:1855
#23 0x00007fc2baf4d31b in julia_typeinf_edge_5 () at inference.jl:1655
#24 0x00007fc2baf4dac7 in jlcall_typeinf_edge_5 ()
   from /home/yuyichao/projects/julia/gc/array-card/usr/lib/julia/sys.so
#25 0x00007fc2c03be38f in jl_call_method_internal (nargs=8, args=0x7ffc935f9810, 
    meth=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/julia_internal.h:69
#26 jl_apply_generic (args=0x7ffc935f9810, nargs=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/gf.c:1855
#27 0x00007fc2baf8ca37 in julia_typeinf_903 () at inference.jl:1663
#28 0x00007fc2baf8ca97 in jlcall_typeinf_903 ()
   from /home/yuyichao/projects/julia/gc/array-card/usr/lib/julia/sys.so
#29 0x00007fc2c03be38f in jl_call_method_internal (nargs=5, args=0x7ffc935fb350, 
    meth=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/julia_internal.h:69
#30 jl_apply_generic (args=0x7ffc935fb350, nargs=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/gf.c:1855
#31 0x00007fc2baf8174a in julia_inlineable_729 () at inference.jl:2545
#32 0x00007fc2baf8ab1c in jlcall_inlineable_729 ()
   from /home/yuyichao/projects/julia/gc/array-card/usr/lib/julia/sys.so
#33 0x00007fc2c03be38f in jl_call_method_internal (nargs=7, args=0x7ffc935fbe58, 
    meth=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/julia_internal.h:69
#34 jl_apply_generic (args=0x7ffc935fbe58, nargs=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/gf.c:1855
#35 0x00007fc2baf76666 in julia_inlining_pass_653 () at inference.jl:3122
#36 0x00007fc2baf7503c in julia_inlining_pass_653 () at inference.jl:3047
#37 0x00007fc2baf7503c in julia_inlining_pass_653 () at inference.jl:3047
#38 0x00007fc2baf78750 in jlcall_inlining_pass_653 ()
   from /home/yuyichao/projects/julia/gc/array-card/usr/lib/julia/sys.so
#39 0x00007fc2c03be38f in jl_call_method_internal (nargs=4, args=0x7ffc935fdca8, 
    meth=<optimized out>)
---Type <return> to continue, or q <return> to quit---
    at /home/yuyichao/projects/julia/gc/array-card/src/julia_internal.h:69
#40 jl_apply_generic (args=0x7ffc935fdca8, nargs=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/gf.c:1855
#41 0x00007fc2baf74bc2 in julia_inlining_pass_653 () at inference.jl:3005
#42 0x00007fc2baf78750 in jlcall_inlining_pass_653 ()
   from /home/yuyichao/projects/julia/gc/array-card/usr/lib/julia/sys.so
#43 0x00007fc2c03be38f in jl_call_method_internal (nargs=4, args=0x7ffc935fe080, 
    meth=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/julia_internal.h:69
#44 jl_apply_generic (args=0x7ffc935fe080, nargs=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/gf.c:1855
#45 0x00007fc2baf5a400 in julia_finish_284 () at inference.jl:1993
#46 0x00007fc2baf5d83b in julia_typeinf_frame_202 () at inference.jl:1928
#47 0x00007fc2baf5ea44 in julia_typeinf_loop_201 () at inference.jl:1681
#48 0x00007fc2baf5f0bc in jlcall_typeinf_loop_201 ()
   from /home/yuyichao/projects/julia/gc/array-card/usr/lib/julia/sys.so
#49 0x00007fc2c03be38f in jl_call_method_internal (nargs=2, args=0x7ffc935fee80, 
    meth=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/julia_internal.h:69
#50 jl_apply_generic (args=0x7ffc935fee80, nargs=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/gf.c:1855
#51 0x00007fc2baf4d31b in julia_typeinf_edge_5 () at inference.jl:1655
#52 0x00007fc2baf4dac7 in jlcall_typeinf_edge_5 ()
   from /home/yuyichao/projects/julia/gc/array-card/usr/lib/julia/sys.so
#53 0x00007fc2c03be38f in jl_call_method_internal (nargs=8, args=0x7ffc935ff000, 
    meth=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/julia_internal.h:69
#54 jl_apply_generic (args=0x7ffc935ff000, nargs=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/gf.c:1855
#55 0x00007fc2baf8ca37 in julia_typeinf_903 () at inference.jl:1663
#56 0x00007fc2baf8ca97 in jlcall_typeinf_903 ()
   from /home/yuyichao/projects/julia/gc/array-card/usr/lib/julia/sys.so
#57 0x00007fc2c03be38f in jl_call_method_internal (nargs=5, args=0x7ffc93600b40, 
    meth=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/julia_internal.h:69
#58 jl_apply_generic (args=0x7ffc93600b40, nargs=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/gf.c:1855
#59 0x00007fc2baf8174a in julia_inlineable_729 () at inference.jl:2545
#60 0x00007fc2baf8ab1c in jlcall_inlineable_729 ()
   from /home/yuyichao/projects/julia/gc/array-card/usr/lib/julia/sys.so
#61 0x00007fc2c03be38f in jl_call_method_internal (nargs=7, args=0x7ffc93601648, 
    meth=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/julia_internal.h:69
#62 jl_apply_generic (args=0x7ffc93601648, nargs=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/gf.c:1855
---Type <return> to continue, or q <return> to quit---
#63 0x00007fc2baf76666 in julia_inlining_pass_653 () at inference.jl:3122
#64 0x00007fc2baf7503c in julia_inlining_pass_653 () at inference.jl:3047
#65 0x00007fc2baf78750 in jlcall_inlining_pass_653 ()
   from /home/yuyichao/projects/julia/gc/array-card/usr/lib/julia/sys.so
#66 0x00007fc2c03be38f in jl_call_method_internal (nargs=4, args=0x7ffc93602ab8, 
    meth=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/julia_internal.h:69
#67 jl_apply_generic (args=0x7ffc93602ab8, nargs=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/gf.c:1855
#68 0x00007fc2baf74bc2 in julia_inlining_pass_653 () at inference.jl:3005
#69 0x00007fc2baf78750 in jlcall_inlining_pass_653 ()
   from /home/yuyichao/projects/julia/gc/array-card/usr/lib/julia/sys.so
#70 0x00007fc2c03be38f in jl_call_method_internal (nargs=4, args=0x7ffc93602e90, 
    meth=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/julia_internal.h:69
#71 jl_apply_generic (args=0x7ffc93602e90, nargs=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/gf.c:1855
#72 0x00007fc2baf5a400 in julia_finish_284 () at inference.jl:1993
#73 0x00007fc2baf5d83b in julia_typeinf_frame_202 () at inference.jl:1928
#74 0x00007fc2baf5ec67 in julia_typeinf_loop_201 () at inference.jl:1698
#75 0x00007fc2baf5f0bc in jlcall_typeinf_loop_201 ()
   from /home/yuyichao/projects/julia/gc/array-card/usr/lib/julia/sys.so
#76 0x00007fc2c03be38f in jl_call_method_internal (nargs=2, args=0x7ffc93603c90, 
    meth=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/julia_internal.h:69
#77 jl_apply_generic (args=0x7ffc93603c90, nargs=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/gf.c:1855
#78 0x00007fc2baf4d31b in julia_typeinf_edge_5 () at inference.jl:1655
#79 0x00007fc2baf4dac7 in jlcall_typeinf_edge_5 ()
   from /home/yuyichao/projects/julia/gc/array-card/usr/lib/julia/sys.so
#80 0x00007fc2c03be38f in jl_call_method_internal (nargs=8, args=0x7ffc93603e18, 
    meth=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/julia_internal.h:69
#81 jl_apply_generic (args=0x7ffc93603e18, nargs=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/gf.c:1855
#82 0x00007fc2baf4b73f in julia_typeinf_ext_0 (linfo=..., 
    toplevel=<optimized out>) at inference.jl:1673
#83 0x00007fc2c03be38f in jl_call_method_internal (nargs=3, args=0x7ffc93604000, 
    meth=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/julia_internal.h:69
#84 jl_apply_generic (args=args@entry=0x7ffc93604000, nargs=nargs@entry=3)
    at /home/yuyichao/projects/julia/gc/array-card/src/gf.c:1855
#85 0x00007fc2c03bef41 in jl_apply (nargs=3, args=0x7ffc93604000)
    at /home/yuyichao/projects/julia/gc/array-card/src/julia.h:1258
#86 jl_type_infer (toplevel=<optimized out>, li=<optimized out>)
---Type <return> to continue, or q <return> to quit---
    at /home/yuyichao/projects/julia/gc/array-card/src/gf.c:413
#87 cache_method (mt=mt@entry=0x7fc0bbd3d960, type=0x7fc0bcc35c30, 
    type@entry=0x7fc0bd4133d0, method=<optimized out>, m=m@entry=0x7fc0bbd42f10, 
    sparams=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/gf.c:816
#88 0x00007fc2c03c06be in jl_mt_assoc_by_type (mt=mt@entry=0x7fc0bbd3d960, 
    tt=tt@entry=0x7fc0bd4133d0, cache=cache@entry=1, inexact=inexact@entry=1)
    at /home/yuyichao/projects/julia/gc/array-card/src/gf.c:975
#89 0x00007fc2c03c1f88 in jl_method_lookup_by_type (cache=1, inexact=1, 
    types=0x7fc0bd4133d0, mt=0x7fc0bbd3d960)
    at /home/yuyichao/projects/julia/gc/array-card/src/gf.c:1384
#90 jl_get_specialization1 (types=0x7fc0bd4133d0, cyclectx=0x2105530)
    at /home/yuyichao/projects/julia/gc/array-card/src/gf.c:1437
#91 0x00007fc2c0378e91 in emit_call (args=args@entry=0x7fc0bda3c740, arglen=6, 
    ctx=ctx@entry=0x7ffc93604c30, expr=expr@entry=0x7fc0bda54630)
    at /home/yuyichao/projects/julia/gc/array-card/src/codegen.cpp:2937
#92 0x00007fc2c042d819 in emit_expr (expr=expr@entry=0x7fc0bda54630, 
    ctx=ctx@entry=0x7ffc93604c30)
    at /home/yuyichao/projects/julia/gc/array-card/src/codegen.cpp:3427
#93 0x00007fc2c042cee9 in emit_assignment (ctx=0x7ffc93604c30, r=0x7fc0bda54630, 
    l=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/codegen.cpp:3173
#94 emit_expr (expr=expr@entry=0x7fc0bda545f0, ctx=0x7ffc93604c30)
    at /home/yuyichao/projects/julia/gc/array-card/src/codegen.cpp:3430
#95 0x00007fc2c042f049 in emit_stmtpos (expr=expr@entry=0x7fc0bda545f0, 
    ctx=ctx@entry=0x7ffc93604c30)
    at /home/yuyichao/projects/julia/gc/array-card/src/codegen.cpp:3292
#96 0x00007fc2c0430aff in emit_function (lam=lam@entry=0x7fc0bd45a270, 
    declarations=declarations@entry=0x7fc0bd45a2f0, 
    cyclectx=cyclectx@entry=0x2105530, definitions=0x7ffc93605170, 
    definitions=0x7ffc93605170)
    at /home/yuyichao/projects/julia/gc/array-card/src/codegen.cpp:4960
#97 0x00007fc2c04333a1 in to_function (li=li@entry=0x7fc0bd45a270, 
    cyclectx=cyclectx@entry=0x0)
    at /home/yuyichao/projects/julia/gc/array-card/src/codegen.cpp:856
#98 0x00007fc2c0433925 in jl_compile_linfo (li=li@entry=0x7fc0bd45a270, 
    cyclectx=cyclectx@entry=0x0)
    at /home/yuyichao/projects/julia/gc/array-card/src/codegen.cpp:1153
#99 0x00007fc2c03be492 in jl_call_method_internal (nargs=1, args=0x7ffc93605378, 
    meth=<optimized out>)
    at /home/yuyichao/projects/julia/gc/array-card/src/julia_internal.h:65
#100 jl_apply_generic (args=args@entry=0x7ffc93605378, nargs=nargs@entry=1)
    at /home/yuyichao/projects/julia/gc/array-card/src/gf.c:1855
#101 0x00007fc2c03d2397 in jl_apply (nargs=1, args=0x7ffc93605378)
    at /home/yuyichao/projects/julia/gc/array-card/src/julia.h:1258
---Type <return> to continue, or q <return> to quit---
#102 jl_module_run_initializer (m=0x7fc0bcfca1d0)
    at /home/yuyichao/projects/julia/gc/array-card/src/module.c:625
#103 0x00007fc2c03e1494 in jl_init_restored_modules (init_order=0x7fc0bd6f7120)
    at /home/yuyichao/projects/julia/gc/array-card/src/dump.c:1824
#104 _jl_restore_incremental (f=f@entry=0x7ffc93605520)
    at /home/yuyichao/projects/julia/gc/array-card/src/dump.c:2332
#105 0x00007fc2c03e5d11 in _jl_restore_incremental (f=0x7ffc93605520)
    at /home/yuyichao/projects/julia/gc/array-card/src/dump.c:2260
#106 jl_restore_incremental (
    fname=0x7fc0bc449f00 "/home/yuyichao/.julia/lib/v0.5/PyCall.ji")
    at /home/yuyichao/projects/julia/gc/array-card/src/dump.c:2356
#107 0x00007fc2c23b73cc in ?? ()
#108 0x00007ffc93605660 in ?? ()
#109 0x00007fc2c040873c in __gnu_cxx::new_allocator<char>::deallocate (
    this=<optimized out>, __p=<optimized out>)
    at /usr/include/c++/5.3.0/ext/new_allocator.h:110
#110 std::allocator_traits<std::allocator<char> >::deallocate (__a=..., 
    __n=<optimized out>, __p=<optimized out>)
    at /usr/include/c++/5.3.0/bits/alloc_traits.h:386
#111 std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_destroy (__size=<optimized out>, this=0x0)
    at /usr/include/c++/5.3.0/bits/basic_string.h:185
#112 std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_dispose (this=0x0) at /usr/include/c++/5.3.0/bits/basic_string.h:180
#113 std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string (this=0x0, __in_chrg=<optimized out>)
    at /usr/include/c++/5.3.0/bits/basic_string.h:543
#114 (anonymous namespace)::JuliaOJIT::getFunctionAddress (this=<optimized out>, 
    Name=...)
    at /home/yuyichao/projects/julia/gc/array-card/src/jitlayers.cpp:381
#115 0x00007fc2c23b7fd6 in ?? ()
#116 0x0000000000000002 in ?? ()
#117 0x00007ffc93605870 in ?? ()
#118 0x0000000000000000 in ?? ()

@ihnorton
Copy link
Member

ihnorton commented Mar 7, 2016

same as #14735?

@yuyichao
Copy link
Contributor

yuyichao commented Mar 7, 2016

Yeah, likely. Somehow this only happens for me after this branch but not on a one week old master.

@schmrlng
Copy link
Contributor

schmrlng commented Mar 7, 2016

This might have the same underlying cause as #14735 but that one used to manifest only during precompilation of packages that use PyCall and not PyCall itself as I see now. That is, I could use PyPlot and Sympy before the change in this pull request just by commenting out the __precompile__() line in those packages, but now I also have to comment out __precompile__() in PyCall as well.

@yuyichao
Copy link
Contributor

yuyichao commented Mar 7, 2016

As a work around, --compilecache=no also works.

@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Apr 4, 2016

  1. described in a detailed blog post

now live at http://juliacomputing.com/blog/2016/04/04/inference-convergence.html (part 1 of maybe more than 1)

@timholy
Copy link
Sponsor Member

timholy commented Apr 9, 2016

This is a fantastic blog post, thanks for writing it. I love the animation illustrating progress on the simple inference example.

A couple of comments:

  • starting at "Historical perspective," the meaning of the diagrams is not spelled out (they are example call-trees, but this should be spelled out)
  • starting at "Corrected convergence," the amount of assumed knowledge about julia's internal implementation increases dramatically.

@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Apr 9, 2016

starting at "Corrected convergence," the amount of assumed knowledge about julia's internal implementation increases dramatically

are you referring just to "When asked for the return type of a function, inference first checks the list in the .tfunc field of the LambdaInfo method definition for whether the return type has been computed previously or is currently being computed (the .tfunc list is a dictionary that maps from a call signature to either the in-process InferenceState object or a pair of inferred function body and return type)." (which upon rereading, I agree is atrocious), or was there more in that section that deserves revisiting?

@timholy
Copy link
Sponsor Member

timholy commented Apr 10, 2016

That's far and away the main one. A bit lower you talk about the tfunc mapping again in terms of what happens when the algorithm converges, but that's a pretty brief mention.

A couple of additional issues (distinct from the "internal implementation" concern):

  • There's an introduction of the notion of adding edges to the inference state, which might be a little confusing given that inference state has heretofore been described as a queue, which (unlike a graph) doesn't so obviously have edges.
  • "implementation proposed for Julia": I thought this work was already merged? (I haven't dug into it, however.)
  • depending on your willingness to invest in explanations, you might consider adding a stepwise example of handling cycles. (I recognize that could be a lot of work.)

@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Apr 12, 2016

thanks. i made a handful of updates (mostly adding image captions and moving references to tfunc out of the main text). a stepwise example of Julia's cycle resolution implementation seems fairly annoying to animate (since it involves moving lots of boxes between lots of groups), and so think this would require more of youtube-level animation to be comprehensible. i'm not quite willing to put that level of effort into it right now.

@timholy
Copy link
Sponsor Member

timholy commented Apr 12, 2016

I don't blame you one bit for capping the effort level there. It's already very useful as it is. inference.jl has always been difficult to grok for me, and this helps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

type inference bug for multi-cycle functions
9 participants