I have some code leading to this error:
julia> logdensityof(m(x), rand(m(x)))
ERROR: syntax: multiple type declarations for "x"
Stacktrace:
[1] top-level scope
@ REPL[74]:1
That's it, pretty useless stack trace. I could see this if you just type garbage at the REPL prompt, but I think what I entered is ok:
julia> dump(:(logdensityof(m(x), rand(m(x)))))
Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol logdensityof
2: Expr
head: Symbol call
args: Array{Any}((2,))
1: Symbol m
2: Symbol x
3: Expr
head: Symbol call
args: Array{Any}((2,))
1: Symbol rand
2: Expr
head: Symbol call
args: Array{Any}((2,))
1: Symbol m
2: Symbol x
Has anyone seen this before? Why no real stack trace? How can I even begin to debug this?
This seems to come from this line of julia-syntax.scm
:
((decl)
;; handle var::T declaration by storing the type in the var-info
;; record. for non-symbols or globals, emit a type assertion.
(let ((vi (get tab (cadr e) #f)))
(if vi
(begin (if (not (equal? (vinfo:type vi) '(core Any)))
(error (string "multiple type declarations for \""
(cadr e) "\"")))
(if (assq (cadr e) captvars)
(error (string "type of \"" (cadr e)
"\" declared in inner scope")))
(vinfo:set-type! vi (caddr e))))))
But it's still not clear why the stack trace is so broken
Is this a revise issue? The line you pasted isn't related to the error at all, no?
Revise seems happy, as far as I can tell
Maybe a parser bug? I mean, I may well have an error, but it's getting the stack trace wrong
can you repro this in a fresh session?
Yes
You can check that the code typed in the REPL is syntactically fine
julia> logdensityof = m = x = rand = Returns(123);
julia> logdensityof(m(x), rand(m(x)))
123
I agree that the stacktrace is not informative though
Can you reproduce it in a session started as julia --startup=no
?
Just as yet another sanity check, did you try renaming the variable x
to something else? Does the syntax error still report the variable name x
? (Otherwise, maybe it's from some dynamically-generated code?)
Also, did you try evaluating the sub-expressions one by one?
(I know that these are kind of stupid things to ask but the error in the OP is very mind-boggling...)
It's tricky, because the problem is in a generated function. I've just tricked it into printing what's generated instead of executing it, having a look at that now
It comes down to
begin
begin
$(Expr(:meta, :inline))
local _retn
_args = argvals(_mc)
_obs = observations(_mc)
_cfg = merge(_cfg, (args = _args, obs = _obs, pars = _pars))
x::Vector{Float64} = _args.x
x::Vector{Float64} = _pars.x
#= /home/chad/git/Tilde.jl/src/primitives/interpret.jl:52 =#
(x, _ctx, _retn) = tilde(unsafe_logdensityof, (Accessors.opticcompose)((Accessors.IndexLens)((1,))), static(:x), x, Normal(), _cfg, _ctx)
#= /home/chad/git/Tilde.jl/src/primitives/interpret.jl:53 =#
isa(_retn, ReturnNow) && return _retn.value
for j = :(:)(2, length(x))
begin
#= /home/chad/git/Tilde.jl/src/primitives/interpret.jl:52 =#
(x, _ctx, _retn) = tilde(unsafe_logdensityof, (Accessors.opticcompose)((Accessors.IndexLens)((j,))), static(:x), x, Normal(μ = x[:-(j, 1)]), _cfg, _ctx)
#= /home/chad/git/Tilde.jl/src/primitives/interpret.jl:53 =#
isa(_retn, ReturnNow) && return _retn.value
end
end
_retn
end
end
This could use a little cleaning up, but I wouldn't think it would lead to the error I'm getting
Can you reproduce it in a session started as
julia --startup=no
?
I'll try that soon. FWIW my startup.jl
is
atreplinit() do repl
repl.options.iocontext[:compact] = true
end
It works for some models:
julia> m1 = @model begin
a ~ Uniform()
b ~ Normal(a,2)
end;
julia> r = rand(m1())
(a = 0.652999, b = 3.04375)
julia> logdensityof(m1(), r)
-2.32655
But then
julia> m2 = @model x begin
x[1] ~ Normal()
for j in 2:length(x)
x[j] ~ Normal(μ = x[j-1])
end
end;
julia> x = zeros(4);
julia> r2 = rand(m2(x))
(x = [0.333947, 1.06483, 2.35892, 1.45661],)
julia> logdensityof(m2(x), r2)
ERROR: syntax: multiple type declarations for "x"
Stacktrace:
[1] top-level scope
@ REPL[160]:1
It's not specific to x
julia> m2 = @model y begin
y[1] ~ Normal()
for j in 2:length(y)
y[j] ~ Normal(μ = y[j-1])
end
end;
julia> y = zeros(4);
julia> r2 = rand(m2(x))
(y = [0.0852394, 0.492802, 0.68513, 0.760316],)
julia> logdensityof(m2(y), r2)
ERROR: syntax: multiple type declarations for "y"
Stacktrace:
[1] top-level scope
@ REPL[164]:1
I think I got it. I pass in named tuples for arguments, observations, and parameters. Then in the generated function, I push some lines like
:($k::$T = _pars.$k)
I thought maybe I needed to get rid of the type annotation, but I think it might work out better to make sure the variable is treated as local. So I added
for k in keys(args) ∪ keys(pars) ∪ keys(data)
push!(loader.args, :(local $k))
end
and I think that fixes things. Thanks all for the helpful discussion :smile:
Chad Scherrer has marked this topic as resolved.
Last updated: Dec 28 2024 at 04:38 UTC