Custom `sinc` path not working
Hi @wsmoses,
Thank you for the guidance today!
Pre-Defined sinc paths
I was trying if a self-defined function called sinc is picked up and replaced with the pre-defined custom paths, and it does not seem to work as expected:
https://fwd.gymni.ch/DdjNuM
#include <cmath>
#include <stdio.h>
double sinc (double x) {
return std::sin(x) / x;
}
double __enzyme_autodiff(void*, double);
int main() {
double x = 3.14;
double grad_x = __enzyme_autodiff((void*)sinc, x);
printf("sinc'(%f) = %f\n", x, grad_x); // -0.318632
x = 0;
double grad_x00 = __enzyme_autodiff((void*)sinc, x);
printf("sinc'(%f) = %f\n", x, grad_x00); // 0.0
return 0;
}
sinc'(3.140000) = -0.318632
sinc'(0.000000) = -5486124068873210445588960243682892870359454172549082081269977249875439498450530608481829736532482212550881929053150599861406478595121674729324160965665746675952409952613381490567235017715679668230311379032918639874384375900517443469363980679948746539362679355976183938475470978590331407354983321197084672.000000
Enzyme Function-Like "sinc"
I then tried enzyme_function_like but that does not do the trick either:
https://fwd.gymni.ch/DHb8VC
#include <cmath>
#include <stdio.h>
__attribute__((enzyme_function_like("sinc")))
double my_sinc (double x) {
return std::sin(x) / x;
}
double __enzyme_autodiff(void*, double);
int main() {
double x = 3.14;
double grad_x = __enzyme_autodiff((void*)my_sinc, x);
printf("sinc'(%f) = %f\n", x, grad_x); // -0.318632
x = 0;
double grad_x0 = __enzyme_autodiff((void*)my_sinc, x);
printf("my_sinc'(%f) = %f\n", x, grad_x0); // 0.0
return 0;
}
sinc'(3.140000) = -0.318632
my_sinc'(0.000000) = -nan
What am I missing? :)
1st example
The 1st example also does not work if declared extern "C": https://fwd.gymni.ch/whurNe No work-around
Explored today: 2nd example posted above
This is a bug that is already fixed in the Julia version but not yet in the C++ version (@wsmoses knows what the fix).
Work-around: The issue only appears if the attributed function is directly called from enzyme autodiff. Using it in a lower layer of the call stack, or wrapping it in an extra function, works: https://fwd.gymni.ch/8PBXdM