Type-instability because of @threads boxing variables

So, I think I have a MWE (and it is a strange type-instability):

Copy and past the code below, and you will see that running:

run()

will result in a type instability, or not, depending on these lines of the test function:

    reduce!(list, list_threaded) # type stable
    #list = reduce!(list, list_threaded) # type unstable

The problem is inferring the type of list. Because it is mutable, and reduce also returns list, both calls above should be equivalent (and they are except if using @threads).

Thus, removing the reassignment of list on the return of reduce solves the problem. Except that the reason I am using that is that by doing that I can use the same function to operate on mutable or immutable list variables. If I remove the reassignment, I cannot use the same interface to operate on immutables. In any case, seems an issue the fact that this is affected by the use of @threads in some other part of the code.

The example:

function reduce!(list,list_threaded)
    list .= list[1]
    for i in 2:length(list_threaded)
        list .+= list_threaded[i]
    end
    return list
end

function test(list,list_threaded)
    #for it in 1:Threads.nthreads() # type stable
    Threads.@threads for it in 1:Threads.nthreads()
        for i in it:Threads.nthreads():length(list)
            list_threaded[it][i] += rand()
        end
    end
    #reduce!(list, list_threaded) # type stable
    list = reduce!(list, list_threaded) # type unstable
    return list
end

function run()
    list = zeros(10^4)
    list_threaded = [ copy(list) for _ in 1:Threads.nthreads() ]
    @code_warntype test(list, list_threaded)
end
1 Like