Does @allocated not work with multithreading?

I’ve been trying to better undertstand how to find allocations in my code, and I stumbled on this simple MWE which either exposes some limitation of @allocated, or (more likely) a limitation of my understanding.

function test() 
    a = @allocated begin
    end
    if a>0 
        println(a)  
        error(" Found an allocation?")
    end 
end

With nothing in the begin/end block, no allocations should be done, and so the function should just finish without an error. This is the case if I just run it on a single thread.

for _ in 1:10000
    test()
end

But now doing the same thing in a threaded loop behaves differently (it returns the error message):

Threads.@threads for _ in 1:10000
    test()
end

Am I doing something dumb here?

I’m using Julia Version 1.5.2 (2020-09-23):

Commit 539f3ce943 (2020-09-23 23:17 UTC)
Platform Info:
  OS: macOS (x86_64-apple-darwin18.7.0)
  CPU: Intel(R) Core(TM) i7-8700B CPU @ 3.20GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-9.0.1 (ORCJIT, skylake)
Environment:
  JULIA_NUM_THREADS = 12

Yes, multithreading causes allocations. The allocations are essentially fundamental to being able to coordinate dataflow and communication between threads.

1 Like

I wouldn’t say they’re essential. BLAS, for example, doesn’t allocate.

1 Like

Well, I think it’s fair to say BLAS does not coordinate (arbitrary) dataflow and communication :slight_smile:

Yes, this is the case. It’s not clearly documented, but @allocated cannot be used concurrently. It uses “a global counter” [^1] to detect allocations. That is to say, with

@sync begin
    @spawn do_some_allocation()
    x = @allocated nothing
end

x can, in principle, include some allocations in do_some_allocation.

[^1]: More specifically this is a set of counters local to OS thread but shared across executions. But at the level of Julia interface, it acts as if a single counter by combining the set of counters.

3 Likes