diff --git a/include/clad/Differentiator/STLBuiltins.h b/include/clad/Differentiator/STLBuiltins.h index 40b562dc4..d6b169ec0 100644 --- a/include/clad/Differentiator/STLBuiltins.h +++ b/include/clad/Differentiator/STLBuiltins.h @@ -585,15 +585,6 @@ template void size_pullback(::std::array* /*a*/, U /*d_y*/, ::std::array* /*d_a*/) noexcept {} template -::clad::ValueAndAdjoint<::std::array, ::std::array> -constructor_reverse_forw(::clad::ConstructorReverseForwTag<::std::array>, - const ::std::array& arr, - const ::std::array& d_arr) { - ::std::array a = arr; - ::std::array d_a = d_arr; - return {a, d_a}; -} -template void constructor_pullback(::std::array* a, const ::std::array& arr, ::std::array* d_a, ::std::array* d_arr) { for (size_t i = 0; i < N; ++i) diff --git a/lib/Differentiator/ReverseModeVisitor.cpp b/lib/Differentiator/ReverseModeVisitor.cpp index 9d280197b..a7d4dc6cb 100644 --- a/lib/Differentiator/ReverseModeVisitor.cpp +++ b/lib/Differentiator/ReverseModeVisitor.cpp @@ -34,7 +34,9 @@ #include #include +#include "llvm/ADT/SmallString.h" #include "llvm/Support/SaveAndRestore.h" +#include #include #include @@ -1309,7 +1311,16 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, clonedExprs[i] = Visit(ILE->getInit(i), member_acess).getExpr(); } Expr* clonedILE = m_Sema.ActOnInitList(noLoc, clonedExprs, noLoc).get(); - return StmtDiff(clonedILE); + + const CXXRecordDecl* RD = ILEType->getAsCXXRecordDecl(); + Expr* adjointInit = nullptr; + if (RD && RD->isAggregate()) { + llvm::SmallVector adjParams; + for (const FieldDecl* FD : RD->fields()) + adjParams.push_back(getZeroInit(FD->getType())); + adjointInit = m_Sema.ActOnInitList(noLoc, adjParams, noLoc).get(); + } + return StmtDiff(clonedILE, nullptr, adjointInit); } // FIXME: This is a makeshift arrangement to differentiate an InitListExpr @@ -2753,6 +2764,9 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, ConstructorPullbackCallInfo constructorPullbackInfo; + bool isConstructInit = + VD->getInit() && isa(VD->getInit()->IgnoreImplicit()); + // VDDerivedInit now serves two purposes -- as the initial derivative value // or the size of the derivative array -- depending on the primal type. if (promoteToFnScope) @@ -2798,7 +2812,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, VDDerivedInit = initDiff.getForwSweepExpr_dx(); } - if (VDType->isStructureOrClassType()) { + if (isConstructInit) { m_TrackConstructorPullbackInfo = true; initDiff = Visit(VD->getInit()); m_TrackConstructorPullbackInfo = false; @@ -2870,13 +2884,8 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, derivedE = BuildOp(UnaryOperatorKind::UO_Deref, derivedE); } - if (VD->getInit()) { - if (VDType->isStructureOrClassType()) { - if (!initDiff.getExpr()) - initDiff = Visit(VD->getInit()); - } else - initDiff = Visit(VD->getInit(), derivedE); - } + if (VD->getInit() && !isConstructInit) + initDiff = Visit(VD->getInit(), derivedE); // If we are differentiating `VarDecl` corresponding to a local variable // inside a loop, then we need to reset it to 0 at each iteration. @@ -4155,7 +4164,6 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, StmtDiff ReverseModeVisitor::VisitCXXConstructExpr(const CXXConstructExpr* CE) { - llvm::SmallVector primalArgs; llvm::SmallVector adjointArgs; llvm::SmallVector reverseForwAdjointArgs; @@ -4214,8 +4222,8 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, // Try to create a pullback constructor call llvm::SmallVector pullbackArgs; - QualType recordType = - m_Context.getRecordType(CE->getConstructor()->getParent()); + const CXXRecordDecl* RD = CE->getConstructor()->getParent(); + QualType recordType = m_Context.getRecordType(RD); QualType recordPointerType = m_Context.getPointerType(recordType); // thisE = object being created by this constructor call. // dThisE = adjoint of the object being created by this constructor call. @@ -4274,6 +4282,24 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, if (Expr* customReverseForwFnCall = BuildCallToCustomForwPassFn( CE->getConstructor(), primalArgs, reverseForwAdjointArgs, /*baseExpr=*/nullptr)) { + if (RD->isAggregate()) { + SmallString<128> Name_class; + llvm::raw_svector_ostream OS_class(Name_class); + RD->getNameForDiagnostic(OS_class, m_Context.getPrintingPolicy(), + /*qualified=*/true); + diag(DiagnosticsEngine::Warning, CE->getBeginLoc(), + "'%0' is an aggregate type and its constructor does not require a " + "user-defined forward sweep function", + {OS_class.str()}); + const FunctionDecl* constr_forw = + cast(customReverseForwFnCall)->getDirectCallee(); + SmallString<128> Name_forw; + llvm::raw_svector_ostream OS_forw(Name_forw); + constr_forw->getNameForDiagnostic( + OS_forw, m_Context.getPrintingPolicy(), /*qualified=*/true); + diag(DiagnosticsEngine::Note, constr_forw->getBeginLoc(), + "'%0' is defined here", {OS_forw.str()}); + } Expr* callRes = StoreAndRef(customReverseForwFnCall); Expr* val = utils::BuildMemberExpr(m_Sema, getCurrentScope(), callRes, "value"); diff --git a/lib/Differentiator/VisitorBase.cpp b/lib/Differentiator/VisitorBase.cpp index 7884ca934..478673ffb 100644 --- a/lib/Differentiator/VisitorBase.cpp +++ b/lib/Differentiator/VisitorBase.cpp @@ -13,8 +13,8 @@ #include "clad/Differentiator/ErrorEstimator.h" #include "clad/Differentiator/Sins.h" #include "clad/Differentiator/StmtClone.h" - #include "clang/AST/ASTContext.h" +#include "clang/AST/Decl.h" #include "clang/AST/Expr.h" #include "clang/AST/TemplateBase.h" #include "clang/Lex/Preprocessor.h" @@ -26,6 +26,7 @@ #include "clang/Sema/Template.h" #include +#include #include #include "clad/Differentiator/Compatibility.h" @@ -418,6 +419,13 @@ namespace clad { Expr* zero = ConstantFolder::synthesizeLiteral(T, m_Context, /*val=*/0); return m_Sema.ActOnInitList(noLoc, {zero}, noLoc).get(); } + if (const auto* RD = T->getAsCXXRecordDecl()) + if (RD->hasDefinition() && !RD->isUnion() && RD->isAggregate()) { + llvm::SmallVector adjParams; + for (const FieldDecl* FD : RD->fields()) + adjParams.push_back(getZeroInit(FD->getType())); + return m_Sema.ActOnInitList(noLoc, adjParams, noLoc).get(); + } return m_Sema.ActOnInitList(noLoc, {}, noLoc).get(); } diff --git a/test/Gradient/STLCustomDerivatives.C b/test/Gradient/STLCustomDerivatives.C index 488e9c619..f480bcce6 100644 --- a/test/Gradient/STLCustomDerivatives.C +++ b/test/Gradient/STLCustomDerivatives.C @@ -499,7 +499,7 @@ int main() { // CHECK-NEXT: clad::tape > _t2 = {}; // CHECK-NEXT: clad::tape _t3 = {}; // CHECK-NEXT: clad::tape > _t4 = {}; -// CHECK-NEXT: std::array _d_a({}); +// CHECK-NEXT: std::array _d_a({{.*}}); // CHECK-NEXT: std::array a; // CHECK-NEXT: std::array _t0 = a; // CHECK-NEXT: {{.*}}fill_reverse_forw(&a, x, &_d_a, *_d_x); @@ -544,7 +544,7 @@ int main() { // CHECK-NEXT: } // CHECK: void fn16_grad(double x, double y, double *_d_x, double *_d_y) { -// CHECK-NEXT: std::array _d_a({}); +// CHECK-NEXT: std::array _d_a({{.*}}); // CHECK-NEXT: std::array a; // CHECK-NEXT: std::array _t0 = a; // CHECK-NEXT: clad::ValueAndAdjoint _t1 = {{.*}}operator_subscript_reverse_forw(&a, 0, &_d_a, _r0); @@ -554,7 +554,7 @@ int main() { // CHECK-NEXT: clad::ValueAndAdjoint _t4 = {{.*}}operator_subscript_reverse_forw(&a, 1, &_d_a, _r1); // CHECK-NEXT: double _t5 = _t4.value; // CHECK-NEXT: _t4.value = y; -// CHECK-NEXT: std::array _d__b({}); +// CHECK-NEXT: std::array _d__b({{.*}}); // CHECK-NEXT: std::array _b0; // CHECK-NEXT: std::array _t6 = _b0; // CHECK-NEXT: clad::ValueAndAdjoint _t7 = {{.*}}operator_subscript_reverse_forw(&_b0, 0, &_d__b, _r2); @@ -568,23 +568,22 @@ int main() { // CHECK-NEXT: clad::ValueAndAdjoint _t13 = {{.*}}operator_subscript_reverse_forw(&_b0, 2, &_d__b, _r4); // CHECK-NEXT: double _t14 = _t13.value; // CHECK-NEXT: _t13.value = x * x; -// CHECK-NEXT: ::clad::ValueAndAdjoint< ::std::array, ::std::array > _t15 = {{.*}}constructor_reverse_forw(clad::ConstructorReverseForwTag >(), _b0, _d__b); -// CHECK-NEXT: std::array _d_b = _t15.adjoint; -// CHECK-NEXT: const std::array b = _t15.value; -// CHECK-NEXT: std::array _t18 = a; -// CHECK-NEXT: clad::ValueAndAdjoint _t19 = {{.*}}back_reverse_forw(&a, &_d_a); +// CHECK-NEXT: std::array _d_b = {{.*}}; +// CHECK-NEXT: const std::array b = _b0; +// CHECK-NEXT: std::array _t17 = a; +// CHECK-NEXT: clad::ValueAndAdjoint _t18 = {{.*}}back_reverse_forw(&a, &_d_a); +// CHECK-NEXT: std::array _t19 = b; +// CHECK-NEXT: {{.*}}value_type _t16 = b.front(); // CHECK-NEXT: std::array _t20 = b; -// CHECK-NEXT: {{.*}}value_type _t17 = b.front(); +// CHECK-NEXT: {{.*}}value_type _t15 = b.at(2); // CHECK-NEXT: std::array _t21 = b; -// CHECK-NEXT: {{.*}}value_type _t16 = b.at(2); -// CHECK-NEXT: std::array _t22 = b; // CHECK-NEXT: { -// CHECK-NEXT: {{.*}}back_pullback(&_t18, 1 * _t16 * _t17, &_d_a); -// CHECK-NEXT: {{.*}}front_pullback(&_t20, _t19.value * 1 * _t16, &_d_b); +// CHECK-NEXT: {{.*}}back_pullback(&_t17, 1 * _t15 * _t16, &_d_a); +// CHECK-NEXT: {{.*}}front_pullback(&_t19, _t18.value * 1 * _t15, &_d_b); // CHECK-NEXT: {{.*}}size_type _r5 = {{0U|0UL}}; -// CHECK-NEXT: {{.*}}at_pullback(&_t21, 2, _t19.value * _t17 * 1, &_d_b, &_r5); +// CHECK-NEXT: {{.*}}at_pullback(&_t20, 2, _t18.value * _t16 * 1, &_d_b, &_r5); // CHECK-NEXT: {{.*}}size_type _r6 = {{0U|0UL}}; -// CHECK-NEXT: {{.*}}operator_subscript_pullback(&_t22, 1, 1, &_d_b, &_r6); +// CHECK-NEXT: {{.*}}operator_subscript_pullback(&_t21, 1, 1, &_d_b, &_r6); // CHECK-NEXT: } // CHECK-NEXT: {{.*}}constructor_pullback(&b, _b0, &_d_b, &_d__b); // CHECK-NEXT: { @@ -629,7 +628,7 @@ int main() { // CHECK-NEXT: } // CHECK: void fn17_grad(double x, double y, double *_d_x, double *_d_y) { -// CHECK-NEXT: std::array _d_a({}); +// CHECK-NEXT: std::array _d_a({{.*}}); // CHECK-NEXT: std::array a; // CHECK-NEXT: std::array _t0 = a; // CHECK-NEXT: {{.*}}fill_reverse_forw(&a, y + x + x, &_d_a, _r0); @@ -653,7 +652,7 @@ int main() { // CHECK-NEXT: } // CHECK: void fn18_grad(double x, double y, double *_d_x, double *_d_y) { -// CHECK-NEXT: std::array _d_a({}); +// CHECK-NEXT: std::array _d_a({{.*}}); // CHECK-NEXT: std::array a; // CHECK-NEXT: std::array _t0 = a; // CHECK-NEXT: clad::ValueAndAdjoint _t1 = {{.*}}operator_subscript_reverse_forw(&a, 1, &_d_a, _r0); diff --git a/test/Gradient/UserDefinedTypes.C b/test/Gradient/UserDefinedTypes.C index 344f185cb..9fb5b14a2 100644 --- a/test/Gradient/UserDefinedTypes.C +++ b/test/Gradient/UserDefinedTypes.C @@ -1,4 +1,4 @@ -// RUN: %cladclang %s -I%S/../../include -oUserDefinedTypes.out 2>&1 | %filecheck %s +// RUN: %cladclang %s -I%S/../../include -oUserDefinedTypes.out -Xclang -verify 2>&1 | %filecheck %s // RUN: ./UserDefinedTypes.out | %filecheck_exec %s // RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -oUserDefinedTypes.out // RUN: ./UserDefinedTypes.out | %filecheck_exec %s @@ -395,10 +395,10 @@ MyStruct fn12(MyStruct s) { // CHECK: void fn12_grad(MyStruct s, MyStruct *_d_s) { // CHECK-NEXT: MyStruct _t0 = s; -// CHECK-NEXT: clad::ValueAndAdjoint _t1 = _t0.operator_equal_forw({2 * s.a, 2 * s.b + 2}, &(*_d_s), {}); +// CHECK-NEXT: clad::ValueAndAdjoint _t1 = _t0.operator_equal_forw({2 * s.a, 2 * s.b + 2}, &(*_d_s), {0., 0.}); // CHECK-NEXT: { -// CHECK-NEXT: MyStruct _r0 = {}; -// CHECK-NEXT: _t0.operator_equal_pullback({2 * s.a, 2 * s.b + 2}, {}, &(*_d_s), &_r0); +// CHECK-NEXT: MyStruct _r0 = {0., 0.}; +// CHECK-NEXT: _t0.operator_equal_pullback({2 * s.a, 2 * s.b + 2}, {0., 0.}, &(*_d_s), &_r0); // CHECK-NEXT: (*_d_s).a += 2 * _r0.a; // CHECK-NEXT: (*_d_s).b += 2 * _r0.b; // CHECK-NEXT: } @@ -467,6 +467,53 @@ void fn13(double *x, double *y, int size) // CHECK-NEXT: } // CHECK-NEXT:} +double fn14(double x, double y) { + MyStruct s = {2 * y, 3 * x + 2}; + return s.a * s.b; +} + +// CHECK: void fn14_grad(double x, double y, double *_d_x, double *_d_y) { +// CHECK-NEXT: MyStruct _d_s = {0., 0.}; +// CHECK-NEXT: MyStruct s = {2 * y, 3 * x + 2}; +// CHECK-NEXT: { +// CHECK-NEXT: _d_s.a += 1 * s.b; +// CHECK-NEXT: _d_s.b += s.a * 1; +// CHECK-NEXT: } +// CHECK-NEXT: { +// CHECK-NEXT: *_d_y += 2 * _d_s.a; +// CHECK-NEXT: *_d_x += 3 * _d_s.b; +// CHECK-NEXT: } +// CHECK-NEXT:} + +template +struct SimpleArray { + T elements[N]; // Aggregate initialization +}; + +namespace clad { +namespace custom_derivatives { +namespace class_functions { +template<::std::size_t N> +::clad::ValueAndAdjoint, SimpleArray> // expected-note {{'clad::custom_derivatives::class_functions::constructor_reverse_forw<2}}{{' is defined here}} +constructor_reverse_forw(::clad::ConstructorReverseForwTag>) { + SimpleArray a; + SimpleArray d_a; + return {a, d_a}; +} +}}} + +double fn15(double x, double y) { + SimpleArray arr; // expected-warning {{'SimpleArray' is an aggregate type and its constructor does not require a user-defined forward sweep function}} + return arr.elements[0]; +} + +// CHECK:void fn15_grad(double x, double y, double *_d_x, double *_d_y) { +// CHECK-NEXT: ::clad::ValueAndAdjoint, SimpleArray > _t0 = clad::custom_derivatives::class_functions::constructor_reverse_forw(clad::ConstructorReverseForwTag >()); +// CHECK-NEXT: SimpleArray _d_arr(_t0.adjoint); +// CHECK-NEXT: SimpleArray arr(_t0.value); +// CHECK-NEXT: _d_arr.elements[0] += 1; +// CHECK-NEXT:} + void print(const Tangent& t) { for (int i = 0; i < 5; ++i) { printf("%.2f", t.data[i]); @@ -535,6 +582,11 @@ int main() { fn13_test.execute(x, y, 3, d_x, d_y); printArray(d_x, size); // CHECK-EXEC: {2.00, 2.00, 2.00} printArray(d_y, size); // CHECK-EXEC: {0.00, 0.00, 0.00} + + INIT_GRADIENT(fn14); + TEST_GRADIENT(fn14, /*numOfDerivativeArgs=*/2, 3, 5, &d_i, &d_j); // CHECK-EXEC: {30.00, 22.00} + + INIT_GRADIENT(fn15); } // CHECK: void sum_pullback(Tangent &t, double _d_y, Tangent *_d_t) { diff --git a/test/Hessian/BuiltinDerivatives.C b/test/Hessian/BuiltinDerivatives.C index b4d12a240..11f78c917 100644 --- a/test/Hessian/BuiltinDerivatives.C +++ b/test/Hessian/BuiltinDerivatives.C @@ -186,16 +186,16 @@ int main() { // CHECK: void f1_darg0_grad(float x, float *_d_x) { // CHECK-NEXT: float _d__d_x = 0.F; // CHECK-NEXT: float _d_x0 = 1; -// CHECK-NEXT: ValueAndPushforward _d__t0 = {}; +// CHECK-NEXT: ValueAndPushforward _d__t0 = {0.F, 0.F}; // CHECK-NEXT: ValueAndPushforward _t00 = clad::custom_derivatives{{(::std)?}}::sin_pushforward(x, _d_x0); -// CHECK-NEXT: ValueAndPushforward _d__t1 = {}; +// CHECK-NEXT: ValueAndPushforward _d__t1 = {0.F, 0.F}; // CHECK-NEXT: ValueAndPushforward _t10 = clad::custom_derivatives{{(::std)?}}::cos_pushforward(x, _d_x0); // CHECK-NEXT: { // CHECK-NEXT: _d__t0.pushforward += 1; // CHECK-NEXT: _d__t1.pushforward += 1; // CHECK-NEXT: } // CHECK-NEXT: { -// CHECK-NEXT: {{.*}}ValueAndPushforward _r3 = {}; +// CHECK-NEXT: {{.*}}ValueAndPushforward _r3 = {0.F, 0.F}; // CHECK-NEXT: clad::custom_derivatives::class_functions::constructor_pullback(&_t10, {{.*}}cos_pushforward(x, _d_x0), &_d__t1, &_r3); // CHECK-NEXT: float _r4 = 0.F; // CHECK-NEXT: float _r5 = 0.F; @@ -204,7 +204,7 @@ int main() { // CHECK-NEXT: _d__d_x += _r5; // CHECK-NEXT: } // CHECK-NEXT: { -// CHECK-NEXT: {{.*}}ValueAndPushforward _r0 = {}; +// CHECK-NEXT: {{.*}}ValueAndPushforward _r0 = {0.F, 0.F}; // CHECK-NEXT: clad::custom_derivatives::class_functions::constructor_pullback(&_t00, {{.*}}sin_pushforward(x, _d_x0), &_d__t0, &_r0); // CHECK-NEXT: float _r1 = 0.F; // CHECK-NEXT: float _r2 = 0.F; @@ -225,11 +225,11 @@ int main() { // CHECK: void f2_darg0_grad(float x, float *_d_x) { // CHECK-NEXT: float _d__d_x = 0.F; // CHECK-NEXT: float _d_x0 = 1; -// CHECK-NEXT: ValueAndPushforward _d__t0 = {}; +// CHECK-NEXT: ValueAndPushforward _d__t0 = {0.F, 0.F}; // CHECK-NEXT: ValueAndPushforward _t00 = clad::custom_derivatives{{(::std)?}}::exp_pushforward(x, _d_x0); // CHECK-NEXT: _d__t0.pushforward += 1; // CHECK-NEXT: { -// CHECK-NEXT: {{.*}}ValueAndPushforward _r0 = {}; +// CHECK-NEXT: {{.*}}ValueAndPushforward _r0 = {0.F, 0.F}; // CHECK-NEXT: {{.*}}constructor_pullback(&_t00, {{.*}}exp_pushforward(x, _d_x0), &_d__t0, &_r0); // CHECK-NEXT: float _r1 = 0.F; // CHECK-NEXT: float _r2 = 0.F; @@ -250,11 +250,11 @@ int main() { // CHECK: void f3_darg0_grad(float x, float *_d_x) { // CHECK-NEXT: float _d__d_x = 0.F; // CHECK-NEXT: float _d_x0 = 1; -// CHECK-NEXT: ValueAndPushforward _d__t0 = {}; +// CHECK-NEXT: ValueAndPushforward _d__t0 = {0.F, 0.F}; // CHECK-NEXT: ValueAndPushforward _t00 = clad::custom_derivatives{{(::std)?}}::log_pushforward(x, _d_x0); // CHECK-NEXT: _d__t0.pushforward += 1; // CHECK-NEXT: { -// CHECK-NEXT: {{.*}}ValueAndPushforward _r0 = {}; +// CHECK-NEXT: {{.*}}ValueAndPushforward _r0 = {0.F, 0.F}; // CHECK-NEXT: {{.*}}constructor_pullback(&_t00, {{.*}}log_pushforward(x, _d_x0), &_d__t0, &_r0); // CHECK-NEXT: float _r1 = 0.F; // CHECK-NEXT: float _r2 = 0.F; @@ -275,11 +275,11 @@ int main() { // CHECK: void f4_darg0_grad(float x, float *_d_x) { // CHECK-NEXT: float _d__d_x = 0.F; // CHECK-NEXT: float _d_x0 = 1; -// CHECK-NEXT: {{(clad::)?}}ValueAndPushforward _d__t0 = {}; +// CHECK-NEXT: {{(clad::)?}}ValueAndPushforward _d__t0 = {0.F, 0.F}; // CHECK-NEXT: {{(clad::)?}}ValueAndPushforward _t00 = clad::custom_derivatives{{(::std)?}}::pow_pushforward(x, 4.F, _d_x0, 0.F); // CHECK-NEXT: _d__t0.pushforward += 1; // CHECK-NEXT: { -// CHECK-NEXT: {{.*}} _r0 = {}; +// CHECK-NEXT: {{.*}} _r0 = {0.F, 0.F}; // CHECK-NEXT: {{.*}}constructor_pullback(&_t00, {{.*}}pow_pushforward(x, 4.F, _d_x0, 0.F), &_d__t0, &_r0); // CHECK-NEXT: float _r1 = 0.F; // CHECK-NEXT: float _r2 = 0.F; @@ -300,11 +300,11 @@ int main() { // CHECK: void f5_darg0_grad(float x, float *_d_x) { // CHECK-NEXT: float _d__d_x = 0.F; // CHECK-NEXT: float _d_x0 = 1; -// CHECK-NEXT: {{(clad::)?}}ValueAndPushforward _d__t0 = {}; +// CHECK-NEXT: {{(clad::)?}}ValueAndPushforward _d__t0 = {0.F, 0.F}; // CHECK-NEXT: {{(clad::)?}}ValueAndPushforward _t00 = clad::custom_derivatives{{(::std)?}}::pow_pushforward(2.F, x, 0.F, _d_x0); // CHECK-NEXT: _d__t0.pushforward += 1; // CHECK-NEXT: { -// CHECK-NEXT: {{.*}} _r0 = {}; +// CHECK-NEXT: {{.*}} _r0 = {0.F, 0.F}; // CHECK-NEXT: {{.*}}constructor_pullback(&_t00, {{.*}}pow_pushforward(2.F, x, 0.F, _d_x0), &_d__t0, &_r0); // CHECK-NEXT: float _r1 = 0.F; // CHECK-NEXT: float _r2 = 0.F; @@ -328,11 +328,11 @@ int main() { // CHECK-NEXT: float _d_x0 = 1; // CHECK-NEXT: float _d__d_y = 0.F; // CHECK-NEXT: float _d_y0 = 0; -// CHECK-NEXT: {{(clad::)?}}ValueAndPushforward _d__t0 = {}; +// CHECK-NEXT: {{(clad::)?}}ValueAndPushforward _d__t0 = {0.F, 0.F}; // CHECK-NEXT: {{(clad::)?}}ValueAndPushforward _t00 = clad::custom_derivatives{{(::std)?}}::pow_pushforward(x, y, _d_x0, _d_y0); // CHECK-NEXT: _d__t0.pushforward += 1; // CHECK-NEXT: { -// CHECK-NEXT: {{.*}} _r0 = {}; +// CHECK-NEXT: {{.*}} _r0 = {0.F, 0.F}; // CHECK-NEXT: {{.*}}constructor_pullback(&_t00, {{.*}}pow_pushforward(x, y, _d_x0, _d_y0), &_d__t0, &_r0); // CHECK-NEXT: float _r1 = 0.F; // CHECK-NEXT: float _r2 = 0.F; @@ -358,11 +358,11 @@ int main() { // CHECK-NEXT: float _d_x0 = 0; // CHECK-NEXT: float _d__d_y = 0.F; // CHECK-NEXT: float _d_y0 = 1; -// CHECK-NEXT: {{(clad::)?}}ValueAndPushforward _d__t0 = {}; +// CHECK-NEXT: {{(clad::)?}}ValueAndPushforward _d__t0 = {0.F, 0.F}; // CHECK-NEXT: {{(clad::)?}}ValueAndPushforward _t00 = clad::custom_derivatives{{(::std)?}}::pow_pushforward(x, y, _d_x0, _d_y0); // CHECK-NEXT: _d__t0.pushforward += 1; // CHECK-NEXT: { -// CHECK-NEXT: {{.*}} _r0 = {}; +// CHECK-NEXT: {{.*}} _r0 = {0.F, 0.F}; // CHECK-NEXT: {{.*}}constructor_pullback(&_t00, {{.*}}pow_pushforward(x, y, _d_x0, _d_y0), &_d__t0, &_r0); // CHECK-NEXT: float _r1 = 0.F; // CHECK-NEXT: float _r2 = 0.F; diff --git a/test/Hessian/NestedFunctionCalls.C b/test/Hessian/NestedFunctionCalls.C index 0aff70f2a..b5c784d84 100644 --- a/test/Hessian/NestedFunctionCalls.C +++ b/test/Hessian/NestedFunctionCalls.C @@ -43,7 +43,7 @@ double f2(double x, double y){ // CHECK-NEXT: double _d_x0 = 1; // CHECK-NEXT: double _d__d_y = 0.; // CHECK-NEXT: double _d_y0 = 0; -// CHECK-NEXT: clad::ValueAndPushforward _d__t0 = {}; +// CHECK-NEXT: clad::ValueAndPushforward _d__t0 = {0., 0.}; // CHECK-NEXT: clad::ValueAndPushforward _t00 = f_pushforward(x, y, _d_x0, _d_y0); // CHECK-NEXT: double _d__d_ans = 0.; // CHECK-NEXT: double _d_ans = _t00.pushforward; @@ -53,7 +53,7 @@ double f2(double x, double y){ // CHECK-NEXT: _d__t0.value += _d_ans0; // CHECK-NEXT: _d__t0.pushforward += _d__d_ans; // CHECK-NEXT: { -// CHECK-NEXT: {{.*}}ValueAndPushforward _r0 = {}; +// CHECK-NEXT: {{.*}}ValueAndPushforward _r0 = {0., 0.}; // CHECK-NEXT: {{.*}}constructor_pullback(&_t00, f_pushforward(x, y, _d_x0, _d_y0), &_d__t0, &_r0); // CHECK-NEXT: double _r1 = 0.; // CHECK-NEXT: double _r2 = 0.; @@ -81,7 +81,7 @@ double f2(double x, double y){ // CHECK-NEXT: double _d_x0 = 0; // CHECK-NEXT: double _d__d_y = 0.; // CHECK-NEXT: double _d_y0 = 1; -// CHECK-NEXT: clad::ValueAndPushforward _d__t0 = {}; +// CHECK-NEXT: clad::ValueAndPushforward _d__t0 = {0., 0.}; // CHECK-NEXT: clad::ValueAndPushforward _t00 = f_pushforward(x, y, _d_x0, _d_y0); // CHECK-NEXT: double _d__d_ans = 0.; // CHECK-NEXT: double _d_ans = _t00.pushforward; @@ -91,7 +91,7 @@ double f2(double x, double y){ // CHECK-NEXT: _d__t0.value += _d_ans0; // CHECK-NEXT: _d__t0.pushforward += _d__d_ans; // CHECK-NEXT: { -// CHECK-NEXT: {{.*}}ValueAndPushforward _r0 = {}; +// CHECK-NEXT: {{.*}}ValueAndPushforward _r0 = {0., 0.}; // CHECK-NEXT: {{.*}}constructor_pullback(&_t00, f_pushforward(x, y, _d_x0, _d_y0), &_d__t0, &_r0); // CHECK-NEXT: double _r1 = 0.; // CHECK-NEXT: double _r2 = 0.;