JET setzt Julias Typ -Inferenzsystem ein, um potenzielle Fehler und Instabilitäten zu erkennen.
Warnung
Bitte beachten Sie, dass aufgrund der engen Integration von JET in den Julia -Compiler die von JET präsentierten Ergebnisse je nach Version von Julia, die Sie verwenden, erheblich variieren können. Darüber hinaus kann die Implementierung des mit Julia gebündelten Base und Standardbündel die Ergebnisse beeinflussen.
Darüber hinaus ist das Plugin -System des Julia Compiler immer noch instabil und seine Schnittstelle ändert sich häufig, sodass jede JET -Version mit nur begrenzten Versionen von Julia kompatibel ist. Der Julia Package Manager wählt automatisch die neueste Version von Jet aus und installiert, die mit Ihrer Julia -Version kompatibel ist. Wenn Sie jedoch die nächtliche Version von Julia verwenden, beachten Sie bitte, dass eine kompatible Version von JET möglicherweise noch nicht veröffentlicht wurde und Jet über den Julia Package Manager möglicherweise nicht ordnungsgemäß funktioniert.
Weitere Befehle, Optionen und Erklärungen in der Dokumentation finden Sie in der Dokumentation.
Jet ist ein Standard -Julia -Paket. Sie können es also einfach über den integrierten Paketmanager von Julia installieren und genau wie jedes andere Paket verwenden:
julia> using Pkg; Pkg . add ( " JET " )
[ some output elided ]
julia> using JET@report_opt Typ -Instabilitäten können in Funktionsaufrufen mit dem Makro @report_opt erkannt werden, das ähnlich dem Makro @code_warntype funktioniert. Beachten Sie, dass, da JET auf Julias Typinferenz angewiesen ist, wenn eine Inferenzkette aufgrund des dynamischen Versandes unterbrochen wird, alle nachgeschalteten Funktionsaufrufe dem Compiler unbekannt sind und Jet sie nicht analysieren kann.
julia> @report_opt foldl ( + , Any[]; init = 0 )
═════ 2 possible errors found ═════
┌ kwcall(::@NamedTuple{init::Int64}, ::typeof(foldl), op::typeof(+), itr::Vector{Any}) @ Base ./reduce.jl:198
│┌ foldl(op::typeof(+), itr::Vector{Any}; kw::@Kwargs{init::Int64}) @ Base ./reduce.jl:198
││┌ kwcall(::@NamedTuple{init::Int64}, ::typeof(mapfoldl), f::typeof(identity), op::typeof(+), itr::Vector{Any}) @ Base ./reduce.jl:175
│││┌ mapfoldl(f::typeof(identity), op::typeof(+), itr::Vector{Any}; init::Int64) @ Base ./reduce.jl:175
││││┌ mapfoldl_impl(f::typeof(identity), op::typeof(+), nt::Int64, itr::Vector{Any}) @ Base ./reduce.jl:44
│││││┌ foldl_impl(op::Base.BottomRF{typeof(+)}, nt::Int64, itr::Vector{Any}) @ Base ./reduce.jl:48
││││││┌ _foldl_impl(op::Base.BottomRF{typeof(+)}, init::Int64, itr::Vector{Any}) @ Base ./reduce.jl:58
│││││││┌ (::Base.BottomRF{typeof(+)})(acc::Int64, x::Any) @ Base ./reduce.jl:86
││││││││ runtime dispatch detected: +(acc::Int64, x::Any)::Any
│││││││└────────────────────
││││││┌ _foldl_impl(op::Base.BottomRF{typeof(+)}, init::Int64, itr::Vector{Any}) @ Base ./reduce.jl:62
│││││││┌ (::Base.BottomRF{typeof(+)})(acc::Any, x::Any) @ Base ./reduce.jl:86
││││││││ runtime dispatch detected: +(acc::Any, x::Any)::Any
│││││││└────────────────────@report_call Dies funktioniert am besten für den Typ stabilen Code. Verwenden Sie also @report_opt großzügig, bevor Sie @report_call verwenden.
julia> @report_call foldl ( + , Char[])
═════ 2 possible errors found ═════
┌ foldl(op::typeof(+), itr::Vector{Char}) @ Base ./reduce.jl:198
│┌ foldl(op::typeof(+), itr::Vector{Char}; kw::@Kwargs{}) @ Base ./reduce.jl:198
││┌ mapfoldl(f::typeof(identity), op::typeof(+), itr::Vector{Char}) @ Base ./reduce.jl:175
│││┌ mapfoldl(f::typeof(identity), op::typeof(+), itr::Vector{Char}; init::Base._InitialValue) @ Base ./reduce.jl:175
││││┌ mapfoldl_impl(f::typeof(identity), op::typeof(+), nt::Base._InitialValue, itr::Vector{Char}) @ Base ./reduce.jl:44
│││││┌ foldl_impl(op::Base.BottomRF{typeof(+)}, nt::Base._InitialValue, itr::Vector{Char}) @ Base ./reduce.jl:48
││││││┌ _foldl_impl(op::Base.BottomRF{typeof(+)}, init::Base._InitialValue, itr::Vector{Char}) @ Base ./reduce.jl:62
│││││││┌ (::Base.BottomRF{typeof(+)})(acc::Char, x::Char) @ Base ./reduce.jl:86
││││││││ no matching method found `+(::Char, ::Char)`: (op::Base.BottomRF{typeof(+)}).rf::typeof(+)(acc::Char, x::Char)
│││││││└────────────────────
│││││┌ foldl_impl(op::Base.BottomRF{typeof(+)}, nt::Base._InitialValue, itr::Vector{Char}) @ Base ./reduce.jl:49
││││││┌ reduce_empty_iter(op::Base.BottomRF{typeof(+)}, itr::Vector{Char}) @ Base ./reduce.jl:383
│││││││┌ reduce_empty_iter(op::Base.BottomRF{typeof(+)}, itr::Vector{Char}, ::Base.HasEltype) @ Base ./reduce.jl:384
││││││││┌ reduce_empty(op::Base.BottomRF{typeof(+)}, ::Type{Char}) @ Base ./reduce.jl:360
│││││││││┌ reduce_empty(::typeof(+), ::Type{Char}) @ Base ./reduce.jl:343
││││││││││ no matching method found `zero(::Type{Char})`: zero(T::Type{Char})
│││││││││└────────────────────report_package Dies sucht nach allen Methodendefinitionen und Analysen von Funktionsaufrufen basierend auf ihren Signaturen. Beachten Sie, dass dies weniger genau ist als @report_call , da die tatsächlichen Eingabetypen für generische Methoden nicht bekannt sein können.
julia> using Pkg; Pkg . activate (; temp = true , io = devnull ); Pkg . add ( " AbstractTrees " ; io = devnull );
julia> Pkg . status ()
Status `/private/var/folders/xh/6zzly9vx71v05_y67nm_s9_c0000gn/T/jl_h07K2m/Project.toml`
[1520ce14] AbstractTrees v0.4.4
julia> report_package ( " AbstractTrees " )
[ some output elided ]
═════ 7 possible errors found ═════
┌ isroot(root::Any, x::Any) @ AbstractTrees ~/.julia/packages/AbstractTrees/EUx8s/src/base.jl:102
│ no matching method found `parent(::Any, ::Any)`: AbstractTrees.parent(root::Any, x::Any)
└────────────────────
┌ AbstractTrees.IndexNode(tree::Any) @ AbstractTrees ~/.julia/packages/AbstractTrees/EUx8s/src/indexing.jl:117
│ no matching method found `rootindex(::Any)`: rootindex(tree::Any)
└────────────────────
┌ parent(idx::AbstractTrees.IndexNode) @ AbstractTrees ~/.julia/packages/AbstractTrees/EUx8s/src/indexing.jl:127
│ no matching method found `parentindex(::Any, ::Any)`: pidx = parentindex((idx::AbstractTrees.IndexNode).tree::Any, (idx::AbstractTrees.IndexNode).index::Any)
└────────────────────
┌ nextsibling(idx::AbstractTrees.IndexNode) @ AbstractTrees ~/.julia/packages/AbstractTrees/EUx8s/src/indexing.jl:132
│ no matching method found `nextsiblingindex(::Any, ::Any)`: sidx = nextsiblingindex((idx::AbstractTrees.IndexNode).tree::Any, (idx::AbstractTrees.IndexNode).index::Any)
└────────────────────
┌ prevsibling(idx::AbstractTrees.IndexNode) @ AbstractTrees ~/.julia/packages/AbstractTrees/EUx8s/src/indexing.jl:137
│ no matching method found `prevsiblingindex(::Any, ::Any)`: sidx = prevsiblingindex((idx::AbstractTrees.IndexNode).tree::Any, (idx::AbstractTrees.IndexNode).index::Any)
└────────────────────
┌ prevsibling(csr::AbstractTrees.IndexedCursor) @ AbstractTrees ~/.julia/packages/AbstractTrees/EUx8s/src/cursors.jl:234
│ no matching method found `getindex(::Nothing, ::Int64)` (1/2 union split): (AbstractTrees.parent(csr::AbstractTrees.IndexedCursor)::Union{Nothing, AbstractTrees.IndexedCursor})[idx::Int64]
└────────────────────
┌ (::AbstractTrees.var"#17#18")(n::Any) @ AbstractTrees ~/.julia/packages/AbstractTrees/EUx8s/src/iteration.jl:323
│ no matching method found `parent(::Any, ::Any)`: AbstractTrees.parent(getfield(#self#::AbstractTrees.var"#17#18", :tree)::Any, n::Any)
└──────────────────── Jet untersucht die Funktionen, die Sie direkt sowie ihre abgeleiteten Callees anrufen. Wenn die Argumententypen für einen Anruf jedoch nicht abgeleitet werden können, analysiert JET die Callee nicht. Infolgedessen bedeutet ein Bericht No errors detected dass Ihre gesamte Codebasis frei von Fehlern ist. Um das Vertrauen in die Ergebnisse von Jet zu erhöhen, verwenden Sie @report_opt , um sicherzustellen, dass Ihr Code abgeleitet ist.
Jet integriert sich in SnoopCompile, und Sie können manchmal SnoopCompile verwenden, um die Daten zu sammeln, um umfassendere Analysen durchzuführen. Die Einschränkung von SnoopCompile besteht darin, dass nur Daten für Anrufe gesammelt werden, die bisher nicht abgeleitet wurden. Daher müssen Sie diese Art der Analyse in einer neuen Sitzung durchführen.
Weitere Einzelheiten finden Sie unter Dokumentation von Snoopcompiles Jet-Integration.
Dieses Projekt begann als mein Studentenarbeitsprojekt an der Kyoto University, das von Prof. Takashi Sakuragawa überwacht wurde. Wir ließen uns stark von Ruby/Typeprof inspirieren, einem experimentellen Typ -Verständnis/Check -Tool für Ruby. Die Grad-These zu diesem Projekt wird unter https://github.com/aviatesk/grad-thesis veröffentlicht, aber derzeit ist es nur auf Japanisch verfügbar.