Skip to content
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

What is the purpose of @preprocess_tester #39

Closed
certik opened this issue Mar 27, 2020 · 2 comments
Closed

What is the purpose of @preprocess_tester #39

certik opened this issue Mar 27, 2020 · 2 comments

Comments

@certik
Copy link
Collaborator

certik commented Mar 27, 2020

I tried this simple input sin2.ll:

; ModuleID = '<stdin>'
source_filename = "<stdin>"

; Function Attrs: norecurse nounwind readnone
define double @tester(double %x) #0 {
entry:
  %0 = fmul double %x, %x
  ret double %0
}

define double @test_derivative(double %x) local_unnamed_addr {
entry:
  %0 = tail call double (double (double)*, ...) @__enzyme_autodiff(double (double)* nonnull @tester, double %x)
  ret double %0
}

declare double @__enzyme_autodiff(double (double)*, ...) local_unnamed_addr

attributes #0 = { norecurse nounwind readnone }

and run it through like this:

opt-6.0 < sin2.ll -load ../../build/Enzyme/LLVMEnzyme-6.so  -enzyme -enzyme_preopt=false -O3 -S

with the result:

; ModuleID = '<stdin>'
source_filename = "<stdin>"

; Function Attrs: norecurse nounwind readnone
define double @tester(double %x) local_unnamed_addr #0 {
entry:
  %0 = fmul double %x, %x
  ret double %0
}

; Function Attrs: norecurse nounwind readnone
define double @test_derivative(double %x) local_unnamed_addr #0 {
entry:
  %factor.i = fmul fast double %x, 2.000000e+00
  ret double %factor.i
}

; Function Attrs: norecurse nounwind readnone
define double @preprocess_tester(double %x) local_unnamed_addr #0 {
entry:
  %0 = fmul double %x, %x
  ret double %0
}

attributes #0 = { norecurse nounwind readnone }

I can see that it left @tester intact that returns x^2. Then it optimized out the @__enzyme_autodiff to just return 2*x.

But why did it create the @preprocess_tester function?

@wsmoses
Copy link
Member

wsmoses commented Mar 27, 2020

For all functions Enzyme analyzes, it creates a copy called preprocess_ where it can do some preprocessing optimizations (useful if you have Enzyme take a derivative of its own output). In this case it didn't do anything (especially since the enzyme_preopt=false flag says only do the bare minimum preprocessing necessary).

All preprocessing functions can be ignored/deleted (they've only been left around so far for debugging purposes).

It's particularly useful to view the preprocessed function if you supply the optional flag enzyme_inline=1 where it tries to inline all functions when doing AD if possible (often positive for performance, and a good comparison to make).

@wsmoses wsmoses closed this as completed Mar 27, 2020
@certik
Copy link
Collaborator Author

certik commented Mar 27, 2020

Cool, thanks for the info.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants