@@ -445,6 +445,123 @@ double fn9(S& s) {
445445// CHECK-NEXT: }
446446// CHECK-NEXT: }
447447
448+ struct arrWrapper {
449+ double arr [2 ];
450+ };
451+
452+ // CHECK: static inline constexpr void constructor_pullback(const arrWrapper &arg, arrWrapper *_d_this, arrWrapper *_d_arg) noexcept {
453+ // CHECK-NEXT: for (unsigned {{int|long}} i = 0; i < 2; ++i)
454+ // CHECK-NEXT: (*_d_arg).arr[i] += _d_this->arr[i];
455+ // CHECK-NEXT: }
456+
457+ double fn10 (double x , double y ) {
458+ arrWrapper a = {x , y };
459+ arrWrapper b = a ;
460+ return b .arr [0 ] + b .arr [1 ];
461+ }
462+
463+ // CHECK: void fn10_grad(double x, double y, double *_d_x, double *_d_y) {
464+ // CHECK-NEXT: arrWrapper _d_a = {{.*0.*}};
465+ // CHECK-NEXT: arrWrapper a = {{.*x, y.*}};
466+ // CHECK-NEXT: arrWrapper _d_b = _d_a;
467+ // CHECK-NEXT: arrWrapper b = a;
468+ // CHECK-NEXT: {
469+ // CHECK-NEXT: _d_b.arr[0] += 1;
470+ // CHECK-NEXT: _d_b.arr[1] += 1;
471+ // CHECK-NEXT: }
472+ // CHECK-NEXT: arrWrapper::constructor_pullback(a, &_d_b, &_d_a);
473+ // CHECK-NEXT: {
474+ // CHECK-NEXT: *_d_x += _d_a.arr[0];
475+ // CHECK-NEXT: *_d_y += _d_a.arr[1];
476+ // CHECK-NEXT: }
477+ // CHECK-NEXT: }
478+
479+ struct arr2DWrapper {
480+ double arr [1 ][2 ];
481+ };
482+
483+ // CHECK: static inline constexpr void constructor_pullback(const arr2DWrapper &arg, arr2DWrapper *_d_this, arr2DWrapper *_d_arg) noexcept {
484+ // CHECK-NEXT: for (unsigned {{int|long}} i = 0; i < 1; ++i)
485+ // CHECK-NEXT: for (unsigned {{int|long}} i0 = 0; i0 < 2; ++i0)
486+ // CHECK-NEXT: (*_d_arg).arr[i][i0] += _d_this->arr[i][i0];
487+ // CHECK-NEXT: }
488+
489+ double fn11 (double x , double y ) {
490+ arr2DWrapper a = {x , y };
491+ arr2DWrapper b = a ;
492+ return b .arr [0 ][0 ] + b .arr [0 ][1 ];
493+ }
494+
495+ // CHECK: void fn11_grad(double x, double y, double *_d_x, double *_d_y) {
496+ // CHECK-NEXT: arr2DWrapper _d_a = {{.*0.*}};
497+ // CHECK-NEXT: arr2DWrapper a = {{.*x, y.*}};
498+ // CHECK-NEXT: arr2DWrapper _d_b = _d_a;
499+ // CHECK-NEXT: arr2DWrapper b = a;
500+ // CHECK-NEXT: {
501+ // CHECK-NEXT: _d_b.arr[0][0] += 1;
502+ // CHECK-NEXT: _d_b.arr[0][1] += 1;
503+ // CHECK-NEXT: }
504+ // CHECK-NEXT: arr2DWrapper::constructor_pullback(a, &_d_b, &_d_a);
505+ // CHECK-NEXT: {
506+ // CHECK-NEXT: *_d_x += _d_a.arr[0][0];
507+ // CHECK-NEXT: *_d_y += _d_a.arr[0][1];
508+ // CHECK-NEXT: }
509+ // CHECK-NEXT: }
510+
511+ struct cust_double {
512+ cust_double (double x = 0 ): val (x ) {}
513+ double val ;
514+ };
515+
516+ // CHECK: static void constructor_pullback(double x, cust_double *_d_this, double *_d_x) {
517+ // CHECK-NEXT: {
518+ // CHECK-NEXT: *_d_x += _d_this->val;
519+ // CHECK-NEXT: _d_this->val = 0.;
520+ // CHECK-NEXT: }
521+ // CHECK-NEXT: }
522+
523+ // CHECK: static inline constexpr void constructor_pullback(const cust_double &arg, cust_double *_d_this, cust_double *_d_arg) noexcept {
524+ // CHECK-NEXT: {
525+ // CHECK-NEXT: (*_d_arg).val += _d_this->val;
526+ // CHECK-NEXT: _d_this->val = 0.;
527+ // CHECK-NEXT: }
528+ // CHECK-NEXT: }
529+
530+ struct arrStructWrapper {
531+ cust_double arr [2 ];
532+ };
533+
534+ // CHECK: static inline constexpr void constructor_pullback(const arrStructWrapper &arg, arrStructWrapper *_d_this, arrStructWrapper *_d_arg) noexcept {
535+ // CHECK-NEXT: for (unsigned {{int|long}} i = 0; i < 2; ++i)
536+ // CHECK-NEXT: cust_double::constructor_pullback(arg.arr[i], &_d_this->arr[i], &(*_d_arg).arr[i]);
537+ // CHECK-NEXT: }
538+
539+ double fn12 (double x , double y ) {
540+ arrStructWrapper a = {x , y };
541+ arrStructWrapper b = a ;
542+ return b .arr [0 ].val + b .arr [1 ].val ;
543+ }
544+
545+ // CHECK: void fn12_grad(double x, double y, double *_d_x, double *_d_y) {
546+ // CHECK-NEXT: arrStructWrapper _d_a = {{.*}};
547+ // CHECK-NEXT: arrStructWrapper a = {{.*x, y.*}};
548+ // CHECK-NEXT: arrStructWrapper _d_b = _d_a;
549+ // CHECK-NEXT: arrStructWrapper b = a;
550+ // CHECK-NEXT: {
551+ // CHECK-NEXT: _d_b.arr[0].val += 1;
552+ // CHECK-NEXT: _d_b.arr[1].val += 1;
553+ // CHECK-NEXT: }
554+ // CHECK-NEXT: arrStructWrapper::constructor_pullback(a, &_d_b, &_d_a);
555+ // CHECK-NEXT: {
556+ // CHECK-NEXT: double _r0 = 0.;
557+ // CHECK-NEXT: cust_double::constructor_pullback(x, &_d_a.arr[0], &_r0);
558+ // CHECK-NEXT: *_d_x += _r0;
559+ // CHECK-NEXT: double _r1 = 0.;
560+ // CHECK-NEXT: cust_double::constructor_pullback(y, &_d_a.arr[1], &_r1);
561+ // CHECK-NEXT: *_d_y += _r1;
562+ // CHECK-NEXT: }
563+ // CHECK-NEXT: }
564+
448565int main () {
449566 double d_i , d_j ;
450567
@@ -474,6 +591,14 @@ int main() {
474591 S s {new double [3 ]{5 , 6 , 7 }}, _d_s {new double [3 ]{0 }};
475592 auto dfn9 = clad ::gradient (fn9 );
476593 dfn9 .execute (s , & _d_s );
477- printf ("{%.2f, %.2f, %.2f}\n" , _d_s .a [0 ], _d_s .a [1 ], _d_s .a [2 ]);
478- // TEST_GRADIENT(fn9, /*numOfDerivativeArgs=*/1, s, &d_s); // CHECK-EXEC: {0.00, 0.00, 1.00}
594+ printf ("{%.2f, %.2f, %.2f}\n" , _d_s .a [0 ], _d_s .a [1 ], _d_s .a [2 ]); // CHECK-EXEC: {0.00, 0.00, 1.00}
595+
596+ INIT_GRADIENT (fn10 );
597+ TEST_GRADIENT (fn10 , /*numOfDerivativeArgs=*/ 2 , 7 , 2 , & d_i , & d_j ); // CHECK-EXEC: {1.00, 1.00}
598+
599+ INIT_GRADIENT (fn11 );
600+ TEST_GRADIENT (fn11 , /*numOfDerivativeArgs=*/ 2 , 9 , -1 , & d_i , & d_j ); // CHECK-EXEC: {1.00, 1.00}
601+
602+ INIT_GRADIENT (fn12 );
603+ TEST_GRADIENT (fn12 , /*numOfDerivativeArgs=*/ 2 , 3 , 6 , & d_i , & d_j ); // CHECK-EXEC: {1.00, 1.00}
479604}
0 commit comments