# Turing models, vectors, and type stability?

**URL:** <https://discourse.julialang.org/t/turing-models-vectors-and-type-stability/119928>\
**Category:** Statistics\
**Created:** [September 26, 2024, 7:04pm UTC](https://discourse.julialang.org/t/turing-models-vectors-and-type-stability/119928 "2024-09-26T19:04:06Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![rkube](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rkube/32/211198_2.png) [@rkube](https://discourse.julialang.org/u/rkube)\
**Post date:** [September 26, 2024, 7:04pm UTC](https://discourse.julialang.org/t/turing-models-vectors-and-type-stability/119928/1 "2024-09-26T19:04:06Z")

</div>

Hi,  
I’m puzzled by a type instability issue in the Turing model below. When the model defines the vector p2 before iterating, the model is type stable. When using the `[...]` notation, the model is unstable.

```julia
using LinearAlgebra
using Random
using Turing

@model function tmodel_v1(x, mat)
    Nx, _ = size(mat)
    p ~ filldist(Normal(0.0, 1.0), Nx)
    σ² ~ truncated(Normal(0.0, 0.01); lower=0)

    p2 = [dot(p, m) for m ∈ eachslice(mat, dims=2)]

    x ~ MvNormal(p2, σ² * I)
end

@model function tmodel_v2(x, mat)
    Nx, Ny = size(mat)

    p ~ filldist(Normal(0.0, 1.0), Nx)
    σ² ~ truncated(Normal(0.0, 0.01); lower=0)

    p2 = zeros(Ny)
    for ix ∈ axes(mat, 2)
        p2[ix] = dot(p, mat[:, ix])
    end

    x ~ MvNormal(p2, σ² * I)
end

x = randn(4)
A = randn(3, 4)

model_unstable = tmodel_v1(x, A)
model_stable = tmodel_v2(x, A)

@code_warntype model_unstable.f(
    model_unstable,
    Turing.VarInfo(model_unstable),
    Turing.SamplingContext(
        Random.GLOBAL_RNG, Turing.SampleFromPrior(), Turing.DefaultContext(),
    ),
    model_unstable.args...,
)

@code_warntype model_stable.f(
    model_unstable,
    Turing.VarInfo(model_unstable),
    Turing.SamplingContext(
        Random.GLOBAL_RNG, Turing.SampleFromPrior(), Turing.DefaultContext(),
    ),
    model_unstable.args...,
)

```

```MethodInstance
  from tmodel_v1( __model__ ::DynamicPPL.Model, __varinfo__ ::DynamicPPL.AbstractVarInfo, __context__ ::AbstractPPL.AbstractContext, x, mat) @ Main ~/julia_envs/bayes_fun/src/test_typestability.jl:7
Arguments
  #self#::Core.Const(tmodel_v1)
  __model__ ::DynamicPPL.Model{typeof(tmodel_v1), (:x, :mat), (), (), Tuple{Vector{Float64}, Matrix{Float64}}, Tuple{}, DynamicPPL.DefaultContext}
  __varinfo__ @_3::DynamicPPL.TypedVarInfo{@NamedTuple{p::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:p, typeof(identity)}, Int64}, Vector{DistributionsAD.TuringScalMvNormal{Vector{Float64}, Float64}}, Vector{AbstractPPL.VarName{:p, typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}, σ²::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:σ², typeof(identity)}, Int64}, Vector{Truncated{Normal{Float64}, Continuous, Float64, Float64, Nothing}}, Vector{AbstractPPL.VarName{:σ², typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}}, Float64}
  __context__ ::Core.Const(DynamicPPL.SamplingContext{DynamicPPL.SampleFromPrior, DynamicPPL.DefaultContext, Random._GLOBAL_RNG}(Random._GLOBAL_RNG(), DynamicPPL.SampleFromPrior(), DynamicPPL.DefaultContext()))
  x@_5::Vector{Float64}
  mat::Matrix{Float64}
Locals
  @_7::Int64
  @_8::Int64
  #11::var"#11#12"
  @_10::Union{}
  @_11::Int64
  @_12::Union{}
  @_13::Int64
  @_14::Int64
  retval#240::Any
  value#237::Vector{Float64}
  value#239::Any
  isassumption#236::Bool
  vn#235::AbstractPPL.VarName
  dist#238::Any
  p2::Vector
  value#232::Union{}
  σ²::Float64
  value#234::Float64
  isassumption#231::Bool
  vn#230::AbstractPPL.VarName{:σ², typeof(identity)}
  dist#233::Truncated{Normal{Float64}, Continuous, Float64, Float64, Nothing}
  value#227::Union{}
  p@_29::Core.Box
  value#229::Vector{Float64}
  isassumption#226::Bool
  vn#225::AbstractPPL.VarName{:p, typeof(identity)}
  dist#228::DistributionsAD.TuringScalMvNormal{Vector{Float64}, Float64}
  Nx::Int64
  p@_35::Union{}
  p@_36::Union{}
  __varinfo__ @_37::DynamicPPL.TypedVarInfo{@NamedTuple{p::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:p, typeof(identity)}, Int64}, Vector{DistributionsAD.TuringScalMvNormal{Vector{Float64}, Float64}}, Vector{AbstractPPL.VarName{:p, typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}, σ²::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:σ², typeof(identity)}, Int64}, Vector{Truncated{Normal{Float64}, Continuous, Float64, Float64, Nothing}}, Vector{AbstractPPL.VarName{:σ², typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}}, Float64}
  x@_38::Any
  @_39::Bool
  @_40::Bool
  @_41::Bool
  @_42::Bool
  @_43::Bool
  @_44::Bool
  @_45::Any
  @_46::Any
Body::Tuple{Any, DynamicPPL.TypedVarInfo{@NamedTuple{p::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:p, typeof(identity)}, Int64}, Vector{DistributionsAD.TuringScalMvNormal{Vector{Float64}, Float64}}, Vector{AbstractPPL.VarName{:p, typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}, σ²::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:σ², typeof(identity)}, Int64}, Vector{Truncated{Normal{Float64}, Continuous, Float64, Float64, Nothing}}, Vector{AbstractPPL.VarName{:σ², typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}}, Float64}}
1 ── (x@_38 = x@_5)
│ ( __varinfo__ @_37 = __varinfo__ @_3)
│ Core.NewvarNode(:(@_7))
│ Core.NewvarNode(:(@_8))
│ Core.NewvarNode(:(#11))
│ Core.NewvarNode(:(@_10))
│ Core.NewvarNode(:(@_11))
│ Core.NewvarNode(:(@_12))
│ Core.NewvarNode(:(@_13))
│ Core.NewvarNode(:(retval#240))
│ Core.NewvarNode(:(value#237))
│ Core.NewvarNode(:(value#239))
│ Core.NewvarNode(:(isassumption#236))
│ Core.NewvarNode(:(vn#235))
│ Core.NewvarNode(:(dist#238))
│ Core.NewvarNode(:(p2))
│ Core.NewvarNode(:(value#232))
│ Core.NewvarNode(:(σ²))
│ Core.NewvarNode(:(value#234))
│ Core.NewvarNode(:(isassumption#231))
│ Core.NewvarNode(:(vn#230))
│ Core.NewvarNode(:(dist#233))
│ Core.NewvarNode(:(value#227))
│ (p@_29 = Core.Box())
│ Core.NewvarNode(:(value#229))
│ Core.NewvarNode(:(isassumption#226))
│ %27 = Main.size(mat)::Tuple{Int64, Int64}
│ %28 = Base.indexed_iterate(%27, 1)::Core.PartialStruct(Tuple{Int64, Int64}, Any[Int64, Core.Const(2)])
│ (Nx = Core.getfield(%28, 1))
│ (@_14 = Core.getfield(%28, 2))
│ %31 = Base.indexed_iterate(%27, 2, @_14::Core.Const(2))::Core.PartialStruct(Tuple{Int64, Int64}, Any[Int64, Core.Const(3)])
│ Core.getfield(%31, 1)
│ %33 = Main.Normal(0.0, 1.0)::Core.Const(Normal{Float64}(μ=0.0, σ=1.0))
│ (dist#228 = Main.filldist(%33, Nx))
│ %35 = Core.apply_type(AbstractPPL.VarName, :p)::Core.Const(AbstractPPL.VarName{:p})
│ %36 = (%35)()::Core.Const(p)
│ (vn#225 = (DynamicPPL.resolve_varnames)(%36, dist#228::Core.PartialStruct(DistributionsAD.TuringScalMvNormal{Vector{Float64}, Float64}, Any[Vector{Float64}, Core.Const(1.0)])))
│ %38 = (DynamicPPL.contextual_isassumption)( __context__ , vn#225)::Core.Const(true)
└─── goto #8 if not %38
2 ── %40 = (DynamicPPL.inargnames)(vn#225, __model__ )::Core.Const(false)
│ %41 = !%40::Core.Const(true)
└─── goto #4 if not %41
3 ── goto #5
4 ── Core.Const(:((DynamicPPL.inmissings)(vn#225, __model__ )))
└─── Core.Const(:(goto %48 if not %44))
5 ┄─ (@_40 = true)
└─── goto #7
6 ── Core.Const(:(Core.isdefined(p@_29, :contents)))
│ Core.Const(:(goto %51 if not %48))
│ Core.Const(:(goto %53))
│ Core.Const(Core.NewvarNode(:(p@_35)))
│ Core.Const(:(p@_35))
│ Core.Const(:(Core.getfield(p@_29, :contents)))
└─── Core.Const(:(@_40 = %53 === Main.missing))
7 ┄─ (@_39 = @_40::Core.Const(true))
└─── goto #9
8 ── Core.Const(:(@_39 = false))
9 ┄─ (isassumption#226 = @_39::Core.Const(true))
│ %59 = (DynamicPPL.contextual_isfixed)( __context__ , vn#225)::Core.Const(false)
└─── goto #11 if not %59
10 ─ Core.Const(:((DynamicPPL.getfixed_nested)( __context__ , vn#225)))
│ Core.Const(:(Core.setfield!(p@_29, :contents, %61)))
└─── Core.Const(:(goto %99))
11 ┄ goto #13 if not isassumption#226::Core.Const(true)
12 ─ %65 = Core.tuple( __context__ )::Core.Const((DynamicPPL.SamplingContext{DynamicPPL.SampleFromPrior, DynamicPPL.DefaultContext, Random._GLOBAL_RNG}(Random._GLOBAL_RNG(), DynamicPPL.SampleFromPrior(), DynamicPPL.DefaultContext()),))
│ %66 = (DynamicPPL.check_tilde_rhs)(dist#228::Core.PartialStruct(DistributionsAD.TuringScalMvNormal{Vector{Float64}, Float64}, Any[Vector{Float64}, Core.Const(1.0)]))::Core.PartialStruct(DistributionsAD.TuringScalMvNormal{Vector{Float64}, Float64}, Any[Vector{Float64}, Core.Const(1.0)])
│ %67 = (DynamicPPL.unwrap_right_vn)(%66, vn#225)::Core.PartialStruct(Tuple{DistributionsAD.TuringScalMvNormal{Vector{Float64}, Float64}, AbstractPPL.VarName{:p, typeof(identity)}}, Any[Core.PartialStruct(DistributionsAD.TuringScalMvNormal{Vector{Float64}, Float64}, Any[Vector{Float64}, Core.Const(1.0)]), AbstractPPL.VarName{:p, typeof(identity)}])
│ %68 = Core.tuple( __varinfo__ @_37)::Tuple{DynamicPPL.TypedVarInfo{@NamedTuple{p::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:p, typeof(identity)}, Int64}, Vector{DistributionsAD.TuringScalMvNormal{Vector{Float64}, Float64}}, Vector{AbstractPPL.VarName{:p, typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}, σ²::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:σ², typeof(identity)}, Int64}, Vector{Truncated{Normal{Float64}, Continuous, Float64, Float64, Nothing}}, Vector{AbstractPPL.VarName{:σ², typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}}, Float64}}
│ %69 = Core._apply_iterate(Base.iterate, DynamicPPL.tilde_assume!!, %65, %67, %68)::Tuple{Vector{Float64}, DynamicPPL.TypedVarInfo{@NamedTuple{p::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:p, typeof(identity)}, Int64}, Vector{DistributionsAD.TuringScalMvNormal{Vector{Float64}, Float64}}, Vector{AbstractPPL.VarName{:p, typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}, σ²::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:σ², typeof(identity)}, Int64}, Vector{Truncated{Normal{Float64}, Continuous, Float64, Float64, Nothing}}, Vector{AbstractPPL.VarName{:σ², typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}}, Float64}}
│ %70 = Base.indexed_iterate(%69, 1)::Core.PartialStruct(Tuple{Vector{Float64}, Int64}, Any[Vector{Float64}, Core.Const(2)])
│ (value#229 = Core.getfield(%70, 1))
│ (@_13 = Core.getfield(%70, 2))
│ %73 = Base.indexed_iterate(%69, 2, @_13::Core.Const(2))::Core.PartialStruct(Tuple{DynamicPPL.TypedVarInfo{@NamedTuple{p::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:p, typeof(identity)}, Int64}, Vector{DistributionsAD.TuringScalMvNormal{Vector{Float64}, Float64}}, Vector{AbstractPPL.VarName{:p, typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}, σ²::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:σ², typeof(identity)}, Int64}, Vector{Truncated{Normal{Float64}, Continuous, Float64, Float64, Nothing}}, Vector{AbstractPPL.VarName{:σ², typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}}, Float64}, Int64}, Any[DynamicPPL.TypedVarInfo{@NamedTuple{p::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:p, typeof(identity)}, Int64}, Vector{DistributionsAD.TuringScalMvNormal{Vector{Float64}, Float64}}, Vector{AbstractPPL.VarName{:p, typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}, σ²::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:σ², typeof(identity)}, Int64}, Vector{Truncated{Normal{Float64}, Continuous, Float64, Float64, Nothing}}, Vector{AbstractPPL.VarName{:σ², typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}}, Float64}, Core.Const(3)])
│ ( __varinfo__ @_37 = Core.getfield(%73, 1))
│ %75 = value#229::Vector{Float64}
│ Core.setfield!(p@_29, :contents, %75)
│ value#229
└─── goto #14
13 ─ Core.Const(:((DynamicPPL.inargnames)(vn#225, __model__ )))
│ Core.Const(:(!%79))
│ Core.Const(:(goto %84 if not %80))
│ Core.Const(:((DynamicPPL.getconditioned_nested)( __context__ , vn#225)))
│ Core.Const(:(Core.setfield!(p@_29, :contents, %82)))
│ Core.Const(:((DynamicPPL.check_tilde_rhs)(dist#228)))
│ Core.Const(:(Core.isdefined(p@_29, :contents)))
│ Core.Const(:(goto %88 if not %85))
│ Core.Const(:(goto %90))
│ Core.Const(Core.NewvarNode(:(p@_36)))
│ Core.Const(:(p@_36))
│ Core.Const(:(Core.getfield(p@_29, :contents)))
│ Core.Const(:(vn#225))
│ Core.Const(:((DynamicPPL.tilde_observe!!)( __context__ , %84, %90, %91, __varinfo__ @_37)))
│ Core.Const(:(Base.indexed_iterate(%92, 1)))
│ Core.Const(:(value#227 = Core.getfield(%93, 1)))
│ Core.Const(:(@_12 = Core.getfield(%93, 2)))
│ Core.Const(:(Base.indexed_iterate(%92, 2, @_12)))
│ Core.Const(:( __varinfo__ @_37 = Core.getfield(%96, 1)))
└─── Core.Const(:(value#227))
14 ┄ %99 = Main.Normal(0.0, 0.01)::Core.Const(Normal{Float64}(μ=0.0, σ=0.01))
│ %100 = (:lower,)::Core.Const((:lower,))
│ %101 = Core.apply_type(Core.NamedTuple, %100)::Core.Const(NamedTuple{(:lower,)})
│ %102 = Core.tuple(0)::Core.Const((0,))
│ %103 = (%101)(%102)::Core.Const((lower = 0,))
│ (dist#233 = Core.kwcall(%103, Main.truncated, %99))
│ %105 = Core.apply_type(AbstractPPL.VarName, :σ²)::Core.Const(AbstractPPL.VarName{:σ²})
│ %106 = (%105)()::Core.Const(σ²)
│ (vn#230 = (DynamicPPL.resolve_varnames)(%106, dist#233::Core.PartialStruct(Truncated{Normal{Float64}, Continuous, Float64, Float64, Nothing}, Any[Core.Const(Normal{Float64}(μ=0.0, σ=0.01)), Core.Const(0.0), Core.Const(nothing), Float64, Float64, Core.Const(1.0), Float64, Float64])))
│ %108 = (DynamicPPL.contextual_isassumption)( __context__ , vn#230)::Core.Const(true)
└─── goto #21 if not %108
15 ─ %110 = (DynamicPPL.inargnames)(vn#230, __model__ )::Core.Const(false)
│ %111 = !%110::Core.Const(true)
└─── goto #17 if not %111
16 ─ goto #18
17 ─ Core.Const(:((DynamicPPL.inmissings)(vn#230, __model__ )))
└─── Core.Const(:(goto %118 if not %114))
18 ┄ (@_42 = true)
└─── goto #20
19 ─ Core.Const(:(@_42 = σ² === Main.missing))
20 ┄ (@_41 = @_42::Core.Const(true))
└─── goto #22
21 ─ Core.Const(:(@_41 = false))
22 ┄ (isassumption#231 = @_41::Core.Const(true))
│ %123 = (DynamicPPL.contextual_isfixed)( __context__ , vn#230)::Core.Const(false)
└─── goto #24 if not %123
23 ─ Core.Const(:(σ² = (DynamicPPL.getfixed_nested)( __context__ , vn#230)))
└─── Core.Const(:(goto %155))
24 ┄ goto #26 if not isassumption#231::Core.Const(true)
25 ─ %128 = Core.tuple( __context__ )::Core.Const((DynamicPPL.SamplingContext{DynamicPPL.SampleFromPrior, DynamicPPL.DefaultContext, Random._GLOBAL_RNG}(Random._GLOBAL_RNG(), DynamicPPL.SampleFromPrior(), DynamicPPL.DefaultContext()),))
│ %129 = (DynamicPPL.check_tilde_rhs)(dist#233::Core.PartialStruct(Truncated{Normal{Float64}, Continuous, Float64, Float64, Nothing}, Any[Core.Const(Normal{Float64}(μ=0.0, σ=0.01)), Core.Const(0.0), Core.Const(nothing), Float64, Float64, Core.Const(1.0), Float64, Float64]))::Core.PartialStruct(Truncated{Normal{Float64}, Continuous, Float64, Float64, Nothing}, Any[Core.Const(Normal{Float64}(μ=0.0, σ=0.01)), Core.Const(0.0), Core.Const(nothing), Float64, Float64, Core.Const(1.0), Float64, Float64])
│ %130 = (DynamicPPL.unwrap_right_vn)(%129, vn#230)::Core.PartialStruct(Tuple{Truncated{Normal{Float64}, Continuous, Float64, Float64, Nothing}, AbstractPPL.VarName{:σ², typeof(identity)}}, Any[Core.PartialStruct(Truncated{Normal{Float64}, Continuous, Float64, Float64, Nothing}, Any[Core.Const(Normal{Float64}(μ=0.0, σ=0.01)), Core.Const(0.0), Core.Const(nothing), Float64, Float64, Core.Const(1.0), Float64, Float64]), AbstractPPL.VarName{:σ², typeof(identity)}])
│ %131 = Core.tuple( __varinfo__ @_37)::Tuple{DynamicPPL.TypedVarInfo{@NamedTuple{p::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:p, typeof(identity)}, Int64}, Vector{DistributionsAD.TuringScalMvNormal{Vector{Float64}, Float64}}, Vector{AbstractPPL.VarName{:p, typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}, σ²::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:σ², typeof(identity)}, Int64}, Vector{Truncated{Normal{Float64}, Continuous, Float64, Float64, Nothing}}, Vector{AbstractPPL.VarName{:σ², typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}}, Float64}}
│ %132 = Core._apply_iterate(Base.iterate, DynamicPPL.tilde_assume!!, %128, %130, %131)::Tuple{Float64, DynamicPPL.TypedVarInfo{@NamedTuple{p::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:p, typeof(identity)}, Int64}, Vector{DistributionsAD.TuringScalMvNormal{Vector{Float64}, Float64}}, Vector{AbstractPPL.VarName{:p, typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}, σ²::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:σ², typeof(identity)}, Int64}, Vector{Truncated{Normal{Float64}, Continuous, Float64, Float64, Nothing}}, Vector{AbstractPPL.VarName{:σ², typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}}, Float64}}
│ %133 = Base.indexed_iterate(%132, 1)::Core.PartialStruct(Tuple{Float64, Int64}, Any[Float64, Core.Const(2)])
│ (value#234 = Core.getfield(%133, 1))
│ (@_11 = Core.getfield(%133, 2))
│ %136 = Base.indexed_iterate(%132, 2, @_11::Core.Const(2))::Core.PartialStruct(Tuple{DynamicPPL.TypedVarInfo{@NamedTuple{p::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:p, typeof(identity)}, Int64}, Vector{DistributionsAD.TuringScalMvNormal{Vector{Float64}, Float64}}, Vector{AbstractPPL.VarName{:p, typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}, σ²::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:σ², typeof(identity)}, Int64}, Vector{Truncated{Normal{Float64}, Continuous, Float64, Float64, Nothing}}, Vector{AbstractPPL.VarName{:σ², typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}}, Float64}, Int64}, Any[DynamicPPL.TypedVarInfo{@NamedTuple{p::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:p, typeof(identity)}, Int64}, Vector{DistributionsAD.TuringScalMvNormal{Vector{Float64}, Float64}}, Vector{AbstractPPL.VarName{:p, typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}, σ²::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:σ², typeof(identity)}, Int64}, Vector{Truncated{Normal{Float64}, Continuous, Float64, Float64, Nothing}}, Vector{AbstractPPL.VarName{:σ², typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}}, Float64}, Core.Const(3)])
│ ( __varinfo__ @_37 = Core.getfield(%136, 1))
│ (σ² = value#234)
│ value#234
└─── goto #27
26 ─ Core.Const(:((DynamicPPL.inargnames)(vn#230, __model__ )))
│ Core.Const(:(!%141))
│ Core.Const(:(goto %145 if not %142))
│ Core.Const(:(σ² = (DynamicPPL.getconditioned_nested)( __context__ , vn#230)))
│ Core.Const(:((DynamicPPL.check_tilde_rhs)(dist#233)))
│ Core.Const(:(σ²))
│ Core.Const(:(vn#230))
│ Core.Const(:((DynamicPPL.tilde_observe!!)( __context__ , %145, %146, %147, __varinfo__ @_37)))
│ Core.Const(:(Base.indexed_iterate(%148, 1)))
│ Core.Const(:(value#232 = Core.getfield(%149, 1)))
│ Core.Const(:(@_10 = Core.getfield(%149, 2)))
│ Core.Const(:(Base.indexed_iterate(%148, 2, @_10)))
│ Core.Const(:( __varinfo__ @_37 = Core.getfield(%152, 1)))
└─── Core.Const(:(value#232))
27 ┄ (#11 = %new(Main.:(var"#11#12"), p@_29))
│ %156 = #11::var"#11#12"
│ %157 = (:dims,)::Core.Const((:dims,))
│ %158 = Core.apply_type(Core.NamedTuple, %157)::Core.Const(NamedTuple{(:dims,)})
│ %159 = Core.tuple(2)::Core.Const((2,))
│ %160 = (%158)(%159)::Core.Const((dims = 2,))
│ %161 = Core.kwcall(%160, Main.eachslice, mat)::Core.PartialStruct(ColumnSlices{Matrix{Float64}, Tuple{Base.OneTo{Int64}}, SubArray{Float64, 1, Matrix{Float64}, Tuple{Base.Slice{Base.OneTo{Int64}}, Int64}, true}}, Any[Matrix{Float64}, Core.Const((Colon(), 1)), Tuple{Base.OneTo{Int64}}])
│ %162 = Base.Generator(%156, %161)::Core.PartialStruct(Base.Generator{ColumnSlices{Matrix{Float64}, Tuple{Base.OneTo{Int64}}, SubArray{Float64, 1, Matrix{Float64}, Tuple{Base.Slice{Base.OneTo{Int64}}, Int64}, true}}, var"#11#12"}, Any[var"#11#12", Core.PartialStruct(ColumnSlices{Matrix{Float64}, Tuple{Base.OneTo{Int64}}, SubArray{Float64, 1, Matrix{Float64}, Tuple{Base.Slice{Base.OneTo{Int64}}, Int64}, true}}, Any[Matrix{Float64}, Core.Const((Colon(), 1)), Tuple{Base.OneTo{Int64}}])])
│ (p2 = Base.collect(%162))
│ %164 = p2::Vector
│ %165 = (σ² * Main.I)::UniformScaling{Float64}
│ (dist#238 = Main.MvNormal(%164, %165))
│ %167 = Core.apply_type(AbstractPPL.VarName, :x)::Core.Const(AbstractPPL.VarName{:x})
│ %168 = (%167)()::Core.Const(x)
│ (vn#235 = (DynamicPPL.resolve_varnames)(%168, dist#238))
│ %170 = (DynamicPPL.contextual_isassumption)( __context__ , vn#235)::Core.Const(true)
└─── goto #34 if not %170
28 ─ %172 = (DynamicPPL.inargnames)(vn#235, __model__ )::Any
│ %173 = !%172::Any
└─── goto #30 if not %173
29 ─ goto #31
30 ─ %176 = (DynamicPPL.inmissings)(vn#235, __model__ )::Any
└─── goto #32 if not %176
31 ┄ (@_44 = true)
└─── goto #33
32 ─ (@_44 = x@_38::Vector{Float64} === Main.missing)
33 ┄ (@_43 = @_44)
└─── goto #35
34 ─ Core.Const(:(@_43 = false))
35 ┄ (isassumption#236 = @_43)
│ %185 = (DynamicPPL.contextual_isfixed)( __context__ , vn#235)::Core.Const(false)
└─── goto #37 if not %185
36 ─ Core.Const(:((DynamicPPL.getfixed_nested)( __context__ , vn#235)))
│ Core.Const(:(x@_38 = %187))
│ Core.Const(:(@_45 = %187))
└─── Core.Const(:(goto %220))
37 ┄ goto #39 if not isassumption#236
38 ─ %192 = Core.tuple( __context__ )::Core.Const((DynamicPPL.SamplingContext{DynamicPPL.SampleFromPrior, DynamicPPL.DefaultContext, Random._GLOBAL_RNG}(Random._GLOBAL_RNG(), DynamicPPL.SampleFromPrior(), DynamicPPL.DefaultContext()),))
│ %193 = (DynamicPPL.check_tilde_rhs)(dist#238)::Any
│ %194 = (DynamicPPL.unwrap_right_vn)(%193, vn#235)::Tuple{Any, AbstractPPL.VarName}
│ %195 = Core.tuple( __varinfo__ @_37)::Tuple{DynamicPPL.TypedVarInfo{@NamedTuple{p::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:p, typeof(identity)}, Int64}, Vector{DistributionsAD.TuringScalMvNormal{Vector{Float64}, Float64}}, Vector{AbstractPPL.VarName{:p, typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}, σ²::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:σ², typeof(identity)}, Int64}, Vector{Truncated{Normal{Float64}, Continuous, Float64, Float64, Nothing}}, Vector{AbstractPPL.VarName{:σ², typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}}, Float64}}
│ %196 = Core._apply_iterate(Base.iterate, DynamicPPL.tilde_assume!!, %192, %194, %195)::Tuple{Any, DynamicPPL.TypedVarInfo{@NamedTuple{p::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:p, typeof(identity)}, Int64}, Vector{DistributionsAD.TuringScalMvNormal{Vector{Float64}, Float64}}, Vector{AbstractPPL.VarName{:p, typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}, σ²::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:σ², typeof(identity)}, Int64}, Vector{Truncated{Normal{Float64}, Continuous, Float64, Float64, Nothing}}, Vector{AbstractPPL.VarName{:σ², typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}}, Float64}}
│ %197 = Base.indexed_iterate(%196, 1)::Core.PartialStruct(Tuple{Any, Int64}, Any[Any, Core.Const(2)])
│ (value#239 = Core.getfield(%197, 1))
│ (@_8 = Core.getfield(%197, 2))
│ %200 = Base.indexed_iterate(%196, 2, @_8::Core.Const(2))::Core.PartialStruct(Tuple{DynamicPPL.TypedVarInfo{@NamedTuple{p::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:p, typeof(identity)}, Int64}, Vector{DistributionsAD.TuringScalMvNormal{Vector{Float64}, Float64}}, Vector{AbstractPPL.VarName{:p, typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}, σ²::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:σ², typeof(identity)}, Int64}, Vector{Truncated{Normal{Float64}, Continuous, Float64, Float64, Nothing}}, Vector{AbstractPPL.VarName{:σ², typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}}, Float64}, Int64}, Any[DynamicPPL.TypedVarInfo{@NamedTuple{p::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:p, typeof(identity)}, Int64}, Vector{DistributionsAD.TuringScalMvNormal{Vector{Float64}, Float64}}, Vector{AbstractPPL.VarName{:p, typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}, σ²::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:σ², typeof(identity)}, Int64}, Vector{Truncated{Normal{Float64}, Continuous, Float64, Float64, Nothing}}, Vector{AbstractPPL.VarName{:σ², typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}}, Float64}, Core.Const(3)])
│ ( __varinfo__ @_37 = Core.getfield(%200, 1))
│ (x@_38 = value#239)
│ (@_46 = value#239)
└─── goto #42
39 ─ %205 = (DynamicPPL.inargnames)(vn#235, __model__ )::Any
│ %206 = !%205::Any
└─── goto #41 if not %206
40 ─ (x@_38 = (DynamicPPL.getconditioned_nested)( __context__ , vn#235))
41 ┄ %209 = (DynamicPPL.check_tilde_rhs)(dist#238)::Any
│ %210 = x@_38::Vector{Float64}
│ %211 = vn#235::AbstractPPL.VarName
│ %212 = (DynamicPPL.tilde_observe!!)( __context__ , %209, %210, %211, __varinfo__ @_37)::Tuple{Vector{Float64}, DynamicPPL.TypedVarInfo{@NamedTuple{p::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:p, typeof(identity)}, Int64}, Vector{DistributionsAD.TuringScalMvNormal{Vector{Float64}, Float64}}, Vector{AbstractPPL.VarName{:p, typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}, σ²::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:σ², typeof(identity)}, Int64}, Vector{Truncated{Normal{Float64}, Continuous, Float64, Float64, Nothing}}, Vector{AbstractPPL.VarName{:σ², typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}}, Float64}}
│ %213 = Base.indexed_iterate(%212, 1)::Core.PartialStruct(Tuple{Vector{Float64}, Int64}, Any[Vector{Float64}, Core.Const(2)])
│ (value#237 = Core.getfield(%213, 1))
│ (@_7 = Core.getfield(%213, 2))
│ %216 = Base.indexed_iterate(%212, 2, @_7::Core.Const(2))::Core.PartialStruct(Tuple{DynamicPPL.TypedVarInfo{@NamedTuple{p::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:p, typeof(identity)}, Int64}, Vector{DistributionsAD.TuringScalMvNormal{Vector{Float64}, Float64}}, Vector{AbstractPPL.VarName{:p, typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}, σ²::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:σ², typeof(identity)}, Int64}, Vector{Truncated{Normal{Float64}, Continuous, Float64, Float64, Nothing}}, Vector{AbstractPPL.VarName{:σ², typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}}, Float64}, Int64}, Any[DynamicPPL.TypedVarInfo{@NamedTuple{p::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:p, typeof(identity)}, Int64}, Vector{DistributionsAD.TuringScalMvNormal{Vector{Float64}, Float64}}, Vector{AbstractPPL.VarName{:p, typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}, σ²::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:σ², typeof(identity)}, Int64}, Vector{Truncated{Normal{Float64}, Continuous, Float64, Float64, Nothing}}, Vector{AbstractPPL.VarName{:σ², typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}}, Float64}, Core.Const(3)])
│ ( __varinfo__ @_37 = Core.getfield(%216, 1))
└─── (@_46 = value#237)
42 ┄ (@_45 = @_46)
│ (retval#240 = @_45)
│ %221 = Core.tuple(retval#240, __varinfo__ @_37)::Tuple{Any, DynamicPPL.TypedVarInfo{@NamedTuple{p::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:p, typeof(identity)}, Int64}, Vector{DistributionsAD.TuringScalMvNormal{Vector{Float64}, Float64}}, Vector{AbstractPPL.VarName{:p, typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}, σ²::DynamicPPL.Metadata{Dict{AbstractPPL.VarName{:σ², typeof(identity)}, Int64}, Vector{Truncated{Normal{Float64}, Continuous, Float64, Float64, Nothing}}, Vector{AbstractPPL.VarName{:σ², typeof(identity)}}, Vector{Float64}, Vector{Set{DynamicPPL.Selector}}}}, Float64}}
└─── return %221

```

I’ve tested both implementations and find that they are themself type stable:

```julia
p0 = randn(3)

dots_1(p, A) = [dot(p, aa) for aa ∈ eachslice(A, dims=2)]

function dots_2(p, A) 
    dots_2 = zeros(4)
    for ix ∈ axes(A, 2)
        dots_2[ix] = dot(p, A[:, ix])
    end
    dots_2
end

dots_1(p0, A) ≈ dots_2(p0, A)

@code_warntype dots_1(p0, A)
@code_warntype dots_2(p0, A)

```

Does anyone have an idea where this type-instability originates from?
