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

Add support for 'std::atan2' and 'std::acos' #1097

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions include/clad/Differentiator/BuiltinDerivatives.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,25 @@ CUDA_HOST_DEVICE ValueAndPushforward<T, T> floor_pushforward(T x, T /*d_x*/) {
return {::std::floor(x), (T)0};
}

template <typename T>
CUDA_HOST_DEVICE ValueAndPushforward<T, T> atan2_pushforward(T y, T x, T d_y,
T d_x) {
return {::std::atan2(y, x),
-(y / ((x * x) + (y * y))) * d_x + x / ((x * x) + (y * y)) * d_y};
}

template <typename T, typename U>
CUDA_HOST_DEVICE void atan2_pullback(T y, T x, U d_z, T* d_y, T* d_x) {
*d_y += x / ((x * x) + (y * y)) * d_z;

*d_x += -(y / ((x * x) + (y * y))) * d_z;
}

template <typename T>
CUDA_HOST_DEVICE ValueAndPushforward<T, T> acos_pushforward(T x, T d_x) {
return {::std::acos(x), ((-1) / (::std::sqrt(1 - x * x))) * d_x};
}

template <typename T>
CUDA_HOST_DEVICE ValueAndPushforward<T, T> ceil_pushforward(T x, T /*d_x*/) {
return {::std::ceil(x), (T)0};
Expand Down Expand Up @@ -321,6 +340,9 @@ inline void free_pushforward(void* ptr, void* d_ptr) {
// These are required because C variants of mathematical functions are
// defined in global namespace.
using std::abs_pushforward;
using std::acos_pushforward;
using std::atan2_pullback;
using std::atan2_pushforward;
using std::ceil_pushforward;
using std::cos_pushforward;
using std::exp_pushforward;
Expand Down
52 changes: 52 additions & 0 deletions test/FirstDerivative/BuiltinDerivatives.C
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,44 @@ double f14(double x) {
return __builtin_pow(x, 3);
}

double f15(double y, double x) {
return std::atan2(y, x);
}

//CHECK: {{float|double}} f15_darg0({{float|double}} y, {{float|double}} x) {
//CHECK-NEXT: {{float|double}} _d_y = 1;
//CHECK-NEXT: {{float|double}} _d_x = 0;
//CHECK-NEXT: {{.*}}ValueAndPushforward<{{float|double}}, {{float|double}}> _t0 = {{.*}}atan2_pushforward(y, x, _d_y, _d_x);
//CHECK-NEXT: return _t0.pushforward;
//CHECK-NEXT: }

//CHECK: {{float|double}} f15_darg1({{float|double}} y, {{float|double}} x) {
//CHECK-NEXT: {{float|double}} _d_y = 0;
//CHECK-NEXT: {{float|double}} _d_x = 1;
//CHECK-NEXT: {{.*}}ValueAndPushforward<{{float|double}}, {{float|double}}> _t0 = {{.*}}atan2_pushforward(y, x, _d_y, _d_x);
//CHECK-NEXT: return _t0.pushforward;
//CHECK-NEXT: }

void f15_grad(double y, double x, double *_d_y, double *_d_x);
//CHECK: void f15_grad(double y, double x, double *_d_y, double *_d_x) {
//CHECK: {
//CHECK-NEXT: double _r0 = 0{{.*}};
//CHECK-NEXT: double _r1 = 0{{.*}};
//CHECK-NEXT: {{.*}}atan2_pullback(y, x, 1, &_r0, &_r1);
//CHECK-NEXT: *_d_y += _r0;
//CHECK-NEXT: *_d_x += _r1;
//CHECK-NEXT: }
//CHECK-NEXT: }

float f16(float x) {
return std::acos(x);
}
// CHECK: {{float|double}} f16_darg0({{float|double}} x) {
//CHECK-NEXT: {{float|double}} _d_x = 1;
//CHECK-NEXT: {{.*}}ValueAndPushforward<{{float|double}}, {{float|double}}> _t0 = {{.*}}acos_pushforward(x, _d_x);
//CHECK-NEXT: return _t0.pushforward;
//CHECK-NEXT: }

int main () { //expected-no-diagnostics
float f_result[2];
double d_result[2];
Expand Down Expand Up @@ -326,5 +364,19 @@ int main () { //expected-no-diagnostics
auto f14_ddarg0 = clad::differentiate<2>(f14, 0);
printf("Result is = %f\n", f14_ddarg0.execute(1)); //CHECK-EXEC: Result is = 6.000000

auto f15_darg0 = clad::differentiate(f15, 0);
printf("Result is = %f\n", f15_darg0.execute(4, 3)); //CHECK-EXEC: Result is = 0.120000

auto f15_darg1 = clad::differentiate(f15, 1);
printf("Result is = %f\n", f15_darg1.execute(4, 3)); //CHECK-EXEC: Result is = -0.160000

d_result[0] = d_result[1] = 0;
clad::gradient(f15);
f15_grad(4, 3, &d_result[0], &d_result[1]);
printf("Result is = {%f, %f}\n", d_result[0], d_result[1]); //CHECK-EXEC: Result is = {0.120000, -0.160000}

auto f16_darg0 = clad::differentiate(f16, 0);
printf("Result is = %f\n", f16_darg0.execute(0.9)); //CHECK-EXEC: Result is = -2.294157

return 0;
}
Loading