Skip to content

Commit 93b8aa7

Browse files
PetroZarytskyivgvassilev
authored andcommitted
Add custom derivatives for std::forward.
Fixes #1274.
1 parent 91aed31 commit 93b8aa7

2 files changed

Lines changed: 47 additions & 0 deletions

File tree

include/clad/Differentiator/STLBuiltins.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -887,6 +887,15 @@ template <typename... Args> auto make_tuple_pushforward(Args... args) noexcept {
887887
second_half_tuple(t));
888888
}
889889

890+
template <class T> constexpr void forward_pullback(T& t, T dy, T* dt) noexcept {
891+
*dt += dy;
892+
}
893+
894+
template <class T>
895+
constexpr void forward_pullback(T&& t, T dy, T* dt) noexcept {
896+
*dt += dy;
897+
}
898+
890899
// std::make_shared<T> custom derivatives...
891900
template <typename T>
892901
clad::ValueAndAdjoint<::std::shared_ptr<T>, ::std::shared_ptr<T>>

test/Gradient/Constructors.C

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,41 @@ double fn7(double x, double y) {
410410
// CHECK-NEXT: }
411411
// CHECK-NEXT: }
412412

413+
double fn8(double u, double v) {
414+
std::pair<double, double> p(u,v);
415+
return p.first + p.second;
416+
}
417+
418+
// CHECK: static constexpr void constructor_pullback(double &__{{u1|x}}, double &__{{u2|y}}, std::pair<double, double> *_d_this, double *_d___{{u1|x}}, double *_d___{{u2|y}}) {{.*}}{
419+
// CHECK-NEXT: std::pair<double, double> *_this = (std::pair<double, double> *)malloc(sizeof(std::pair<double, double>));
420+
// CHECK: double _t0 = __{{u1|x}};
421+
// CHECK-NEXT: _this->first = std::forward<double &>(__{{u1|x}});
422+
// CHECK-NEXT: double _t1 = __{{u2|y}};
423+
// CHECK-NEXT: _this->second = std::forward<double &>(__{{u2|y}});
424+
// CHECK-NEXT: {
425+
// CHECK-NEXT: clad::custom_derivatives::std::forward_pullback(__{{u2|y}}, _d_this->second, &*_d___{{u2|y}});
426+
// CHECK-NEXT: __{{u2|y}} = _t1;
427+
// CHECK-NEXT: _d_this->second = 0.;
428+
// CHECK-NEXT: }
429+
// CHECK-NEXT: {
430+
// CHECK-NEXT: clad::custom_derivatives::std::forward_pullback(__{{u1|x}}, _d_this->first, &*_d___{{u1|x}});
431+
// CHECK-NEXT: __{{u1|x}} = _t0;
432+
// CHECK-NEXT: _d_this->first = 0.;
433+
// CHECK-NEXT: }
434+
// CHECK-NEXT: free(_this);
435+
// CHECK-NEXT: }
436+
437+
// CHECK: void fn8_grad(double u, double v, double *_d_u, double *_d_v) {
438+
// CHECK-NEXT: std::pair<double, double> p(u, v);
439+
// CHECK-NEXT: std::pair<double, double> _d_p(p);
440+
// CHECK-NEXT: clad::zero_init(_d_p);
441+
// CHECK-NEXT: {
442+
// CHECK-NEXT: _d_p.first += 1;
443+
// CHECK-NEXT: _d_p.second += 1;
444+
// CHECK-NEXT: }
445+
// CHECK-NEXT: pair::constructor_pullback(u, v, &_d_p, &*_d_u, &*_d_v);
446+
// CHECK-NEXT: }
447+
413448
int main() {
414449
double d_i, d_j;
415450

@@ -432,4 +467,7 @@ int main() {
432467

433468
INIT_GRADIENT(fn7);
434469
TEST_GRADIENT(fn7, /*numOfDerivativeArgs=*/2, 2, 9, &d_i, &d_j); // CHECK-EXEC: {12.00, 0.00}
470+
471+
INIT_GRADIENT(fn8);
472+
TEST_GRADIENT(fn8, /*numOfDerivativeArgs=*/2, 7, 2, &d_i, &d_j); // CHECK-EXEC: {1.00, 1.00}
435473
}

0 commit comments

Comments
 (0)