From 654faee85321023ae4697cc4dc5f302268d12d30 Mon Sep 17 00:00:00 2001 From: "petro.zarytskyi" Date: Wed, 27 Dec 2023 14:55:24 +0200 Subject: [PATCH] Improve storing of LHS/RHS in multiplication/division operators. --- .../clad/Differentiator/ReverseModeVisitor.h | 4 ++ include/clad/Differentiator/VisitorBase.h | 4 ++ lib/Differentiator/ReverseModeVisitor.cpp | 46 +++++++++------ lib/Differentiator/VisitorBase.cpp | 5 +- test/CUDA/GradientCuda.cu | 19 +++---- test/ErrorEstimation/BasicOps.C | 26 ++++----- test/ErrorEstimation/ConditonalStatements.C | 8 +-- test/ErrorEstimation/LoopsAndArraysExec.C | 26 ++++----- test/Gradient/Assignments.C | 16 +++--- test/Gradient/Functors.C | 8 ++- test/Gradient/Gradients.C | 52 ++++++++++++----- test/Gradient/Loops.C | 38 ++++++------- test/Gradient/MemberFunctions.C | 56 ++++++++++++++----- test/Gradient/TemplateFunctors.C | 14 +++-- test/Gradient/constexprTest.C | 14 ++--- test/Hessian/BuiltinDerivatives.C | 22 +++++--- test/Jacobian/Functors.C | 24 +++++--- test/Jacobian/Jacobian.C | 12 ++++ 18 files changed, 245 insertions(+), 149 deletions(-) diff --git a/include/clad/Differentiator/ReverseModeVisitor.h b/include/clad/Differentiator/ReverseModeVisitor.h index 0968055a6..31e19e51f 100644 --- a/include/clad/Differentiator/ReverseModeVisitor.h +++ b/include/clad/Differentiator/ReverseModeVisitor.h @@ -218,6 +218,10 @@ namespace clad { /// to avoid recomputiation. bool UsefulToStoreGlobal(clang::Expr* E); + /// For an expr E, decides if we should recompute it or store it. + /// This is the central point for checkpointing. + bool ShouldRecompute(const clang::Expr* E); + /// Builds a variable declaration and stores it in the function /// global scope. /// diff --git a/include/clad/Differentiator/VisitorBase.h b/include/clad/Differentiator/VisitorBase.h index f46addf2a..6e8c65006 100644 --- a/include/clad/Differentiator/VisitorBase.h +++ b/include/clad/Differentiator/VisitorBase.h @@ -363,6 +363,10 @@ namespace clad { bool forceDeclCreation = false, clang::VarDecl::InitializationStyle IS = clang::VarDecl::InitializationStyle::CInit); + /// For an expr E, decides if it is useful to store it in a temporary + /// variable and replace E's further usage by a reference to that variable + /// to avoid recomputation. + static bool UsefulToStore(clang::Expr* E); /// A flag for silencing warnings/errors output by diag function. bool silenceDiags = false; /// Shorthand to issues a warning or error. diff --git a/lib/Differentiator/ReverseModeVisitor.cpp b/lib/Differentiator/ReverseModeVisitor.cpp index 38b35b473..7c8f25ad4 100644 --- a/lib/Differentiator/ReverseModeVisitor.cpp +++ b/lib/Differentiator/ReverseModeVisitor.cpp @@ -2162,7 +2162,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, StmtDiff RResult; // If R has no side effects, it can be just cloned // (no need to store it). - if (utils::ContainsFunctionCalls(R) || R->HasSideEffects(m_Context)) { + if (!ShouldRecompute(R)) { RDelayed = std::unique_ptr( new DelayedStoreResult(DelayedGlobalStoreAndRef(R))); RResult = RDelayed->Result; @@ -2177,30 +2177,39 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, // dxi/xr = xl // df/dxr += df/dxi * dxi/xr = df/dxi * xl // Store left multiplier and assign it with L. - Expr* LStored = Ldiff.getExpr(); + StmtDiff LStored = Ldiff; + if (!ShouldRecompute(LStored.getExpr())) + LStored = GlobalStoreAndRef(LStored.getExpr(), /*prefix=*/"_t", + /*force=*/true); Expr::EvalResult dummy; if (RDelayed || !clad_compat::Expr_EvaluateAsConstantExpr(R, dummy, m_Context)) { Expr* dr = nullptr; if (dfdx()) - dr = BuildOp(BO_Mul, Ldiff.getRevSweepAsExpr(), dfdx()); + dr = BuildOp(BO_Mul, LStored.getRevSweepAsExpr(), dfdx()); Rdiff = Visit(R, dr); // Assign right multiplier's variable with R. if (RDelayed) RDelayed->Finalize(Rdiff.getExpr()); } - std::tie(Ldiff, Rdiff) = std::make_pair(LStored, RResult.getExpr()); + std::tie(Ldiff, Rdiff) = + std::make_pair(LStored.getExpr(), RResult.getExpr()); } else if (opCode == BO_Div) { // xi = xl / xr // dxi/xl = 1 / xr // df/dxl += df/dxi * dxi/xl = df/dxi * (1/xr) auto RDelayed = DelayedGlobalStoreAndRef(R); StmtDiff RResult = RDelayed.Result; - Expr* RStored = StoreAndRef(RResult.getExpr_dx(), direction::reverse); + Expr* RStored = + StoreAndRef(RResult.getRevSweepAsExpr(), direction::reverse); Expr* dl = nullptr; if (dfdx()) dl = BuildOp(BO_Div, dfdx(), RStored); Ldiff = Visit(L, dl); + StmtDiff LStored = Ldiff; + if (!ShouldRecompute(LStored.getExpr())) + LStored = GlobalStoreAndRef(LStored.getExpr(), /*prefix=*/"_t", + /*force=*/true); // dxi/xr = -xl / (xr * xr) // df/dxl += df/dxi * dxi/xr = df/dxi * (-xl /(xr * xr)) // Wrap R * R in parentheses: (R * R). otherwise code like 1 / R * R is @@ -2209,17 +2218,17 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, Expr* dr = nullptr; if (dfdx()) { Expr* RxR = BuildParens(BuildOp(BO_Mul, RStored, RStored)); - dr = - BuildOp(BO_Mul, dfdx(), - BuildOp(UO_Minus, - BuildOp(BO_Div, Ldiff.getRevSweepAsExpr(), RxR))); + dr = BuildOp( + BO_Mul, dfdx(), + BuildOp(UO_Minus, + BuildOp(BO_Div, LStored.getRevSweepAsExpr(), RxR))); dr = StoreAndRef(dr, direction::reverse); } Rdiff = Visit(R, dr); RDelayed.Finalize(Rdiff.getExpr()); } std::tie(Ldiff, Rdiff) = - std::make_pair(Ldiff.getExpr(), RResult.getExpr()); + std::make_pair(LStored.getExpr(), RResult.getExpr()); } else if (BinOp->isAssignmentOp()) { if (L->isModifiableLvalue(m_Context) != Expr::MLV_Valid) { diag(DiagnosticsEngine::Warning, @@ -2392,7 +2401,8 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, } else if (opCode == BO_DivAssign) { auto RDelayed = DelayedGlobalStoreAndRef(R); StmtDiff RResult = RDelayed.Result; - Expr* RStored = StoreAndRef(RResult.getExpr_dx(), direction::reverse); + Expr* RStored = + StoreAndRef(RResult.getRevSweepAsExpr(), direction::reverse); addToCurrentBlock(BuildOp(BO_AddAssign, AssignedDiff, BuildOp(BO_Div, oldValue, RStored)), direction::reverse); @@ -2785,6 +2795,10 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, return StmtDiff(subExprDiff.getExpr(), subExprDiff.getExpr_dx()); } + bool ReverseModeVisitor::ShouldRecompute(const Expr* E) { + return !(utils::ContainsFunctionCalls(E) || E->HasSideEffects(m_Context)); + } + bool ReverseModeVisitor::UsefulToStoreGlobal(Expr* E) { if (!E) return false; @@ -2944,12 +2958,12 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, ReverseModeVisitor::DelayedGlobalStoreAndRef(Expr* E, llvm::StringRef prefix) { assert(E && "must be provided"); - if (isa(E) /*!UsefulToStoreGlobal(E)*/) { - Expr* Cloned = Clone(E); + if (!UsefulToStore(E)) { + StmtDiff Ediff = Visit(E); Expr::EvalResult evalRes; bool isConst = clad_compat::Expr_EvaluateAsConstantExpr(E, evalRes, m_Context); - return DelayedStoreResult{*this, StmtDiff{Cloned, Cloned}, + return DelayedStoreResult{*this, Ediff, /*isConstant*/ isConst, /*isInsideLoop*/ false, /*pNeedsUpdate=*/false}; @@ -2959,14 +2973,14 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, auto CladTape = MakeCladTapeFor(dummy); Expr* Push = CladTape.Push; Expr* Pop = CladTape.Pop; - return DelayedStoreResult{*this, StmtDiff{Push, Pop, nullptr, Pop}, + return DelayedStoreResult{*this, StmtDiff{Push, nullptr, nullptr, Pop}, /*isConstant*/ false, /*isInsideLoop*/ true, /*pNeedsUpdate=*/true}; } Expr* Ref = BuildDeclRef(GlobalStoreImpl( getNonConstType(E->getType(), m_Context, m_Sema), prefix)); // Return reference to the declaration instead of original expression. - return DelayedStoreResult{*this, StmtDiff{Ref, Ref}, + return DelayedStoreResult{*this, StmtDiff{Ref, nullptr, nullptr, Ref}, /*isConstant*/ false, /*isInsideLoop*/ false, /*pNeedsUpdate=*/true}; } diff --git a/lib/Differentiator/VisitorBase.cpp b/lib/Differentiator/VisitorBase.cpp index 888fc54bf..3de0394e9 100644 --- a/lib/Differentiator/VisitorBase.cpp +++ b/lib/Differentiator/VisitorBase.cpp @@ -312,10 +312,7 @@ namespace clad { return StoreAndRef(E, Type, block, prefix, forceDeclCreation, IS); } - /// For an expr E, decides if it is useful to store it in a temporary variable - /// and replace E's further usage by a reference to that variable to avoid - /// recomputiation. - static bool UsefulToStore(Expr* E) { + bool VisitorBase::UsefulToStore(Expr* E) { if (!E) return false; Expr* B = E->IgnoreParenImpCasts(); diff --git a/test/CUDA/GradientCuda.cu b/test/CUDA/GradientCuda.cu index 5647b65bd..9d4a79adb 100644 --- a/test/CUDA/GradientCuda.cu +++ b/test/CUDA/GradientCuda.cu @@ -50,7 +50,7 @@ auto gauss_g = clad::gradient(gauss, "p"); //CHECK-NEXT: _t2 = t; //CHECK-NEXT: _t3 = (2 * sigma * sigma); //CHECK-NEXT: t = -t / _t3; -//CHECK-NEXT: _t6 = 2.; +//CHECK-NEXT: _t6 = std::pow(2 * 3.1415926535897931, -dim / 2.); //CHECK-NEXT: _t5 = std::pow(sigma, -0.5); //CHECK-NEXT: _t4 = std::exp(t); //CHECK-NEXT: goto _label0; @@ -58,19 +58,18 @@ auto gauss_g = clad::gradient(gauss, "p"); //CHECK-NEXT: { //CHECK-NEXT: double _grad0 = 0.; //CHECK-NEXT: double _grad1 = 0.; -//CHECK-NEXT: clad::custom_derivatives{{(::std)?}}::pow_pullback(2 * 3.1415926535897931, -dim / _t6, 1 * _t4 * _t5, &_grad0, &_grad1); +//CHECK-NEXT: clad::custom_derivatives{{(::std)?}}::pow_pullback(2 * 3.1415926535897931, -dim / 2., 1 * _t4 * _t5, &_grad0, &_grad1); //CHECK-NEXT: double _r1 = _grad0; //CHECK-NEXT: double _r2 = _grad1; -//CHECK-NEXT: _d_dim += -_r2 / _t6; -//CHECK-NEXT: double _r3 = _r2 * --dim / (_t6 * _t6); +//CHECK-NEXT: _d_dim += -_r2 / 2.; //CHECK-NEXT: double _grad2 = 0.; //CHECK-NEXT: double _grad3 = 0.; -//CHECK-NEXT: clad::custom_derivatives{{(::std)?}}::pow_pullback(sigma, -0.5, std::pow(2 * 3.1415926535897931, -dim / _t6) * 1 * _t4, &_grad2, &_grad3); -//CHECK-NEXT: double _r4 = _grad2; -//CHECK-NEXT: _d_sigma += _r4; -//CHECK-NEXT: double _r5 = _grad3; -//CHECK-NEXT: double _r6 = std::pow(2 * 3.1415926535897931, -dim / _t6) * _t5 * 1 * clad::custom_derivatives::exp_pushforward(t, 1.).pushforward; -//CHECK-NEXT: _d_t += _r6; +//CHECK-NEXT: clad::custom_derivatives{{(::std)?}}::pow_pullback(sigma, -0.5, _t6 * 1 * _t4, &_grad2, &_grad3); +//CHECK-NEXT: double _r3 = _grad2; +//CHECK-NEXT: _d_sigma += _r3; +//CHECK-NEXT: double _r4 = _grad3; +//CHECK-NEXT: double _r5 = _t6 * _t5 * 1 * clad::custom_derivatives::exp_pushforward(t, 1.).pushforward; +//CHECK-NEXT: _d_t += _r5; //CHECK-NEXT: } //CHECK-NEXT: { //CHECK-NEXT: t = _t2; diff --git a/test/ErrorEstimation/BasicOps.C b/test/ErrorEstimation/BasicOps.C index b7441eda7..6b11d07c7 100644 --- a/test/ErrorEstimation/BasicOps.C +++ b/test/ErrorEstimation/BasicOps.C @@ -82,22 +82,20 @@ float func2(float x, float y) { //CHECK-NEXT: double _delta_x = 0; //CHECK-NEXT: float _EERepl_x0 = x; //CHECK-NEXT: float _EERepl_x1; -//CHECK-NEXT: float _t1; //CHECK-NEXT: float _d_z = 0; //CHECK-NEXT: double _delta_z = 0; //CHECK-NEXT: float _EERepl_z0; //CHECK-NEXT: _t0 = x; //CHECK-NEXT: x = x - y - y * y; //CHECK-NEXT: _EERepl_x1 = x; -//CHECK-NEXT: _t1 = x; -//CHECK-NEXT: float z = y / _t1; +//CHECK-NEXT: float z = y / x; //CHECK-NEXT: _EERepl_z0 = z; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: _d_z += 1; //CHECK-NEXT: { -//CHECK-NEXT: * _d_y += _d_z / _t1; -//CHECK-NEXT: float _r0 = _d_z * -y / (_t1 * _t1); +//CHECK-NEXT: * _d_y += _d_z / x; +//CHECK-NEXT: float _r0 = _d_z * -y / (x * x); //CHECK-NEXT: * _d_x += _r0; //CHECK-NEXT: _delta_z += std::abs(_d_z * _EERepl_z0 * {{.+}}); //CHECK-NEXT: } @@ -392,16 +390,18 @@ float func9(float x, float y) { //CHECK-NEXT: float _t3; //CHECK-NEXT: double _t4; //CHECK-NEXT: float _t5; -//CHECK-NEXT: float _t7; +//CHECK-NEXT: double _t7; +//CHECK-NEXT: float _t8; //CHECK-NEXT: float _EERepl_z1; //CHECK-NEXT: _t1 = x; //CHECK-NEXT: float z = helper(x, y) + helper2(x); //CHECK-NEXT: _EERepl_z0 = z; //CHECK-NEXT: _t3 = z; //CHECK-NEXT: _t5 = x; -//CHECK-NEXT: _t7 = y; +//CHECK-NEXT: _t7 = helper2(x); +//CHECK-NEXT: _t8 = y; //CHECK-NEXT: _t4 = helper2(y); -//CHECK-NEXT: z += helper2(x) * _t4; +//CHECK-NEXT: z += _t7 * _t4; //CHECK-NEXT: _EERepl_z1 = z; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: @@ -413,12 +413,12 @@ float func9(float x, float y) { //CHECK-NEXT: double _t6 = 0; //CHECK-NEXT: helper2_pullback(_t5, _r_d0 * _t4, &* _d_x, _t6); //CHECK-NEXT: float _r3 = * _d_x; -//CHECK-NEXT: y = _t7; -//CHECK-NEXT: double _t8 = 0; -//CHECK-NEXT: helper2_pullback(_t7, helper2(x) * _r_d0, &* _d_y, _t8); +//CHECK-NEXT: y = _t8; +//CHECK-NEXT: double _t9 = 0; +//CHECK-NEXT: helper2_pullback(_t8, _t7 * _r_d0, &* _d_y, _t9); //CHECK-NEXT: float _r4 = * _d_y; -//CHECK-NEXT: _delta_z += _t6 + _t8; -//CHECK-NEXT: _final_error += std::abs(_r4 * _t7 * {{.+}}); +//CHECK-NEXT: _delta_z += _t6 + _t9; +//CHECK-NEXT: _final_error += std::abs(_r4 * _t8 * {{.+}}); //CHECK-NEXT: _final_error += std::abs(_r3 * _t5 * {{.+}}); //CHECK-NEXT: } //CHECK-NEXT: { diff --git a/test/ErrorEstimation/ConditonalStatements.C b/test/ErrorEstimation/ConditonalStatements.C index 4fc2794e8..30b826081 100644 --- a/test/ErrorEstimation/ConditonalStatements.C +++ b/test/ErrorEstimation/ConditonalStatements.C @@ -168,7 +168,6 @@ float func4(float x, float y) { //CHECK-NEXT: float _EERepl_x1; //CHECK-NEXT: float _t1; //CHECK-NEXT: float _EERepl_x2; -//CHECK-NEXT: float _t2; //CHECK-NEXT: double _ret_value0 = 0; //CHECK-NEXT: _cond0 = !x; //CHECK-NEXT: if (_cond0) @@ -178,13 +177,12 @@ float func4(float x, float y) { //CHECK-NEXT: _cond0 ? (x += 1) : (x *= x); //CHECK-NEXT: _EERepl_x2 = x; //CHECK-NEXT: _EERepl_x1 = x; -//CHECK-NEXT: _t2 = x; -//CHECK-NEXT: _ret_value0 = y / _t2; +//CHECK-NEXT: _ret_value0 = y / x; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: * _d_y += 1 / _t2; -//CHECK-NEXT: float _r0 = 1 * -y / (_t2 * _t2); +//CHECK-NEXT: * _d_y += 1 / x; +//CHECK-NEXT: float _r0 = 1 * -y / (x * x); //CHECK-NEXT: * _d_x += _r0; //CHECK-NEXT: } //CHECK-NEXT: { diff --git a/test/ErrorEstimation/LoopsAndArraysExec.C b/test/ErrorEstimation/LoopsAndArraysExec.C index 40d3e6771..caa79678f 100644 --- a/test/ErrorEstimation/LoopsAndArraysExec.C +++ b/test/ErrorEstimation/LoopsAndArraysExec.C @@ -146,7 +146,6 @@ double divSum(float* a, float* b, int n) { //CHECK-NEXT: unsigned long _t0; //CHECK-NEXT: int _d_i = 0; //CHECK-NEXT: clad::tape _t1 = {}; -//CHECK-NEXT: clad::tape _t2 = {}; //CHECK-NEXT: clad::tape _EERepl_sum1 = {}; //CHECK-NEXT: double sum = 0; //CHECK-NEXT: _EERepl_sum0 = sum; @@ -154,7 +153,7 @@ double divSum(float* a, float* b, int n) { //CHECK-NEXT: for (int i = 0; i < n; i++) { //CHECK-NEXT: _t0++; //CHECK-NEXT: clad::push(_t1, sum); -//CHECK-NEXT: sum += a[i] / clad::push(_t2, b[i]); +//CHECK-NEXT: sum += a[i] / b[i]; //CHECK-NEXT: clad::push(_EERepl_sum1, sum); //CHECK-NEXT: } //CHECK-NEXT: goto _label0; @@ -165,28 +164,27 @@ double divSum(float* a, float* b, int n) { //CHECK-NEXT: { //CHECK-NEXT: sum = clad::pop(_t1); //CHECK-NEXT: double _r_d0 = _d_sum; -//CHECK-NEXT: float _r0 = clad::pop(_t2); -//CHECK-NEXT: _d_a[i] += _r_d0 / _r0; -//CHECK-NEXT: double _r1 = _r_d0 * -a[i] / (_r0 * _r0); -//CHECK-NEXT: _d_b[i] += _r1; -//CHECK-NEXT: double _r2 = clad::pop(_EERepl_sum1); -//CHECK-NEXT: _delta_sum += std::abs(_r_d0 * _r2 * {{.+}}); +//CHECK-NEXT: _d_a[i] += _r_d0 / b[i]; +//CHECK-NEXT: double _r0 = _r_d0 * -a[i] / (b[i] * b[i]); +//CHECK-NEXT: _d_b[i] += _r0; +//CHECK-NEXT: double _r1 = clad::pop(_EERepl_sum1); +//CHECK-NEXT: _delta_sum += std::abs(_r_d0 * _r1 * {{.+}}); //CHECK-NEXT: } //CHECK-NEXT: } //CHECK-NEXT: _delta_sum += std::abs(_d_sum * _EERepl_sum0 * {{.+}}); //CHECK-NEXT: clad::array _delta_a(_d_a.size()); //CHECK-NEXT: int i = 0; //CHECK-NEXT: for (; i < _d_a.size(); i++) { -//CHECK-NEXT: double _t3 = std::abs(_d_a[i] * a[i] * {{.+}}); -//CHECK-NEXT: _delta_a[i] += _t3; -//CHECK-NEXT: _final_error += _t3; +//CHECK-NEXT: double _t2 = std::abs(_d_a[i] * a[i] * {{.+}}); +//CHECK-NEXT: _delta_a[i] += _t2; +//CHECK-NEXT: _final_error += _t2; //CHECK-NEXT: } //CHECK-NEXT: clad::array _delta_b(_d_b.size()); //CHECK-NEXT: i = 0; //CHECK-NEXT: for (; i < _d_b.size(); i++) { -//CHECK-NEXT: double _t4 = std::abs(_d_b[i] * b[i] * {{.+}}); -//CHECK-NEXT: _delta_b[i] += _t4; -//CHECK-NEXT: _final_error += _t4; +//CHECK-NEXT: double _t3 = std::abs(_d_b[i] * b[i] * {{.+}}); +//CHECK-NEXT: _delta_b[i] += _t3; +//CHECK-NEXT: _final_error += _t3; //CHECK-NEXT: } //CHECK-NEXT: _final_error += _delta_sum; //CHECK-NEXT: } diff --git a/test/Gradient/Assignments.C b/test/Gradient/Assignments.C index 5712e2adb..42e316b0f 100644 --- a/test/Gradient/Assignments.C +++ b/test/Gradient/Assignments.C @@ -294,7 +294,6 @@ double f7(double x, double y) { //CHECK-NEXT: double _t4; //CHECK-NEXT: double _t5; //CHECK-NEXT: double _t6; -//CHECK-NEXT: double _t7; //CHECK-NEXT: double t[3] = {1, x, x * x}; //CHECK-NEXT: t[0]++; //CHECK-NEXT: t[0]--; @@ -309,17 +308,16 @@ double f7(double x, double y) { //CHECK-NEXT: _t3 = t[0]; //CHECK-NEXT: t[0] *= t[1]; //CHECK-NEXT: _t4 = t[0]; -//CHECK-NEXT: _t5 = t[1]; -//CHECK-NEXT: t[0] /= _t5; -//CHECK-NEXT: _t6 = t[0]; +//CHECK-NEXT: t[0] /= t[1]; +//CHECK-NEXT: _t5 = t[0]; //CHECK-NEXT: t[0] -= t[1]; -//CHECK-NEXT: _t7 = x; +//CHECK-NEXT: _t6 = x; //CHECK-NEXT: x = ++t[0]; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: _d_t[0] += 1; //CHECK-NEXT: { -//CHECK-NEXT: x = _t7; +//CHECK-NEXT: x = _t6; //CHECK-NEXT: double _r_d6 = * _d_x; //CHECK-NEXT: _d_t[0] += _r_d6; //CHECK-NEXT: --t[0]; @@ -327,7 +325,7 @@ double f7(double x, double y) { //CHECK-NEXT: * _d_x; //CHECK-NEXT: } //CHECK-NEXT: { -//CHECK-NEXT: t[0] = _t6; +//CHECK-NEXT: t[0] = _t5; //CHECK-NEXT: double _r_d5 = _d_t[0]; //CHECK-NEXT: _d_t[1] += -_r_d5; //CHECK-NEXT: _d_t[0]; @@ -335,8 +333,8 @@ double f7(double x, double y) { //CHECK-NEXT: { //CHECK-NEXT: t[0] = _t4; //CHECK-NEXT: double _r_d4 = _d_t[0]; -//CHECK-NEXT: _d_t[0] += _r_d4 / _t5; -//CHECK-NEXT: double _r0 = _r_d4 * -t[0] / (_t5 * _t5); +//CHECK-NEXT: _d_t[0] += _r_d4 / t[1]; +//CHECK-NEXT: double _r0 = _r_d4 * -t[0] / (t[1] * t[1]); //CHECK-NEXT: _d_t[1] += _r0; //CHECK-NEXT: _d_t[0] -= _r_d4; //CHECK-NEXT: _d_t[0]; diff --git a/test/Gradient/Functors.C b/test/Gradient/Functors.C index 422935edc..d1979b2b9 100644 --- a/test/Gradient/Functors.C +++ b/test/Gradient/Functors.C @@ -57,12 +57,14 @@ struct ExperimentVolatile { }; // CHECK: void operator_call_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) volatile { + // CHECK-NEXT: double _t0; + // CHECK-NEXT: _t0 = this->x * i; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { // CHECK-NEXT: (* _d_this).x += 1 * j * i; // CHECK-NEXT: * _d_i += this->x * 1 * j; - // CHECK-NEXT: * _d_j += this->x * i * 1; + // CHECK-NEXT: * _d_j += _t0 * 1; // CHECK-NEXT: } // CHECK-NEXT: } }; @@ -81,12 +83,14 @@ struct ExperimentConstVolatile { }; // CHECK: void operator_call_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) const volatile { + // CHECK-NEXT: double _t0; + // CHECK-NEXT: _t0 = this->x * i; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { // CHECK-NEXT: (* _d_this).x += 1 * j * i; // CHECK-NEXT: * _d_i += this->x * 1 * j; - // CHECK-NEXT: * _d_j += this->x * i * 1; + // CHECK-NEXT: * _d_j += _t0 * 1; // CHECK-NEXT: } // CHECK-NEXT: } }; diff --git a/test/Gradient/Gradients.C b/test/Gradient/Gradients.C index b6823266f..663abdeb2 100644 --- a/test/Gradient/Gradients.C +++ b/test/Gradient/Gradients.C @@ -121,13 +121,11 @@ double f_div1(double x, double y) { } //CHECK: void f_div1_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { -//CHECK-NEXT: double _t0; -//CHECK-NEXT: _t0 = y; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: * _d_x += 1 / _t0; -//CHECK-NEXT: double _r0 = 1 * -x / (_t0 * _t0); +//CHECK-NEXT: * _d_x += 1 / y; +//CHECK-NEXT: double _r0 = 1 * -x / (y * y); //CHECK-NEXT: * _d_y += _r0; //CHECK-NEXT: } //CHECK-NEXT: } @@ -152,13 +150,38 @@ double f_div2(double x, double y) { void f_div2_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y); +double f_div3(double x, double y) { + return (x = y) / (y * y); +} + +//CHECK: void f_div3_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { +//CHECK-NEXT: double _t0; +//CHECK-NEXT: double _t1; +//CHECK-NEXT: double _t2; +//CHECK-NEXT: _t1 = x; +//CHECK-NEXT: _t2 = (x = y); +//CHECK-NEXT: _t0 = (y * y); +//CHECK-NEXT: goto _label0; +//CHECK-NEXT: _label0: +//CHECK-NEXT: { +//CHECK-NEXT: * _d_x += 1 / _t0; +//CHECK-NEXT: x = _t1; +//CHECK-NEXT: double _r_d0 = * _d_x; +//CHECK-NEXT: * _d_y += _r_d0; +//CHECK-NEXT: * _d_x -= _r_d0; +//CHECK-NEXT: double _r0 = 1 * -_t2 / (_t0 * _t0); +//CHECK-NEXT: * _d_y += _r0 * y; +//CHECK-NEXT: * _d_y += y * _r0; +//CHECK-NEXT: } +//CHECK-NEXT: } + +void f_div3_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y); + double f_c(double x, double y) { return -x*y + (x + y)*(x/y) - x*x; } //CHECK: void f_c_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { -//CHECK-NEXT: double _t0; -//CHECK-NEXT: _t0 = y; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { @@ -166,8 +189,8 @@ double f_c(double x, double y) { //CHECK-NEXT: * _d_y += -x * 1; //CHECK-NEXT: * _d_x += 1 * (x / y); //CHECK-NEXT: * _d_y += 1 * (x / y); -//CHECK-NEXT: * _d_x += (x + y) * 1 / _t0; -//CHECK-NEXT: double _r0 = (x + y) * 1 * -x / (_t0 * _t0); +//CHECK-NEXT: * _d_x += (x + y) * 1 / y; +//CHECK-NEXT: double _r0 = (x + y) * 1 * -x / (y * y); //CHECK-NEXT: * _d_y += _r0; //CHECK-NEXT: * _d_x += -1 * x; //CHECK-NEXT: * _d_x += x * -1; @@ -418,14 +441,12 @@ void f_norm_grad(double x, double* _d_z, double* _d_d); //CHECK: void f_norm_grad(double x, double y, double z, double d, clad::array_ref _d_x, clad::array_ref _d_y, clad::array_ref _d_z, clad::array_ref _d_d) { -//CHECK-NEXT: double _t0; -//CHECK-NEXT: _t0 = d; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { //CHECK-NEXT: double _grad4 = 0.; //CHECK-NEXT: double _grad5 = 0.; -//CHECK-NEXT: clad::custom_derivatives::pow_pullback(sum_of_powers(x, y, z, d), 1 / _t0, 1, &_grad4, &_grad5); +//CHECK-NEXT: clad::custom_derivatives::pow_pullback(sum_of_powers(x, y, z, d), 1 / d, 1, &_grad4, &_grad5); //CHECK-NEXT: double _r0 = _grad4; //CHECK-NEXT: double _grad0 = 0.; //CHECK-NEXT: double _grad1 = 0.; @@ -441,7 +462,7 @@ void f_norm_grad(double x, //CHECK-NEXT: double _r4 = _grad3; //CHECK-NEXT: * _d_d += _r4; //CHECK-NEXT: double _r5 = _grad5; -//CHECK-NEXT: double _r6 = _r5 * -1 / (_t0 * _t0); +//CHECK-NEXT: double _r6 = _r5 * -1 / (d * d); //CHECK-NEXT: * _d_d += _r6; //CHECK-NEXT: } //CHECK-NEXT: } @@ -452,6 +473,8 @@ double f_sin(double x, double y) { void f_sin_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y); //CHECK: void f_sin_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { +//CHECK-NEXT: double _t0; +//CHECK-NEXT: _t0 = (std::sin(x) + std::sin(y)); //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { @@ -459,8 +482,8 @@ void f_sin_grad(double x, double y, clad::array_ref _d_x, clad::array_re //CHECK-NEXT: * _d_x += _r0; //CHECK-NEXT: double _r1 = 1 * (x + y) * clad::custom_derivatives::sin_pushforward(y, 1.).pushforward; //CHECK-NEXT: * _d_y += _r1; -//CHECK-NEXT: * _d_x += (std::sin(x) + std::sin(y)) * 1; -//CHECK-NEXT: * _d_y += (std::sin(x) + std::sin(y)) * 1; +//CHECK-NEXT: * _d_x += _t0 * 1; +//CHECK-NEXT: * _d_y += _t0 * 1; //CHECK-NEXT: } //CHECK-NEXT: } @@ -738,6 +761,7 @@ int main() { TEST(f_mult2, 1, 1); // CHECK-EXEC: Result is = {12.00, 12.00} TEST(f_div1, 1, 1); // CHECK-EXEC: Result is = {1.00, -1.00} TEST(f_div2, 1, 1); // CHECK-EXEC: Result is = {0.75, -0.75} + TEST(f_div3, 1, 1); // CHECK-EXEC: Result is = {0.00, -1.00} TEST(f_c, 1, 1); // CHECK-EXEC: Result is = {0.00, -2.00} TEST(f_rosenbrock, 1, 1); // CHECK-EXEC: Result is = {0.00, 0.00} TEST(f_cond1, 3, 2); // CHECK-EXEC: Result is = {1.00, 0.00} diff --git a/test/Gradient/Loops.C b/test/Gradient/Loops.C index e97b53b06..992945be6 100644 --- a/test/Gradient/Loops.C +++ b/test/Gradient/Loops.C @@ -323,7 +323,7 @@ double f_log_gaus(double* x, double* p /*means*/, double n, double sigma) { double gaus = 1./std::sqrt(std::pow(2*M_PI, n) * sigma) * std::exp(power); return std::log(gaus); } -//CHECK-NEXT: void f_log_gaus_grad_1(double *x, double *p, double n, double sigma, clad::array_ref _d_p) { +//CHECK: void f_log_gaus_grad_1(double *x, double *p, double n, double sigma, clad::array_ref _d_p) { //CHECK-NEXT: double _d_n = 0; //CHECK-NEXT: double _d_sigma = 0; //CHECK-NEXT: double _d_power = 0; @@ -335,6 +335,7 @@ double f_log_gaus(double* x, double* p /*means*/, double n, double sigma) { //CHECK-NEXT: double _t4; //CHECK-NEXT: double _t5; //CHECK-NEXT: double _t6; +//CHECK-NEXT: double _t7; //CHECK-NEXT: double _d_gaus = 0; //CHECK-NEXT: double power = 0; //CHECK-NEXT: _t0 = 0; @@ -347,7 +348,8 @@ double f_log_gaus(double* x, double* p /*means*/, double n, double sigma) { //CHECK-NEXT: _t4 = sq(sigma); //CHECK-NEXT: _t3 = (2 * _t4); //CHECK-NEXT: power = -power / _t3; -//CHECK-NEXT: _t6 = std::sqrt(std::pow(2 * 3.1415926535897931, n) * sigma); +//CHECK-NEXT: _t7 = std::pow(2 * 3.1415926535897931, n); +//CHECK-NEXT: _t6 = std::sqrt(_t7 * sigma); //CHECK-NEXT: _t5 = std::exp(power); //CHECK-NEXT: double gaus = 1. / _t6 * _t5; //CHECK-NEXT: goto _label0; @@ -358,14 +360,14 @@ double f_log_gaus(double* x, double* p /*means*/, double n, double sigma) { //CHECK-NEXT: } //CHECK-NEXT: { //CHECK-NEXT: double _r3 = _d_gaus * _t5 * -1. / (_t6 * _t6); -//CHECK-NEXT: double _r4 = _r3 * clad::custom_derivatives::sqrt_pushforward(std::pow(2 * 3.1415926535897931, n) * sigma, 1.).pushforward; +//CHECK-NEXT: double _r4 = _r3 * clad::custom_derivatives::sqrt_pushforward(_t7 * sigma, 1.).pushforward; //CHECK-NEXT: double _grad2 = 0.; //CHECK-NEXT: double _grad3 = 0.; //CHECK-NEXT: clad::custom_derivatives::pow_pullback(2 * 3.1415926535897931, n, _r4 * sigma, &_grad2, &_grad3); //CHECK-NEXT: double _r5 = _grad2; //CHECK-NEXT: double _r6 = _grad3; //CHECK-NEXT: _d_n += _r6; -//CHECK-NEXT: _d_sigma += std::pow(2 * 3.1415926535897931, n) * _r4; +//CHECK-NEXT: _d_sigma += _t7 * _r4; //CHECK-NEXT: double _r7 = 1. / _t6 * _d_gaus * clad::custom_derivatives::exp_pushforward(power, 1.).pushforward; //CHECK-NEXT: _d_power += _r7; //CHECK-NEXT: } @@ -1563,34 +1565,32 @@ double f_loop_init_var(double lower, double upper) { // CHECK: void f_loop_init_var_grad(double lower, double upper, clad::array_ref _d_lower, clad::array_ref _d_upper) { // CHECK-NEXT: double _d_sum = 0; // CHECK-NEXT: double _d_num_points = 0; -// CHECK-NEXT: double _t0; // CHECK-NEXT: double _d_interval = 0; -// CHECK-NEXT: unsigned long _t1; +// CHECK-NEXT: unsigned long _t0; // CHECK-NEXT: double _d_x = 0; +// CHECK-NEXT: clad::tape _t1 = {}; // CHECK-NEXT: clad::tape _t2 = {}; -// CHECK-NEXT: clad::tape _t3 = {}; // CHECK-NEXT: double sum = 0; // CHECK-NEXT: double num_points = 10000; -// CHECK-NEXT: _t0 = num_points; -// CHECK-NEXT: double interval = (upper - lower) / _t0; -// CHECK-NEXT: _t1 = 0; -// CHECK-NEXT: for (double x = lower; x <= upper; clad::push(_t2, x) , (x += interval)) { -// CHECK-NEXT: _t1++; -// CHECK-NEXT: clad::push(_t3, sum); +// CHECK-NEXT: double interval = (upper - lower) / num_points; +// CHECK-NEXT: _t0 = 0; +// CHECK-NEXT: for (double x = lower; x <= upper; clad::push(_t1, x) , (x += interval)) { +// CHECK-NEXT: _t0++; +// CHECK-NEXT: clad::push(_t2, sum); // CHECK-NEXT: sum += x * x * interval; // CHECK-NEXT: } // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: _d_sum += 1; // CHECK-NEXT: { -// CHECK-NEXT: for (; _t1; _t1--) { +// CHECK-NEXT: for (; _t0; _t0--) { // CHECK-NEXT: { -// CHECK-NEXT: x = clad::pop(_t2); +// CHECK-NEXT: x = clad::pop(_t1); // CHECK-NEXT: double _r_d0 = _d_x; // CHECK-NEXT: _d_interval += _r_d0; // CHECK-NEXT: } // CHECK-NEXT: { -// CHECK-NEXT: sum = clad::pop(_t3); +// CHECK-NEXT: sum = clad::pop(_t2); // CHECK-NEXT: double _r_d1 = _d_sum; // CHECK-NEXT: _d_x += _r_d1 * interval * x; // CHECK-NEXT: _d_x += x * _r_d1 * interval; @@ -1600,9 +1600,9 @@ double f_loop_init_var(double lower, double upper) { // CHECK-NEXT: * _d_lower += _d_x; // CHECK-NEXT: } // CHECK-NEXT: { -// CHECK-NEXT: * _d_upper += _d_interval / _t0; -// CHECK-NEXT: * _d_lower += -_d_interval / _t0; -// CHECK-NEXT: double _r0 = _d_interval * -(upper - lower) / (_t0 * _t0); +// CHECK-NEXT: * _d_upper += _d_interval / num_points; +// CHECK-NEXT: * _d_lower += -_d_interval / num_points; +// CHECK-NEXT: double _r0 = _d_interval * -(upper - lower) / (num_points * num_points); // CHECK-NEXT: _d_num_points += _r0; // CHECK-NEXT: } // CHECK-NEXT: } diff --git a/test/Gradient/MemberFunctions.C b/test/Gradient/MemberFunctions.C index 70d9a7cef..68e29694c 100644 --- a/test/Gradient/MemberFunctions.C +++ b/test/Gradient/MemberFunctions.C @@ -55,12 +55,14 @@ public: } // CHECK: void volatile_mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) volatile { + // CHECK-NEXT: double _t0; + // CHECK-NEXT: _t0 = (this->x + this->y); // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { // CHECK-NEXT: (* _d_this).x += 1 * i; // CHECK-NEXT: (* _d_this).y += 1 * i; - // CHECK-NEXT: * _d_i += (this->x + this->y) * 1; + // CHECK-NEXT: * _d_i += _t0 * 1; // CHECK-NEXT: * _d_i += 1 * j; // CHECK-NEXT: * _d_j += i * 1; // CHECK-NEXT: } @@ -71,12 +73,14 @@ public: } // CHECK: void const_volatile_mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) const volatile { + // CHECK-NEXT: double _t0; + // CHECK-NEXT: _t0 = (this->x + this->y); // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { // CHECK-NEXT: (* _d_this).x += 1 * i; // CHECK-NEXT: (* _d_this).y += 1 * i; - // CHECK-NEXT: * _d_i += (this->x + this->y) * 1; + // CHECK-NEXT: * _d_i += _t0 * 1; // CHECK-NEXT: * _d_i += 1 * j; // CHECK-NEXT: * _d_j += i * 1; // CHECK-NEXT: } @@ -117,12 +121,14 @@ public: } // CHECK: void volatile_lval_ref_mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) volatile & { + // CHECK-NEXT: double _t0; + // CHECK-NEXT: _t0 = (this->x + this->y); // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { // CHECK-NEXT: (* _d_this).x += 1 * i; // CHECK-NEXT: (* _d_this).y += 1 * i; - // CHECK-NEXT: * _d_i += (this->x + this->y) * 1; + // CHECK-NEXT: * _d_i += _t0 * 1; // CHECK-NEXT: * _d_i += 1 * j; // CHECK-NEXT: * _d_j += i * 1; // CHECK-NEXT: } @@ -133,12 +139,14 @@ public: } // CHECK: void const_volatile_lval_ref_mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) const volatile & { + // CHECK-NEXT: double _t0; + // CHECK-NEXT: _t0 = (this->x + this->y); // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { // CHECK-NEXT: (* _d_this).x += 1 * i; // CHECK-NEXT: (* _d_this).y += 1 * i; - // CHECK-NEXT: * _d_i += (this->x + this->y) * 1; + // CHECK-NEXT: * _d_i += _t0 * 1; // CHECK-NEXT: * _d_i += 1 * j; // CHECK-NEXT: * _d_j += i * 1; // CHECK-NEXT: } @@ -179,12 +187,14 @@ public: } // CHECK: void volatile_rval_ref_mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) volatile && { + // CHECK-NEXT: double _t0; + // CHECK-NEXT: _t0 = (this->x + this->y); // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { // CHECK-NEXT: (* _d_this).x += 1 * i; // CHECK-NEXT: (* _d_this).y += 1 * i; - // CHECK-NEXT: * _d_i += (this->x + this->y) * 1; + // CHECK-NEXT: * _d_i += _t0 * 1; // CHECK-NEXT: * _d_i += 1 * j; // CHECK-NEXT: * _d_j += i * 1; // CHECK-NEXT: } @@ -195,12 +205,14 @@ public: } // CHECK: void const_volatile_rval_ref_mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) const volatile && { + // CHECK-NEXT: double _t0; + // CHECK-NEXT: _t0 = (this->x + this->y); // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { // CHECK-NEXT: (* _d_this).x += 1 * i; // CHECK-NEXT: (* _d_this).y += 1 * i; - // CHECK-NEXT: * _d_i += (this->x + this->y) * 1; + // CHECK-NEXT: * _d_i += _t0 * 1; // CHECK-NEXT: * _d_i += 1 * j; // CHECK-NEXT: * _d_j += i * 1; // CHECK-NEXT: } @@ -243,12 +255,14 @@ public: } // CHECK: void volatile_noexcept_mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) volatile noexcept { + // CHECK-NEXT: double _t0; + // CHECK-NEXT: _t0 = (this->x + this->y); // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { // CHECK-NEXT: (* _d_this).x += 1 * i; // CHECK-NEXT: (* _d_this).y += 1 * i; - // CHECK-NEXT: * _d_i += (this->x + this->y) * 1; + // CHECK-NEXT: * _d_i += _t0 * 1; // CHECK-NEXT: * _d_i += 1 * j; // CHECK-NEXT: * _d_j += i * 1; // CHECK-NEXT: } @@ -259,12 +273,14 @@ public: } // CHECK: void const_volatile_noexcept_mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) const volatile noexcept { + // CHECK-NEXT: double _t0; + // CHECK-NEXT: _t0 = (this->x + this->y); // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { // CHECK-NEXT: (* _d_this).x += 1 * i; // CHECK-NEXT: (* _d_this).y += 1 * i; - // CHECK-NEXT: * _d_i += (this->x + this->y) * 1; + // CHECK-NEXT: * _d_i += _t0 * 1; // CHECK-NEXT: * _d_i += 1 * j; // CHECK-NEXT: * _d_j += i * 1; // CHECK-NEXT: } @@ -307,12 +323,14 @@ public: } // CHECK: void volatile_lval_ref_noexcept_mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) volatile & noexcept { + // CHECK-NEXT: double _t0; + // CHECK-NEXT: _t0 = (this->x + this->y); // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { // CHECK-NEXT: (* _d_this).x += 1 * i; // CHECK-NEXT: (* _d_this).y += 1 * i; - // CHECK-NEXT: * _d_i += (this->x + this->y) * 1; + // CHECK-NEXT: * _d_i += _t0 * 1; // CHECK-NEXT: * _d_i += 1 * j; // CHECK-NEXT: * _d_j += i * 1; // CHECK-NEXT: } @@ -323,12 +341,14 @@ public: } // CHECK: void const_volatile_lval_ref_noexcept_mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) const volatile & noexcept { + // CHECK-NEXT: double _t0; + // CHECK-NEXT: _t0 = (this->x + this->y); // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { // CHECK-NEXT: (* _d_this).x += 1 * i; // CHECK-NEXT: (* _d_this).y += 1 * i; - // CHECK-NEXT: * _d_i += (this->x + this->y) * 1; + // CHECK-NEXT: * _d_i += _t0 * 1; // CHECK-NEXT: * _d_i += 1 * j; // CHECK-NEXT: * _d_j += i * 1; // CHECK-NEXT: } @@ -371,12 +391,14 @@ public: } // CHECK: void volatile_rval_ref_noexcept_mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) volatile && noexcept { + // CHECK-NEXT: double _t0; + // CHECK-NEXT: _t0 = (this->x + this->y); // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { // CHECK-NEXT: (* _d_this).x += 1 * i; // CHECK-NEXT: (* _d_this).y += 1 * i; - // CHECK-NEXT: * _d_i += (this->x + this->y) * 1; + // CHECK-NEXT: * _d_i += _t0 * 1; // CHECK-NEXT: * _d_i += 1 * j; // CHECK-NEXT: * _d_j += i * 1; // CHECK-NEXT: } @@ -387,12 +409,14 @@ public: } // CHECK: void const_volatile_rval_ref_noexcept_mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) const volatile && noexcept { + // CHECK-NEXT: double _t0; + // CHECK-NEXT: _t0 = (this->x + this->y); // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { // CHECK-NEXT: (* _d_this).x += 1 * i; // CHECK-NEXT: (* _d_this).y += 1 * i; - // CHECK-NEXT: * _d_i += (this->x + this->y) * 1; + // CHECK-NEXT: * _d_i += _t0 * 1; // CHECK-NEXT: * _d_i += 1 * j; // CHECK-NEXT: * _d_j += i * 1; // CHECK-NEXT: } @@ -654,12 +678,14 @@ int main() { // CHECK: void const_volatile_lval_ref_mem_fn_grad_0(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i) const volatile & { // CHECK-NEXT: double _d_j = 0; + // CHECK-NEXT: double _t0; + // CHECK-NEXT: _t0 = (this->x + this->y); // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { // CHECK-NEXT: (* _d_this).x += 1 * i; // CHECK-NEXT: (* _d_this).y += 1 * i; - // CHECK-NEXT: * _d_i += (this->x + this->y) * 1; + // CHECK-NEXT: * _d_i += _t0 * 1; // CHECK-NEXT: * _d_i += 1 * j; // CHECK-NEXT: _d_j += i * 1; // CHECK-NEXT: } @@ -669,12 +695,14 @@ int main() { // CHECK: void const_volatile_rval_ref_mem_fn_grad_1(double i, double j, clad::array_ref _d_this, clad::array_ref _d_j) const volatile && { // CHECK-NEXT: double _d_i = 0; + // CHECK-NEXT: double _t0; + // CHECK-NEXT: _t0 = (this->x + this->y); // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { // CHECK-NEXT: (* _d_this).x += 1 * i; // CHECK-NEXT: (* _d_this).y += 1 * i; - // CHECK-NEXT: _d_i += (this->x + this->y) * 1; + // CHECK-NEXT: _d_i += _t0 * 1; // CHECK-NEXT: _d_i += 1 * j; // CHECK-NEXT: * _d_j += i * 1; // CHECK-NEXT: } diff --git a/test/Gradient/TemplateFunctors.C b/test/Gradient/TemplateFunctors.C index ebd824f1d..cf7783b7b 100644 --- a/test/Gradient/TemplateFunctors.C +++ b/test/Gradient/TemplateFunctors.C @@ -59,12 +59,14 @@ template struct ExperimentConstVolatile { }; // CHECK: void operator_call_grad(double i, double j, clad::array_ref > _d_this, clad::array_ref _d_i, clad::array_ref _d_j) const volatile { +// CHECK-NEXT: double _t0; +// CHECK-NEXT: _t0 = this->x * i; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { // CHECK-NEXT: (* _d_this).x += 1 * i * i; // CHECK-NEXT: * _d_i += this->x * 1 * i; -// CHECK-NEXT: * _d_i += this->x * i * 1; +// CHECK-NEXT: * _d_i += _t0 * 1; // CHECK-NEXT: (* _d_this).y += 1 * j; // CHECK-NEXT: * _d_j += this->y * 1; // CHECK-NEXT: } @@ -81,16 +83,20 @@ template <> struct ExperimentConstVolatile { }; // CHECK: void operator_call_grad(long double i, long double j, clad::array_ref > _d_this, clad::array_ref _d_i, clad::array_ref _d_j) const volatile { +// CHECK-NEXT: double _t0; +// CHECK-NEXT: double _t1; +// CHECK-NEXT: _t0 = this->x * i; +// CHECK-NEXT: _t1 = this->y * j; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { // CHECK-NEXT: (* _d_this).x += 1 * j * i * i; // CHECK-NEXT: * _d_i += this->x * 1 * j * i; -// CHECK-NEXT: * _d_i += this->x * i * 1 * j; -// CHECK-NEXT: * _d_j += this->x * i * i * 1; +// CHECK-NEXT: * _d_i += _t0 * 1 * j; +// CHECK-NEXT: * _d_j += _t0 * i * 1; // CHECK-NEXT: (* _d_this).y += 1 * i * j; // CHECK-NEXT: * _d_j += this->y * 1 * i; -// CHECK-NEXT: * _d_i += this->y * j * 1; +// CHECK-NEXT: * _d_i += _t1 * 1; // CHECK-NEXT: } // CHECK-NEXT: } diff --git a/test/Gradient/constexprTest.C b/test/Gradient/constexprTest.C index 6c103b3cb..aee824e3e 100644 --- a/test/Gradient/constexprTest.C +++ b/test/Gradient/constexprTest.C @@ -33,21 +33,19 @@ constexpr double fn( double a, double b, double c) { //CHECK: constexpr void fn_grad(double a, double b, double c, clad::array_ref _d_a, clad::array_ref _d_b, clad::array_ref _d_c) { //CHECK-NEXT: double _d_val = 0; -//CHECK-NEXT: double _t0; //CHECK-NEXT: double _d_result = 0; //CHECK-NEXT: double val = 98.; -//CHECK-NEXT: _t0 = c; -//CHECK-NEXT: double result = a * b / _t0 * (a + b) * 100 + c; +//CHECK-NEXT: double result = a * b / c * (a + b) * 100 + c; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: _d_result += 1; //CHECK-NEXT: { -//CHECK-NEXT: * _d_a += _d_result * 100 * (a + b) / _t0 * b; -//CHECK-NEXT: * _d_b += a * _d_result * 100 * (a + b) / _t0; -//CHECK-NEXT: double _r0 = _d_result * 100 * (a + b) * -a * b / (_t0 * _t0); +//CHECK-NEXT: * _d_a += _d_result * 100 * (a + b) / c * b; +//CHECK-NEXT: * _d_b += a * _d_result * 100 * (a + b) / c; +//CHECK-NEXT: double _r0 = _d_result * 100 * (a + b) * -a * b / (c * c); //CHECK-NEXT: * _d_c += _r0; -//CHECK-NEXT: * _d_a += a * b / _t0 * _d_result * 100; -//CHECK-NEXT: * _d_b += a * b / _t0 * _d_result * 100; +//CHECK-NEXT: * _d_a += a * b / c * _d_result * 100; +//CHECK-NEXT: * _d_b += a * b / c * _d_result * 100; //CHECK-NEXT: * _d_c += _d_result; //CHECK-NEXT: } //CHECK-NEXT:} diff --git a/test/Hessian/BuiltinDerivatives.C b/test/Hessian/BuiltinDerivatives.C index 765846e49..40a512602 100644 --- a/test/Hessian/BuiltinDerivatives.C +++ b/test/Hessian/BuiltinDerivatives.C @@ -21,6 +21,8 @@ float f1(float x) { // CHECK-NEXT: } // CHECK: void sin_pushforward_pullback(float x, float d_x, ValueAndPushforward _d_y, clad::array_ref _d_x, clad::array_ref _d_d_x) { +// CHECK-NEXT: float _t0; +// CHECK-NEXT: _t0 = ::std::cos(x); // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { @@ -28,7 +30,7 @@ float f1(float x) { // CHECK-NEXT: * _d_x += _r0; // CHECK-NEXT: float _r1 = _d_y.pushforward * d_x * clad::custom_derivatives{{(::std)?}}::cos_pushforward(x, 1.F).pushforward; // CHECK-NEXT: * _d_x += _r1; -// CHECK-NEXT: * _d_d_x += ::std::cos(x) * _d_y.pushforward; +// CHECK-NEXT: * _d_d_x += _t0 * _d_y.pushforward; // CHECK-NEXT: } // CHECK-NEXT: } @@ -94,6 +96,8 @@ float f2(float x) { // CHECK-NEXT: } // CHECK: void exp_pushforward_pullback(float x, float d_x, ValueAndPushforward _d_y, clad::array_ref _d_x, clad::array_ref _d_d_x) { +// CHECK-NEXT: float _t0; +// CHECK-NEXT: _t0 = ::std::exp(x); // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { @@ -101,7 +105,7 @@ float f2(float x) { // CHECK-NEXT: * _d_x += _r0; // CHECK-NEXT: float _r1 = _d_y.pushforward * d_x * clad::custom_derivatives{{(::std)?}}::exp_pushforward(x, 1.F).pushforward; // CHECK-NEXT: * _d_x += _r1; -// CHECK-NEXT: * _d_d_x += ::std::exp(x) * _d_y.pushforward; +// CHECK-NEXT: * _d_d_x += _t0 * _d_y.pushforward; // CHECK-NEXT: } // CHECK-NEXT: } @@ -140,16 +144,14 @@ float f3(float x) { // CHECK-NEXT: } // CHECK: void log_pushforward_pullback(float x, float d_x, ValueAndPushforward _d_y, clad::array_ref _d_x, clad::array_ref _d_d_x) { -// CHECK-NEXT: double _t0; -// CHECK-NEXT: _t0 = x; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { // CHECK-NEXT: float _r0 = _d_y.value * clad::custom_derivatives{{(::std)?}}::log_pushforward(x, 1.F).pushforward; // CHECK-NEXT: * _d_x += _r0; -// CHECK-NEXT: double _r1 = _d_y.pushforward * d_x * -1. / (_t0 * _t0); +// CHECK-NEXT: double _r1 = _d_y.pushforward * d_x * -1. / (x * x); // CHECK-NEXT: * _d_x += _r1; -// CHECK-NEXT: * _d_d_x += (1. / _t0) * _d_y.pushforward; +// CHECK-NEXT: * _d_d_x += (1. / x) * _d_y.pushforward; // CHECK-NEXT: } // CHECK-NEXT: } @@ -194,14 +196,16 @@ float f4(float x) { // CHECK-NEXT: float _cond0; // CHECK-NEXT: float _t1; // CHECK-NEXT: float _t2; +// CHECK-NEXT: float _t3; // CHECK-NEXT: float val = ::std::pow(x, exponent); // CHECK-NEXT: _t0 = ::std::pow(x, exponent - 1); // CHECK-NEXT: float derivative = (exponent * _t0) * d_x; // CHECK-NEXT: _cond0 = d_exponent; // CHECK-NEXT: if (_cond0) { // CHECK-NEXT: _t1 = derivative; +// CHECK-NEXT: _t3 = ::std::pow(x, exponent); // CHECK-NEXT: _t2 = ::std::log(x); -// CHECK-NEXT: derivative += (::std::pow(x, exponent) * _t2) * d_exponent; +// CHECK-NEXT: derivative += (_t3 * _t2) * d_exponent; // CHECK-NEXT: } // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: @@ -219,9 +223,9 @@ float f4(float x) { // CHECK-NEXT: * _d_x += _r4; // CHECK-NEXT: float _r5 = _grad5; // CHECK-NEXT: * _d_exponent += _r5; -// CHECK-NEXT: float _r6 = ::std::pow(x, exponent) * _r_d0 * d_exponent * clad::custom_derivatives{{(::std)?}}::log_pushforward(x, 1.F).pushforward; +// CHECK-NEXT: float _r6 = _t3 * _r_d0 * d_exponent * clad::custom_derivatives{{(::std)?}}::log_pushforward(x, 1.F).pushforward; // CHECK-NEXT: * _d_x += _r6; -// CHECK-NEXT: * _d_d_exponent += (::std::pow(x, exponent) * _t2) * _r_d0; +// CHECK-NEXT: * _d_d_exponent += (_t3 * _t2) * _r_d0; // CHECK-NEXT: } // CHECK-NEXT: { // CHECK-NEXT: * _d_exponent += _d_derivative * d_x * _t0; diff --git a/test/Jacobian/Functors.C b/test/Jacobian/Functors.C index de53a00cf..33fff79d6 100644 --- a/test/Jacobian/Functors.C +++ b/test/Jacobian/Functors.C @@ -72,17 +72,21 @@ struct ExperimentVolatile { } // CHECK: void operator_call_jac(double i, double j, double *output, double *jacobianMatrix) volatile { + // CHECK-NEXT: double _t0; + // CHECK-NEXT: double _t1; + // CHECK-NEXT: _t0 = this->x * i; // CHECK-NEXT: output[0] = this->x * i * i * j; + // CHECK-NEXT: _t1 = this->y * i; // CHECK-NEXT: output[1] = this->y * i * j * j; // CHECK-NEXT: { // CHECK-NEXT: jacobianMatrix[2UL] += this->y * 1 * j * j; - // CHECK-NEXT: jacobianMatrix[3UL] += this->y * i * 1 * j; - // CHECK-NEXT: jacobianMatrix[3UL] += this->y * i * j * 1; + // CHECK-NEXT: jacobianMatrix[3UL] += _t1 * 1 * j; + // CHECK-NEXT: jacobianMatrix[3UL] += _t1 * j * 1; // CHECK-NEXT: } // CHECK-NEXT: { // CHECK-NEXT: jacobianMatrix[0UL] += this->x * 1 * j * i; - // CHECK-NEXT: jacobianMatrix[0UL] += this->x * i * 1 * j; - // CHECK-NEXT: jacobianMatrix[1UL] += this->x * i * i * 1; + // CHECK-NEXT: jacobianMatrix[0UL] += _t0 * 1 * j; + // CHECK-NEXT: jacobianMatrix[1UL] += _t0 * i * 1; // CHECK-NEXT: } // CHECK-NEXT: } }; @@ -99,17 +103,21 @@ struct ExperimentConstVolatile { } // CHECK: void operator_call_jac(double i, double j, double *output, double *jacobianMatrix) const volatile { + // CHECK-NEXT: double _t0; + // CHECK-NEXT: double _t1; + // CHECK-NEXT: _t0 = this->x * i; // CHECK-NEXT: output[0] = this->x * i * i * j; + // CHECK-NEXT: _t1 = this->y * i; // CHECK-NEXT: output[1] = this->y * i * j * j; // CHECK-NEXT: { // CHECK-NEXT: jacobianMatrix[2UL] += this->y * 1 * j * j; - // CHECK-NEXT: jacobianMatrix[3UL] += this->y * i * 1 * j; - // CHECK-NEXT: jacobianMatrix[3UL] += this->y * i * j * 1; + // CHECK-NEXT: jacobianMatrix[3UL] += _t1 * 1 * j; + // CHECK-NEXT: jacobianMatrix[3UL] += _t1 * j * 1; // CHECK-NEXT: } // CHECK-NEXT: { // CHECK-NEXT: jacobianMatrix[0UL] += this->x * 1 * j * i; - // CHECK-NEXT: jacobianMatrix[0UL] += this->x * i * 1 * j; - // CHECK-NEXT: jacobianMatrix[1UL] += this->x * i * i * 1; + // CHECK-NEXT: jacobianMatrix[0UL] += _t0 * 1 * j; + // CHECK-NEXT: jacobianMatrix[1UL] += _t0 * i * 1; // CHECK-NEXT: } // CHECK-NEXT: } }; diff --git a/test/Jacobian/Jacobian.C b/test/Jacobian/Jacobian.C index 667ecc001..625aa94b8 100644 --- a/test/Jacobian/Jacobian.C +++ b/test/Jacobian/Jacobian.C @@ -52,9 +52,15 @@ void f_3(double x, double y, double z, double *_result) { void f_3_jac(double x, double y, double z, double *_result, double *jacobianMatrix); //CHECK: void f_3_jac(double x, double y, double z, double *_result, double *jacobianMatrix) { //CHECK-NEXT: double _d_constant = 0; +//CHECK-NEXT: double _t0; +//CHECK-NEXT: double _t1; +//CHECK-NEXT: double _t2; //CHECK-NEXT: double constant = 42; +//CHECK-NEXT: _t0 = sin(x); //CHECK-NEXT: _result[0] = sin(x) * constant; +//CHECK-NEXT: _t1 = sin(y); //CHECK-NEXT: _result[1] = sin(y) * constant; +//CHECK-NEXT: _t2 = sin(z); //CHECK-NEXT: _result[2] = sin(z) * constant; //CHECK-NEXT: { //CHECK-NEXT: double _r2 = 1 * constant * clad::custom_derivatives::sin_pushforward(z, 1.).pushforward; @@ -91,9 +97,15 @@ void f_4(double x, double y, double z, double *_result) { void f_4_jac(double x, double y, double z, double *_result, double *jacobianMatrix); //CHECK: void f_4_jac(double x, double y, double z, double *_result, double *jacobianMatrix) { //CHECK-NEXT: double _d_constant = 0; +//CHECK-NEXT: double _t0; +//CHECK-NEXT: double _t1; +//CHECK-NEXT: double _t2; //CHECK-NEXT: double constant = 42; +//CHECK-NEXT: _t0 = multiply(x, y); //CHECK-NEXT: _result[0] = multiply(x, y) * constant; +//CHECK-NEXT: _t1 = multiply(y, z); //CHECK-NEXT: _result[1] = multiply(y, z) * constant; +//CHECK-NEXT: _t2 = multiply(z, x); //CHECK-NEXT: _result[2] = multiply(z, x) * constant; //CHECK-NEXT: { //CHECK-NEXT: double _jac4 = 0.;