-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Some instances of invoke #206
Comments
#212 largely solves this problem. In particular, it basically resolves 1 and 2 above, but will not prevent inlining away things which have rules. In particular it will just mean that if you are unlucky enough to call Completely resolving this problem looks likely to be a bit more work, and to be a bit of a pain. This is because the compiler "lowers" Expr(:call, invoke, f, TT, args...) gets converted to Expr(:invoke, a_method_instance, f, args...) This is a problem because we lose access to In order to resolve this, I believe it will be necessary to customise the compilation pipeline earlier on. This is moderately straightforward, but I'm inclined to leave it until we find it to be a problem in practice, given that there are other more pressing things to deal with. |
Just out of curiosity, would |
Almost certainly -- I've not looked in to exactly what happens yet, but I suspect our best bet will be to provide some kind of informative error if someone attempts to AD through |
Didn't mean to close this. |
invoke
is an interesting built-in function. I came across a use of it when debugging a PR linked to #197 .invoke
recapRecall that invoke behaves as follows:
invoke
lets us call whichever method of a function applies to the types provided in the second argument.There is, in principle, no particular performance penalty associated to this, it just changes which
Method
offoo
is specialised toFloat64
. In this case, aMethodInstance
is produced for theMethod
returned bywhich is specialised for
Float64
argument types.The IR generated for a call to invoke varies depending on a few different factors. I believe that all possible cases are considered below:
1. Statically-Resolvable Types + Inlinable
If an
invoke
call appears inside another function the compiler is at liberty to entirely inline it away. For example, the optimised IR associated tobar
is2. Statically-Resolvable Types + Not Inlinable
In instances where the compiler is able to resolve the
MethodInstance
statically, but not inline the call away, it will produce an:invoke
Expr
(not to be confused with the functioninvoke
). For exampleInterestingly, one cannot tell from looking at the displayed IR that the call to
invoke
was there -- i.e. the print-out of the IR is the same as that which would have been generated if the definition ofbaz
wereThe difference, however, is most certainly there:
By looking at the
def
field of theMethodInstance
associated to the:invoke
Expr
, we see that it has specialised thefoo(x::Any)
method offoo
.3. Dynamically-Resolved Types
If the types are not known to the invoke call statically, then a
:call
toinvoke
(the built-in) appears in the IR. For example:In this case it is plain to see what is going on from the
Main.invoke
:call
expression near the end of the IR.Differentiating
invoke
invoke
complicates the AD story only slightly. We address each of the above cases in turn:1. Statically-Resolvable Types + Inlinable
In this case, we need to avoid inlining if there is a method of
rrule!!
which is applicable to the set of types provided toinvoke
. If this is not the case, then we can safetly inline.2. Statically-Resolvable Types + Not Inlinable
Derive a rule as usual, but the code which we look up must be the code based on the types provided, rather than the values of the arguments. If there's an applicable method of
rrule!!
, use that, otherwise derive the rule.3. Dynamically-Resolved Types
Basically the same as 2.
Implementation Strategy
I think the way to do this is to implement a method of
is_primitive
which callsis_primitive
on the function and the types provided to invoke. Something like(this code won't run as written, but it should illustrate what I mean).
We then need to modify the implementation of
build_rrule
to keep track of both the types which identify the method that we specialise, and the types of the arguments that we pass to the specialised method. At present, they are always the same thing.Summary
Supporting
invoke
is a bit of work, but should ultimately be fairly straightforward if the above is all correct.The text was updated successfully, but these errors were encountered: