Iโve recently added a new feature to CounterfactualExplanations.jl
that adds support for multi-processing through MPI. On the user-end, this is handled through a simple macro:
ces = @with_parallelizer parallelizer begin
generate_counterfactual(
xs,
target,
counterfactual_data,
M,
generator
)
end
Now I realised that this causes an issue for keyword arguments that are passed to generate_counterfactual
as Symbol
s, because they are turned into QuoteNodes
inside the macro, e.g.
ces = @with_parallelizer MPIParallelizer() begin
generate_counterfactual(
xs,
target,
counterfactual_data,
M,
generator;
initialization=:identity
)
end
throws an error:
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ TypeError โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ โ
โ TypeError: in keyword argument initialization, expected Symbol, got a value of type QuoteNode โ
โ โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
In this PR Iโve added a fix that relies on call eval
on the QuoteNode
inside the final quote
that is returned by the macro:
macro with_parallelizer(parallelizer, expr)
[...]
# Parallelize:
output = quote
@assert CounterfactualExplanations.parallelizable($f) "`f` is not a parallelizable process."
kws = [Pair(k, typeof(v) == QuoteNode ? eval(v) : v) for (k, v) in $aakws]
output = CounterfactualExplanations.parallelize($pllr, $f, $escaped_args...; kws...)
output
end
return output
end
This feels dodgy (as do most things when I dare to write a macro) but if I understand the following section of the docs on macro hygiene correctly, it is fine/standard?
[โฆ] For example, many macros simply wrap their arguments in a
QuoteNode
or other similarExpr
. Some examples of this include@task body
which simply returnsschedule(Task(() -> $body))
, and@eval expr
, which simply returnseval(QuoteNode(expr))
.
Is this indeed fine? If not, any suggestions as to how I can deal with the QuoteNode
or improve/avoid the macro altogether?
Thanks!