diff --git a/include/clad/Differentiator/ErrorEstimator.h b/include/clad/Differentiator/ErrorEstimator.h index 1de49ad0b..a58749bc2 100644 --- a/include/clad/Differentiator/ErrorEstimator.h +++ b/include/clad/Differentiator/ErrorEstimator.h @@ -44,6 +44,8 @@ class ErrorEstimationHandler : public ExternalRMVSource { clang::Expr* m_IdxExpr; /// A set of declRefExprs for parameter value replacements. std::unordered_map m_ParamRepls; + /// A map from var decls to their size variables (e.g. `var_size`). + std::unordered_map m_ArrSizes; /// An expression to match nested function call errors with their /// assignee (if any exists). clang::Expr* m_NestedFuncError = nullptr; @@ -244,6 +246,11 @@ class ErrorEstimationHandler : public ExternalRMVSource { /// loop. void EmitDeclErrorStmts(VarDeclDiff VDDiff, bool isInsideLoop); + /// This function returns the size expression for a given variable + /// (`var.size()` for clad::array/clad::array_ref + /// or `var_size` for array/pointer types) + clang::Expr* getSizeExpr(const clang::VarDecl* VD); + void InitialiseRMV(ReverseModeVisitor& RMV) override; void ForgetRMV() override; void ActBeforeCreatingDerivedFnParamTypes(unsigned&) override; @@ -255,6 +262,7 @@ class ErrorEstimationHandler : public ExternalRMVSource { void ActOnEndOfDerivedFnBody() override; void ActBeforeDifferentiatingStmtInVisitCompoundStmt() override; void ActAfterProcessingStmtInVisitCompoundStmt() override; + void ActAfterProcessingArraySubscriptExpr(const clang::Expr* revArrSub) override; void ActBeforeDifferentiatingSingleStmtBranchInVisitIfStmt() override; void ActBeforeFinalisingVisitBranchSingleStmtInIfVisitStmt() override; void ActBeforeDifferentiatingLoopInitStmt() override; diff --git a/include/clad/Differentiator/ExternalRMVSource.h b/include/clad/Differentiator/ExternalRMVSource.h index b5fcde1ab..3b3d951e2 100644 --- a/include/clad/Differentiator/ExternalRMVSource.h +++ b/include/clad/Differentiator/ExternalRMVSource.h @@ -59,6 +59,9 @@ class ExternalRMVSource { virtual void ActAfterParsingDiffArgs(const DiffRequest& request, DiffParams& args) {} + /// This is called after processing array subscript expressions. + virtual void ActAfterProcessingArraySubscriptExpr(const clang::Expr* revArrSub) {} + /// This is called just before creating derived function parameter types. virtual void ActBeforeCreatingDerivedFnParamTypes(unsigned& numExtraParam) {} diff --git a/include/clad/Differentiator/MultiplexExternalRMVSource.h b/include/clad/Differentiator/MultiplexExternalRMVSource.h index 7864828b0..367d62f93 100644 --- a/include/clad/Differentiator/MultiplexExternalRMVSource.h +++ b/include/clad/Differentiator/MultiplexExternalRMVSource.h @@ -27,6 +27,7 @@ class MultiplexExternalRMVSource : public ExternalRMVSource { void ActOnEndOfDerive() override; void ActAfterParsingDiffArgs(const DiffRequest& request, DiffParams& args) override; + void ActAfterProcessingArraySubscriptExpr(const clang::Expr* revArrSub) override; void ActBeforeCreatingDerivedFnParamTypes(unsigned& numExtraParams) override; void ActAfterCreatingDerivedFnParamTypes( llvm::SmallVectorImpl& paramTypes) override; diff --git a/lib/Differentiator/ErrorEstimator.cpp b/lib/Differentiator/ErrorEstimator.cpp index cbab2a49e..16b5a0b48 100644 --- a/lib/Differentiator/ErrorEstimator.cpp +++ b/lib/Differentiator/ErrorEstimator.cpp @@ -184,13 +184,14 @@ void ErrorEstimationHandler::SaveParamValue(DeclRefExpr* paramRef) { std::string name = "_EERepl_" + paramDecl->getNameAsString(); VarDecl* savedDecl; if (utils::isArrayOrPointerType(paramType)) { - auto diffVar = m_RMV->m_Variables[paramDecl]; + Expr* size = getSizeExpr(paramDecl); auto QType = m_RMV->GetCladArrayOfType( getUnderlyingArrayType(paramType, m_RMV->m_Context)); savedDecl = m_RMV->BuildVarDecl( - QType, name, m_RMV->BuildArrayRefSizeExpr(diffVar), + QType, name, size, /*DirectInit=*/false, /*TSI=*/nullptr, VarDecl::InitializationStyle::CallInit); + size = m_RMV->Clone(size); m_RMV->AddToGlobalBlock(m_RMV->BuildDeclStmt(savedDecl)); ReverseModeVisitor::Stmts loopBody; // Get iter variable. @@ -205,7 +206,7 @@ void ErrorEstimationHandler::SaveParamValue(DeclRefExpr* paramRef) { getArraySubscriptExpr(paramRef, currIdx, /*isCladSpType=*/false))); Expr* conditionExpr = - m_RMV->BuildOp(BO_LT, currIdx, m_RMV->BuildArrayRefSizeExpr(diffVar)); + m_RMV->BuildOp(BO_LT, currIdx, size); Expr* incExpr = m_RMV->BuildOp(UO_PostInc, currIdx); // Make for loop. Stmt* ArrayParamLoop = new (m_RMV->m_Context) ForStmt( @@ -227,10 +228,14 @@ Expr* ErrorEstimationHandler::RegisterVariable(VarDecl* VD, // 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())) { + if (utils::isArrayOrPointerType(VDType)) { VarDecl* EstVD; - auto sizeExpr = m_RMV->BuildArrayRefSizeExpr(diffVar); + auto diffVar = m_RMV->m_Variables[VD]; + Expr* sizeExpr = nullptr; + if (m_RMV->isCladArrayType(diffVar->getType())) + sizeExpr = m_RMV->BuildArrayRefSizeExpr(diffVar); + else + sizeExpr = getSizeExpr(VD); QType = m_RMV->GetCladArrayOfType( getUnderlyingArrayType(VDType, m_RMV->m_Context)); EstVD = m_RMV->BuildVarDecl( @@ -243,8 +248,7 @@ Expr* ErrorEstimationHandler::RegisterVariable(VarDecl* VD, 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; + QType = m_RMV->m_Context.DoubleTy; init = init ? init : m_RMV->getZeroInit(QType); // Store the "_delta_*" value. if (!toCurrentScope) { @@ -355,6 +359,7 @@ void ErrorEstimationHandler::EmitFinalErrorStmts( m_RMV->BuildOp(BO_AddAssign, deltaVar, errorExpr)); } else { auto LdiffExpr = m_RMV->m_Variables[decl]; + Expr* size = getSizeExpr(decl); VarDecl* idxExprDecl = nullptr; // Save our index expression so it can be used later. if (!m_IdxExpr) { @@ -384,7 +389,7 @@ void ErrorEstimationHandler::EmitFinalErrorStmts( loopBody.push_back(deltaAssignExpr); loopBody.push_back(finalAssignExpr); Expr* conditionExpr = m_RMV->BuildOp( - BO_LT, m_IdxExpr, m_RMV->BuildArrayRefSizeExpr(LdiffExpr)); + BO_LT, m_IdxExpr, size); 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, @@ -421,7 +426,7 @@ void ErrorEstimationHandler::EmitUnaryOpErrorStmts(StmtDiff var, // 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. + // and pops. Expr* popVal = m_RMV->StoreAndRef(savedVar.getExpr_dx(), direction::reverse); savedVar = {savedVar.getExpr(), popVal}; @@ -562,6 +567,57 @@ void ErrorEstimationHandler::ActAfterProcessingStmtInVisitCompoundStmt() { EmitErrorEstimationStmts(direction::reverse); } +void ErrorEstimationHandler::ActAfterProcessingArraySubscriptExpr(const Expr* revArrSub) { + if (const auto* ASE = dyn_cast(revArrSub)) { + if (const auto* DRE = dyn_cast(ASE->getBase()->IgnoreImplicit())) { + const auto* VD = cast(DRE->getDecl()); + Expr* VDdiff = m_RMV->m_Variables[VD]; + // We only need to track sizes for arrays and pointers. + if (!utils::isArrayOrPointerType(VDdiff->getType())) + return; + // Here, we're essentially constructing `var_size = max(var_size, idx);`. + // However, due to the fact that `max` is not a standard function, + // we achieve the same with `var_size = (var_size >= idx) ? var_size : idx;` + Expr* size = getSizeExpr(VD); + Expr* idx = m_RMV->Clone(ASE->getIdx()); + Expr* compareSizeAndIdx = m_RMV->BuildOp(BO_GE, size, idx); + compareSizeAndIdx = utils::BuildParenExpr(m_RMV->m_Sema, compareSizeAndIdx); + size = m_RMV->Clone(size); + idx = m_RMV->Clone(idx); + Expr* extendedSize = m_RMV->m_Sema.ActOnConditionalOp(noLoc, + noLoc, + compareSizeAndIdx, + size, idx).get(); + size = m_RMV->Clone(size); + Stmt* updateSize = m_RMV->BuildOp(BO_Assign, size, extendedSize); + m_RMV->addToCurrentBlock(updateSize, direction::reverse); + } + } +} + +Expr* ErrorEstimationHandler::getSizeExpr(const VarDecl* VD) { + auto diffVar = m_RMV->m_Variables[VD]; + // Use `.size()` for clad::array. + if (m_RMV->isCladArrayType(diffVar->getType())) + return m_RMV->BuildArrayRefSizeExpr(diffVar); + + // For every array/pointer variable `arr` + // we create `arr_size` to track the size. + auto foundSize = m_ArrSizes.find(VD); + // If the size variable is already generated, just clone the decl ref. + if (foundSize!=m_ArrSizes.end()) { + return m_RMV->Clone(foundSize->second); + } + // If the size variable is not generated yet, + // generate it now. + QualType intTy = m_RMV->m_Context.getSizeType(); + VarDecl* sizeVD = m_RMV->BuildGlobalVarDecl(intTy, VD->getNameAsString() + "_size", m_RMV->getZeroInit(intTy)); + m_RMV->AddToGlobalBlock(m_RMV->BuildDeclStmt(sizeVD)); + Expr* size = m_RMV->BuildDeclRef(sizeVD); + m_ArrSizes[VD] = size; + return size; +} + void ErrorEstimationHandler:: ActBeforeDifferentiatingSingleStmtBranchInVisitIfStmt() { m_ShouldEmit.push(true); diff --git a/lib/Differentiator/MultiplexExternalRMVSource.cpp b/lib/Differentiator/MultiplexExternalRMVSource.cpp index 1b6f9c10f..ba51b54db 100644 --- a/lib/Differentiator/MultiplexExternalRMVSource.cpp +++ b/lib/Differentiator/MultiplexExternalRMVSource.cpp @@ -42,6 +42,13 @@ void MultiplexExternalRMVSource::ActAfterParsingDiffArgs( } } +void MultiplexExternalRMVSource::ActAfterProcessingArraySubscriptExpr( + const clang::Expr* revArrSub){ + for (auto source : m_Sources) { + source->ActAfterProcessingArraySubscriptExpr(revArrSub); + } +} + void MultiplexExternalRMVSource::ActBeforeCreatingDerivedFnParamTypes( unsigned& numExtraParams) { for (auto source : m_Sources) { diff --git a/lib/Differentiator/ReverseModeVisitor.cpp b/lib/Differentiator/ReverseModeVisitor.cpp index 81c69e62b..561026a10 100644 --- a/lib/Differentiator/ReverseModeVisitor.cpp +++ b/lib/Differentiator/ReverseModeVisitor.cpp @@ -1310,6 +1310,8 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, // Add it to the body statements. addToCurrentBlock(add_assign, direction::reverse); } + if (m_ExternalSource) + m_ExternalSource->ActAfterProcessingArraySubscriptExpr(valueForRevSweep); return StmtDiff(cloned, result, forwSweepDerivative, valueForRevSweep); } diff --git a/test/ErrorEstimation/LoopsAndArrays.C b/test/ErrorEstimation/LoopsAndArrays.C index 384da5253..2380b708e 100644 --- a/test/ErrorEstimation/LoopsAndArrays.C +++ b/test/ErrorEstimation/LoopsAndArrays.C @@ -22,6 +22,7 @@ float func(float* p, int n) { //CHECK-NEXT: int _d_i = 0; //CHECK-NEXT: int i = 0; //CHECK-NEXT: clad::tape _t1 = {}; +//CHECK-NEXT: unsigned long p_size = 0; //CHECK-NEXT: clad::tape _EERepl_sum1 = {}; //CHECK-NEXT: float sum = 0; //CHECK-NEXT: _EERepl_sum0 = sum; @@ -41,14 +42,15 @@ float func(float* p, int n) { //CHECK-NEXT: sum = clad::pop(_t1); //CHECK-NEXT: float _r_d0 = _d_sum; //CHECK-NEXT: _d_p[i] += _r_d0; +//CHECK-NEXT: p_size = (p_size >= i) ? p_size : i; //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: clad::array _delta_p(p_size); //CHECK-NEXT: int i0 = 0; -//CHECK-NEXT: for (; i0 < _d_p.size(); i0++) { +//CHECK-NEXT: for (; i0 < 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; @@ -173,8 +175,8 @@ float func3(float x, float y) { //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: *_d_x += _r_d0; +//CHECK-NEXT: *_d_y += _r_d0; //CHECK-NEXT: _delta_arr[0] += std::abs(_r_d0 * _EERepl_arr0 * {{.+}}); //CHECK-NEXT: _final_error += _delta_arr[0]; //CHECK-NEXT: _d_arr[0]; @@ -202,12 +204,14 @@ float func4(float x[10], float y[10]) { //CHECK-NEXT: unsigned long _t0; //CHECK-NEXT: int _d_i = 0; //CHECK-NEXT: int i = 0; +//CHECK-NEXT: unsigned long x_size = 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: clad::array _delta_x(x_size); +//CHECK-NEXT: clad::array _EERepl_x0(x_size); +//CHECK-NEXT: for (int i0 = 0; i0 < x_size; i0++) { //CHECK-NEXT: _EERepl_x0[i0] = x[i0]; //CHECK-NEXT: } +//CHECK-NEXT: unsigned long y_size = 0; //CHECK-NEXT: clad::tape _EERepl_x1 = {}; //CHECK-NEXT: clad::tape _t2 = {}; //CHECK-NEXT: clad::tape _EERepl_sum1 = {}; @@ -232,6 +236,7 @@ float func4(float x[10], float y[10]) { //CHECK-NEXT: sum = clad::pop(_t2); //CHECK-NEXT: float _r_d1 = _d_sum; //CHECK-NEXT: _d_x[i] += _r_d1; +//CHECK-NEXT: x_size = (x_size >= i) ? x_size : i; //CHECK-NEXT: float _r1 = clad::pop(_EERepl_sum1); //CHECK-NEXT: _delta_sum += std::abs(_r_d1 * _r1 * {{.+}}); //CHECK-NEXT: } @@ -239,21 +244,23 @@ float func4(float x[10], float y[10]) { //CHECK-NEXT: x[i] = clad::pop(_t1); //CHECK-NEXT: float _r_d0 = _d_x[i]; //CHECK-NEXT: _d_y[i] += _r_d0; +//CHECK-NEXT: y_size = (y_size >= i) ? y_size : i; //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: x_size = (x_size >= i) ? x_size : i; //CHECK-NEXT: } //CHECK-NEXT: } //CHECK-NEXT: _delta_sum += std::abs(_d_sum * _EERepl_sum0 * {{.+}}); //CHECK-NEXT: int i0 = 0; -//CHECK-NEXT: for (; i0 < _d_x.size(); i0++) { +//CHECK-NEXT: for (; i0 < 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: clad::array _delta_y(y_size); //CHECK-NEXT: i0 = 0; -//CHECK-NEXT: for (; i0 < _d_y.size(); i0++) { +//CHECK-NEXT: for (; i0 < 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; @@ -270,12 +277,15 @@ double func5(double* x, double* y, double* output) { } //CHECK: void func5_grad(double *x, double *y, double *output, double *_d_x, double *_d_y, double *_d_output, double &_final_error) { +//CHECK-NEXT: unsigned long output_size = 0; //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: clad::array _delta_output(output_size); +//CHECK-NEXT: clad::array _EERepl_output0(output_size); +//CHECK-NEXT: for (int i = 0; i < output_size; i++) { //CHECK-NEXT: _EERepl_output0[i] = output[i]; //CHECK-NEXT: } +//CHECK-NEXT: unsigned long x_size = 0; +//CHECK-NEXT: unsigned long y_size = 0; //CHECK-NEXT: double _EERepl_output1; //CHECK-NEXT: double _t1; //CHECK-NEXT: double _EERepl_output2; @@ -296,58 +306,76 @@ double func5(double* x, double* y, double* output) { //CHECK-NEXT: _label0: //CHECK-NEXT: { //CHECK-NEXT: _d_output[0] += 1; +//CHECK-NEXT: output_size = (output_size >= 0) ? output_size : 0; //CHECK-NEXT: _d_output[1] += 1; +//CHECK-NEXT: output_size = (output_size >= 1) ? output_size : 1; //CHECK-NEXT: _d_output[2] += 1; +//CHECK-NEXT: output_size = (output_size >= 2) ? output_size : 2; //CHECK-NEXT: } //CHECK-NEXT: { //CHECK-NEXT: output[2] = _t2; //CHECK-NEXT: double _r_d2 = _d_output[2]; //CHECK-NEXT: _d_output[2] -= _r_d2; //CHECK-NEXT: _d_x[0] += _r_d2 * y[1]; +//CHECK-NEXT: x_size = (x_size >= 0) ? x_size : 0; //CHECK-NEXT: _d_y[1] += x[0] * _r_d2; +//CHECK-NEXT: y_size = (y_size >= 1) ? y_size : 1; //CHECK-NEXT: _d_y[0] += -_r_d2 * x[1]; +//CHECK-NEXT: y_size = (y_size >= 0) ? y_size : 0; //CHECK-NEXT: _d_x[1] += y[0] * -_r_d2; +//CHECK-NEXT: x_size = (x_size >= 1) ? x_size : 1; //CHECK-NEXT: _delta_output[2] += std::abs(_r_d2 * _EERepl_output3 * {{.+}}); //CHECK-NEXT: _final_error += _delta_output[2]; +//CHECK-NEXT: output_size = (output_size >= 2) ? output_size : 2; //CHECK-NEXT: } //CHECK-NEXT: { //CHECK-NEXT: output[1] = _t1; //CHECK-NEXT: double _r_d1 = _d_output[1]; //CHECK-NEXT: _d_output[1] -= _r_d1; //CHECK-NEXT: _d_x[2] += _r_d1 * y[0]; +//CHECK-NEXT: x_size = (x_size >= 2) ? x_size : 2; //CHECK-NEXT: _d_y[0] += x[2] * _r_d1; +//CHECK-NEXT: y_size = (y_size >= 0) ? y_size : 0; //CHECK-NEXT: _d_x[0] += -_r_d1 * y[2]; +//CHECK-NEXT: x_size = (x_size >= 0) ? x_size : 0; //CHECK-NEXT: _d_y[2] += x[0] * -_r_d1; +//CHECK-NEXT: y_size = (y_size >= 2) ? y_size : 2; //CHECK-NEXT: _delta_output[1] += std::abs(_r_d1 * _EERepl_output2 * {{.+}}); //CHECK-NEXT: _final_error += _delta_output[1]; +//CHECK-NEXT: output_size = (output_size >= 1) ? output_size : 1; //CHECK-NEXT: } //CHECK-NEXT: { //CHECK-NEXT: output[0] = _t0; //CHECK-NEXT: double _r_d0 = _d_output[0]; //CHECK-NEXT: _d_output[0] -= _r_d0; //CHECK-NEXT: _d_x[1] += _r_d0 * y[2]; +//CHECK-NEXT: x_size = (x_size >= 1) ? x_size : 1; //CHECK-NEXT: _d_y[2] += x[1] * _r_d0; +//CHECK-NEXT: y_size = (y_size >= 2) ? y_size : 2; //CHECK-NEXT: _d_x[2] += -_r_d0 * y[1]; +//CHECK-NEXT: x_size = (x_size >= 2) ? x_size : 2; //CHECK-NEXT: _d_y[1] += x[2] * -_r_d0; +//CHECK-NEXT: y_size = (y_size >= 1) ? y_size : 1; //CHECK-NEXT: _delta_output[0] += std::abs(_r_d0 * _EERepl_output1 * {{.+}}); //CHECK-NEXT: _final_error += _delta_output[0]; +//CHECK-NEXT: output_size = (output_size >= 0) ? output_size : 0; //CHECK-NEXT: } -//CHECK-NEXT: clad::array _delta_x(_d_x.size()); +//CHECK-NEXT: clad::array _delta_x(x_size); //CHECK-NEXT: int i = 0; -//CHECK-NEXT: for (; i < _d_x.size(); i++) { +//CHECK-NEXT: for (; i < 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: clad::array _delta_y(y_size); //CHECK-NEXT: i = 0; -//CHECK-NEXT: for (; i < _d_y.size(); i++) { +//CHECK-NEXT: for (; i < 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: i = 0; -//CHECK-NEXT: for (; i < _d_output.size(); i++) { +//CHECK-NEXT: for (; i < 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; diff --git a/test/ErrorEstimation/LoopsAndArraysExec.C b/test/ErrorEstimation/LoopsAndArraysExec.C index c505082b9..a2a9c3ce9 100644 --- a/test/ErrorEstimation/LoopsAndArraysExec.C +++ b/test/ErrorEstimation/LoopsAndArraysExec.C @@ -23,6 +23,7 @@ double runningSum(float* f, int n) { //CHECK-NEXT: int _d_i = 0; //CHECK-NEXT: int i = 0; //CHECK-NEXT: clad::tape _t1 = {}; +//CHECK-NEXT: unsigned long f_size = 0; //CHECK-NEXT: clad::tape _EERepl_sum1 = {}; //CHECK-NEXT: double sum = 0; //CHECK-NEXT: _EERepl_sum0 = sum; @@ -42,15 +43,17 @@ double runningSum(float* f, int n) { //CHECK-NEXT: sum = clad::pop(_t1); //CHECK-NEXT: double _r_d0 = _d_sum; //CHECK-NEXT: _d_f[i] += _r_d0; +//CHECK-NEXT: f_size = (f_size >= i) ? f_size : i; //CHECK-NEXT: _d_f[i - 1] += _r_d0; +//CHECK-NEXT: f_size = (f_size >= i - 1) ? f_size : i - 1; //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: clad::array _delta_f(f_size); //CHECK-NEXT: int i0 = 0; -//CHECK-NEXT: for (; i0 < _d_f.size(); i0++) { +//CHECK-NEXT: for (; i0 < 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; @@ -79,6 +82,8 @@ 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: unsigned long a_size = 0; +//CHECK-NEXT: unsigned long b_size = 0; //CHECK-NEXT: clad::tape _EERepl_sum1 = {}; //CHECK-NEXT: double sum = 0; //CHECK-NEXT: _EERepl_sum0 = sum; @@ -104,7 +109,9 @@ double mulSum(float* a, float* b, int n) { //CHECK-NEXT: sum = clad::pop(_t3); //CHECK-NEXT: double _r_d0 = _d_sum; //CHECK-NEXT: _d_a[i] += _r_d0 * b[j]; +//CHECK-NEXT: a_size = (a_size >= i) ? a_size : i; //CHECK-NEXT: _d_b[j] += a[i] * _r_d0; +//CHECK-NEXT: b_size = (b_size >= j) ? b_size : j; //CHECK-NEXT: double _r0 = clad::pop(_EERepl_sum1); //CHECK-NEXT: _delta_sum += std::abs(_r_d0 * _r0 * {{.+}}); //CHECK-NEXT: } @@ -116,16 +123,16 @@ double mulSum(float* a, float* b, int n) { //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: clad::array _delta_a(a_size); //CHECK-NEXT: int i0 = 0; -//CHECK-NEXT: for (; i0 < _d_a.size(); i0++) { +//CHECK-NEXT: for (; i0 < 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: clad::array _delta_b(b_size); //CHECK-NEXT: i0 = 0; -//CHECK-NEXT: for (; i0 < _d_b.size(); i0++) { +//CHECK-NEXT: for (; i0 < 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; @@ -149,6 +156,8 @@ double divSum(float* a, float* b, int n) { //CHECK-NEXT: int _d_i = 0; //CHECK-NEXT: int i = 0; //CHECK-NEXT: clad::tape _t1 = {}; +//CHECK-NEXT: unsigned long b_size = 0; +//CHECK-NEXT: unsigned long a_size = 0; //CHECK-NEXT: clad::tape _EERepl_sum1 = {}; //CHECK-NEXT: double sum = 0; //CHECK-NEXT: _EERepl_sum0 = sum; @@ -167,24 +176,27 @@ double divSum(float* a, float* b, int n) { //CHECK-NEXT: { //CHECK-NEXT: sum = clad::pop(_t1); //CHECK-NEXT: double _r_d0 = _d_sum; +//CHECK-NEXT: b_size = (b_size >= i) ? b_size : i; //CHECK-NEXT: _d_a[i] += _r_d0 / b[i]; +//CHECK-NEXT: a_size = (a_size >= i) ? a_size : i; //CHECK-NEXT: double _r0 = _r_d0 * -a[i] / (b[i] * b[i]); //CHECK-NEXT: _d_b[i] += _r0; +//CHECK-NEXT: b_size = (b_size >= i) ? b_size : i; //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: clad::array _delta_a(a_size); //CHECK-NEXT: int i0 = 0; -//CHECK-NEXT: for (; i0 < _d_a.size(); i0++) { +//CHECK-NEXT: for (; i0 < 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: clad::array _delta_b(b_size); //CHECK-NEXT: i0 = 0; -//CHECK-NEXT: for (; i0 < _d_b.size(); i0++) { +//CHECK-NEXT: for (; i0 < 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;