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

Correctly generate pullbacks with object return types in the reverse mode #1216

Open
PetroZarytskyi opened this issue Jan 15, 2025 · 0 comments

Comments

@PetroZarytskyi
Copy link
Collaborator

PetroZarytskyi commented Jan 15, 2025

struct A {
  double x;
  A() = default;
  A(double px) : x(px) {}
  A(const A& b) : x(b.x) {}
};

namespace clad {
namespace custom_derivatives {
namespace class_functions {
  void constructor_pullback(A* a, double x, A* d_a, double* d_x) {
      *d_x += d_a->x;
  }
  void constructor_pullback(A* a, const A& b, A* d_a, A* d_b) {
      d_b->x += d_a->x;
  }
}}}

A operator+(const A& a, const A& b) {
  A res;
  res.x = a.x + b.x;
  return res;
}

double f(double x, double y) {
  A t1{1};
  A t2{x};
  A sum = t1 + t2;
  return sum.x;
}


int main(int argc, char* argv[]) {
    auto df = clad::gradient(f);
    double dx, dy;
    dx = 0; dy = 0;
    df.execute(3, 4, &dx, &dy);
    std::cout << dx << ' ' << dy << '\n';
}

Expected output:
1 0
Output:
segmentation fault

Note that the bug happens because of the way operator+ is differentiated:

void operator_plus_pullback(const A &a, const A &b, A _d_y, A *_d_a, A *_d_b) {
    A res;
    A _d_res({});
    clad::zero_init(_d_res);
    double _t0 = res.x;
    res.x = a.x + b.x;
    ...::constructor_pullback(nullptr, res, nullptr, &_d_res); // <--- This line corresponds to the return-stmt
    {                            // Instead of the last nullptr we are supposed to have _d_y
        res.x = _t0;
        double _r_d0 = _d_res.x;
        _d_res.x = 0.;
        (*_d_a).x += _r_d0;
        (*_d_b).x += _r_d0;
    }
}
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

1 participant