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

simulate has type instability with POMDPs 0.7.3 when testing with Julia 1.0 #12

Closed
lassepe opened this issue Sep 18, 2019 · 8 comments
Closed

Comments

@lassepe
Copy link
Member

lassepe commented Sep 18, 2019

The test's fail when used with POMDPs 0.7.3 because simulate is type unstable and therefore the @inferred test fails.

@lassepe
Copy link
Member Author

lassepe commented Sep 18, 2019

Notice: this is only an issue with julia 1.0. In julia 0.7 and julia 1.1 and 1.2 the inference works.

@lassepe lassepe changed the title simulate has type instability with POMDPs 0.7.3 simulate has type instability with POMDPs 0.7.3 when testing with Julia 1.0 Sep 18, 2019
@zsunberg
Copy link
Member

Yeah... I think just do

[compat]
julia = "^1.1"

or do if VERSION >= v"1.1" in that test

@lassepe
Copy link
Member Author

lassepe commented Sep 18, 2019

I don't see why this is happening since gen(DDNOut...) seems to be type stable in 1.0

@lassepe
Copy link
Member Author

lassepe commented Sep 18, 2019

It seems to be mainly that in Julia 1.0.5 it can't figure out that the both branches result in the same type for r. Here is a minimal example. I will remove support for version 1.0 then. (Also in BasicPOMCP).

using Random
using POMDPs
using POMCPOW
using POMDPModels

pomdp = BabyPOMDP()
s = first(states(pomdp))
a = first(actions(pomdp))
solver = POMCPOWSolver()
rng = MersenneTwister(1)
function f(pomdp, s, a, rng)
    if rand() > 0.5
        sp, o, r = gen(DDNOut(:sp, :o, :r), pomdp, s, a, rng)
    else
        sp, r = gen(DDNOut(:sp, :r), pomdp, s, a, rng)
    end
    return r
end

f(pomdp, s, a, rng)
@code_warntype f(pomdp, s, a, rng)

Julia 1.0.5:

Body::Any
12 1 ── %1  = Random.GLOBAL_RNG::MersenneTwister              │╻         rand
   │    %2  = (Base.getfield)(%1, :idxF)::Int64               ││╻╷╷╷╷╷    rand
   │    %3  = Random.MT_CACHE_F::Int64                        │││┃││││     rand
   │    %4  = (%2 === %3)::Bool                               ││││┃││││     rand
   └───       goto #3 if not %4                               │││││┃│        rand
   2 ── %6  = $(Expr(:gc_preserve_begin, :(%1)))              ││││││┃│╷       reserve_1
   │    %7  = (Base.getfield)(%1, :state)::Random.DSFMT.DSFMT_state││╻         gen_rand
   │    %8  = (Base.getfield)(%1, :vals)::Array{Float64,1}    ││││││││┃│        macro expansion
   │    %9  = $(Expr(:foreigncall, :(:jl_array_ptr), Ptr{Float64}, svec(Any), :(:ccall), 1, :(%8)))::Ptr{Float64}
   │    %10 = (Base.getfield)(%1, :vals)::Array{Float64,1}    │││││││││╻         getproperty
   │    %11 = (Base.arraylen)(%10)::Int64                     │││││││││╻         length
   │          invoke Random.dsfmt_fill_array_close1_open2!(%7::Random.DSFMT.DSFMT_state, %9::Ptr{Float64}, %11::Int64)
   │          $(Expr(:gc_preserve_end, :(%6)))                │││││││││ 
   └───       (Base.setfield!)(%1, :idxF, 0)                  ││││││││╻╷        mt_setfull!
   3 ──       goto #4                                         ││││││╻         reserve_1
   4 ── %16 = (Base.getfield)(%1, :vals)::Array{Float64,1}    ││││││╻╷╷       rand_inbounds
   │    %17 = (Base.getfield)(%1, :idxF)::Int64               │││││││┃│        mt_pop!
   │    %18 = (Base.add_int)(%17, 1)::Int64                   ││││││││╻         +
   │          (Base.setfield!)(%1, :idxF, %18)                ││││││││╻         setproperty!
   │    %20 = (Base.arrayref)(false, %16, %18)::Float64       ││││││││╻         getindex
   └───       goto #6                                         ││││││││  
   5 ──       $(Expr(:unreachable))                           ││││││││  
   6 ┄─       goto #7                                         │││││││   
   7 ──       goto #8                                         ││││││    
   8 ──       goto #9                                         │││││     
   9 ── %26 = (Base.sub_float)(%20, 1.0)::Float64             ││││╻         -
   └───       goto #10                                        ││││      
   10 ─       goto #11                                        │││       
   11 ─       goto #12                                        ││        
   12 ─ %30 = (Base.lt_float)(0.5, %26)::Bool                 ││╻         <
   └───       goto #14 if not %30                             │         
13 13 ─ %32 = invoke Main.DDNOut(:sp::Symbol, :o::Vararg{Symbol,N} where N, :r)::DDNOut{_1} where _1
   │    %33 = (Main.gen)(%32, pomdp, s, a, rng)::Any          │         
   │    %34 = (Base.indexed_iterate)(%33, 1)::Any             │         
   │          (Core.getfield)(%34, 1)                         │         
   │    %36 = (Core.getfield)(%34, 2)::Any                    │         
   │    %37 = (Base.indexed_iterate)(%33, 2, %36)::Any        │         
   │          (Core.getfield)(%37, 1)                         │         
   │    %39 = (Core.getfield)(%37, 2)::Any                    │         
   │    %40 = (Base.indexed_iterate)(%33, 3, %39)::Any        │         
   │    %41 = (Core.getfield)(%40, 1)::Any                    │         
   └───       goto #15                                        │         
15 14 ─ %43 = invoke Main.DDNOut(:sp::Symbol, :r::Vararg{Symbol,N} where N)::DDNOut{_1} where _1
   │    %44 = (Main.gen)(%43, pomdp, s, a, rng)::Any          │         
   │    %45 = (Base.indexed_iterate)(%44, 1)::Any             │         
   │          (Core.getfield)(%45, 1)                         │         
   │    %47 = (Core.getfield)(%45, 2)::Any                    │         
   │    %48 = (Base.indexed_iterate)(%44, 2, %47)::Any        │         
   └─── %49 = (Core.getfield)(%48, 1)::Any                    │         
17 15 ┄ %50 = φ (#13 => %41, #14 => %49)::Any                 │         
   └───       return %50

Julia 1.2

Variables
  #self#::Core.Compiler.Const(f, false)
  pomdp::BabyPOMDP
  s::Bool
  a::Bool
  rng::MersenneTwister
  o::Bool
  @_7::Int64
  sp::Bool
  @_9::Int64
  r::Float64

Body::Float64
1 ─       Core.NewvarNode(:(o))
│         Core.NewvarNode(:(@_7))
│         Core.NewvarNode(:(sp))
│         Core.NewvarNode(:(@_9))
│         Core.NewvarNode(:(r))
│   %6  = Main.rand()::Float64
│   %7  = (%6 > 0.5)::Bool
└──       goto #3 if not %7
2 ─ %9  = Main.DDNOut(:sp, :o, :r)::Core.Compiler.Const(DDNOut{(:sp, :o, :r)}(), false)
│   %10 = Main.gen(%9, pomdp, s, a, rng)::Tuple{Bool,Bool,Float64}
│   %11 = Base.indexed_iterate(%10, 1)::Core.Compiler.PartialStruct(Tuple{Bool,Int64}, Any[Bool, Core.Compiler.Const(2, false)])
│         (sp = Core.getfield(%11, 1))
│         (@_7 = Core.getfield(%11, 2))
│   %14 = Base.indexed_iterate(%10, 2, @_7::Core.Compiler.Const(2, false))::Core.Compiler.PartialStruct(Tuple{Bool,Int64}, Any[Bool, Core.Compiler.Const(3, false)])
│         (o = Core.getfield(%14, 1))
│         (@_7 = Core.getfield(%14, 2))
│   %17 = Base.indexed_iterate(%10, 3, @_7::Core.Compiler.Const(3, false))::Core.Compiler.PartialStruct(Tuple{Float64,Int64}, Any[Float64, Core.Compiler.Const(4, false)])
│         (r = Core.getfield(%17, 1))
└──       goto #4
3 ─ %20 = Main.DDNOut(:sp, :r)::Core.Compiler.Const(DDNOut{(:sp, :r)}(), false)
│   %21 = Main.gen(%20, pomdp, s, a, rng)::Tuple{Bool,Float64}
│   %22 = Base.indexed_iterate(%21, 1)::Core.Compiler.PartialStruct(Tuple{Bool,Int64}, Any[Bool, Core.Compiler.Const(2, false)])
│         (sp = Core.getfield(%22, 1))
│         (@_9 = Core.getfield(%22, 2))
│   %25 = Base.indexed_iterate(%21, 2, @_9::Core.Compiler.Const(2, false))::Core.Compiler.PartialStruct(Tuple{Float64,Int64}, Any[Float64, Core.Compiler.Const(3, false)])
└──       (r = Core.getfield(%25, 1))
4 ┄       return r

lassepe added a commit that referenced this issue Sep 18, 2019
lassepe added a commit that referenced this issue Sep 18, 2019
@lassepe lassepe closed this as completed Sep 19, 2019
@zsunberg
Copy link
Member

zsunberg commented Sep 19, 2019 via email

@lassepe
Copy link
Member Author

lassepe commented Sep 19, 2019 via email

@lassepe
Copy link
Member Author

lassepe commented Sep 19, 2019

With a type annotation, of R::Float64 the tests pass but the solver is still de-facto unusable because of the internal type instability. I would stick with not supporting Julia 1.0 starting from version 0.3.0 of this package. If people want to use POMCPOW or BasicPOMCP with Julia 1.0 they have to use an older release.

@zsunberg
Copy link
Member

yes, this seems like the right thing to do - it's fine to make them use version >= 1.1

zsunberg pushed a commit that referenced this issue Sep 20, 2019
* V0.8 compat

* Remove support for Julia 1.0

- fixes #12

* Deprecate current_obs and implement currentobs and history on POWTreeObsNode

* Never hand POWTreeObsNode to actions(m,b)

* Bump version
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

No branches or pull requests

2 participants