Passing macro as function argument?

I’m trying to benchmark various parallelization approaches, and realized I’m not sure how to change which macro is called…? Is this possible?

function count_threads(macro_name=Threads.@threads)
    n = Threads.nthreads()
    a = zeros(n)
    # next line is psuedocode
    @macro_name for i = 1:n
           a[i] = Threads.threadid()
    end
    length(unique(a))
end

you can’t because macros are expanded before run time.

1 Like

ah I see, thanks.

But if you want to use different parallelisms (or not) methods, you should probably look into high-level interfaces like ThreadsX.jl or FLoops.jl

1 Like

A little-known fact is that macros are represented as values just like functions or anything else, they are just a bit harder to get at. And calling them gives the expanded code.

julia> m = Base.var"@time"
@time (macro with 1 method)

julia> typeof(m)
Base.var"#@time"

julia> m(LineNumberNode(@__LINE__, @__FILE__), @__MODULE__, :(1+2))
quote
    #= timing.jl:206 =#
    ...
end

So you can do what you want if you make count_threads a generated function.

4 Likes

thanks! I’ve been meaning to try out ThreadsX.jl. Unfortunately, FLoops doesn’t pass this test: `Threads.@threads` doesn't compose with `ThreadProc` · Issue #249 · JuliaParallel/Dagger.jl · GitHub