blob: 53972e1851e0028ca5fd9350d62ebdd4da2a81cc [file] [log] [blame] [edit]
// RUN: %clang++ -std=c++11 -fno-exceptions -ffast-math -O2 %s -S -emit-llvm -o - | %opt - %OPloadEnzyme %enzyme -S | %lli -
// RUN: %clang++ -std=c++11 -fno-exceptions -ffast-math -O3 %s -S -emit-llvm -o - | %opt - %OPloadEnzyme %enzyme -S | %lli -
// RUN: %clang++ -std=c++11 -fno-exceptions -ffast-math -O2 %s -S -emit-llvm -o - | %opt - %OPloadEnzyme %enzyme -enzyme-inline=1 -S | %lli -
// RUN: %clang++ -std=c++11 -fno-exceptions -ffast-math -O3 %s -S -emit-llvm -o - | %opt - %OPloadEnzyme %enzyme -enzyme-inline=1 -S | %lli -
#include <stdio.h>
#include "../test_utils.h"
void __enzyme_autodiff(...);
template <typename... Args>
double __enzyme_autodiff(void *, Args...);
struct Object
{
virtual double eval(double v) = 0;
double val;
};
struct Object1 : Object
{
double eval(double v)
{
return val * v;
}
};
struct Object2 : Object
{
double eval(double v)
{
return val + v;
}
};
double eval(Object &o, double v)
{
return o.eval(v);
}
double deval(Object &o, Object &d_o, double v)
{
return __enzyme_autodiff((void *)(eval),
enzyme_dup, &o, &d_o,
v);
}
template<typename T>
T __enzyme_virtualreverse(T);
int main()
{
double v = 10;
Object *o = new Object1();
o->val = 2;
Object *d_o = new Object1();
*((void**)d_o) = __enzyme_virtualreverse(*(void**)d_o);
d_o->val = 0;
double res;
res = deval(*o, *d_o, v);
printf("res=%f\n", res);
APPROX_EQ(res, 2.0, 1e-7);
o = new Object2();
o->val = 2;
d_o = new Object2();
*((void**)d_o) = __enzyme_virtualreverse(*(void**)d_o);
d_o->val = 0;
res = deval(*o, *d_o, v);
printf("res=%f\n", res);
APPROX_EQ(res, 1.0, 1e-7);
}