From 80052c54b2b5987fd959fcb914ce8a1ea6d9fc1e Mon Sep 17 00:00:00 2001 From: "petro.zarytskyi" Date: Fri, 16 Feb 2024 16:50:48 +0200 Subject: [PATCH] Simplify error estimation by removing _EERepl_ and _delta_ --- include/clad/Differentiator/ErrorEstimator.h | 105 +----- .../clad/Differentiator/ExternalRMVSource.h | 5 +- .../MultiplexExternalRMVSource.h | 3 +- lib/Differentiator/ErrorEstimator.cpp | 310 +++--------------- .../MultiplexExternalRMVSource.cpp | 5 +- lib/Differentiator/ReverseModeVisitor.cpp | 2 +- test/ErrorEstimation/Assignments.C | 60 +--- test/ErrorEstimation/BasicOps.C | 144 +++----- test/ErrorEstimation/ConditonalStatements.C | 57 +--- test/ErrorEstimation/LoopsAndArrays.C | 140 ++------ test/ErrorEstimation/LoopsAndArraysExec.C | 73 +---- test/Misc/RunDemos.C | 42 +-- 12 files changed, 193 insertions(+), 753 deletions(-) diff --git a/include/clad/Differentiator/ErrorEstimator.h b/include/clad/Differentiator/ErrorEstimator.h index 1de49ad0b..9a0187901 100644 --- a/include/clad/Differentiator/ErrorEstimator.h +++ b/include/clad/Differentiator/ErrorEstimator.h @@ -27,8 +27,6 @@ class ErrorEstimationHandler : public ExternalRMVSource { // multiple header files. // `Stmts` is originally defined in `VisitorBase`. using Stmts = llvm::SmallVector; - /// Keeps a track of the delta error expression we shouldn't emit. - bool m_DoNotEmitDelta; /// Reference to the final error parameter in the augumented target /// function. clang::Expr* m_FinalError; @@ -42,22 +40,19 @@ class ErrorEstimationHandler : public ExternalRMVSource { Stmts m_ReverseErrorStmts; /// The index expression for emitting final errors for input param errors. clang::Expr* m_IdxExpr; - /// A set of declRefExprs for parameter value replacements. - std::unordered_map m_ParamRepls; /// An expression to match nested function call errors with their /// assignee (if any exists). clang::Expr* m_NestedFuncError = nullptr; std::stack m_ShouldEmit; ReverseModeVisitor* m_RMV; - clang::Expr* m_DeltaVar = nullptr; llvm::SmallVectorImpl* m_ParamTypes = nullptr; llvm::SmallVectorImpl* m_Params = nullptr; public: using direction = rmv::direction; ErrorEstimationHandler() - : m_DoNotEmitDelta(false), m_FinalError(nullptr), m_RetErrorExpr(nullptr), + : m_FinalError(nullptr), m_RetErrorExpr(nullptr), m_EstModel(nullptr), m_IdxExpr(nullptr) {} ~ErrorEstimationHandler() override = default; @@ -81,22 +76,16 @@ class ErrorEstimationHandler : public ExternalRMVSource { clang::Expr* getArraySubscriptExpr(clang::Expr* arrBase, clang::Expr* idx, bool isCladSpType = true); - /// \returns The final error expression so far. - clang::Expr* GetFinalErrorExpr() { return m_FinalError; } - - /// Function to build the final error statemnt of the function. This is the - /// last statement of any target function in error estimation and - /// aggregates the error in all the registered variables. - void BuildFinalErrorStmt(); + /// Function to build the error statement corresponding + /// to the function's return statement. + void BuildReturnErrorStmt(); /// Function to emit error statements into the derivative body. /// - /// \param[in] var The variable whose error statement we want to emit. - /// \param[in] deltaVar The "_delta_" expression of the variable 'var'. - /// \param[in] errorExpr The error expression (LHS) of the variable 'var'. - /// \param[in] isInsideLoop A flag to indicate if 'val' is inside a loop. - void AddErrorStmtToBlock(clang::Expr* var, clang::Expr* deltaVar, - clang::Expr* errorExpr, bool isInsideLoop = false); + /// \param[in] errorExpr The error expression (LHS) of the variable. + /// \param[in] addToTheFront A flag to decide whether the error stmts + /// should be added to the beginning of the block or the current position. + void AddErrorStmtToBlock(clang::Expr* errorExpr, bool addToTheFront=true); /// Emit the error estimation related statements that were saved to be /// emitted at later points into specific blocks. @@ -124,44 +113,12 @@ class ErrorEstimationHandler : public ExternalRMVSource { llvm::SmallVectorImpl& CallArgs, llvm::SmallVectorImpl& ArgResultDecls, size_t numArgs); - /// Save values of registered variables so that they can be replaced - /// properly in case of re-assignments. - /// - /// \param[in] val The value to save. - /// \param[in] isInsideLoop A flag to indicate if 'val' is inside a loop. - /// - /// \returns The saved variable and its derivative. - StmtDiff SaveValue(clang::Expr* val, bool isInLoop = false); - - /// Save the orignal values of the input parameters in case of - /// re-assignments. - /// - /// \param[in] paramRef The DeclRefExpr of the input parameter. - void SaveParamValue(clang::DeclRefExpr* paramRef); - - /// Register variables to be used while accumulating error. - /// Register variable declarations so that they may be used while - /// calculating the final error estimates. Any unregistered variables will - /// not be considered for the final estimation. + /// Checks if a variable should be considered in error estimation. /// - /// \param[in] VD The variable declaration to be registered. - /// \param[in] toCurrentScope Add the created "_delta_" variable declaration - /// to the current scope instead of the global scope. + /// \param[in] VD The variable declaration. /// - /// \returns The Variable declaration of the '_delta_' prefixed variable. - clang::Expr* RegisterVariable(clang::VarDecl* VD, - bool toCurrentScope = false); - - /// Checks if a variable can be registered for error estimation. - /// - /// \param[in] VD The variable declaration to be registered. - /// - /// \returns True if the variable can be registered, false otherwise. - bool CanRegisterVariable(clang::VarDecl* VD); - - /// Calculate aggregate error from m_EstimateVar. - /// Builds the final error estimation statement. - clang::Stmt* CalculateAggregateError(); + /// \returns true if the variable should be considered, false otherwise. + bool ShouldEstimateErrorFor(clang::VarDecl* VD); /// Get the underlying DeclRefExpr type it it exists. /// @@ -170,14 +127,6 @@ class ErrorEstimationHandler : public ExternalRMVSource { /// \returns The DeclRefExpr of input or null. clang::DeclRefExpr* GetUnderlyingDeclRefOrNull(clang::Expr* expr); - /// Get the parameter replacement (if any). - /// - /// \param[in] VD The parameter variable declaration to get replacement - /// for. - /// - /// \returns The underlying replaced Expr. - clang::Expr* GetParamReplacement(const clang::ParmVarDecl* VD); - /// An abstraction of the error estimation model's AssignError. /// /// \param[in] val The variable to get the error for. @@ -190,16 +139,6 @@ class ErrorEstimationHandler : public ExternalRMVSource { return m_EstModel->AssignError({var, varDiff}, varName); } - /// An abstraction of the error estimation model's IsVariableRegistered. - /// - /// \param[in] VD The variable declaration to check the status of. - /// - /// \returns the reference to the respective '_delta_' expression if the - /// variable is registered, null otherwise. - clang::Expr* IsRegistered(clang::VarDecl* VD) { - return m_EstModel->IsVariableRegistered(VD); - } - /// This function adds the final error and the other parameter errors to the /// forward block. /// @@ -215,17 +154,6 @@ class ErrorEstimationHandler : public ExternalRMVSource { /// loop. void EmitUnaryOpErrorStmts(StmtDiff var, bool isInsideLoop); - /// This function registers all LHS declRefExpr in binary operations. - /// - /// \param[in] LExpr The LHS of the operation. - /// \param[in] RExpr The RHS of the operation. - /// \param[in] isAssign A flag to know if the current operation is a simple - /// assignment. - /// - /// \returns The delta value of the input 'var'. - clang::Expr* RegisterBinaryOpLHS(clang::Expr* LExpr, clang::Expr* RExpr, - bool isAssign); - /// This function emits the error in a binary operation. /// /// \param[in] LExpr The LHS of the operation. @@ -234,8 +162,7 @@ class ErrorEstimationHandler : public ExternalRMVSource { /// \param[in] deltaVar The delta value of the LHS. /// \param[in] isInsideLoop A flag to keep track of if we are inside a /// loop. - void EmitBinaryOpErrorStmts(clang::Expr* LExpr, clang::Expr* oldValue, - clang::Expr* deltaVar, bool isInsideLoop); + void EmitBinaryOpErrorStmts(clang::Expr* LExpr, clang::Expr* oldValue); /// This function emits the error in declaration statements. /// @@ -267,10 +194,8 @@ class ErrorEstimationHandler : public ExternalRMVSource { llvm::SmallVectorImpl& derivedCallArgs, llvm::SmallVectorImpl& ArgResultDecls, bool asGrad) override; - void - ActAfterCloningLHSOfAssignOp(clang::Expr*& LCloned, clang::Expr*& R, - clang::BinaryOperator::Opcode& opCode) override; - void ActBeforeFinalisingAssignOp(clang::Expr*&, clang::Expr*&) override; + void ActBeforeFinalisingAssignOp(clang::Expr*&, clang::Expr*&, clang::Expr*&, + clang::BinaryOperator::Opcode&) override; void ActBeforeFinalizingDifferentiateSingleStmt(const direction& d) override; void ActBeforeFinalizingDifferentiateSingleExpr(const direction& d) override; void ActBeforeDifferentiatingCallExpr( diff --git a/include/clad/Differentiator/ExternalRMVSource.h b/include/clad/Differentiator/ExternalRMVSource.h index b5fcde1ab..cf9cb536a 100644 --- a/include/clad/Differentiator/ExternalRMVSource.h +++ b/include/clad/Differentiator/ExternalRMVSource.h @@ -138,8 +138,9 @@ class ExternalRMVSource { clang::BinaryOperatorKind& opCode) { } - /// This is called just after finaising processing of assignment operator. - virtual void ActBeforeFinalisingAssignOp(clang::Expr*&, clang::Expr*&){}; + /// This is called just after finalising processing of assignment operator. + virtual void ActBeforeFinalisingAssignOp(clang::Expr*&, clang::Expr*&, clang::Expr*&, + clang::BinaryOperator::Opcode&){}; /// This is called at that beginning of /// `ReverseModeVisitor::DifferentiateSingleStmt`. diff --git a/include/clad/Differentiator/MultiplexExternalRMVSource.h b/include/clad/Differentiator/MultiplexExternalRMVSource.h index 7864828b0..6a8145255 100644 --- a/include/clad/Differentiator/MultiplexExternalRMVSource.h +++ b/include/clad/Differentiator/MultiplexExternalRMVSource.h @@ -53,7 +53,8 @@ class MultiplexExternalRMVSource : public ExternalRMVSource { void ActBeforeFinalisingPostIncDecOp(StmtDiff& diff) override; void ActAfterCloningLHSOfAssignOp(clang::Expr*&, clang::Expr*&, clang::BinaryOperatorKind& opCode) override; - void ActBeforeFinalisingAssignOp(clang::Expr*&, clang::Expr*&) override; + void ActBeforeFinalisingAssignOp(clang::Expr*&, clang::Expr*&, clang::Expr*&, + clang::BinaryOperator::Opcode&) override; void ActOnStartOfDifferentiateSingleStmt() override; void ActBeforeFinalizingDifferentiateSingleStmt(const direction& d) override; void ActBeforeFinalizingDifferentiateSingleExpr(const direction& d) override; diff --git a/lib/Differentiator/ErrorEstimator.cpp b/lib/Differentiator/ErrorEstimator.cpp index cbab2a49e..588ca402a 100644 --- a/lib/Differentiator/ErrorEstimator.cpp +++ b/lib/Differentiator/ErrorEstimator.cpp @@ -53,51 +53,29 @@ Expr* ErrorEstimationHandler::getArraySubscriptExpr( } } -void ErrorEstimationHandler::BuildFinalErrorStmt() { - Expr* finExpr = nullptr; +void ErrorEstimationHandler::BuildReturnErrorStmt() { // If we encountered any arithmetic expression in the return statement, // we must add its error to the final estimate. if (m_RetErrorExpr) { auto flitr = FloatingLiteral::Create(m_RMV->m_Context, llvm::APFloat(1.0), true, m_RMV->m_Context.DoubleTy, noLoc); - finExpr = + Expr* finExpr = m_EstModel->AssignError(StmtDiff(m_RetErrorExpr, flitr), "return_expr"); + m_RMV->addToCurrentBlock( + m_RMV->BuildOp(BO_AddAssign, m_FinalError, finExpr), + direction::forward); } - - // Build the final error statement with the sum of all _delta_*. - Expr* addErrorExpr = m_EstModel->CalculateAggregateError(); - if (addErrorExpr) { - if (finExpr) - addErrorExpr = m_RMV->BuildOp(BO_Add, addErrorExpr, finExpr); - } else if (finExpr) { - addErrorExpr = finExpr; - } - - // Finally add the final error expression to the derivative body. - m_RMV->addToCurrentBlock( - m_RMV->BuildOp(BO_AddAssign, m_FinalError, addErrorExpr), - direction::forward); } -void ErrorEstimationHandler::AddErrorStmtToBlock(Expr* var, Expr* deltaVar, - Expr* errorExpr, - bool isInsideLoop /*=false*/) { - - if (auto ASE = dyn_cast(var)) { - deltaVar = getArraySubscriptExpr(deltaVar, ASE->getIdx()); - m_RMV->addToCurrentBlock(m_RMV->BuildOp(BO_AddAssign, deltaVar, errorExpr), - direction::reverse); - // immediately emit fin_err += delta_[]. - // This is done to avoid adding all errors at the end - // and only add the errors that were calculated. - m_RMV->addToCurrentBlock( - m_RMV->BuildOp(BO_AddAssign, m_FinalError, deltaVar), - direction::reverse); - - } else - m_RMV->addToCurrentBlock(m_RMV->BuildOp(BO_AddAssign, deltaVar, errorExpr), - direction::reverse); +void ErrorEstimationHandler::AddErrorStmtToBlock(Expr* errorExpr, bool addToTheFront) { + Stmt* errorStmt = m_RMV->BuildOp(BO_AddAssign, m_FinalError, errorExpr); + if (addToTheFront) { + auto &block = m_RMV->getCurrentBlock(direction::reverse); + block.insert(block.begin(), errorStmt); + } else { + m_RMV->addToCurrentBlock(errorStmt, direction::reverse); + } } void ErrorEstimationHandler::EmitErrorEstimationStmts( @@ -152,117 +130,7 @@ void ErrorEstimationHandler::EmitNestedFunctionParamError( } } -StmtDiff ErrorEstimationHandler::SaveValue(Expr* val, - bool isInsideLoop /*=false*/) { - // Definite not null. - DeclRefExpr* declRefVal = GetUnderlyingDeclRefOrNull(val); - assert(declRefVal && "Val cannot be null!"); - std::string name = "_EERepl_" + declRefVal->getDecl()->getNameAsString(); - if (isInsideLoop) { - auto tape = m_RMV->MakeCladTapeFor(val, name); - m_ForwardReplStmts.push_back(tape.Push); - // Nice to store pop values becuase user might refer to getExpr - // multiple times in Assign Error. - Expr* popVal = m_RMV->StoreAndRef(tape.Pop, direction::reverse); - return StmtDiff(tape.Push, popVal); - } else { - QualType QTval = val->getType(); - if (auto AType = dyn_cast(QTval)) - QTval = AType->getElementType(); - - auto savedVD = m_RMV->GlobalStoreImpl(QTval, name); - auto savedRef = m_RMV->BuildDeclRef(savedVD); - m_ForwardReplStmts.push_back(m_RMV->BuildOp(BO_Assign, savedRef, val)); - return StmtDiff(savedRef, savedRef); - } -} - -void ErrorEstimationHandler::SaveParamValue(DeclRefExpr* paramRef) { - assert(paramRef && "Must have a value"); - VarDecl* paramDecl = cast(paramRef->getDecl()); - QualType paramType = paramRef->getType(); - std::string name = "_EERepl_" + paramDecl->getNameAsString(); - VarDecl* savedDecl; - if (utils::isArrayOrPointerType(paramType)) { - auto diffVar = m_RMV->m_Variables[paramDecl]; - auto QType = m_RMV->GetCladArrayOfType( - getUnderlyingArrayType(paramType, m_RMV->m_Context)); - savedDecl = m_RMV->BuildVarDecl( - QType, name, m_RMV->BuildArrayRefSizeExpr(diffVar), - /*DirectInit=*/false, - /*TSI=*/nullptr, VarDecl::InitializationStyle::CallInit); - m_RMV->AddToGlobalBlock(m_RMV->BuildDeclStmt(savedDecl)); - ReverseModeVisitor::Stmts loopBody; - // Get iter variable. - auto loopIdx = - m_RMV->BuildVarDecl(m_RMV->m_Context.IntTy, "i", - m_RMV->getZeroInit(m_RMV->m_Context.IntTy)); - auto currIdx = m_RMV->BuildDeclRef(loopIdx); - // Build the assign expression. - loopBody.push_back(m_RMV->BuildOp( - BO_Assign, - getArraySubscriptExpr(m_RMV->BuildDeclRef(savedDecl), currIdx), - getArraySubscriptExpr(paramRef, currIdx, - /*isCladSpType=*/false))); - Expr* conditionExpr = - m_RMV->BuildOp(BO_LT, currIdx, m_RMV->BuildArrayRefSizeExpr(diffVar)); - Expr* incExpr = m_RMV->BuildOp(UO_PostInc, currIdx); - // Make for loop. - Stmt* ArrayParamLoop = new (m_RMV->m_Context) ForStmt( - m_RMV->m_Context, m_RMV->BuildDeclStmt(loopIdx), conditionExpr, nullptr, - incExpr, m_RMV->MakeCompoundStmt(loopBody), noLoc, noLoc, noLoc); - m_RMV->AddToGlobalBlock(ArrayParamLoop); - } else - savedDecl = m_RMV->GlobalStoreImpl(paramType, name, paramRef); - m_ParamRepls.emplace(paramDecl, m_RMV->BuildDeclRef(savedDecl)); -} - -Expr* ErrorEstimationHandler::RegisterVariable(VarDecl* VD, - bool toCurrentScope /*=false*/) { - if (!CanRegisterVariable(VD)) - return nullptr; - // Get the init error from setError. - Expr* init = m_EstModel->SetError(VD); - auto VDType = VD->getType(); - // The type of the _delta_ value should be customisable. - QualType QType; - Expr* deltaVar = nullptr; - auto diffVar = m_RMV->m_Variables[VD]; - if (m_RMV->isCladArrayType(diffVar->getType())) { - VarDecl* EstVD; - auto sizeExpr = m_RMV->BuildArrayRefSizeExpr(diffVar); - QType = m_RMV->GetCladArrayOfType( - getUnderlyingArrayType(VDType, m_RMV->m_Context)); - EstVD = m_RMV->BuildVarDecl( - QType, "_delta_" + VD->getNameAsString(), sizeExpr, - /*DirectInit=*/false, - /*TSI=*/nullptr, VarDecl::InitializationStyle::CallInit); - if (!toCurrentScope) - m_RMV->AddToGlobalBlock(m_RMV->BuildDeclStmt(EstVD)); - else - m_RMV->addToCurrentBlock(m_RMV->BuildDeclStmt(EstVD), direction::forward); - deltaVar = m_RMV->BuildDeclRef(EstVD); - } else { - QType = utils::isArrayOrPointerType(VDType) ? VDType - : m_RMV->m_Context.DoubleTy; - init = init ? init : m_RMV->getZeroInit(QType); - // Store the "_delta_*" value. - if (!toCurrentScope) { - auto EstVD = m_RMV->GlobalStoreImpl( - QType, "_delta_" + VD->getNameAsString(), init); - deltaVar = m_RMV->BuildDeclRef(EstVD); - } else { - deltaVar = m_RMV->StoreAndRef(init, QType, direction::forward, - "_delta_" + VD->getNameAsString(), - /*forceDeclCreation=*/true); - } - } - // Register the variable for estimate calculation. - m_EstModel->AddVarToEstimate(VD, deltaVar); - return deltaVar; -} - -bool ErrorEstimationHandler::CanRegisterVariable(VarDecl* VD) { +bool ErrorEstimationHandler::ShouldEstimateErrorFor(VarDecl* VD) { // Get the types on the declartion and initalization expression. QualType varDeclBase = VD->getType(); @@ -315,44 +183,19 @@ DeclRefExpr* ErrorEstimationHandler::GetUnderlyingDeclRefOrNull(Expr* expr) { return dyn_cast(expr->IgnoreImplicit()); } -Expr* ErrorEstimationHandler::GetParamReplacement(const ParmVarDecl* VD) { - auto it = m_ParamRepls.find(VD); - if (it != m_ParamRepls.end()) - return it->second; - return nullptr; -} - void ErrorEstimationHandler::EmitFinalErrorStmts( llvm::SmallVectorImpl& params, unsigned numParams) { // Emit error variables of parameters at the end. for (size_t i = 0; i < numParams; i++) { - // Right now, we just ignore them since we have no way of knowing - // the size of an array. - // if (m_RMV->isArrayOrPointerType(params[i]->getType())) - // continue; - - // Check if the declaration was registered - auto decl = dyn_cast(params[i]); - Expr* deltaVar = IsRegistered(decl); - - // If not registered, check if it is eligible for registration and do - // the needful. - if (!deltaVar) { - deltaVar = RegisterVariable(decl, /*toCurrentScope=*/true); - } - - // If till now, we have a delta declaration, emit it into the code. - if (deltaVar) { + auto* decl = cast(params[i]); + if (ShouldEstimateErrorFor(decl)) { if (!m_RMV->isArrayOrPointerType(params[i]->getType())) { - // Since we need the input value of x, check for a replacement. - // If no replacement found, use the actual declRefExpr. - auto savedVal = GetParamReplacement(params[i]); - savedVal = savedVal ? savedVal : m_RMV->BuildDeclRef(decl); + auto* paramClone = m_RMV->BuildDeclRef(decl); // Finally emit the error. - auto errorExpr = GetError(savedVal, m_RMV->m_Variables[decl], + auto* errorExpr = GetError(paramClone, m_RMV->m_Variables[decl], params[i]->getNameAsString()); m_RMV->addToCurrentBlock( - m_RMV->BuildOp(BO_AddAssign, deltaVar, errorExpr)); + m_RMV->BuildOp(BO_AddAssign, m_FinalError, errorExpr)); } else { auto LdiffExpr = m_RMV->m_Variables[decl]; VarDecl* idxExprDecl = nullptr; @@ -363,32 +206,21 @@ void ErrorEstimationHandler::EmitFinalErrorStmts( m_RMV->getZeroInit(m_RMV->m_Context.IntTy)); m_IdxExpr = m_RMV->BuildDeclRef(idxExprDecl); } - Expr *Ldiff, *Ldelta; + Expr* Ldiff = nullptr; Ldiff = getArraySubscriptExpr( LdiffExpr, m_IdxExpr, m_RMV->isCladArrayType(LdiffExpr->getType())); - Ldelta = getArraySubscriptExpr(deltaVar, m_IdxExpr); - auto savedVal = GetParamReplacement(params[i]); - savedVal = savedVal ? savedVal : m_RMV->BuildDeclRef(decl); - auto LRepl = getArraySubscriptExpr(savedVal, m_IdxExpr); + auto* paramClone = m_RMV->BuildDeclRef(decl); + auto* LRepl = getArraySubscriptExpr(paramClone, m_IdxExpr); // Build the loop to put in reverse mode. Expr* errorExpr = GetError(LRepl, Ldiff, params[i]->getNameAsString()); - auto commonVarDecl = - m_RMV->BuildVarDecl(errorExpr->getType(), "_t", errorExpr); - Expr* commonVarExpr = m_RMV->BuildDeclRef(commonVarDecl); - Expr* deltaAssignExpr = - m_RMV->BuildOp(BO_AddAssign, Ldelta, commonVarExpr); Expr* finalAssignExpr = - m_RMV->BuildOp(BO_AddAssign, m_FinalError, commonVarExpr); - ReverseModeVisitor::Stmts loopBody; - loopBody.push_back(m_RMV->BuildDeclStmt(commonVarDecl)); - loopBody.push_back(deltaAssignExpr); - loopBody.push_back(finalAssignExpr); + m_RMV->BuildOp(BO_AddAssign, m_FinalError, errorExpr); Expr* conditionExpr = m_RMV->BuildOp( BO_LT, m_IdxExpr, m_RMV->BuildArrayRefSizeExpr(LdiffExpr)); Expr* incExpr = m_RMV->BuildOp(UO_PostInc, m_IdxExpr); Stmt* ArrayParamLoop = new (m_RMV->m_Context) ForStmt(m_RMV->m_Context, nullptr, conditionExpr, nullptr, incExpr, - m_RMV->MakeCompoundStmt(loopBody), noLoc, noLoc, noLoc); + finalAssignExpr, noLoc, noLoc, noLoc); // For multiple array parameters, we want to keep the same // iterative variable, so reset that here in the case that this // is not out first array. @@ -403,7 +235,7 @@ void ErrorEstimationHandler::EmitFinalErrorStmts( } } } - BuildFinalErrorStmt(); + BuildReturnErrorStmt(); } void ErrorEstimationHandler::EmitUnaryOpErrorStmts(StmtDiff var, @@ -412,69 +244,24 @@ void ErrorEstimationHandler::EmitUnaryOpErrorStmts(StmtDiff var, if (DeclRefExpr* DRE = GetUnderlyingDeclRefOrNull(var.getExpr())) { // First check if it was registered. // If not, we don't care about it. - if (auto deltaVar = IsRegistered(cast(DRE->getDecl()))) { - // Create a variable/tape call to store the current value of the - // the sub-expression so that it can be used later. - StmtDiff savedVar = m_RMV->GlobalStoreAndRef( - DRE, "_EERepl_" + DRE->getDecl()->getNameAsString()); - if (isInsideLoop) { - // It is nice to save the pop value. - // We do not know how many times the user will use dx, - // hence we should pop values beforehand to avoid unequal pushes - // and and pops. - Expr* popVal = - m_RMV->StoreAndRef(savedVar.getExpr_dx(), direction::reverse); - savedVar = {savedVar.getExpr(), popVal}; - } - Expr* erroExpr = GetError(savedVar.getExpr_dx(), var.getExpr_dx(), + if (ShouldEstimateErrorFor(cast(DRE->getDecl()))) { + Expr* erroExpr = GetError(DRE, var.getExpr_dx(), DRE->getDecl()->getNameAsString()); - AddErrorStmtToBlock(var.getExpr(), deltaVar, erroExpr, isInsideLoop); + AddErrorStmtToBlock(erroExpr); } } } -Expr* ErrorEstimationHandler::RegisterBinaryOpLHS(Expr* LExpr, Expr* RExpr, - bool isAssign) { - DeclRefExpr* LRef = GetUnderlyingDeclRefOrNull(LExpr); - DeclRefExpr* RRef = GetUnderlyingDeclRefOrNull(RExpr); - VarDecl* Ldecl = LRef ? dyn_cast(LRef->getDecl()) : nullptr; - // In the case that an RHS expression is a declReference, we do not emit - // any error because the assignment operation entials zero error. - // However, for compound assignment operators, the RHS may be a - // declRefExpr but here we will need to emit its error. - // This variable checks for the above conditions. - bool declRefOk = !RRef || !isAssign; - Expr* deltaVar = nullptr; - // If the LHS can be decayed to a VarDecl and all other requirements - // are met, we should register the variable if it has not been already. - // We also do not support array input types yet. - if (Ldecl && declRefOk) { - deltaVar = IsRegistered(Ldecl); - // Usually we would expect independent variable to qualify for these - // checks. - if (!deltaVar) { - deltaVar = RegisterVariable(Ldecl); - SaveParamValue(LRef); - } - } - return deltaVar; -} - -void ErrorEstimationHandler::EmitBinaryOpErrorStmts(Expr* LExpr, Expr* oldValue, - Expr* deltaVar, - bool isInsideLoop) { - if (!deltaVar) - return; - // For now save all lhs. - // FIXME: We can optimize stores here by using the ones created - // previously. - StmtDiff savedExpr = SaveValue(LExpr, isInsideLoop); +void ErrorEstimationHandler::EmitBinaryOpErrorStmts(Expr* LExpr, Expr* oldValue) { // Assign the error. auto decl = GetUnderlyingDeclRefOrNull(LExpr)->getDecl(); + if (!ShouldEstimateErrorFor(cast(decl))) + return; + bool errorFromFunctionCall = (bool)m_NestedFuncError; Expr* errorExpr = - UpdateErrorForFuncCallAssigns(this, savedExpr.getExpr_dx(), oldValue, + UpdateErrorForFuncCallAssigns(this, LExpr, oldValue, m_NestedFuncError, decl->getNameAsString()); - AddErrorStmtToBlock(LExpr, deltaVar, errorExpr, isInsideLoop); + AddErrorStmtToBlock(errorExpr, /*addToTheFront=*/!errorFromFunctionCall); // If there are assign statements to emit in reverse, do that. EmitErrorEstimationStmts(direction::reverse); } @@ -482,21 +269,20 @@ void ErrorEstimationHandler::EmitBinaryOpErrorStmts(Expr* LExpr, Expr* oldValue, void ErrorEstimationHandler::EmitDeclErrorStmts(VarDeclDiff VDDiff, bool isInsideLoop) { auto VD = VDDiff.getDecl(); - if (!CanRegisterVariable(VD)) + if (!ShouldEstimateErrorFor(VD)) return; // Build the delta expresion for the variable to be registered. - auto EstVD = RegisterVariable(VD); DeclRefExpr* VDRef = m_RMV->BuildDeclRef(VD); // FIXME: We should do this for arrays too. if (!VD->getType()->isArrayType()) { - StmtDiff savedDecl = SaveValue(VDRef, isInsideLoop); // If the VarDecl has an init, we should assign it with an error. if (VD->getInit() && !GetUnderlyingDeclRefOrNull(VD->getInit())) { + bool errorFromFunctionCall = (bool)m_NestedFuncError; Expr* errorExpr = UpdateErrorForFuncCallAssigns( - this, savedDecl.getExpr_dx(), + this, VDRef, m_RMV->BuildDeclRef(VDDiff.getDecl_dx()), m_NestedFuncError, VD->getNameAsString()); - AddErrorStmtToBlock(VDRef, EstVD, errorExpr, isInsideLoop); + AddErrorStmtToBlock(errorExpr, /*addToTheFront=*/!errorFromFunctionCall); } } } @@ -620,18 +406,16 @@ void ErrorEstimationHandler::ActBeforeFinalizingVisitCallExpr( } } -void ErrorEstimationHandler::ActAfterCloningLHSOfAssignOp( - clang::Expr*& LCloned, clang::Expr*& R, - clang::BinaryOperator::Opcode& opCode) { - m_DeltaVar = RegisterBinaryOpLHS(LCloned, R, - /*isAssign=*/opCode == BO_Assign); -} - void ErrorEstimationHandler::ActBeforeFinalisingAssignOp( - clang::Expr*& LCloned, clang::Expr*& oldValue) { - // Now, we should emit the delta for LHS if it met all the - // requirements previously. - EmitBinaryOpErrorStmts(LCloned, oldValue, m_DeltaVar, m_RMV->isInsideLoop); + clang::Expr*& LCloned, clang::Expr*& oldValue, + clang::Expr*& R, clang::BinaryOperator::Opcode& opCode) { + // In the case that an RHS expression is a declReference, we do not emit + // any error because the assignment operation entials zero error. + // However, for compound assignment operators, the RHS may be a + // declRefExpr but here we will need to emit its error. + // This checks for the above conditions. + if (opCode != BO_Assign || !isa(R->IgnoreImplicit())) + EmitBinaryOpErrorStmts(LCloned, oldValue); } void ErrorEstimationHandler::ActBeforeFinalizingDifferentiateSingleStmt( diff --git a/lib/Differentiator/MultiplexExternalRMVSource.cpp b/lib/Differentiator/MultiplexExternalRMVSource.cpp index 1b6f9c10f..716a10aaa 100644 --- a/lib/Differentiator/MultiplexExternalRMVSource.cpp +++ b/lib/Differentiator/MultiplexExternalRMVSource.cpp @@ -170,9 +170,10 @@ void MultiplexExternalRMVSource::ActAfterCloningLHSOfAssignOp( } void MultiplexExternalRMVSource::ActBeforeFinalisingAssignOp( - clang::Expr*& LCloned, clang::Expr*& oldValue) { + clang::Expr*& LCloned, clang::Expr*& oldValue, clang::Expr*& R, + clang::BinaryOperator::Opcode& opCode) { for (auto source : m_Sources) { - source->ActBeforeFinalisingAssignOp(LCloned, oldValue); + source->ActBeforeFinalisingAssignOp(LCloned, oldValue, R, opCode); } } diff --git a/lib/Differentiator/ReverseModeVisitor.cpp b/lib/Differentiator/ReverseModeVisitor.cpp index 6e3f1af48..cc7cf6d66 100644 --- a/lib/Differentiator/ReverseModeVisitor.cpp +++ b/lib/Differentiator/ReverseModeVisitor.cpp @@ -2498,7 +2498,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, } else llvm_unreachable("unknown assignment opCode"); if (m_ExternalSource) - m_ExternalSource->ActBeforeFinalisingAssignOp(LCloned, oldValue); + m_ExternalSource->ActBeforeFinalisingAssignOp(LCloned, ResultRef, R, opCode); // Output statements from Visit(L). for (auto it = Lblock_begin; it != Lblock_end; ++it) diff --git a/test/ErrorEstimation/Assignments.C b/test/ErrorEstimation/Assignments.C index 3325b7e60..668e8ccaf 100644 --- a/test/ErrorEstimation/Assignments.C +++ b/test/ErrorEstimation/Assignments.C @@ -14,13 +14,9 @@ float func(float x, float y) { //CHECK: void func_grad(float x, float y, clad::array_ref _d_x, clad::array_ref _d_y, double &_final_error) { //CHECK-NEXT: float _t0; -//CHECK-NEXT: double _delta_x = 0; -//CHECK-NEXT: float _EERepl_x0 = x; -//CHECK-NEXT: float _EERepl_x1; //CHECK-NEXT: float _t1; //CHECK-NEXT: _t0 = x; //CHECK-NEXT: x = x + y; -//CHECK-NEXT: _EERepl_x1 = x; //CHECK-NEXT: _t1 = y; //CHECK-NEXT: y = x; //CHECK-NEXT: goto _label0; @@ -34,18 +30,16 @@ float func(float x, float y) { //CHECK-NEXT: * _d_y; //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: _final_error += std::abs(* _d_x * x * {{.+}}); //CHECK-NEXT: x = _t0; //CHECK-NEXT: float _r_d0 = * _d_x; //CHECK-NEXT: * _d_x -= _r_d0; //CHECK-NEXT: * _d_x += _r_d0; //CHECK-NEXT: * _d_y += _r_d0; -//CHECK-NEXT: _delta_x += std::abs(_r_d0 * _EERepl_x1 * {{.+}}); //CHECK-NEXT: * _d_x; //CHECK-NEXT: } -//CHECK-NEXT: _delta_x += std::abs(* _d_x * _EERepl_x0 * {{.+}}); -//CHECK-NEXT: double _delta_y = 0; -//CHECK-NEXT: _delta_y += std::abs(* _d_y * y * {{.+}}); -//CHECK-NEXT: _final_error += _delta_{{y|x}} + _delta_{{y|x}}; +//CHECK-NEXT: _final_error += std::abs(* _d_x * x * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(* _d_y * y * {{.+}}); //CHECK-NEXT: } float func2(float x, int y) { @@ -55,16 +49,13 @@ float func2(float x, int y) { //CHECK: void func2_grad(float x, int y, clad::array_ref _d_x, clad::array_ref _d_y, double &_final_error) { //CHECK-NEXT: float _t0; -//CHECK-NEXT: double _delta_x = 0; -//CHECK-NEXT: float _EERepl_x0 = x; -//CHECK-NEXT: float _EERepl_x1; //CHECK-NEXT: _t0 = x; //CHECK-NEXT: x = y * x + x * x; -//CHECK-NEXT: _EERepl_x1 = x; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: * _d_x += 1; //CHECK-NEXT: { +//CHECK-NEXT: _final_error += std::abs(* _d_x * x * {{.+}}); //CHECK-NEXT: x = _t0; //CHECK-NEXT: float _r_d0 = * _d_x; //CHECK-NEXT: * _d_x -= _r_d0; @@ -72,11 +63,9 @@ float func2(float x, int y) { //CHECK-NEXT: * _d_x += y * _r_d0; //CHECK-NEXT: * _d_x += _r_d0 * x; //CHECK-NEXT: * _d_x += x * _r_d0; -//CHECK-NEXT: _delta_x += std::abs(_r_d0 * _EERepl_x1 * {{.+}}); //CHECK-NEXT: * _d_x; //CHECK-NEXT: } -//CHECK-NEXT: _delta_x += std::abs(* _d_x * _EERepl_x0 * {{.+}}); -//CHECK-NEXT: _final_error += _delta_x; +//CHECK-NEXT: _final_error += std::abs(* _d_x * x * {{.+}}); //CHECK-NEXT: } float func3(int x, int y) { @@ -108,34 +97,25 @@ float func4(float x, float y) { //CHECK: void func4_grad(float x, float y, clad::array_ref _d_x, clad::array_ref _d_y, double &_final_error) { //CHECK-NEXT: double _d_z = 0; -//CHECK-NEXT: double _delta_z = 0; -//CHECK-NEXT: double _EERepl_z0; //CHECK-NEXT: float _t0; -//CHECK-NEXT: double _delta_x = 0; -//CHECK-NEXT: float _EERepl_x0 = x; -//CHECK-NEXT: float _EERepl_x1; //CHECK-NEXT: double z = y; -//CHECK-NEXT: _EERepl_z0 = z; //CHECK-NEXT: _t0 = x; //CHECK-NEXT: x = z + y; -//CHECK-NEXT: _EERepl_x1 = x; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: * _d_x += 1; //CHECK-NEXT: { +//CHECK-NEXT: _final_error += std::abs(* _d_x * x * {{.+}}); //CHECK-NEXT: x = _t0; //CHECK-NEXT: float _r_d0 = * _d_x; //CHECK-NEXT: * _d_x -= _r_d0; //CHECK-NEXT: _d_z += _r_d0; //CHECK-NEXT: * _d_y += _r_d0; -//CHECK-NEXT: _delta_x += std::abs(_r_d0 * _EERepl_x1 * {{.+}}); //CHECK-NEXT: * _d_x; //CHECK-NEXT: } //CHECK-NEXT: * _d_y += _d_z; -//CHECK-NEXT: _delta_x += std::abs(* _d_x * _EERepl_x0 * {{.+}}); -//CHECK-NEXT: double _delta_y = 0; -//CHECK-NEXT: _delta_y += std::abs(* _d_y * y * {{.+}}); -//CHECK-NEXT: _final_error += _delta_{{x|y|z}} + _delta_{{x|y|z}} + _delta_{{x|y|z}}; +//CHECK-NEXT: _final_error += std::abs(* _d_x * x * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(* _d_y * y * {{.+}}); //CHECK-NEXT: } float func5(float x, float y) { @@ -147,29 +127,23 @@ float func5(float x, float y) { //CHECK: void func5_grad(float x, float y, clad::array_ref _d_x, clad::array_ref _d_y, double &_final_error) { //CHECK-NEXT: int _d_z = 0; //CHECK-NEXT: float _t0; -//CHECK-NEXT: double _delta_x = 0; -//CHECK-NEXT: float _EERepl_x0 = x; -//CHECK-NEXT: float _EERepl_x1; //CHECK-NEXT: int z = 56; //CHECK-NEXT: _t0 = x; //CHECK-NEXT: x = z + y; -//CHECK-NEXT: _EERepl_x1 = x; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: * _d_x += 1; //CHECK-NEXT: { +//CHECK-NEXT: _final_error += std::abs(* _d_x * x * {{.+}}); //CHECK-NEXT: x = _t0; //CHECK-NEXT: float _r_d0 = * _d_x; //CHECK-NEXT: * _d_x -= _r_d0; //CHECK-NEXT: _d_z += _r_d0; //CHECK-NEXT: * _d_y += _r_d0; -//CHECK-NEXT: _delta_x += std::abs(_r_d0 * _EERepl_x1 * {{.+}}); //CHECK-NEXT: * _d_x; //CHECK-NEXT: } -//CHECK-NEXT: _delta_x += std::abs(* _d_x * _EERepl_x0 * {{.+}}); -//CHECK-NEXT: double _delta_y = 0; -//CHECK-NEXT: _delta_y += std::abs(* _d_y * y * {{.+}}); -//CHECK-NEXT: _final_error += _delta_{{x|y}} + _delta_{{x|y}}; +//CHECK-NEXT: _final_error += std::abs(* _d_x * x * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(* _d_y * y * {{.+}}); //CHECK-NEXT: } float func6(float x) { return x; } @@ -178,9 +152,7 @@ float func6(float x) { return x; } //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: * _d_x += 1; -//CHECK-NEXT: double _delta_x = 0; -//CHECK-NEXT: _delta_x += std::abs(* _d_x * x * {{.+}}); -//CHECK-NEXT: _final_error += _delta_x; +//CHECK-NEXT: _final_error += std::abs(* _d_x * x * {{.+}}); //CHECK-NEXT: } float func7(float x, float y) { return (x * y); } @@ -194,11 +166,9 @@ float func7(float x, float y) { return (x * y); } //CHECK-NEXT: * _d_x += 1 * y; //CHECK-NEXT: * _d_y += x * 1; //CHECK-NEXT: } -//CHECK-NEXT: double _delta_x = 0; -//CHECK-NEXT: _delta_x += std::abs(* _d_x * x * {{.+}}); -//CHECK-NEXT: double _delta_y = 0; -//CHECK-NEXT: _delta_y += std::abs(* _d_y * y * {{.+}}); -//CHECK-NEXT: _final_error += _delta_{{x|y}} + _delta_{{x|y}} + std::abs(1. * _ret_value0 * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(* _d_x * x * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(* _d_y * y * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(1. * _ret_value0 * {{.+}}); //CHECK-NEXT: } int main() { diff --git a/test/ErrorEstimation/BasicOps.C b/test/ErrorEstimation/BasicOps.C index a0889138b..09ced8043 100644 --- a/test/ErrorEstimation/BasicOps.C +++ b/test/ErrorEstimation/BasicOps.C @@ -15,58 +15,44 @@ float func(float x, float y) { //CHECK: void func_grad(float x, float y, clad::array_ref _d_x, clad::array_ref _d_y, double &_final_error) { //CHECK-NEXT: float _t0; -//CHECK-NEXT: double _delta_x = 0; -//CHECK-NEXT: float _EERepl_x0 = x; -//CHECK-NEXT: float _EERepl_x1; //CHECK-NEXT: float _t1; -//CHECK-NEXT: double _delta_y = 0; -//CHECK-NEXT: float _EERepl_y0 = y; -//CHECK-NEXT: float _EERepl_y1; -//CHECK-NEXT: float _EERepl_y2; //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; -//CHECK-NEXT: _EERepl_x1 = x; //CHECK-NEXT: _t1 = y; -//CHECK-NEXT: _EERepl_y1 = y; //CHECK-NEXT: y = y + y++ + y; -//CHECK-NEXT: _EERepl_y2 = y; //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: _final_error += std::abs(_d_z * z * {{.+}}); //CHECK-NEXT: * _d_y += _d_z * x; //CHECK-NEXT: * _d_x += y * _d_z; -//CHECK-NEXT: _delta_z += std::abs(_d_z * _EERepl_z0 * {{.+}}); //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: _final_error += std::abs(* _d_y * y * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(* _d_y * y * {{.+}}); //CHECK-NEXT: y = _t1; //CHECK-NEXT: float _r_d1 = * _d_y; //CHECK-NEXT: * _d_y -= _r_d1; //CHECK-NEXT: * _d_y += _r_d1; //CHECK-NEXT: * _d_y += _r_d1; //CHECK-NEXT: y--; -//CHECK-NEXT: _delta_y += std::abs(* _d_y * _EERepl_y1 * {{.+}}); //CHECK-NEXT: * _d_y += _r_d1; -//CHECK-NEXT: _delta_y += std::abs(_r_d1 * _EERepl_y2 * {{.+}}); //CHECK-NEXT: * _d_y; //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: _final_error += std::abs(* _d_x * x * {{.+}}); //CHECK-NEXT: x = _t0; //CHECK-NEXT: float _r_d0 = * _d_x; //CHECK-NEXT: * _d_x -= _r_d0; //CHECK-NEXT: * _d_x += _r_d0; //CHECK-NEXT: * _d_y += _r_d0; -//CHECK-NEXT: _delta_x += std::abs(_r_d0 * _EERepl_x1 * {{.+}}); //CHECK-NEXT: * _d_x; //CHECK-NEXT: } -//CHECK-NEXT: _delta_x += std::abs(* _d_x * _EERepl_x0 * {{.+}}); -//CHECK-NEXT: _delta_y += std::abs(* _d_y * _EERepl_y0 * {{.+}}); -//CHECK-NEXT: _final_error += _delta_{{x|y|z}} + _delta_{{x|y|z}} + _delta_{{x|y|z}}; +//CHECK-NEXT: _final_error += std::abs(* _d_x * x * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(* _d_y * y * {{.+}}); //CHECK-NEXT: } // This function may evaluate incorrectly due to absence of usage of @@ -79,27 +65,21 @@ float func2(float x, float y) { //CHECK: void func2_grad(float x, float y, clad::array_ref _d_x, clad::array_ref _d_y, double &_final_error) { //CHECK-NEXT: float _t0; -//CHECK-NEXT: double _delta_x = 0; -//CHECK-NEXT: float _EERepl_x0 = x; -//CHECK-NEXT: float _EERepl_x1; //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: 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: _final_error += std::abs(_d_z * z * {{.+}}); //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: } //CHECK-NEXT: { +//CHECK-NEXT: _final_error += std::abs(* _d_x * x * {{.+}}); //CHECK-NEXT: x = _t0; //CHECK-NEXT: float _r_d0 = * _d_x; //CHECK-NEXT: * _d_x -= _r_d0; @@ -107,13 +87,10 @@ float func2(float x, float y) { //CHECK-NEXT: * _d_y += -_r_d0; //CHECK-NEXT: * _d_y += -_r_d0 * y; //CHECK-NEXT: * _d_y += y * -_r_d0; -//CHECK-NEXT: _delta_x += std::abs(_r_d0 * _EERepl_x1 * {{.+}}); //CHECK-NEXT: * _d_x; //CHECK-NEXT: } -//CHECK-NEXT: _delta_x += std::abs(* _d_x * _EERepl_x0 * {{.+}}); -//CHECK-NEXT: double _delta_y = 0; -//CHECK-NEXT: _delta_y += std::abs(* _d_y * y * {{.+}}); -//CHECK-NEXT: _final_error += _delta_{{x|y|z}} + _delta_{{x|y|z}} + _delta_{{x|y|z}}; +//CHECK-NEXT: _final_error += std::abs(* _d_x * x * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(* _d_y * y * {{.+}}); //CHECK-NEXT: } @@ -127,34 +104,22 @@ float func3(float x, float y) { //CHECK: void func3_grad(float x, float y, clad::array_ref _d_x, clad::array_ref _d_y, double &_final_error) { //CHECK-NEXT: float _t0; -//CHECK-NEXT: double _delta_x = 0; -//CHECK-NEXT: float _EERepl_x0 = x; -//CHECK-NEXT: float _EERepl_x1; //CHECK-NEXT: float _d_z = 0; -//CHECK-NEXT: double _delta_z = 0; -//CHECK-NEXT: float _EERepl_z0; //CHECK-NEXT: float _t1; //CHECK-NEXT: float _t2; -//CHECK-NEXT: double _delta_y = 0; -//CHECK-NEXT: float _EERepl_y0 = y; -//CHECK-NEXT: float _EERepl_y1; //CHECK-NEXT: float _d_t = 0; -//CHECK-NEXT: double _delta_t = 0; -//CHECK-NEXT: float _EERepl_t0; //CHECK-NEXT: _t0 = x; //CHECK-NEXT: x = x - y - y * y; -//CHECK-NEXT: _EERepl_x1 = x; //CHECK-NEXT: float z = y; -//CHECK-NEXT: _EERepl_z0 = z; //CHECK-NEXT: _t2 = y; //CHECK-NEXT: _t1 = (y = x + x); //CHECK-NEXT: float t = x * z * _t1; -//CHECK-NEXT: _EERepl_t0 = t; -//CHECK-NEXT: _EERepl_y1 = y; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: _d_t += 1; //CHECK-NEXT: { +//CHECK-NEXT: _final_error += std::abs(_d_t * t * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(* _d_y * y * {{.+}}); //CHECK-NEXT: * _d_x += _d_t * _t1 * z; //CHECK-NEXT: _d_z += x * _d_t * _t1; //CHECK-NEXT: * _d_y += x * z * _d_t; @@ -163,11 +128,10 @@ float func3(float x, float y) { //CHECK-NEXT: * _d_y -= _r_d1; //CHECK-NEXT: * _d_x += _r_d1; //CHECK-NEXT: * _d_x += _r_d1; -//CHECK-NEXT: _delta_y += std::abs(_r_d1 * _EERepl_y1 * {{.+}}); -//CHECK-NEXT: _delta_t += std::abs(_d_t * _EERepl_t0 * {{.+}}); //CHECK-NEXT: } //CHECK-NEXT: * _d_y += _d_z; //CHECK-NEXT: { +//CHECK-NEXT: _final_error += std::abs(* _d_x * x * {{.+}}); //CHECK-NEXT: x = _t0; //CHECK-NEXT: float _r_d0 = * _d_x; //CHECK-NEXT: * _d_x -= _r_d0; @@ -175,12 +139,10 @@ float func3(float x, float y) { //CHECK-NEXT: * _d_y += -_r_d0; //CHECK-NEXT: * _d_y += -_r_d0 * y; //CHECK-NEXT: * _d_y += y * -_r_d0; -//CHECK-NEXT: _delta_x += std::abs(_r_d0 * _EERepl_x1 * {{.+}}); //CHECK-NEXT: * _d_x; //CHECK-NEXT: } -//CHECK-NEXT: _delta_x += std::abs(* _d_x * _EERepl_x0 * {{.+}}); -//CHECK-NEXT: _delta_y += std::abs(* _d_y * _EERepl_y0 * {{.+}}); -//CHECK-NEXT: _final_error += _delta_{{t|x|y|z}} + _delta_{{t|x|y|z}} + _delta_{{t|x|y|z}} + _delta_{{t|x|y|z}}; +//CHECK-NEXT: _final_error += std::abs(* _d_x * x * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(* _d_y * y * {{.+}}); //CHECK-NEXT: } // Function call custom derivative exists but no assign expr @@ -200,11 +162,9 @@ float func4(float x, float y) { return std::pow(x, y); } //CHECK-NEXT: float _r1 = _grad1; //CHECK-NEXT: * _d_y += _r1; //CHECK-NEXT: } -//CHECK-NEXT: double _delta_x = 0; -//CHECK-NEXT: _delta_x += std::abs(* _d_x * x * {{.+}}); -//CHECK-NEXT: double _delta_y = 0; -//CHECK-NEXT: _delta_y += std::abs(* _d_y * y * {{.+}}); -//CHECK-NEXT: _final_error += _delta_{{x|y}} + _delta_{{x|y}} + std::abs(1. * _ret_value0 * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(* _d_x * x * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(* _d_y * y * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(1. * _ret_value0 * {{.+}}); //CHECK-NEXT: } // Function call custom derivative exists and is assigned @@ -215,13 +175,9 @@ float func5(float x, float y) { //CHECK: void func5_grad(float x, float y, clad::array_ref _d_x, clad::array_ref _d_y, double &_final_error) { //CHECK-NEXT: float _t0; -//CHECK-NEXT: double _delta_y = 0; -//CHECK-NEXT: float _EERepl_y0 = y; -//CHECK-NEXT: float _EERepl_y1; //CHECK-NEXT: double _ret_value0 = 0; //CHECK-NEXT: _t0 = y; //CHECK-NEXT: y = std::sin(x); -//CHECK-NEXT: _EERepl_y1 = y; //CHECK-NEXT: _ret_value0 = y * y; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: @@ -230,18 +186,17 @@ float func5(float x, float y) { //CHECK-NEXT: * _d_y += y * 1; //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: _final_error += std::abs(* _d_y * y * {{.+}}); //CHECK-NEXT: y = _t0; //CHECK-NEXT: float _r_d0 = * _d_y; //CHECK-NEXT: * _d_y -= _r_d0; //CHECK-NEXT: float _r0 = _r_d0 * clad::custom_derivatives{{(::std)?}}::sin_pushforward(x, 1.F).pushforward; //CHECK-NEXT: * _d_x += _r0; -//CHECK-NEXT: _delta_y += std::abs(_r_d0 * _EERepl_y1 * {{.+}}); //CHECK-NEXT: * _d_y; //CHECK-NEXT: } -//CHECK-NEXT: double _delta_x = 0; -//CHECK-NEXT: _delta_x += std::abs(* _d_x * x * {{.+}}); -//CHECK-NEXT: _delta_y += std::abs(* _d_y * _EERepl_y0 * {{.+}}); -//CHECK-NEXT: _final_error += _delta_{{x|y}} + _delta_{{x|y}} + std::abs(1. * _ret_value0 * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(* _d_x * x * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(* _d_y * y * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(1. * _ret_value0 * {{.+}}); //CHECK-NEXT: } // Function call non custom derivative @@ -256,11 +211,9 @@ double helper(double x, double y) { return x * y; } //CHECK-NEXT: * _d_x += _d_y0 * y; //CHECK-NEXT: * _d_y += x * _d_y0; //CHECK-NEXT: } -//CHECK-NEXT: double _delta_x = 0; -//CHECK-NEXT: _delta_x += std::abs(* _d_x * x * {{.+}}); -//CHECK-NEXT: double _delta_y = 0; -//CHECK-NEXT: _delta_y += std::abs(* _d_y * y * {{.+}}); -//CHECK-NEXT: _final_error += _delta_{{y|x}} + _delta_{{y|x}} + std::abs(1. * _ret_value0 * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(* _d_x * x * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(* _d_y * y * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(1. * _ret_value0 * {{.+}}); //CHECK-NEXT: } float func6(float x, float y) { @@ -270,11 +223,8 @@ float func6(float x, float y) { //CHECK: void func6_grad(float x, float y, clad::array_ref _d_x, clad::array_ref _d_y, double &_final_error) { //CHECK-NEXT: float _d_z = 0; -//CHECK-NEXT: double _delta_z = 0; -//CHECK-NEXT: float _EERepl_z0; //CHECK-NEXT: double _ret_value0 = 0; //CHECK-NEXT: float z = helper(x, y); -//CHECK-NEXT: _EERepl_z0 = z; //CHECK-NEXT: _ret_value0 = z * z; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: @@ -291,13 +241,11 @@ float func6(float x, float y) { //CHECK-NEXT: * _d_x += _r0; //CHECK-NEXT: double _r1 = _grad1; //CHECK-NEXT: * _d_y += _r1; -//CHECK-NEXT: _delta_z += _t0; +//CHECK-NEXT: _final_error += _t0; //CHECK-NEXT: } -//CHECK-NEXT: double _delta_x = 0; -//CHECK-NEXT: _delta_x += std::abs(* _d_x * x * {{.+}}); -//CHECK-NEXT: double _delta_y = 0; -//CHECK-NEXT: _delta_y += std::abs(* _d_y * y * {{.+}}); -//CHECK-NEXT: _final_error += _delta_{{y|x|z}} + _delta_{{y|x|z}} + _delta_{{y|x|z}} + std::abs(1. * _ret_value0 * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(* _d_x * x * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(* _d_y * y * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(1. * _ret_value0 * {{.+}}); //CHECK-NEXT: } float func7(float x) { @@ -315,9 +263,7 @@ float func7(float x) { //CHECK-NEXT: _d_z += 1; //CHECK-NEXT: } //CHECK-NEXT: * _d_x += _d_z; -//CHECK-NEXT: double _delta_x = 0; -//CHECK-NEXT: _delta_x += std::abs(* _d_x * x * {{.+}}); -//CHECK-NEXT: _final_error += _delta_x; +//CHECK-NEXT: _final_error += std::abs(* _d_x * x * {{.+}}); //CHECK-NEXT: } @@ -343,17 +289,12 @@ float func8(float x, float y) { //CHECK: void func8_grad(float x, float y, clad::array_ref _d_x, clad::array_ref _d_y, double &_final_error) { //CHECK-NEXT: float _d_z = 0; -//CHECK-NEXT: double _delta_z = 0; -//CHECK-NEXT: float _EERepl_z0; //CHECK-NEXT: float _t0; //CHECK-NEXT: float _t1; -//CHECK-NEXT: float _EERepl_z1; //CHECK-NEXT: float z; -//CHECK-NEXT: _EERepl_z0 = z; //CHECK-NEXT: _t0 = z; //CHECK-NEXT: _t1 = x; //CHECK-NEXT: z = y + helper2(x); -//CHECK-NEXT: _EERepl_z1 = z; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: _d_z += 1; @@ -366,14 +307,11 @@ float func8(float x, float y) { //CHECK-NEXT: double _t2 = 0; //CHECK-NEXT: helper2_pullback(_t1, _r_d0, &* _d_x, _t2); //CHECK-NEXT: float _r0 = * _d_x; -//CHECK-NEXT: _delta_z += _t2; +//CHECK-NEXT: _final_error += _t2; //CHECK-NEXT: _final_error += std::abs(_r0 * _t1 * {{.+}}); //CHECK-NEXT: } -//CHECK-NEXT: double _delta_x = 0; -//CHECK-NEXT: _delta_x += std::abs(* _d_x * x * {{.+}}); -//CHECK-NEXT: double _delta_y = 0; -//CHECK-NEXT: _delta_y += std::abs(* _d_y * y * {{.+}}); -//CHECK-NEXT: _final_error += _delta_{{x|y|z}} + _delta_{{x|y|z}} + _delta_{{x|y|z}}; +//CHECK-NEXT: _final_error += std::abs(* _d_x * x * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(* _d_y * y * {{.+}}); //CHECK-NEXT: } float func9(float x, float y) { @@ -385,24 +323,19 @@ float func9(float x, float y) { //CHECK: void func9_grad(float x, float y, clad::array_ref _d_x, clad::array_ref _d_y, double &_final_error) { //CHECK-NEXT: float _t1; //CHECK-NEXT: float _d_z = 0; -//CHECK-NEXT: double _delta_z = 0; -//CHECK-NEXT: float _EERepl_z0; //CHECK-NEXT: float _t3; //CHECK-NEXT: double _t4; //CHECK-NEXT: float _t5; //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 = helper2(x); //CHECK-NEXT: _t8 = y; //CHECK-NEXT: _t4 = helper2(y); //CHECK-NEXT: z += _t7 * _t4; -//CHECK-NEXT: _EERepl_z1 = z; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: _d_z += 1; @@ -417,7 +350,7 @@ float func9(float x, float y) { //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 + _t9; +//CHECK-NEXT: _final_error += _t6 + _t9; //CHECK-NEXT: _final_error += std::abs(_r4 * _t8 * {{.+}}); //CHECK-NEXT: _final_error += std::abs(_r3 * _t5 * {{.+}}); //CHECK-NEXT: } @@ -434,14 +367,11 @@ float func9(float x, float y) { //CHECK-NEXT: double _t2 = 0; //CHECK-NEXT: helper2_pullback(_t1, _d_z, &* _d_x, _t2); //CHECK-NEXT: float _r2 = * _d_x; -//CHECK-NEXT: _delta_z += _t0 + _t2; +//CHECK-NEXT: _final_error += _t0 + _t2; //CHECK-NEXT: _final_error += std::abs(_r2 * _t1 * {{.+}}); //CHECK-NEXT: } -//CHECK-NEXT: double _delta_x = 0; -//CHECK-NEXT: _delta_x += std::abs(* _d_x * x * {{.+}}); -//CHECK-NEXT: double _delta_y = 0; -//CHECK-NEXT: _delta_y += std::abs(* _d_y * y * {{.+}}); -//CHECK-NEXT: _final_error += _delta_{{x|y|z}} + _delta_{{x|y|z}} + _delta_{{x|y|z}}; +//CHECK-NEXT: _final_error += std::abs(* _d_x * x * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(* _d_y * y * {{.+}}); //CHECK-NEXT: } int main() { diff --git a/test/ErrorEstimation/ConditonalStatements.C b/test/ErrorEstimation/ConditonalStatements.C index 24c88ad99..59d9327b8 100644 --- a/test/ErrorEstimation/ConditonalStatements.C +++ b/test/ErrorEstimation/ConditonalStatements.C @@ -20,28 +20,19 @@ float func(float x, float y) { //CHECK: void func_grad(float x, float y, clad::array_ref _d_x, clad::array_ref _d_y, double &_final_error) { //CHECK-NEXT: bool _cond0; //CHECK-NEXT: float _t0; -//CHECK-NEXT: double _delta_y = 0; -//CHECK-NEXT: float _EERepl_y0 = y; -//CHECK-NEXT: float _EERepl_y1; //CHECK-NEXT: float _d_temp = 0; -//CHECK-NEXT: double _delta_temp = 0; -//CHECK-NEXT: float _EERepl_temp0; //CHECK-NEXT: float temp = 0; //CHECK-NEXT: float _t1; -//CHECK-NEXT: float _EERepl_temp1; //CHECK-NEXT: float _t2; //CHECK-NEXT: double _ret_value0 = 0; //CHECK-NEXT: _cond0 = x > y; //CHECK-NEXT: if (_cond0) { //CHECK-NEXT: _t0 = y; //CHECK-NEXT: y = y * x; -//CHECK-NEXT: _EERepl_y1 = y; //CHECK-NEXT: } else { //CHECK-NEXT: temp = y; -//CHECK-NEXT: _EERepl_temp0 = temp; //CHECK-NEXT: _t1 = temp; //CHECK-NEXT: temp = y * y; -//CHECK-NEXT: _EERepl_temp1 = temp; //CHECK-NEXT: _t2 = x; //CHECK-NEXT: x = y; //CHECK-NEXT: } @@ -54,12 +45,12 @@ float func(float x, float y) { //CHECK-NEXT: } //CHECK-NEXT: if (_cond0) { //CHECK-NEXT: { +//CHECK-NEXT: _final_error += std::abs(* _d_y * y * {{.+}}); //CHECK-NEXT: y = _t0; //CHECK-NEXT: float _r_d0 = * _d_y; //CHECK-NEXT: * _d_y -= _r_d0; //CHECK-NEXT: * _d_y += _r_d0 * x; //CHECK-NEXT: * _d_x += y * _r_d0; -//CHECK-NEXT: _delta_y += std::abs(_r_d0 * _EERepl_y1 * {{.+}}); //CHECK-NEXT: * _d_y; //CHECK-NEXT: } //CHECK-NEXT: } else { @@ -71,22 +62,21 @@ float func(float x, float y) { //CHECK-NEXT: * _d_x; //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: _final_error += std::abs(_d_temp * temp * {{.+}}); //CHECK-NEXT: temp = _t1; //CHECK-NEXT: float _r_d1 = _d_temp; //CHECK-NEXT: _d_temp -= _r_d1; //CHECK-NEXT: * _d_y += _r_d1 * y; //CHECK-NEXT: * _d_y += y * _r_d1; -//CHECK-NEXT: _delta_temp += std::abs(_r_d1 * _EERepl_temp1 * {{.+}}); //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: _final_error += std::abs(_d_temp * temp * {{.+}}); //CHECK-NEXT: * _d_y += _d_temp; -//CHECK-NEXT: _delta_temp += std::abs(_d_temp * _EERepl_temp0 * {{.+}}); //CHECK-NEXT: } //CHECK-NEXT: } -//CHECK-NEXT: double _delta_x = 0; -//CHECK-NEXT: _delta_x += std::abs(* _d_x * x * {{.+}}); -//CHECK-NEXT: _delta_y += std::abs(* _d_y * _EERepl_y0 * {{.+}}); -//CHECK-NEXT: _final_error += _delta_{{x|y|temp}} + _delta_{{x|y|temp}} + _delta_{{x|y|temp}} + std::abs(1. * _ret_value0 * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(* _d_x * x * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(* _d_y * y * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(1. * _ret_value0 * {{.+}}); //CHECK-NEXT: } // Single return statement if/else @@ -100,12 +90,9 @@ float func2(float x) { //CHECK: void func2_grad(float x, clad::array_ref _d_x, double &_final_error) { //CHECK-NEXT: float _d_z = 0; -//CHECK-NEXT: double _delta_z = 0; -//CHECK-NEXT: float _EERepl_z0; //CHECK-NEXT: bool _cond0; //CHECK-NEXT: double _ret_value0 = 0; //CHECK-NEXT: float z = x * x; -//CHECK-NEXT: _EERepl_z0 = z; //CHECK-NEXT: _cond0 = z > 9; //CHECK-NEXT: if (_cond0) { //CHECK-NEXT: _ret_value0 = x + x; @@ -127,13 +114,12 @@ float func2(float x) { //CHECK-NEXT: * _d_x += x * 1; //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: _final_error += std::abs(_d_z * z * {{.+}}); //CHECK-NEXT: * _d_x += _d_z * x; //CHECK-NEXT: * _d_x += x * _d_z; -//CHECK-NEXT: _delta_z += std::abs(_d_z * _EERepl_z0 * {{.+}}); //CHECK-NEXT: } -//CHECK-NEXT: double _delta_x = 0; -//CHECK-NEXT: _delta_x += std::abs(* _d_x * x * {{.+}}); -//CHECK-NEXT: _final_error += _delta_{{x|z}} + _delta_{{x|z}} + std::abs(1. * _ret_value0 * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(* _d_x * x * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(1. * _ret_value0 * {{.+}}); //CHECK-NEXT: } float func3(float x, float y) { return x > 30 ? x * y : x + y; } @@ -152,11 +138,9 @@ float func3(float x, float y) { return x > 30 ? x * y : x + y; } //CHECK-NEXT: * _d_x += 1; //CHECK-NEXT: * _d_y += 1; //CHECK-NEXT: } -//CHECK-NEXT: double _delta_x = 0; -//CHECK-NEXT: _delta_x += std::abs(* _d_x * x * {{.+}}); -//CHECK-NEXT: double _delta_y = 0; -//CHECK-NEXT: _delta_y += std::abs(* _d_y * y * {{.+}}); -//CHECK-NEXT: _final_error += _delta_{{x|y}} + _delta_{{x|y}} + std::abs(1. * _ret_value0 * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(* _d_x * x * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(* _d_y * y * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(1. * _ret_value0 * {{.+}}); //CHECK-NEXT: } float func4(float x, float y) { @@ -167,11 +151,7 @@ float func4(float x, float y) { //CHECK: void func4_grad(float x, float y, clad::array_ref _d_x, clad::array_ref _d_y, double &_final_error) { //CHECK-NEXT: bool _cond0; //CHECK-NEXT: float _t0; -//CHECK-NEXT: double _delta_x = 0; -//CHECK-NEXT: float _EERepl_x0 = x; -//CHECK-NEXT: float _EERepl_x1; //CHECK-NEXT: float _t1; -//CHECK-NEXT: float _EERepl_x2; //CHECK-NEXT: double _ret_value0 = 0; //CHECK-NEXT: _cond0 = !x; //CHECK-NEXT: if (_cond0) @@ -179,8 +159,6 @@ float func4(float x, float y) { //CHECK-NEXT: else //CHECK-NEXT: _t1 = x; //CHECK-NEXT: _cond0 ? (x += 1) : (x *= x); -//CHECK-NEXT: _EERepl_x2 = x; -//CHECK-NEXT: _EERepl_x1 = x; //CHECK-NEXT: _ret_value0 = y / x; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: @@ -191,23 +169,22 @@ float func4(float x, float y) { //CHECK-NEXT: } //CHECK-NEXT: { //CHECK-NEXT: if (_cond0) { +//CHECK-NEXT: _final_error += std::abs(* _d_x * x * {{.+}}); //CHECK-NEXT: x = _t0; //CHECK-NEXT: float _r_d0 = * _d_x; -//CHECK-NEXT: _delta_x += std::abs(_r_d0 * _EERepl_x1 * {{.+}}); //CHECK-NEXT: } else { +//CHECK-NEXT: _final_error += std::abs(* _d_x * x * {{.+}}); //CHECK-NEXT: x = _t1; //CHECK-NEXT: float _r_d1 = * _d_x; //CHECK-NEXT: * _d_x -= _r_d1; //CHECK-NEXT: * _d_x += _r_d1 * x; //CHECK-NEXT: * _d_x += x * _r_d1; -//CHECK-NEXT: _delta_x += std::abs(_r_d1 * _EERepl_x2 * {{.+}}); //CHECK-NEXT: } //CHECK-NEXT: _cond0 ? * _d_x : * _d_x; //CHECK-NEXT: } -//CHECK-NEXT: _delta_x += std::abs(* _d_x * _EERepl_x0 * {{.+}}); -//CHECK-NEXT: double _delta_y = 0; -//CHECK-NEXT: _delta_y += std::abs(* _d_y * y * {{.+}}); -//CHECK-NEXT: _final_error += _delta_{{x|y}} + _delta_{{x|y}} + std::abs(1. * _ret_value0 * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(* _d_x * x * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(* _d_y * y * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(1. * _ret_value0 * {{.+}}); //CHECK-NEXT: } int main() { diff --git a/test/ErrorEstimation/LoopsAndArrays.C b/test/ErrorEstimation/LoopsAndArrays.C index 0290ebefc..361499991 100644 --- a/test/ErrorEstimation/LoopsAndArrays.C +++ b/test/ErrorEstimation/LoopsAndArrays.C @@ -16,21 +16,16 @@ float func(float* p, int n) { //CHECK: void func_grad(float *p, int n, clad::array_ref _d_p, clad::array_ref _d_n, double &_final_error) { //CHECK-NEXT: float _d_sum = 0; -//CHECK-NEXT: double _delta_sum = 0; -//CHECK-NEXT: float _EERepl_sum0; //CHECK-NEXT: unsigned long _t0; //CHECK-NEXT: int _d_i = 0; //CHECK-NEXT: int i = 0; //CHECK-NEXT: clad::tape _t1 = {}; -//CHECK-NEXT: clad::tape _EERepl_sum1 = {}; //CHECK-NEXT: float sum = 0; -//CHECK-NEXT: _EERepl_sum0 = sum; //CHECK-NEXT: _t0 = 0; //CHECK-NEXT: for (i = 0; i < n; i++) { //CHECK-NEXT: _t0++; //CHECK-NEXT: clad::push(_t1, sum); //CHECK-NEXT: sum += p[i]; -//CHECK-NEXT: clad::push(_EERepl_sum1, sum); //CHECK-NEXT: } //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: @@ -38,22 +33,16 @@ float func(float* p, int n) { //CHECK-NEXT: for (; _t0; _t0--) { //CHECK-NEXT: i--; //CHECK-NEXT: { +//CHECK-NEXT: _final_error += std::abs(_d_sum * sum * {{.+}}); //CHECK-NEXT: sum = clad::pop(_t1); //CHECK-NEXT: float _r_d0 = _d_sum; //CHECK-NEXT: _d_p[i] += _r_d0; -//CHECK-NEXT: float _r0 = clad::pop(_EERepl_sum1); -//CHECK-NEXT: _delta_sum += std::abs(_r_d0 * _r0 * {{.+}}); //CHECK-NEXT: } //CHECK-NEXT: } -//CHECK-NEXT: _delta_sum += std::abs(_d_sum * _EERepl_sum0 * {{.+}}); -//CHECK-NEXT: clad::array _delta_p(_d_p.size()); +//CHECK-NEXT: _final_error += std::abs(_d_sum * sum * {{.+}}); //CHECK-NEXT: int i0 = 0; -//CHECK-NEXT: for (; i0 < _d_p.size(); i0++) { -//CHECK-NEXT: double _t2 = std::abs(_d_p[i0] * p[i0] * {{.+}}); -//CHECK-NEXT: _delta_p[i0] += _t2; -//CHECK-NEXT: _final_error += _t2; -//CHECK-NEXT: } -//CHECK-NEXT: _final_error += _delta_sum; +//CHECK-NEXT: for (; i0 < _d_p.size(); i0++) +//CHECK-NEXT: _final_error += std::abs(_d_p[i0] * p[i0] * {{.+}}); //CHECK-NEXT: } @@ -68,28 +57,20 @@ float func2(float x) { //CHECK: void func2_grad(float x, clad::array_ref _d_x, double &_final_error) { //CHECK-NEXT: float _d_z = 0; -//CHECK-NEXT: double _delta_z = 0; -//CHECK-NEXT: float _EERepl_z0; //CHECK-NEXT: unsigned long _t0; //CHECK-NEXT: int _d_i = 0; //CHECK-NEXT: int i = 0; //CHECK-NEXT: clad::tape _t1 = {}; //CHECK-NEXT: float _d_m = 0; -//CHECK-NEXT: double _delta_m = 0; -//CHECK-NEXT: clad::tape _EERepl_m0 = {}; //CHECK-NEXT: float m = 0; //CHECK-NEXT: clad::tape _t2 = {}; -//CHECK-NEXT: clad::tape _EERepl_z1 = {}; //CHECK-NEXT: float z; -//CHECK-NEXT: _EERepl_z0 = z; //CHECK-NEXT: _t0 = 0; //CHECK-NEXT: for (i = 0; i < 9; i++) { //CHECK-NEXT: _t0++; //CHECK-NEXT: clad::push(_t1, m) , m = x * x; -//CHECK-NEXT: clad::push(_EERepl_m0, m); //CHECK-NEXT: clad::push(_t2, z); //CHECK-NEXT: z = m + m; -//CHECK-NEXT: clad::push(_EERepl_z1, z); //CHECK-NEXT: } //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: @@ -97,26 +78,22 @@ float func2(float x) { //CHECK-NEXT: for (; _t0; _t0--) { //CHECK-NEXT: i--; //CHECK-NEXT: { +//CHECK-NEXT: _final_error += std::abs(_d_z * z * {{.+}}); //CHECK-NEXT: z = clad::pop(_t2); //CHECK-NEXT: float _r_d0 = _d_z; //CHECK-NEXT: _d_z -= _r_d0; //CHECK-NEXT: _d_m += _r_d0; //CHECK-NEXT: _d_m += _r_d0; -//CHECK-NEXT: float _r1 = clad::pop(_EERepl_z1); -//CHECK-NEXT: _delta_z += std::abs(_r_d0 * _r1 * {{.+}}); //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: _final_error += std::abs(_d_m * m * {{.+}}); //CHECK-NEXT: * _d_x += _d_m * x; //CHECK-NEXT: * _d_x += x * _d_m; //CHECK-NEXT: _d_m = 0; //CHECK-NEXT: m = clad::pop(_t1); -//CHECK-NEXT: float _r0 = clad::pop(_EERepl_m0); -//CHECK-NEXT: _delta_m += std::abs(_d_m * _r0 * {{.+}}); //CHECK-NEXT: } //CHECK-NEXT: } -//CHECK-NEXT: double _delta_x = 0; -//CHECK-NEXT: _delta_x += std::abs(* _d_x * x * {{.+}}); -//CHECK-NEXT: _final_error += _delta_{{x|z|m}} + _delta_{{x|z|m}} + _delta_{{x|z|m}}; +//CHECK-NEXT: _final_error += std::abs(* _d_x * x * {{.+}}); //CHECK-NEXT: } float func3(float x, float y) { @@ -129,61 +106,48 @@ float func3(float x, float y) { //CHECK: void func3_grad(float x, float y, clad::array_ref _d_x, clad::array_ref _d_y, double &_final_error) { //CHECK-NEXT: clad::array _d_arr(3UL); -//CHECK-NEXT: clad::array _delta_arr(_d_arr.size()); //CHECK-NEXT: double _t0; -//CHECK-NEXT: double _EERepl_arr0; //CHECK-NEXT: double _t1; -//CHECK-NEXT: double _EERepl_arr1; //CHECK-NEXT: double _t2; -//CHECK-NEXT: double _EERepl_arr2; //CHECK-NEXT: double arr[3]; //CHECK-NEXT: _t0 = arr[0]; //CHECK-NEXT: arr[0] = x + y; -//CHECK-NEXT: _EERepl_arr0 = arr[0]; //CHECK-NEXT: _t1 = arr[1]; //CHECK-NEXT: arr[1] = x * x; -//CHECK-NEXT: _EERepl_arr1 = arr[1]; //CHECK-NEXT: _t2 = arr[2]; //CHECK-NEXT: arr[2] = arr[0] + arr[1]; -//CHECK-NEXT: _EERepl_arr2 = arr[2]; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: _d_arr[2] += 1; //CHECK-NEXT: { +//CHECK-NEXT: _final_error += std::abs(_d_arr[2] * arr[2] * {{.+}}); //CHECK-NEXT: arr[2] = _t2; //CHECK-NEXT: double _r_d2 = _d_arr[2]; //CHECK-NEXT: _d_arr[2] -= _r_d2; //CHECK-NEXT: _d_arr[0] += _r_d2; //CHECK-NEXT: _d_arr[1] += _r_d2; -//CHECK-NEXT: _delta_arr[2] += std::abs(_r_d2 * _EERepl_arr2 * {{.+}}); -//CHECK-NEXT: _final_error += _delta_arr[2]; //CHECK-NEXT: _d_arr[2]; //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: _final_error += std::abs(_d_arr[1] * arr[1] * {{.+}}); //CHECK-NEXT: arr[1] = _t1; //CHECK-NEXT: double _r_d1 = _d_arr[1]; //CHECK-NEXT: _d_arr[1] -= _r_d1; //CHECK-NEXT: * _d_x += _r_d1 * x; //CHECK-NEXT: * _d_x += x * _r_d1; -//CHECK-NEXT: _delta_arr[1] += std::abs(_r_d1 * _EERepl_arr1 * {{.+}}); -//CHECK-NEXT: _final_error += _delta_arr[1]; //CHECK-NEXT: _d_arr[1]; //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: _final_error += std::abs(_d_arr[0] * arr[0] * {{.+}}); //CHECK-NEXT: arr[0] = _t0; //CHECK-NEXT: double _r_d0 = _d_arr[0]; //CHECK-NEXT: _d_arr[0] -= _r_d0; //CHECK-NEXT: * _d_x += _r_d0; //CHECK-NEXT: * _d_y += _r_d0; -//CHECK-NEXT: _delta_arr[0] += std::abs(_r_d0 * _EERepl_arr0 * {{.+}}); -//CHECK-NEXT: _final_error += _delta_arr[0]; //CHECK-NEXT: _d_arr[0]; //CHECK-NEXT: } -//CHECK-NEXT: double _delta_x = 0; -//CHECK-NEXT: _delta_x += std::abs(* _d_x * x * {{.+}}); -//CHECK-NEXT: double _delta_y = 0; -//CHECK-NEXT: _delta_y += std::abs(* _d_y * y * {{.+}}); -//CHECK-NEXT: _final_error += _delta_{{y|x}} + _delta_{{y|x}}; +//CHECK-NEXT: _final_error += std::abs(* _d_x * x * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(* _d_y * y * {{.+}}); //CHECK-NEXT: } float func4(float x[10], float y[10]) { @@ -197,31 +161,19 @@ float func4(float x[10], float y[10]) { //CHECK: void func4_grad(float x[10], float y[10], clad::array_ref _d_x, clad::array_ref _d_y, double &_final_error) { //CHECK-NEXT: float _d_sum = 0; -//CHECK-NEXT: double _delta_sum = 0; -//CHECK-NEXT: float _EERepl_sum0; //CHECK-NEXT: unsigned long _t0; //CHECK-NEXT: int _d_i = 0; //CHECK-NEXT: int i = 0; //CHECK-NEXT: clad::tape _t1 = {}; -//CHECK-NEXT: clad::array _delta_x(_d_x.size()); -//CHECK-NEXT: clad::array _EERepl_x0(_d_x.size()); -//CHECK-NEXT: for (int i0 = 0; i0 < _d_x.size(); i0++) { -//CHECK-NEXT: _EERepl_x0[i0] = x[i0]; -//CHECK-NEXT: } -//CHECK-NEXT: clad::tape _EERepl_x1 = {}; //CHECK-NEXT: clad::tape _t2 = {}; -//CHECK-NEXT: clad::tape _EERepl_sum1 = {}; //CHECK-NEXT: float sum = 0; -//CHECK-NEXT: _EERepl_sum0 = sum; //CHECK-NEXT: _t0 = 0; //CHECK-NEXT: for (i = 0; i < 10; i++) { //CHECK-NEXT: _t0++; //CHECK-NEXT: clad::push(_t1, x[i]); //CHECK-NEXT: x[i] += y[i]; -//CHECK-NEXT: clad::push(_EERepl_x1, x[i]); //CHECK-NEXT: clad::push(_t2, sum); //CHECK-NEXT: sum += x[i]; -//CHECK-NEXT: clad::push(_EERepl_sum1, sum); //CHECK-NEXT: } //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: @@ -229,36 +181,25 @@ float func4(float x[10], float y[10]) { //CHECK-NEXT: for (; _t0; _t0--) { //CHECK-NEXT: i--; //CHECK-NEXT: { +//CHECK-NEXT: _final_error += std::abs(_d_sum * sum * {{.+}}); //CHECK-NEXT: sum = clad::pop(_t2); //CHECK-NEXT: float _r_d1 = _d_sum; //CHECK-NEXT: _d_x[i] += _r_d1; -//CHECK-NEXT: float _r1 = clad::pop(_EERepl_sum1); -//CHECK-NEXT: _delta_sum += std::abs(_r_d1 * _r1 * {{.+}}); //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: _final_error += std::abs(_d_x[i] * x[i] * {{.+}}); //CHECK-NEXT: x[i] = clad::pop(_t1); //CHECK-NEXT: float _r_d0 = _d_x[i]; //CHECK-NEXT: _d_y[i] += _r_d0; -//CHECK-NEXT: float _r0 = clad::pop(_EERepl_x1); -//CHECK-NEXT: _delta_x[i] += std::abs(_r_d0 * _r0 * {{.+}}); -//CHECK-NEXT: _final_error += _delta_x[i]; //CHECK-NEXT: } //CHECK-NEXT: } -//CHECK-NEXT: _delta_sum += std::abs(_d_sum * _EERepl_sum0 * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(_d_sum * sum * {{.+}}); //CHECK-NEXT: int i0 = 0; -//CHECK-NEXT: for (; i0 < _d_x.size(); i0++) { -//CHECK-NEXT: double _t3 = std::abs(_d_x[i0] * _EERepl_x0[i0] * {{.+}}); -//CHECK-NEXT: _delta_x[i0] += _t3; -//CHECK-NEXT: _final_error += _t3; -//CHECK-NEXT: } -//CHECK-NEXT: clad::array _delta_y(_d_y.size()); +//CHECK-NEXT: for (; i0 < _d_x.size(); i0++) +//CHECK-NEXT: _final_error += std::abs(_d_x[i0] * x[i0] * {{.+}}); //CHECK-NEXT: i0 = 0; -//CHECK-NEXT: for (; i0 < _d_y.size(); i0++) { -//CHECK-NEXT: double _t4 = std::abs(_d_y[i0] * y[i0] * {{.+}}); -//CHECK-NEXT: _delta_y[i0] += _t4; -//CHECK-NEXT: _final_error += _t4; -//CHECK-NEXT: } -//CHECK-NEXT: _final_error += _delta_sum; +//CHECK-NEXT: for (; i0 < _d_y.size(); i0++) +//CHECK-NEXT: _final_error += std::abs(_d_y[i0] * y[i0] * {{.+}}); //CHECK-NEXT: } @@ -271,26 +212,15 @@ double func5(double* x, double* y, double* output) { //CHECK: void func5_grad(double *x, double *y, double *output, clad::array_ref _d_x, clad::array_ref _d_y, clad::array_ref _d_output, double &_final_error) { //CHECK-NEXT: double _t0; -//CHECK-NEXT: clad::array _delta_output(_d_output.size()); -//CHECK-NEXT: clad::array _EERepl_output0(_d_output.size()); -//CHECK-NEXT: for (int i = 0; i < _d_output.size(); i++) { -//CHECK-NEXT: _EERepl_output0[i] = output[i]; -//CHECK-NEXT: } -//CHECK-NEXT: double _EERepl_output1; //CHECK-NEXT: double _t1; -//CHECK-NEXT: double _EERepl_output2; //CHECK-NEXT: double _t2; -//CHECK-NEXT: double _EERepl_output3; //CHECK-NEXT: double _ret_value0 = 0; //CHECK-NEXT: _t0 = output[0]; //CHECK-NEXT: output[0] = x[1] * y[2] - x[2] * y[1]; -//CHECK-NEXT: _EERepl_output1 = output[0]; //CHECK-NEXT: _t1 = output[1]; //CHECK-NEXT: output[1] = x[2] * y[0] - x[0] * y[2]; -//CHECK-NEXT: _EERepl_output2 = output[1]; //CHECK-NEXT: _t2 = output[2]; //CHECK-NEXT: output[2] = x[0] * y[1] - y[0] * x[1]; -//CHECK-NEXT: _EERepl_output3 = output[2]; //CHECK-NEXT: _ret_value0 = output[0] + output[1] + output[2]; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: @@ -300,6 +230,7 @@ double func5(double* x, double* y, double* output) { //CHECK-NEXT: _d_output[2] += 1; //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: _final_error += std::abs(_d_output[2] * output[2] * {{.+}}); //CHECK-NEXT: output[2] = _t2; //CHECK-NEXT: double _r_d2 = _d_output[2]; //CHECK-NEXT: _d_output[2] -= _r_d2; @@ -307,10 +238,9 @@ double func5(double* x, double* y, double* output) { //CHECK-NEXT: _d_y[1] += x[0] * _r_d2; //CHECK-NEXT: _d_y[0] += -_r_d2 * x[1]; //CHECK-NEXT: _d_x[1] += y[0] * -_r_d2; -//CHECK-NEXT: _delta_output[2] += std::abs(_r_d2 * _EERepl_output3 * {{.+}}); -//CHECK-NEXT: _final_error += _delta_output[2]; //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: _final_error += std::abs(_d_output[1] * output[1] * {{.+}}); //CHECK-NEXT: output[1] = _t1; //CHECK-NEXT: double _r_d1 = _d_output[1]; //CHECK-NEXT: _d_output[1] -= _r_d1; @@ -318,10 +248,9 @@ double func5(double* x, double* y, double* output) { //CHECK-NEXT: _d_y[0] += x[2] * _r_d1; //CHECK-NEXT: _d_x[0] += -_r_d1 * y[2]; //CHECK-NEXT: _d_y[2] += x[0] * -_r_d1; -//CHECK-NEXT: _delta_output[1] += std::abs(_r_d1 * _EERepl_output2 * {{.+}}); -//CHECK-NEXT: _final_error += _delta_output[1]; //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: _final_error += std::abs(_d_output[0] * output[0] * {{.+}}); //CHECK-NEXT: output[0] = _t0; //CHECK-NEXT: double _r_d0 = _d_output[0]; //CHECK-NEXT: _d_output[0] -= _r_d0; @@ -329,29 +258,16 @@ double func5(double* x, double* y, double* output) { //CHECK-NEXT: _d_y[2] += x[1] * _r_d0; //CHECK-NEXT: _d_x[2] += -_r_d0 * y[1]; //CHECK-NEXT: _d_y[1] += x[2] * -_r_d0; -//CHECK-NEXT: _delta_output[0] += std::abs(_r_d0 * _EERepl_output1 * {{.+}}); -//CHECK-NEXT: _final_error += _delta_output[0]; //CHECK-NEXT: } -//CHECK-NEXT: clad::array _delta_x(_d_x.size()); //CHECK-NEXT: int i = 0; -//CHECK-NEXT: for (; i < _d_x.size(); i++) { -//CHECK-NEXT: double _t3 = std::abs(_d_x[i] * x[i] * {{.+}}); -//CHECK-NEXT: _delta_x[i] += _t3; -//CHECK-NEXT: _final_error += _t3; -//CHECK-NEXT: } -//CHECK-NEXT: clad::array _delta_y(_d_y.size()); +//CHECK-NEXT: for (; i < _d_x.size(); i++) +//CHECK-NEXT: _final_error += std::abs(_d_x[i] * x[i] * {{.+}}); //CHECK-NEXT: i = 0; -//CHECK-NEXT: for (; i < _d_y.size(); i++) { -//CHECK-NEXT: double _t4 = std::abs(_d_y[i] * y[i] * {{.+}}); -//CHECK-NEXT: _delta_y[i] += _t4; -//CHECK-NEXT: _final_error += _t4; -//CHECK-NEXT: } +//CHECK-NEXT: for (; i < _d_y.size(); i++) +//CHECK-NEXT: _final_error += std::abs(_d_y[i] * y[i] * {{.+}}); //CHECK-NEXT: i = 0; -//CHECK-NEXT: for (; i < _d_output.size(); i++) { -//CHECK-NEXT: double _t5 = std::abs(_d_output[i] * _EERepl_output0[i] * {{.+}}); -//CHECK-NEXT: _delta_output[i] += _t5; -//CHECK-NEXT: _final_error += _t5; -//CHECK-NEXT: } +//CHECK-NEXT: for (; i < _d_output.size(); i++) +//CHECK-NEXT: _final_error += std::abs(_d_output[i] * output[i] * {{.+}}); //CHECK-NEXT: _final_error += std::abs(1. * _ret_value0 * {{.+}}); //CHECK-NEXT: } diff --git a/test/ErrorEstimation/LoopsAndArraysExec.C b/test/ErrorEstimation/LoopsAndArraysExec.C index 5bc4f2daa..3e53fc399 100644 --- a/test/ErrorEstimation/LoopsAndArraysExec.C +++ b/test/ErrorEstimation/LoopsAndArraysExec.C @@ -17,21 +17,16 @@ double runningSum(float* f, int n) { //CHECK: void runningSum_grad(float *f, int n, clad::array_ref _d_f, clad::array_ref _d_n, double &_final_error) { //CHECK-NEXT: double _d_sum = 0; -//CHECK-NEXT: double _delta_sum = 0; -//CHECK-NEXT: double _EERepl_sum0; //CHECK-NEXT: unsigned long _t0; //CHECK-NEXT: int _d_i = 0; //CHECK-NEXT: int i = 0; //CHECK-NEXT: clad::tape _t1 = {}; -//CHECK-NEXT: clad::tape _EERepl_sum1 = {}; //CHECK-NEXT: double sum = 0; -//CHECK-NEXT: _EERepl_sum0 = sum; //CHECK-NEXT: _t0 = 0; //CHECK-NEXT: for (i = 1; i < n; i++) { //CHECK-NEXT: _t0++; //CHECK-NEXT: clad::push(_t1, sum); //CHECK-NEXT: sum += f[i] + f[i - 1]; -//CHECK-NEXT: clad::push(_EERepl_sum1, sum); //CHECK-NEXT: } //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: @@ -39,23 +34,17 @@ double runningSum(float* f, int n) { //CHECK-NEXT: for (; _t0; _t0--) { //CHECK-NEXT: i--; //CHECK-NEXT: { +//CHECK-NEXT: _final_error += std::abs(_d_sum * sum * {{.+}}); //CHECK-NEXT: sum = clad::pop(_t1); //CHECK-NEXT: double _r_d0 = _d_sum; //CHECK-NEXT: _d_f[i] += _r_d0; //CHECK-NEXT: _d_f[i - 1] += _r_d0; -//CHECK-NEXT: double _r0 = clad::pop(_EERepl_sum1); -//CHECK-NEXT: _delta_sum += std::abs(_r_d0 * _r0 * {{.+}}); //CHECK-NEXT: } //CHECK-NEXT: } -//CHECK-NEXT: _delta_sum += std::abs(_d_sum * _EERepl_sum0 * {{.+}}); -//CHECK-NEXT: clad::array _delta_f(_d_f.size()); +//CHECK-NEXT: _final_error += std::abs(_d_sum * sum * {{.+}}); //CHECK-NEXT: int i0 = 0; -//CHECK-NEXT: for (; i0 < _d_f.size(); i0++) { -//CHECK-NEXT: double _t2 = std::abs(_d_f[i0] * f[i0] * {{.+}}); -//CHECK-NEXT: _delta_f[i0] += _t2; -//CHECK-NEXT: _final_error += _t2; -//CHECK-NEXT: } -//CHECK-NEXT: _final_error += _delta_sum; +//CHECK-NEXT: for (; i0 < _d_f.size(); i0++) +//CHECK-NEXT: _final_error += std::abs(_d_f[i0] * f[i0] * {{.+}}); //CHECK-NEXT: } double mulSum(float* a, float* b, int n) { @@ -69,8 +58,6 @@ double mulSum(float* a, float* b, int n) { //CHECK: void mulSum_grad(float *a, float *b, int n, clad::array_ref _d_a, clad::array_ref _d_b, clad::array_ref _d_n, double &_final_error) { //CHECK-NEXT: double _d_sum = 0; -//CHECK-NEXT: double _delta_sum = 0; -//CHECK-NEXT: double _EERepl_sum0; //CHECK-NEXT: unsigned long _t0; //CHECK-NEXT: int _d_i = 0; //CHECK-NEXT: int i = 0; @@ -79,9 +66,7 @@ double mulSum(float* a, float* b, int n) { //CHECK-NEXT: int _d_j = 0; //CHECK-NEXT: int j = 0; //CHECK-NEXT: clad::tape _t3 = {}; -//CHECK-NEXT: clad::tape _EERepl_sum1 = {}; //CHECK-NEXT: double sum = 0; -//CHECK-NEXT: _EERepl_sum0 = sum; //CHECK-NEXT: _t0 = 0; //CHECK-NEXT: for (i = 0; i < n; i++) { //CHECK-NEXT: _t0++; @@ -90,7 +75,6 @@ double mulSum(float* a, float* b, int n) { //CHECK-NEXT: clad::back(_t1)++; //CHECK-NEXT: clad::push(_t3, sum); //CHECK-NEXT: sum += a[i] * b[j]; -//CHECK-NEXT: clad::push(_EERepl_sum1, sum); //CHECK-NEXT: } //CHECK-NEXT: } //CHECK-NEXT: goto _label0; @@ -101,12 +85,11 @@ double mulSum(float* a, float* b, int n) { //CHECK-NEXT: { //CHECK-NEXT: for (; clad::back(_t1); clad::back(_t1)--) { //CHECK-NEXT: j--; +//CHECK-NEXT: _final_error += std::abs(_d_sum * sum * {{.+}}); //CHECK-NEXT: sum = clad::pop(_t3); //CHECK-NEXT: double _r_d0 = _d_sum; //CHECK-NEXT: _d_a[i] += _r_d0 * b[j]; //CHECK-NEXT: _d_b[j] += a[i] * _r_d0; -//CHECK-NEXT: double _r0 = clad::pop(_EERepl_sum1); -//CHECK-NEXT: _delta_sum += std::abs(_r_d0 * _r0 * {{.+}}); //CHECK-NEXT: } //CHECK-NEXT: { //CHECK-NEXT: _d_j = 0; @@ -115,22 +98,13 @@ double mulSum(float* a, float* b, int n) { //CHECK-NEXT: clad::pop(_t1); //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: _final_error += std::abs(_d_sum * sum * {{.+}}); //CHECK-NEXT: int i0 = 0; -//CHECK-NEXT: for (; i0 < _d_a.size(); i0++) { -//CHECK-NEXT: double _t4 = std::abs(_d_a[i0] * a[i0] * {{.+}}); -//CHECK-NEXT: _delta_a[i0] += _t4; -//CHECK-NEXT: _final_error += _t4; -//CHECK-NEXT: } -//CHECK-NEXT: clad::array _delta_b(_d_b.size()); +//CHECK-NEXT: for (; i0 < _d_a.size(); i0++) +//CHECK-NEXT: _final_error += std::abs(_d_a[i0] * a[i0] * {{.+}}); //CHECK-NEXT: i0 = 0; -//CHECK-NEXT: for (; i0 < _d_b.size(); i0++) { -//CHECK-NEXT: double _t5 = std::abs(_d_b[i0] * b[i0] * {{.+}}); -//CHECK-NEXT: _delta_b[i0] += _t5; -//CHECK-NEXT: _final_error += _t5; -//CHECK-NEXT: } -//CHECK-NEXT: _final_error += _delta_sum; +//CHECK-NEXT: for (; i0 < _d_b.size(); i0++) +//CHECK-NEXT: _final_error += std::abs(_d_b[i0] * b[i0] * {{.+}}); //CHECK-NEXT: } double divSum(float* a, float* b, int n) { @@ -143,21 +117,16 @@ double divSum(float* a, float* b, int n) { //CHECK: void divSum_grad(float *a, float *b, int n, clad::array_ref _d_a, clad::array_ref _d_b, clad::array_ref _d_n, double &_final_error) { //CHECK-NEXT: double _d_sum = 0; -//CHECK-NEXT: double _delta_sum = 0; -//CHECK-NEXT: double _EERepl_sum0; //CHECK-NEXT: unsigned long _t0; //CHECK-NEXT: int _d_i = 0; //CHECK-NEXT: int i = 0; //CHECK-NEXT: clad::tape _t1 = {}; -//CHECK-NEXT: clad::tape _EERepl_sum1 = {}; //CHECK-NEXT: double sum = 0; -//CHECK-NEXT: _EERepl_sum0 = sum; //CHECK-NEXT: _t0 = 0; //CHECK-NEXT: for (i = 0; i < n; i++) { //CHECK-NEXT: _t0++; //CHECK-NEXT: clad::push(_t1, sum); //CHECK-NEXT: sum += a[i] / b[i]; -//CHECK-NEXT: clad::push(_EERepl_sum1, sum); //CHECK-NEXT: } //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: @@ -165,31 +134,21 @@ double divSum(float* a, float* b, int n) { //CHECK-NEXT: for (; _t0; _t0--) { //CHECK-NEXT: i--; //CHECK-NEXT: { +//CHECK-NEXT: _final_error += std::abs(_d_sum * sum * {{.+}}); //CHECK-NEXT: sum = clad::pop(_t1); //CHECK-NEXT: double _r_d0 = _d_sum; //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: _final_error += std::abs(_d_sum * sum * {{.+}}); //CHECK-NEXT: int i0 = 0; -//CHECK-NEXT: for (; i0 < _d_a.size(); i0++) { -//CHECK-NEXT: double _t2 = std::abs(_d_a[i0] * a[i0] * {{.+}}); -//CHECK-NEXT: _delta_a[i0] += _t2; -//CHECK-NEXT: _final_error += _t2; -//CHECK-NEXT: } -//CHECK-NEXT: clad::array _delta_b(_d_b.size()); +//CHECK-NEXT: for (; i0 < _d_a.size(); i0++) +//CHECK-NEXT: _final_error += std::abs(_d_a[i0] * a[i0] * {{.+}}); //CHECK-NEXT: i0 = 0; -//CHECK-NEXT: for (; i0 < _d_b.size(); i0++) { -//CHECK-NEXT: double _t3 = std::abs(_d_b[i0] * b[i0] * {{.+}}); -//CHECK-NEXT: _delta_b[i0] += _t3; -//CHECK-NEXT: _final_error += _t3; -//CHECK-NEXT: } -//CHECK-NEXT: _final_error += _delta_sum; +//CHECK-NEXT: for (; i0 < _d_b.size(); i0++) +//CHECK-NEXT: _final_error += std::abs(_d_b[i0] * b[i0] * {{.+}}); //CHECK-NEXT: } int main() { diff --git a/test/Misc/RunDemos.C b/test/Misc/RunDemos.C index 3830821d7..f58e58a18 100644 --- a/test/Misc/RunDemos.C +++ b/test/Misc/RunDemos.C @@ -108,21 +108,16 @@ //CHECK_FLOAT_SUM: void vanillaSum_grad(float x, unsigned int n, clad::array_ref _d_x, clad::array_ref _d_n, double &_final_error) { //CHECK_FLOAT_SUM: float _d_sum = 0; -//CHECK_FLOAT_SUM: double _delta_sum = 0; -//CHECK_FLOAT_SUM: float _EERepl_sum0; //CHECK_FLOAT_SUM: unsigned long _t0; //CHECK_FLOAT_SUM: unsigned int _d_i = 0; //CHECK_FLOAT_SUM: unsigned int i = 0; //CHECK_FLOAT_SUM: clad::tape _t1 = {}; -//CHECK_FLOAT_SUM: clad::tape _EERepl_sum1 = {}; //CHECK_FLOAT_SUM: float sum = 0.; -//CHECK_FLOAT_SUM: _EERepl_sum0 = sum; //CHECK_FLOAT_SUM: _t0 = 0; //CHECK_FLOAT_SUM: for (i = 0; i < n; i++) { //CHECK_FLOAT_SUM: _t0++; //CHECK_FLOAT_SUM: clad::push(_t1, sum); //CHECK_FLOAT_SUM: sum = sum + x; -//CHECK_FLOAT_SUM: clad::push(_EERepl_sum1, sum); //CHECK_FLOAT_SUM: } //CHECK_FLOAT_SUM: goto _label0; //CHECK_FLOAT_SUM: _label0: @@ -130,19 +125,16 @@ //CHECK_FLOAT_SUM: for (; _t0; _t0--) { //CHECK_FLOAT_SUM: i--; //CHECK_FLOAT_SUM: { +//CHECK_FLOAT_SUM: _final_error += std::abs(_d_sum * sum * 1.1920928955078125E-7); //CHECK_FLOAT_SUM: sum = clad::pop(_t1); //CHECK_FLOAT_SUM: float _r_d0 = _d_sum; //CHECK_FLOAT_SUM: _d_sum -= _r_d0; //CHECK_FLOAT_SUM: _d_sum += _r_d0; //CHECK_FLOAT_SUM: * _d_x += _r_d0; -//CHECK_FLOAT_SUM: float _r0 = clad::pop(_EERepl_sum1); -//CHECK_FLOAT_SUM: _delta_sum += std::abs(_r_d0 * _r0 * 1.1920928955078125E-7); //CHECK_FLOAT_SUM: } //CHECK_FLOAT_SUM: } -//CHECK_FLOAT_SUM: _delta_sum += std::abs(_d_sum * _EERepl_sum0 * 1.1920928955078125E-7); -//CHECK_FLOAT_SUM: double _delta_x = 0; -//CHECK_FLOAT_SUM: _delta_x += std::abs(* _d_x * x * 1.1920928955078125E-7); -//CHECK_FLOAT_SUM: _final_error += _delta_x + _delta_sum; +//CHECK_FLOAT_SUM: _final_error += std::abs(_d_sum * sum * 1.1920928955078125E-7); +//CHECK_FLOAT_SUM: _final_error += std::abs(* _d_x * x * 1.1920928955078125E-7); //CHECK_FLOAT_SUM: } //-----------------------------------------------------------------------------/ @@ -160,31 +152,23 @@ // CHECK_CUSTOM_MODEL_EXEC: The code is: // CHECK_CUSTOM_MODEL_EXEC-NEXT: void func_grad(float x, float y, clad::array_ref _d_x, clad::array_ref _d_y, double &_final_error) { // CHECK_CUSTOM_MODEL_EXEC-NEXT: float _d_z = 0; -// CHECK_CUSTOM_MODEL_EXEC-NEXT: double _delta_z = 0; -// CHECK_CUSTOM_MODEL_EXEC-NEXT: float _EERepl_z0; // CHECK_CUSTOM_MODEL_EXEC-NEXT: float _t0; -// CHECK_CUSTOM_MODEL_EXEC-NEXT: float _EERepl_z1; // CHECK_CUSTOM_MODEL_EXEC-NEXT: float z; -// CHECK_CUSTOM_MODEL_EXEC-NEXT: _EERepl_z0 = z; // CHECK_CUSTOM_MODEL_EXEC-NEXT: _t0 = z; // CHECK_CUSTOM_MODEL_EXEC-NEXT: z = x + y; -// CHECK_CUSTOM_MODEL_EXEC-NEXT: _EERepl_z1 = z; // CHECK_CUSTOM_MODEL_EXEC-NEXT: goto _label0; // CHECK_CUSTOM_MODEL_EXEC-NEXT: _label0: // CHECK_CUSTOM_MODEL_EXEC-NEXT: _d_z += 1; // CHECK_CUSTOM_MODEL_EXEC-NEXT: { +// CHECK_CUSTOM_MODEL_EXEC-NEXT: _final_error += _d_z * z; // CHECK_CUSTOM_MODEL_EXEC-NEXT: z = _t0; // CHECK_CUSTOM_MODEL_EXEC-NEXT: float _r_d0 = _d_z; // CHECK_CUSTOM_MODEL_EXEC-NEXT: _d_z -= _r_d0; // CHECK_CUSTOM_MODEL_EXEC-NEXT: * _d_x += _r_d0; // CHECK_CUSTOM_MODEL_EXEC-NEXT: * _d_y += _r_d0; -// CHECK_CUSTOM_MODEL_EXEC-NEXT: _delta_z += _r_d0 * _EERepl_z1; // CHECK_CUSTOM_MODEL_EXEC-NEXT: } -// CHECK_CUSTOM_MODEL_EXEC-NEXT: double _delta_x = 0; -// CHECK_CUSTOM_MODEL_EXEC-NEXT: _delta_x += * _d_x * x; -// CHECK_CUSTOM_MODEL_EXEC-NEXT: double _delta_y = 0; -// CHECK_CUSTOM_MODEL_EXEC-NEXT: _delta_y += * _d_y * y; -// CHECK_CUSTOM_MODEL_EXEC-NEXT: _final_error += _delta_{{x|y|z}} + _delta_{{x|y|z}} + _delta_{{x|y|z}}; +// CHECK_CUSTOM_MODEL_EXEC-NEXT: _final_error += * _d_x * x; +// CHECK_CUSTOM_MODEL_EXEC-NEXT: _final_error += * _d_y * y; // CHECK_CUSTOM_MODEL_EXEC-NEXT: } //-----------------------------------------------------------------------------/ @@ -202,31 +186,23 @@ // CHECK_PRINT_MODEL_EXEC: The code is: // CHECK_PRINT_MODEL_EXEC-NEXT: void func_grad(float x, float y, clad::array_ref _d_x, clad::array_ref _d_y, double &_final_error) { // CHECK_PRINT_MODEL_EXEC-NEXT: float _d_z = 0; -// CHECK_PRINT_MODEL_EXEC-NEXT: double _delta_z = 0; -// CHECK_PRINT_MODEL_EXEC-NEXT: float _EERepl_z0; // CHECK_PRINT_MODEL_EXEC-NEXT: float _t0; -// CHECK_PRINT_MODEL_EXEC-NEXT: float _EERepl_z1; // CHECK_PRINT_MODEL_EXEC-NEXT: float z; -// CHECK_PRINT_MODEL_EXEC-NEXT: _EERepl_z0 = z; // CHECK_PRINT_MODEL_EXEC-NEXT: _t0 = z; // CHECK_PRINT_MODEL_EXEC-NEXT: z = x + y; -// CHECK_PRINT_MODEL_EXEC-NEXT: _EERepl_z1 = z; // CHECK_PRINT_MODEL_EXEC-NEXT: goto _label0; // CHECK_PRINT_MODEL_EXEC-NEXT: _label0: // CHECK_PRINT_MODEL_EXEC-NEXT: _d_z += 1; // CHECK_PRINT_MODEL_EXEC-NEXT: { +// CHECK_PRINT_MODEL_EXEC-NEXT: _final_error += clad::getErrorVal(_d_z, z, "z"); // CHECK_PRINT_MODEL_EXEC-NEXT: z = _t0; // CHECK_PRINT_MODEL_EXEC-NEXT: float _r_d0 = _d_z; // CHECK_PRINT_MODEL_EXEC-NEXT: _d_z -= _r_d0; // CHECK_PRINT_MODEL_EXEC-NEXT: * _d_x += _r_d0; // CHECK_PRINT_MODEL_EXEC-NEXT: * _d_y += _r_d0; -// CHECK_PRINT_MODEL_EXEC-NEXT: _delta_z += clad::getErrorVal(_r_d0, _EERepl_z1, "z"); // CHECK_PRINT_MODEL_EXEC-NEXT: } -// CHECK_PRINT_MODEL_EXEC-NEXT: double _delta_x = 0; -// CHECK_PRINT_MODEL_EXEC-NEXT: _delta_x += clad::getErrorVal(* _d_x, x, "x"); -// CHECK_PRINT_MODEL_EXEC-NEXT: double _delta_y = 0; -// CHECK_PRINT_MODEL_EXEC-NEXT: _delta_y += clad::getErrorVal(* _d_y, y, "y"); -// CHECK_PRINT_MODEL_EXEC-NEXT: _final_error += _delta_{{x|y|z}} + _delta_{{x|y|z}} + _delta_{{x|y|z}}; +// CHECK_PRINT_MODEL_EXEC-NEXT: _final_error += clad::getErrorVal(* _d_x, x, "x"); +// CHECK_PRINT_MODEL_EXEC-NEXT: _final_error += clad::getErrorVal(* _d_y, y, "y"); // CHECK_PRINT_MODEL_EXEC-NEXT: } // CHECK_PRINT_MODEL_EXEC: Error in z : {{.+}} // CHECK_PRINT_MODEL_EXEC-NEXT: Error in x : {{.+}}