diff --git a/include/clad/Differentiator/ErrorEstimator.h b/include/clad/Differentiator/ErrorEstimator.h index 1de49ad0b..9dc2a5320 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,23 +40,20 @@ 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_EstModel(nullptr), m_IdxExpr(nullptr) {} + : m_FinalError(nullptr), m_RetErrorExpr(nullptr), m_EstModel(nullptr), + m_IdxExpr(nullptr) {} ~ErrorEstimationHandler() override = default; /// Function to set the error estimation model currently in use. @@ -70,33 +65,16 @@ class ErrorEstimationHandler : public ExternalRMVSource { /// \param[in] finErrExpr The final error expression. void SetFinalErrorExpr(clang::Expr* finErrExpr) { m_FinalError = finErrExpr; } - /// Shorthand to get array subscript expressions. - /// - /// \param[in] arrBase The base expression of the array. - /// \param[in] idx The index expression. - /// \param[in] isCladSpType Keeps track of if we have to build a clad - /// special type (i.e. clad::Array or clad::ArrayRef). - /// - /// \returns An expression of the kind arrBase[idx]. - 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 +102,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. - /// - /// \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. - /// - /// \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. + /// Checks if a variable should be considered in error estimation. /// - /// \param[in] VD The variable declaration to be registered. + /// \param[in] VD The variable declaration. /// - /// \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 +116,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 +128,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 +143,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 +151,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. /// @@ -256,21 +172,19 @@ class ErrorEstimationHandler : public ExternalRMVSource { void ActBeforeDifferentiatingStmtInVisitCompoundStmt() override; void ActAfterProcessingStmtInVisitCompoundStmt() override; void ActBeforeDifferentiatingSingleStmtBranchInVisitIfStmt() override; - void ActBeforeFinalisingVisitBranchSingleStmtInIfVisitStmt() override; + void ActBeforeFinalizingVisitBranchSingleStmtInIfVisitStmt() override; void ActBeforeDifferentiatingLoopInitStmt() override; void ActBeforeDifferentiatingSingleStmtLoopBody() override; void ActAfterProcessingSingleStmtBodyInVisitForLoop() override; - void ActBeforeFinalisingVisitReturnStmt(StmtDiff& retExprDiff) override; - void ActBeforeFinalisingPostIncDecOp(StmtDiff& diff) override; + void ActBeforeFinalizingVisitReturnStmt(StmtDiff& retExprDiff) override; + void ActBeforeFinalizingPostIncDecOp(StmtDiff& diff) override; void ActBeforeFinalizingVisitCallExpr( const clang::CallExpr*& CE, clang::Expr*& fnDecl, 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 ActBeforeFinalizingAssignOp(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/EstimationModel.h b/include/clad/Differentiator/EstimationModel.h index 5ddb30715..2cb87fbde 100644 --- a/include/clad/Differentiator/EstimationModel.h +++ b/include/clad/Differentiator/EstimationModel.h @@ -34,20 +34,6 @@ namespace clad { /// Clear the variable estimate map so that we can start afresh. void clearEstimationVariables() { m_EstimateVar.clear(); } - /// Check if a variable is registered for estimation. - /// - /// \param[in] VD The variable to check. - /// - /// \returns The delta expression of the variable if it is registered, - /// nullptr otherwise. - clang::Expr* IsVariableRegistered(const clang::VarDecl* VD); - - /// Track the variable declaration and utilize it in error - /// estimation. - /// - /// \param[in] VD The declaration to track. - void AddVarToEstimate(clang::VarDecl* VD, clang::Expr* VDRef); - /// Helper to build a function call expression. /// /// \param[in] funcName The name of the function to build the expression @@ -86,31 +72,6 @@ namespace clad { virtual clang::Expr* AssignError(StmtDiff refExpr, const std::string& name) = 0; - /// Initializes errors for '_delta_' statements. - /// This function returns the initial error assignment. Similar to - /// AssignError, however, this function is only called during declaration of - /// variables. This function is separate from AssignError to keep - /// implementation of different estimation models more flexible. - /// - /// The default definition is as follows: - /// \n \code - /// clang::Expr* SetError(clang::VarDecl* declStmt) { - /// return nullptr; - /// } - /// \endcode - /// The above will return a 0 expression to be assigned to the '_delta_' - /// declaration of input decl. - /// - /// \param[in] decl The declaration to which the error has to be assigned. - /// - /// \returns The error expression for declaration statements. - virtual clang::Expr* SetError(clang::VarDecl* decl); - - /// Calculate aggregate error from m_EstimateVar. - /// - /// \returns the final error estimation statement. - clang::Expr* CalculateAggregateError(); - friend class ErrorEstimationHandler; }; diff --git a/include/clad/Differentiator/ExternalRMVSource.h b/include/clad/Differentiator/ExternalRMVSource.h index b5fcde1ab..4879cc18a 100644 --- a/include/clad/Differentiator/ExternalRMVSource.h +++ b/include/clad/Differentiator/ExternalRMVSource.h @@ -104,7 +104,7 @@ class ExternalRMVSource { /// This is called just before finalising processing of Single statement /// branch in `VisitBranch` lambda in - virtual void ActBeforeFinalisingVisitBranchSingleStmtInIfVisitStmt() {} + virtual void ActBeforeFinalizingVisitBranchSingleStmtInIfVisitStmt() {} /// This is called just before differentiating init statement of loops. virtual void ActBeforeDifferentiatingLoopInitStmt() {} @@ -117,7 +117,7 @@ class ExternalRMVSource { virtual void ActAfterProcessingSingleStmtBodyInVisitForLoop() {} /// This is called just before finalising `VisitReturnStmt`. - virtual void ActBeforeFinalisingVisitReturnStmt(StmtDiff& retExprDiff) {} + virtual void ActBeforeFinalizingVisitReturnStmt(StmtDiff& retExprDiff) {} /// This ic called just before finalising `VisitCallExpr`. /// @@ -131,15 +131,17 @@ class ExternalRMVSource { /// This is called just before finalising processing of post and pre /// increment and decrement operations. - virtual void ActBeforeFinalisingPostIncDecOp(StmtDiff& diff){}; + virtual void ActBeforeFinalizingPostIncDecOp(StmtDiff& diff){}; /// This is called just after cloning of LHS assignment operation. virtual void ActAfterCloningLHSOfAssignOp(clang::Expr*&, clang::Expr*&, 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 ActBeforeFinalizingAssignOp(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..2e1f35f8b 100644 --- a/include/clad/Differentiator/MultiplexExternalRMVSource.h +++ b/include/clad/Differentiator/MultiplexExternalRMVSource.h @@ -40,20 +40,21 @@ class MultiplexExternalRMVSource : public ExternalRMVSource { void ActBeforeDifferentiatingStmtInVisitCompoundStmt() override; void ActAfterProcessingStmtInVisitCompoundStmt() override; void ActBeforeDifferentiatingSingleStmtBranchInVisitIfStmt() override; - void ActBeforeFinalisingVisitBranchSingleStmtInIfVisitStmt() override; + void ActBeforeFinalizingVisitBranchSingleStmtInIfVisitStmt() override; void ActBeforeDifferentiatingLoopInitStmt() override; void ActBeforeDifferentiatingSingleStmtLoopBody() override; void ActAfterProcessingSingleStmtBodyInVisitForLoop() override; - void ActBeforeFinalisingVisitReturnStmt(StmtDiff& retExprDiff) override; + void ActBeforeFinalizingVisitReturnStmt(StmtDiff& retExprDiff) override; void ActBeforeFinalizingVisitCallExpr( const clang::CallExpr*& CE, clang::Expr*& OverloadedDerivedFn, llvm::SmallVectorImpl& derivedCallArgs, llvm::SmallVectorImpl& ArgResultDecls, bool asGrad) override; - void ActBeforeFinalisingPostIncDecOp(StmtDiff& diff) override; + void ActBeforeFinalizingPostIncDecOp(StmtDiff& diff) override; void ActAfterCloningLHSOfAssignOp(clang::Expr*&, clang::Expr*&, clang::BinaryOperatorKind& opCode) override; - void ActBeforeFinalisingAssignOp(clang::Expr*&, clang::Expr*&) override; + void ActBeforeFinalizingAssignOp(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/include/clad/Differentiator/VisitorBase.h b/include/clad/Differentiator/VisitorBase.h index b6c95662a..eabcac02f 100644 --- a/include/clad/Differentiator/VisitorBase.h +++ b/include/clad/Differentiator/VisitorBase.h @@ -424,6 +424,13 @@ namespace clad { clang::Expr* BuildArraySubscript(clang::Expr* Base, const llvm::SmallVectorImpl& IS); + + /// Build an array subscript expression with a given base expression and + /// one index. + clang::Expr* BuildArraySubscript(clang::Expr* Base, clang::Expr*& Idx) { + llvm::SmallVector IS = {Idx}; + return BuildArraySubscript(Base, IS); + } /// Find namespace clad declaration. clang::NamespaceDecl* GetCladNamespace(); /// Find declaration of clad::class templated type diff --git a/lib/Differentiator/ErrorEstimator.cpp b/lib/Differentiator/ErrorEstimator.cpp index cbab2a49e..358e36cfb 100644 --- a/lib/Differentiator/ErrorEstimator.cpp +++ b/lib/Differentiator/ErrorEstimator.cpp @@ -17,8 +17,7 @@ QualType getUnderlyingArrayType(QualType baseType, ASTContext& C) { } else if (auto PTType = baseType->getAs()) { return PTType->getPointeeType(); } - assert(0 && "Unreachable"); - return {}; + return baseType; } Expr* UpdateErrorForFuncCallAssigns(ErrorEstimationHandler* handler, @@ -39,65 +38,30 @@ void ErrorEstimationHandler::SetErrorEstimationModel( m_EstModel = estModel; } -Expr* ErrorEstimationHandler::getArraySubscriptExpr( - Expr* arrBase, Expr* idx, bool isCladSpType /*=true*/) { - if (isCladSpType) { - return m_RMV->m_Sema - .ActOnArraySubscriptExpr(m_RMV->getCurrentScope(), arrBase, - arrBase->getExprLoc(), idx, noLoc) - .get(); - } else { - return m_RMV->m_Sema - .CreateBuiltinArraySubscriptExpr(arrBase, noLoc, idx, noLoc) - .get(); - } -} - -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,124 +116,11 @@ 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(); - QualType varDeclType = - utils::isArrayOrPointerType(varDeclBase) - ? getUnderlyingArrayType(varDeclBase, m_RMV->m_Context) - : varDeclBase; + QualType varDeclType = getUnderlyingArrayType(varDeclBase, m_RMV->m_Context); const Expr* init = VD->getInit(); // If declarationg type in not floating point type, we want to do two // things. @@ -315,44 +166,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], - params[i]->getNameAsString()); + 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 +189,20 @@ void ErrorEstimationHandler::EmitFinalErrorStmts( m_RMV->getZeroInit(m_RMV->m_Context.IntTy)); m_IdxExpr = m_RMV->BuildDeclRef(idxExprDecl); } - Expr *Ldiff, *Ldelta; - 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); + Expr* Ldiff = nullptr; + Ldiff = m_RMV->BuildArraySubscript(LdiffExpr, m_IdxExpr); + auto* paramClone = m_RMV->BuildDeclRef(decl); + auto* LRepl = m_RMV->BuildArraySubscript(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 +217,7 @@ void ErrorEstimationHandler::EmitFinalErrorStmts( } } } - BuildFinalErrorStmt(); + BuildReturnErrorStmt(); } void ErrorEstimationHandler::EmitUnaryOpErrorStmts(StmtDiff var, @@ -412,69 +226,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(), - DRE->getDecl()->getNameAsString()); - AddErrorStmtToBlock(var.getExpr(), deltaVar, erroExpr, isInsideLoop); + if (ShouldEstimateErrorFor(cast(DRE->getDecl()))) { + Expr* erroExpr = + GetError(DRE, var.getExpr_dx(), DRE->getDecl()->getNameAsString()); + 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(); - Expr* errorExpr = - UpdateErrorForFuncCallAssigns(this, savedExpr.getExpr_dx(), oldValue, - m_NestedFuncError, decl->getNameAsString()); - AddErrorStmtToBlock(LExpr, deltaVar, errorExpr, isInsideLoop); + if (!ShouldEstimateErrorFor(cast(decl))) + return; + bool errorFromFunctionCall = (bool)m_NestedFuncError; + Expr* errorExpr = UpdateErrorForFuncCallAssigns( + this, LExpr, oldValue, m_NestedFuncError, decl->getNameAsString()); + AddErrorStmtToBlock(errorExpr, /*addToTheFront=*/!errorFromFunctionCall); // If there are assign statements to emit in reverse, do that. EmitErrorEstimationStmts(direction::reverse); } @@ -482,21 +251,19 @@ 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(), - m_RMV->BuildDeclRef(VDDiff.getDecl_dx()), m_NestedFuncError, - VD->getNameAsString()); - AddErrorStmtToBlock(VDRef, EstVD, errorExpr, isInsideLoop); + this, VDRef, m_RMV->BuildDeclRef(VDDiff.getDecl_dx()), + m_NestedFuncError, VD->getNameAsString()); + AddErrorStmtToBlock(errorExpr, /*addToTheFront=*/!errorFromFunctionCall); } } } @@ -568,7 +335,7 @@ void ErrorEstimationHandler:: } void ErrorEstimationHandler:: - ActBeforeFinalisingVisitBranchSingleStmtInIfVisitStmt() { + ActBeforeFinalizingVisitBranchSingleStmtInIfVisitStmt() { // In error estimation, manually emit the code here instead of // DifferentiateSingleStmt to maintain correct order. EmitErrorEstimationStmts(direction::forward); @@ -587,7 +354,7 @@ void ErrorEstimationHandler::ActAfterProcessingSingleStmtBodyInVisitForLoop() { EmitErrorEstimationStmts(direction::forward); } -void ErrorEstimationHandler::ActBeforeFinalisingVisitReturnStmt( +void ErrorEstimationHandler::ActBeforeFinalizingVisitReturnStmt( StmtDiff& retExprDiff) { // If the return expression is not a DeclRefExpression and is of type // float, we should add it to the error estimate because returns are @@ -595,7 +362,7 @@ void ErrorEstimationHandler::ActBeforeFinalisingVisitReturnStmt( SaveReturnExpr(retExprDiff.getExpr()); } -void ErrorEstimationHandler::ActBeforeFinalisingPostIncDecOp(StmtDiff& diff) { +void ErrorEstimationHandler::ActBeforeFinalizingPostIncDecOp(StmtDiff& diff) { EmitUnaryOpErrorStmts(diff, m_RMV->isInsideLoop); } @@ -620,18 +387,17 @@ void ErrorEstimationHandler::ActBeforeFinalizingVisitCallExpr( } } -void ErrorEstimationHandler::ActAfterCloningLHSOfAssignOp( - clang::Expr*& LCloned, clang::Expr*& R, +void ErrorEstimationHandler::ActBeforeFinalizingAssignOp( + clang::Expr*& LCloned, clang::Expr*& oldValue, 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); + DeclRefExpr* RRef = GetUnderlyingDeclRefOrNull(R); + // 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 || !RRef) + EmitBinaryOpErrorStmts(LCloned, oldValue); } void ErrorEstimationHandler::ActBeforeFinalizingDifferentiateSingleStmt( diff --git a/lib/Differentiator/EstimationModel.cpp b/lib/Differentiator/EstimationModel.cpp index e72963c6f..da92afc04 100644 --- a/lib/Differentiator/EstimationModel.cpp +++ b/lib/Differentiator/EstimationModel.cpp @@ -15,44 +15,6 @@ namespace clad { FPErrorEstimationModel::~FPErrorEstimationModel() {} - Expr* FPErrorEstimationModel::IsVariableRegistered(const VarDecl* VD) { - auto it = m_EstimateVar.find(VD); - if (it != m_EstimateVar.end()) - return it->second; - return nullptr; - } - - void FPErrorEstimationModel::AddVarToEstimate(VarDecl* VD, Expr* VDRef) { - m_EstimateVar.emplace(VD, VDRef); - } - - // FIXME: Maybe this should be left to the user too. - Expr* FPErrorEstimationModel::CalculateAggregateError() { - Expr* addExpr = nullptr; - // Loop over all the error variables and form the final error expression of - // the form... _final_error = _delta_var + _delta_var1 +... - for (auto var : m_EstimateVar) { - // Errors through array subscript expressions are already captured - // to avoid having long add expression at the end and to only add - // the values to the final error that have a non zero delta. - if (isArrayOrPointerType(var.first->getType())) - continue; - - if (!addExpr) { - addExpr = var.second; - continue; - } - addExpr = BuildOp(BO_Add, addExpr, var.second); - } - // Return an expression that can be directly assigned to final error. - return addExpr; - } - - // Return nullptr here, this is interpreted as 0 internally. - Expr* FPErrorEstimationModel::SetError(VarDecl* declStmt) { - return nullptr; - } - Expr* FPErrorEstimationModel::GetFunctionCall( std::string funcName, std::string nmspace, llvm::SmallVectorImpl& callArgs) { diff --git a/lib/Differentiator/MultiplexExternalRMVSource.cpp b/lib/Differentiator/MultiplexExternalRMVSource.cpp index 1b6f9c10f..837990656 100644 --- a/lib/Differentiator/MultiplexExternalRMVSource.cpp +++ b/lib/Differentiator/MultiplexExternalRMVSource.cpp @@ -114,9 +114,9 @@ void MultiplexExternalRMVSource:: } void MultiplexExternalRMVSource:: - ActBeforeFinalisingVisitBranchSingleStmtInIfVisitStmt() { + ActBeforeFinalizingVisitBranchSingleStmtInIfVisitStmt() { for (auto source : m_Sources) { - source->ActBeforeFinalisingVisitBranchSingleStmtInIfVisitStmt(); + source->ActBeforeFinalizingVisitBranchSingleStmtInIfVisitStmt(); } } @@ -139,10 +139,10 @@ void MultiplexExternalRMVSource:: } } -void MultiplexExternalRMVSource::ActBeforeFinalisingVisitReturnStmt( +void MultiplexExternalRMVSource::ActBeforeFinalizingVisitReturnStmt( StmtDiff& retExprDiff) { for (auto source : m_Sources) { - source->ActBeforeFinalisingVisitReturnStmt(retExprDiff); + source->ActBeforeFinalizingVisitReturnStmt(retExprDiff); } } @@ -156,10 +156,10 @@ void MultiplexExternalRMVSource::ActBeforeFinalizingVisitCallExpr( } } -void MultiplexExternalRMVSource::ActBeforeFinalisingPostIncDecOp( +void MultiplexExternalRMVSource::ActBeforeFinalizingPostIncDecOp( StmtDiff& diff) { for (auto source : m_Sources) { - source->ActBeforeFinalisingPostIncDecOp(diff); + source->ActBeforeFinalizingPostIncDecOp(diff); } } void MultiplexExternalRMVSource::ActAfterCloningLHSOfAssignOp( @@ -169,10 +169,11 @@ void MultiplexExternalRMVSource::ActAfterCloningLHSOfAssignOp( } } -void MultiplexExternalRMVSource::ActBeforeFinalisingAssignOp( - clang::Expr*& LCloned, clang::Expr*& oldValue) { +void MultiplexExternalRMVSource::ActBeforeFinalizingAssignOp( + clang::Expr*& LCloned, clang::Expr*& oldValue, clang::Expr*& R, + clang::BinaryOperator::Opcode& opCode) { for (auto source : m_Sources) { - source->ActBeforeFinalisingAssignOp(LCloned, oldValue); + source->ActBeforeFinalizingAssignOp(LCloned, oldValue, R, opCode); } } diff --git a/lib/Differentiator/ReverseModeVisitor.cpp b/lib/Differentiator/ReverseModeVisitor.cpp index a181785ca..2bcd1a7f7 100644 --- a/lib/Differentiator/ReverseModeVisitor.cpp +++ b/lib/Differentiator/ReverseModeVisitor.cpp @@ -890,7 +890,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, if (m_ExternalSource) m_ExternalSource - ->ActBeforeFinalisingVisitBranchSingleStmtInIfVisitStmt(); + ->ActBeforeFinalizingVisitBranchSingleStmtInIfVisitStmt(); Stmt* Forward = unwrapIfSingleStmt(endBlock(direction::forward)); Stmt* Reverse = unwrapIfSingleStmt(BranchDiff.getStmt_dx()); @@ -1215,7 +1215,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, // ValueAndPushforward. if (!isCladValueAndPushforwardType(type)) { if (m_ExternalSource) - m_ExternalSource->ActBeforeFinalisingVisitReturnStmt(ExprDiff); + m_ExternalSource->ActBeforeFinalizingVisitReturnStmt(ExprDiff); } // Create goto to the label. @@ -2168,7 +2168,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, ResultRef = diff_dx; valueForRevPass = diff.getRevSweepAsExpr(); if (m_ExternalSource) - m_ExternalSource->ActBeforeFinalisingPostIncDecOp(diff); + m_ExternalSource->ActBeforeFinalizingPostIncDecOp(diff); } else if (opCode == UO_PreInc || opCode == UO_PreDec) { diff = Visit(E, dfdx()); Expr* diff_dx = diff.getExpr_dx(); @@ -2572,7 +2572,8 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, } else llvm_unreachable("unknown assignment opCode"); if (m_ExternalSource) - m_ExternalSource->ActBeforeFinalisingAssignOp(LCloned, oldValue); + m_ExternalSource->ActBeforeFinalizingAssignOp(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 4817fe4c6..f809f32b4 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; @@ -33,17 +29,15 @@ float func(float x, float y) { //CHECK-NEXT: * _d_x += _r_d1; //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: } -//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) { @@ -53,16 +47,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; @@ -70,10 +61,8 @@ 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: } -//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) { @@ -104,33 +93,24 @@ 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: } //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) { @@ -142,28 +122,22 @@ 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: } -//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; } @@ -172,9 +146,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); } @@ -188,11 +160,30 @@ 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: } + +float func8(int x, int y) { + x = y * y; + return x; +} + +//CHECK: void func8_grad(int x, int y, clad::array_ref _d_x, clad::array_ref _d_y, double &_final_error) { +//CHECK-NEXT: int _t0; +//CHECK-NEXT: _t0 = x; +//CHECK-NEXT: x = y * y; +//CHECK-NEXT: goto _label0; +//CHECK-NEXT: _label0: +//CHECK-NEXT: * _d_x += 1; +//CHECK-NEXT: { +//CHECK-NEXT: x = _t0; +//CHECK-NEXT: int _r_d0 = * _d_x; +//CHECK-NEXT: * _d_x -= _r_d0; +//CHECK-NEXT: * _d_y += _r_d0 * y; +//CHECK-NEXT: * _d_y += y * _r_d0; +//CHECK-NEXT: } //CHECK-NEXT: } int main() { @@ -203,4 +194,5 @@ int main() { clad::estimate_error(func5); clad::estimate_error(func6); clad::estimate_error(func7); + clad::estimate_error(func8); } diff --git a/test/ErrorEstimation/BasicOps.C b/test/ErrorEstimation/BasicOps.C index 104ca9721..75c4e1f96 100644 --- a/test/ErrorEstimation/BasicOps.C +++ b/test/ErrorEstimation/BasicOps.C @@ -15,56 +15,42 @@ 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: } //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: } -//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 @@ -77,27 +63,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; @@ -105,12 +85,9 @@ 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: } -//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: } @@ -124,34 +101,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; @@ -160,11 +125,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; @@ -172,11 +136,9 @@ 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: } -//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 @@ -196,11 +158,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 @@ -211,13 +171,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: @@ -226,17 +182,16 @@ 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: } -//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 @@ -251,11 +206,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) { @@ -265,11 +218,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: @@ -286,13 +236,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) { @@ -310,9 +258,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: } @@ -338,17 +284,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; @@ -361,14 +302,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) { @@ -380,24 +318,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; @@ -412,7 +345,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: } @@ -429,14 +362,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 f9454134b..aa01c61ea 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: } //CHECK-NEXT: } else { //CHECK-NEXT: { @@ -69,22 +60,21 @@ float func(float x, float y) { //CHECK-NEXT: * _d_y += _r_d2; //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 @@ -98,12 +88,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; @@ -125,13 +112,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; } @@ -150,11 +136,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) { @@ -165,11 +149,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) @@ -177,8 +157,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: @@ -188,21 +166,20 @@ float func4(float x, float y) { //CHECK-NEXT: * _d_x += _r0; //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: _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 253c7a68f..1bce92a9a 100644 --- a/test/ErrorEstimation/LoopsAndArrays.C +++ b/test/ErrorEstimation/LoopsAndArrays.C @@ -17,21 +17,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: @@ -39,22 +34,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: } @@ -69,28 +58,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: @@ -98,26 +79,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) { @@ -130,58 +107,45 @@ 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: } //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: } //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: } -//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]) { @@ -195,31 +159,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: @@ -227,36 +179,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: } @@ -269,26 +210,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: @@ -298,6 +228,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; @@ -305,10 +236,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; @@ -316,10 +246,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; @@ -327,29 +256,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 fb067c942..242413965 100644 --- a/test/ErrorEstimation/LoopsAndArraysExec.C +++ b/test/ErrorEstimation/LoopsAndArraysExec.C @@ -18,21 +18,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: @@ -40,23 +35,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) { @@ -70,8 +59,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; @@ -80,9 +67,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++; @@ -91,7 +76,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; @@ -102,12 +86,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; @@ -116,22 +99,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) { @@ -144,21 +118,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: @@ -166,31 +135,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 c72587d93..24dbf467c 100644 --- a/test/Misc/RunDemos.C +++ b/test/Misc/RunDemos.C @@ -109,21 +109,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: @@ -131,19 +126,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: } //-----------------------------------------------------------------------------/ @@ -161,31 +153,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: } //-----------------------------------------------------------------------------/ @@ -203,31 +187,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 : {{.+}}