| // RUN: %clang++ -ffast-math -O0 %s -S -emit-llvm -o - | %opt - %OPloadEnzyme %enzyme -S | %lli - |
| // RUN: %clang++ -ffast-math -O1 %s -S -emit-llvm -o - | %opt - %OPloadEnzyme %enzyme -S | %lli - |
| // RUN: %clang++ -ffast-math -O2 %s -S -emit-llvm -o - | %opt - %OPloadEnzyme %enzyme -S | %lli - |
| // RUN: %clang++ -ffast-math -O3 %s -S -emit-llvm -o - | %opt - %OPloadEnzyme %enzyme -S | %lli - |
| // RUN: %clang++ -ffast-math -O0 %s -S -emit-llvm -o - | %opt - %OPloadEnzyme %enzyme -enzyme-inline=1 -S | %lli - |
| // RUN: %clang++ -ffast-math -O1 %s -S -emit-llvm -o - | %opt - %OPloadEnzyme %enzyme -enzyme-inline=1 -S | %lli - |
| // RUN: %clang++ -ffast-math -O2 %s -S -emit-llvm -o - | %opt - %OPloadEnzyme %enzyme -enzyme-inline=1 -S | %lli - |
| // RUN: %clang++ -ffast-math -O3 %s -S -emit-llvm -o - | %opt - %OPloadEnzyme %enzyme -enzyme-inline=1 -S | %lli - |
| |
| //#include <math.h> |
| |
| #include "../test_utils.h" |
| |
| #include <complex> // std::complex, std::abs, std::arg |
| |
| void __enzyme_autodiff(...); |
| |
| using namespace std; |
| |
| double h( const complex<double>& c ) |
| { |
| //double theta = c.real()+3*c.imag(); |
| double theta = std::abs(c); |
| //double theta = arg(c); |
| return theta * theta; |
| } |
| |
| double h2( const double& c ) |
| { |
| double theta = std::abs(c); |
| return theta * theta; |
| } |
| |
| int main () |
| { |
| std::complex<double> mycomplex (3.0,4.0); |
| |
| std::complex<double> dc(0.0,0.0); |
| |
| double x = -3.0; |
| double dx = 0.0; |
| //Works with real number |
| __enzyme_autodiff(&h2, enzyme_dup, &x,&dx); |
| |
| APPROX_EQ(dx, -6.0, 1e-7); |
| |
| //Compilation fails for complex number |
| //"attempting to differentiate function without definition"' failed. |
| __enzyme_autodiff(&h, enzyme_dup, &mycomplex,&dc); |
| |
| printf("grad energy of particle is %f, %f\n", real(dc), imag(dc)); |
| |
| APPROX_EQ(real(dc), 6.0, 1e-7); |
| APPROX_EQ(imag(dc), 8.0, 1e-7); |
| |
| return 0; |
| } |