@inbounds Threads.@threads
This won’t work.
Threads.@threads creates a closure, which effectively “protects” everything inside from the @inbounds.
You should do something more like
Threads.@threads for $(esc(expr.args[1].args[1])) = $(esc(expr.args[1].args[2]))
@inbounds begin
$(esc(expr.args[2]))
end
end
EDIT:
My preferred approach to macros is to esc everything, and gensym all the symbols I add manually.
Except for very simple macros, I prefer handling hygiene manually. I find it much simpler and more intuitive.
That said, for the @simd, you’re not inserting symbols of your own, so just esc the entire expression.
You can interpolate the modules if you’re worried about someone breaking your macro by defining their own @inbounds and @simd in the scope they’re trying to use @usethreads:
julia> macro usethreads(cond::Bool, expr)
@assert expr.head == :for
if cond
quote
Threads.@threads for $(esc(expr.args[1].args[1])) = $(esc(expr.args[1].args[2]))
@inbounds begin
$(esc(expr.args[2]))
end
end
end
else
quote
$Base.@inbounds $Base.@simd for $(expr.args[1].args[1]) = $(expr.args[1].args[2])
$(expr.args[2])
end
end |> esc
end
end
@usethreads (macro with 1 method)
julia> @usethreads false for i = 1:3
println(Threads.threadid())
end
1
1
1