Type stability of different for loops

question

#1

Hi all-

I am experiencing a type instability problem with my code. I was able to narrow down the problem and find a solution, but it doesn’t make sense to me. It seems that iterating over objects rather than indices is the culprit. Below, I posted simplified examples in which @code_warntype reveals a problematic Union. I am wondering why this is happening and if it is an inherent limitation of type inference.

using Combinatorics,StatsFuns

#not type stable 
#Union{Nothing, Tuple{Tuple{Int64,Array{Bool,1}},Tuple{Int64,Array{Int64,1}}}}
function myFun1(n1,n2)
    M = multiset_permutations([fill(true,n1);fill(false,n2)],n1+n2)
    LLs = fill(0.0,length(M))
    for (i,m) in enumerate(M)
        m
    end
    return logsumexp(LLs)
end

#not type stable 
#Union{Nothing, Tuple{Tuple{Int64,Array{Bool,1}},Tuple{Int64,Array{Int64,1}}}}
function myFun2(n1,n2)
    M = multiset_permutations([fill(true,n1);fill(false,n2)],n1+n2)
    LLs = fill(0.0,length(M))
    for m in M
        m
    end
    return logsumexp(LLs)
end


#type stable 
function myFun3(n1,n2)
    M = collect(multiset_permutations([fill(true,n1);fill(false,n2)],n1+n2))
    LLs = fill(0.0,length(M))
    for i in 1:length(M)
        M[i]
    end
    return logsumexp(LLs)
end


#2

Your loops don’t do anything, right? Also what are n1 and n2? Presumably Ints? myFun3 does not work for me on Julia 1.0:

julia> myFun3(n1,n2)
ERROR: MethodError: no method matching getindex(::Combinatorics.MultiSetPermutations{Array{Bool,1}}, ::Int64)
Stacktrace:
 [1] myFun3(::Int64, ::Int64) at ./REPL[9]:5
 [2] top-level scope at none:0

#3

My apologies. I forgot to add collect() to the multisets in myFun3. I corrected the initial post and it now works as intended. The type instability problem did not depend on the code in the for loop so I removed it to simplify the example.


#4

Yes, n1 and n2 are Integers.