diff --git a/include/clad/Differentiator/DerivativeBuilder.h b/include/clad/Differentiator/DerivativeBuilder.h index 75a500244..b95312c93 100644 --- a/include/clad/Differentiator/DerivativeBuilder.h +++ b/include/clad/Differentiator/DerivativeBuilder.h @@ -37,6 +37,7 @@ namespace clad { class CladPlugin; clang::FunctionDecl* ProcessDiffRequest(CladPlugin& P, DiffRequest& request); + void AddRequestToSchedule(CladPlugin& P, const DiffRequest& request); } // namespace plugin } // namespace clad diff --git a/include/clad/Differentiator/DiffPlanner.h b/include/clad/Differentiator/DiffPlanner.h index 7c108fa23..187810364 100644 --- a/include/clad/Differentiator/DiffPlanner.h +++ b/include/clad/Differentiator/DiffPlanner.h @@ -20,68 +20,77 @@ namespace clang { namespace clad { - /// A struct containing information about request to differentiate a function. - struct DiffRequest { - /// Function to be differentiated. - const clang::FunctionDecl* Function = nullptr; - /// Name of the base function to be differentiated. Can be different from - /// function->getNameAsString() when higher-order derivatives are computed. - std::string BaseFunctionName = {}; - /// Current derivative order to be computed. - unsigned CurrentDerivativeOrder = 1; - /// Highest requested derivative order. - unsigned RequestedDerivativeOrder = 1; - /// Context in which the function is being called, or a call to - /// clad::gradient/differentiate, where function is the first arg. - clang::CallExpr* CallContext = nullptr; - /// Args provided to the call to clad::gradient/differentiate. - const clang::Expr* Args = nullptr; - /// Requested differentiation mode, forward or reverse. - DiffMode Mode = DiffMode::unknown; - /// If function appears in the call to clad::gradient/differentiate, - /// the call must be updated and the first arg replaced by the derivative. - bool CallUpdateRequired = false; - /// A flag to enable/disable diag warnings/errors during differentiation. - bool VerboseDiags = false; - /// A flag to enable TBR analysis during reverse-mode differentiation. - bool EnableTBRAnalysis = false; - /// Puts the derived function and its code in the diff call - void updateCall(clang::FunctionDecl* FD, clang::FunctionDecl* OverloadedFD, - clang::Sema& SemaRef); - /// Functor type to be differentiated, if any. - /// - /// It is required because we cannot always determine if we are - /// differentiating a call operator using the function to be - /// differentiated, for example, when we are computing higher - /// order derivatives. - const clang::CXXRecordDecl* Functor = nullptr; - - /// Stores differentiation parameters information. Stored information - /// includes info on indices range for array parameters, and nested data - /// member information for record (class) type parameters. - DiffInputVarsInfo DVI; - - // A flag to enable the use of enzyme for backend instead of clad - bool use_enzyme = false; - - /// Recomputes `DiffInputVarsInfo` using the current values of data members. - /// - /// Differentiation parameters info is computed by parsing the argument - /// expression for the clad differentiation function calls. The argument is - /// used to specify independent parameter(s) for differentiation. There are - /// three valid options for the argument expression: - /// 1) A string literal, containing comma-separated names of function's - /// parameters, as defined in function's definition. If any of the - /// parameters are of array or pointer type the indexes of the array - /// that needs to be differentiated can also be specified, e.g. - /// "arr[1]" or "arr[2:5]". The function will be differentiated w.r.t. - /// all the specified parameters. - /// 2) A numeric literal. The function will be differentiated w.r.t. to - /// the parameter corresponding to literal's value index. - /// 3) If no argument is provided, a default argument is used. The - /// function will be differentiated w.r.t. to its every parameter. - void UpdateDiffParamsInfo(clang::Sema& semaRef); - }; +/// A struct containing information about request to differentiate a function. +struct DiffRequest { + /// Function to be differentiated. + const clang::FunctionDecl* Function = nullptr; + /// Name of the base function to be differentiated. Can be different from + /// function->getNameAsString() when higher-order derivatives are computed. + std::string BaseFunctionName = {}; + /// Current derivative order to be computed. + unsigned CurrentDerivativeOrder = 1; + /// Highest requested derivative order. + unsigned RequestedDerivativeOrder = 1; + /// Context in which the function is being called, or a call to + /// clad::gradient/differentiate, where function is the first arg. + clang::CallExpr* CallContext = nullptr; + /// Args provided to the call to clad::gradient/differentiate. + const clang::Expr* Args = nullptr; + /// Requested differentiation mode, forward or reverse. + DiffMode Mode = DiffMode::unknown; + /// If function appears in the call to clad::gradient/differentiate, + /// the call must be updated and the first arg replaced by the derivative. + bool CallUpdateRequired = false; + /// A flag to enable/disable diag warnings/errors during differentiation. + bool VerboseDiags = false; + /// A flag to enable TBR analysis during reverse-mode differentiation. + bool EnableTBRAnalysis = false; + /// Puts the derived function and its code in the diff call + void updateCall(clang::FunctionDecl* FD, clang::FunctionDecl* OverloadedFD, + clang::Sema& SemaRef); + /// Functor type to be differentiated, if any. + /// + /// It is required because we cannot always determine if we are + /// differentiating a call operator using the function to be + /// differentiated, for example, when we are computing higher + /// order derivatives. + const clang::CXXRecordDecl* Functor = nullptr; + + /// Stores differentiation parameters information. Stored information + /// includes info on indices range for array parameters, and nested data + /// member information for record (class) type parameters. + DiffInputVarsInfo DVI; + + // A flag to enable the use of enzyme for backend instead of clad + bool use_enzyme = false; + + /// A pointer to keep track of the prototype of the derived function. + /// This will be particularly useful for pushforward and pullback functions. + clang::FunctionDecl* DerivedFDPrototype = nullptr; + + /// A boolean to indicate if only the declaration of the derived function + /// is required (and not the definition or body). + /// This will be particularly useful for pushforward and pullback functions. + bool DeclarationOnly = false; + + /// Recomputes `DiffInputVarsInfo` using the current values of data members. + /// + /// Differentiation parameters info is computed by parsing the argument + /// expression for the clad differentiation function calls. The argument is + /// used to specify independent parameter(s) for differentiation. There are + /// three valid options for the argument expression: + /// 1) A string literal, containing comma-separated names of function's + /// parameters, as defined in function's definition. If any of the + /// parameters are of array or pointer type the indexes of the array + /// that needs to be differentiated can also be specified, e.g. + /// "arr[1]" or "arr[2:5]". The function will be differentiated w.r.t. + /// all the specified parameters. + /// 2) A numeric literal. The function will be differentiated w.r.t. to + /// the parameter corresponding to literal's value index. + /// 3) If no argument is provided, a default argument is used. The + /// function will be differentiated w.r.t. to its every parameter. + void UpdateDiffParamsInfo(clang::Sema& semaRef); +}; using DiffSchedule = llvm::SmallVector; using DiffInterval = std::vector; diff --git a/lib/Differentiator/BaseForwardModeVisitor.cpp b/lib/Differentiator/BaseForwardModeVisitor.cpp index 520e025c7..1a6ce1e01 100644 --- a/lib/Differentiator/BaseForwardModeVisitor.cpp +++ b/lib/Differentiator/BaseForwardModeVisitor.cpp @@ -492,17 +492,23 @@ BaseForwardModeVisitor::DerivePushforward(const FunctionDecl* FD, m_Derivative->setParams(params); m_Derivative->setBody(nullptr); - beginScope(Scope::FnScope | Scope::DeclScope); - m_DerivativeFnScope = getCurrentScope(); - beginBlock(); + if (!request.DeclarationOnly) { + beginScope(Scope::FnScope | Scope::DeclScope); + m_DerivativeFnScope = getCurrentScope(); + beginBlock(); - // execute the functor inside the function body. - ExecuteInsidePushforwardFunctionBlock(); + // execute the functor inside the function body. + ExecuteInsidePushforwardFunctionBlock(); - Stmt* derivativeBody = endBlock(); - m_Derivative->setBody(derivativeBody); + Stmt* derivativeBody = endBlock(); + m_Derivative->setBody(derivativeBody); + + endScope(); // Function body scope + + if (request.DerivedFDPrototype) + m_Derivative->setPreviousDeclaration(request.DerivedFDPrototype); + } - endScope(); // Function body scope m_Sema.PopFunctionScopeInfo(); m_Sema.PopDeclContext(); endScope(); // Function decl scope @@ -1136,9 +1142,18 @@ StmtDiff BaseForwardModeVisitor::VisitCallExpr(const CallExpr* CE) { // pushforwardFnRequest.RequestedDerivativeOrder = m_DerivativeOrder; // Silence diag outputs in nested derivation process. pushforwardFnRequest.VerboseDiags = false; + + // Derive declaration of the pushforward function. + pushforwardFnRequest.DeclarationOnly = true; FunctionDecl* pushforwardFD = plugin::ProcessDiffRequest(m_CladPlugin, pushforwardFnRequest); + // Add the request to derive the definition of the pushforward function + // into the queue. + pushforwardFnRequest.DeclarationOnly = false; + pushforwardFnRequest.DerivedFDPrototype = pushforwardFD; + plugin::AddRequestToSchedule(m_CladPlugin, pushforwardFnRequest); + if (pushforwardFD) { if (baseDiff.getExpr()) { callDiff = diff --git a/test/FirstDerivative/CallArguments.C b/test/FirstDerivative/CallArguments.C index c81155a51..7c84dfbff 100644 --- a/test/FirstDerivative/CallArguments.C +++ b/test/FirstDerivative/CallArguments.C @@ -106,9 +106,7 @@ float f_const_helper(const float x) { return x * x; } -// CHECK: clad::ValueAndPushforward f_const_helper_pushforward(const float x, const float _d_x) { -// CHECK-NEXT: return {x * x, _d_x * x + x * _d_x}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward f_const_helper_pushforward(const float x, const float _d_x); float f_const_args_func_7(const float x, const float y) { return f_const_helper(x) + f_const_helper(y) - y; @@ -168,5 +166,9 @@ int main () { // expected-no-diagnostics printf("f8_darg0=%f\n", f8.execute(f8x,2.F)); //CHECK-EXEC: f8_darg0=2.000000 +// CHECK: clad::ValueAndPushforward f_const_helper_pushforward(const float x, const float _d_x) { +// CHECK-NEXT: return {x * x, _d_x * x + x * _d_x}; +// CHECK-NEXT: } + return 0; } diff --git a/test/FirstDerivative/FunctionCalls.C b/test/FirstDerivative/FunctionCalls.C index a3654f503..79e5a6b8f 100644 --- a/test/FirstDerivative/FunctionCalls.C +++ b/test/FirstDerivative/FunctionCalls.C @@ -125,9 +125,7 @@ double test_7(double i, double j) { return res; } -// CHECK: void increment_pushforward(int &i, int &_d_i) { -// CHECK-NEXT: ++i; -// CHECK-NEXT: } +// CHECK: void increment_pushforward(int &i, int &_d_i); // CHECK: double test_7_darg0(double i, double j) { // CHECK-NEXT: double _d_i = 1; @@ -154,9 +152,7 @@ double test_8(double x) { return func_with_enum(x, e); } -// CHECK: clad::ValueAndPushforward func_with_enum_pushforward(double x, E e, double _d_x) { -// CHECK-NEXT: return {x * x, _d_x * x + x * _d_x}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward func_with_enum_pushforward(double x, E e, double _d_x); // CHECK: double test_8_darg0(double x) { // CHECK-NEXT: double _d_x = 1; @@ -178,4 +174,12 @@ int main () { clad::differentiate(test_8); // expected-error {{TBR analysis is not meant for forward mode AD.}} clad::differentiate(test_8); // expected-error {{Both enable and disable TBR options are specified.}} return 0; + +// CHECK: void increment_pushforward(int &i, int &_d_i) { +// CHECK-NEXT: ++i; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward func_with_enum_pushforward(double x, E e, double _d_x) { +// CHECK-NEXT: return {x * x, _d_x * x + x * _d_x}; +// CHECK-NEXT: } } diff --git a/test/FirstDerivative/FunctionCallsWithResults.C b/test/FirstDerivative/FunctionCallsWithResults.C index f694aaaa3..0323f84d6 100644 --- a/test/FirstDerivative/FunctionCallsWithResults.C +++ b/test/FirstDerivative/FunctionCallsWithResults.C @@ -84,9 +84,7 @@ double sum_of_squares(double u, double v) { return u*u + v*v; } -// CHECK: clad::ValueAndPushforward sum_of_squares_pushforward(double u, double v, double _d_u, double _d_v) { -// CHECK-NEXT: return {u * u + v * v, _d_u * u + u * _d_u + _d_v * v + v * _d_v}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward sum_of_squares_pushforward(double u, double v, double _d_u, double _d_v); double fn1(double i, double j) { double res = sum_of_squares(i, j); @@ -106,23 +104,13 @@ double fn1(double i, double j) { // CHECK-NEXT: return _d_res; // CHECK-NEXT: } -// CHECK: clad::ValueAndPushforward fn1_pushforward(double i, double j, double _d_i, double _d_j) { -// CHECK-NEXT: clad::ValueAndPushforward _t0 = sum_of_squares_pushforward(i, j, _d_i, _d_j); -// CHECK-NEXT: double _d_res = _t0.pushforward; -// CHECK-NEXT: double res = _t0.value; -// CHECK-NEXT: clad::ValueAndPushforward _t1 = sum_of_squares_pushforward(j, i, _d_j, _d_i); -// CHECK-NEXT: _d_res += _t1.pushforward; -// CHECK-NEXT: res += _t1.value; -// CHECK-NEXT: return {res, _d_res}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward fn1_pushforward(double i, double j, double _d_i, double _d_j); double sum_of_pairwise_product(double u, double v, double w) { return u*v + v*w + w*u; } -// CHECK: clad::ValueAndPushforward sum_of_pairwise_product_pushforward(double u, double v, double w, double _d_u, double _d_v, double _d_w) { -// CHECK-NEXT: return {u * v + v * w + w * u, _d_u * v + u * _d_v + _d_v * w + v * _d_w + _d_w * u + w * _d_u}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward sum_of_pairwise_product_pushforward(double u, double v, double w, double _d_u, double _d_v, double _d_w); double fn2(double i, double j) { double res = fn1(i, j); @@ -144,12 +132,9 @@ double fn2(double i, double j) { void square_inplace(double& u) { u = u*u; -} +} -// CHECK: void square_inplace_pushforward(double &u, double &_d_u) { -// CHECK-NEXT: _d_u = _d_u * u + u * _d_u; -// CHECK-NEXT: u = u * u; -// CHECK-NEXT: } +// CHECK: void square_inplace_pushforward(double &u, double &_d_u); double fn3(double i, double j) { square_inplace(i); @@ -193,13 +178,7 @@ double fn5(double i, double j) { return fn5(0, i); } -// CHECK: clad::ValueAndPushforward fn5_pushforward(double i, double j, double _d_i, double _d_j) { -// CHECK-NEXT: if (i < 2) { -// CHECK-NEXT: return {j, _d_j}; -// CHECK-NEXT: } -// CHECK-NEXT: clad::ValueAndPushforward _t0 = fn5_pushforward(0, i, 0, _d_i); -// CHECK-NEXT: return {_t0.value, _t0.pushforward}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward fn5_pushforward(double i, double j, double _d_i, double _d_j); // CHECK: double fn5_darg0(double i, double j) { // CHECK-NEXT: double _d_i = 1; @@ -217,12 +196,7 @@ double fn6(double i, double j, double k) { return i+j+k + fn6(i-1, j-1, k-1); } -// CHECK: clad::ValueAndPushforward fn6_pushforward(double i, double j, double k, double _d_i, double _d_j, double _d_k) { -// CHECK-NEXT: if (i < 0.5) -// CHECK-NEXT: return {0, 0}; -// CHECK-NEXT: clad::ValueAndPushforward _t0 = fn6_pushforward(i - 1, j - 1, k - 1, _d_i - 0, _d_j - 0, _d_k - 0); -// CHECK-NEXT: return {i + j + k + _t0.value, _d_i + _d_j + _d_k + _t0.pushforward}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward fn6_pushforward(double i, double j, double k, double _d_i, double _d_j, double _d_k); // CHECK: double fn6_darg0(double i, double j, double k) { // CHECK-NEXT: double _d_i = 1; @@ -238,9 +212,7 @@ double helperFn(double&& i, double&& j) { return i+j; } -// CHECK: clad::ValueAndPushforward helperFn_pushforward(double &&i, double &&j, double &&_d_i, double &&_d_j) { -// CHECK-NEXT: return {i + j, _d_i + _d_j}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward helperFn_pushforward(double &&i, double &&j, double &&_d_i, double &&_d_j); double fn7(double i, double j) { return helperFn(helperFn(7*i, 9*j), i+j); @@ -259,15 +231,7 @@ void modifyArr(double* arr, int n, double val) { arr[i] = val; } -// CHECK: void modifyArr_pushforward(double *arr, int n, double val, double *_d_arr, int _d_n, double _d_val) { -// CHECK-NEXT: { -// CHECK-NEXT: int _d_i = 0; -// CHECK-NEXT: for (int i = 0; i < n; ++i) { -// CHECK-NEXT: _d_arr[i] = _d_val; -// CHECK-NEXT: arr[i] = val; -// CHECK-NEXT: } -// CHECK-NEXT: } -// CHECK-NEXT: } +// CHECK: void modifyArr_pushforward(double *arr, int n, double val, double *_d_arr, int _d_n, double _d_val); double sum(double* arr, int n) { double val = 0; @@ -276,29 +240,14 @@ double sum(double* arr, int n) { return val; } -// CHECK: clad::ValueAndPushforward sum_pushforward(double *arr, int n, double *_d_arr, int _d_n) { -// CHECK-NEXT: double _d_val = 0; -// CHECK-NEXT: double val = 0; -// CHECK-NEXT: { -// CHECK-NEXT: int _d_i = 0; -// CHECK-NEXT: for (int i = 0; i < n; ++i) { -// CHECK-NEXT: _d_val += _d_arr[i]; -// CHECK-NEXT: val += arr[i]; -// CHECK-NEXT: } -// CHECK-NEXT: } -// CHECK-NEXT: return {val, _d_val}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward sum_pushforward(double *arr, int n, double *_d_arr, int _d_n); double check_and_return(double x, char c) { if (c == 'a') return x; return 1; } -// CHECK: clad::ValueAndPushforward check_and_return_pushforward(double x, char c, double _d_x, char _d_c) { -// CHECK-NEXT: if (c == 'a') -// CHECK-NEXT: return {x, _d_x}; -// CHECK-NEXT: return {1, 0}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward check_and_return_pushforward(double x, char c, double _d_x, char _d_c); double fn8(double i, double j) { double arr[5] = {}; @@ -357,4 +306,75 @@ int main () { TEST(fn7, 3, 5); // CHECK-EXEC: {8.00} TEST(fn8, 3, 5); // CHECK-EXEC: {19.04} return 0; + +// CHECK: clad::ValueAndPushforward sum_of_squares_pushforward(double u, double v, double _d_u, double _d_v) { +// CHECK-NEXT: return {u * u + v * v, _d_u * u + u * _d_u + _d_v * v + v * _d_v}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward fn1_pushforward(double i, double j, double _d_i, double _d_j) { +// CHECK-NEXT: clad::ValueAndPushforward _t0 = sum_of_squares_pushforward(i, j, _d_i, _d_j); +// CHECK-NEXT: double _d_res = _t0.pushforward; +// CHECK-NEXT: double res = _t0.value; +// CHECK-NEXT: clad::ValueAndPushforward _t1 = sum_of_squares_pushforward(j, i, _d_j, _d_i); +// CHECK-NEXT: _d_res += _t1.pushforward; +// CHECK-NEXT: res += _t1.value; +// CHECK-NEXT: return {res, _d_res}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward sum_of_pairwise_product_pushforward(double u, double v, double w, double _d_u, double _d_v, double _d_w) { +// CHECK-NEXT: return {u * v + v * w + w * u, _d_u * v + u * _d_v + _d_v * w + v * _d_w + _d_w * u + w * _d_u}; +// CHECK-NEXT: } + +// CHECK: void square_inplace_pushforward(double &u, double &_d_u) { +// CHECK-NEXT: _d_u = _d_u * u + u * _d_u; +// CHECK-NEXT: u = u * u; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward fn5_pushforward(double i, double j, double _d_i, double _d_j) { +// CHECK-NEXT: if (i < 2) { +// CHECK-NEXT: return {j, _d_j}; +// CHECK-NEXT: } +// CHECK-NEXT: clad::ValueAndPushforward _t0 = fn5_pushforward(0, i, 0, _d_i); +// CHECK-NEXT: return {_t0.value, _t0.pushforward}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward fn6_pushforward(double i, double j, double k, double _d_i, double _d_j, double _d_k) { +// CHECK-NEXT: if (i < 0.5) +// CHECK-NEXT: return {0, 0}; +// CHECK-NEXT: clad::ValueAndPushforward _t0 = fn6_pushforward(i - 1, j - 1, k - 1, _d_i - 0, _d_j - 0, _d_k - 0); +// CHECK-NEXT: return {i + j + k + _t0.value, _d_i + _d_j + _d_k + _t0.pushforward}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward helperFn_pushforward(double &&i, double &&j, double &&_d_i, double &&_d_j) { +// CHECK-NEXT: return {i + j, _d_i + _d_j}; +// CHECK-NEXT: } + +// CHECK: void modifyArr_pushforward(double *arr, int n, double val, double *_d_arr, int _d_n, double _d_val) { +// CHECK-NEXT: { +// CHECK-NEXT: int _d_i = 0; +// CHECK-NEXT: for (int i = 0; i < n; ++i) { +// CHECK-NEXT: _d_arr[i] = _d_val; +// CHECK-NEXT: arr[i] = val; +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward sum_pushforward(double *arr, int n, double *_d_arr, int _d_n) { +// CHECK-NEXT: double _d_val = 0; +// CHECK-NEXT: double val = 0; +// CHECK-NEXT: { +// CHECK-NEXT: int _d_i = 0; +// CHECK-NEXT: for (int i = 0; i < n; ++i) { +// CHECK-NEXT: _d_val += _d_arr[i]; +// CHECK-NEXT: val += arr[i]; +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: return {val, _d_val}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward check_and_return_pushforward(double x, char c, double _d_x, char _d_c) { +// CHECK-NEXT: if (c == 'a') +// CHECK-NEXT: return {x, _d_x}; +// CHECK-NEXT: return {1, 0}; +// CHECK-NEXT: } } diff --git a/test/FirstDerivative/FunctionsInNamespaces.C b/test/FirstDerivative/FunctionsInNamespaces.C index 2e1720fc9..18ef5a817 100644 --- a/test/FirstDerivative/FunctionsInNamespaces.C +++ b/test/FirstDerivative/FunctionsInNamespaces.C @@ -44,14 +44,7 @@ int test_1(int x, int y) { return function_namespace2::func3(x, y); } -// CHECK: clad::ValueAndPushforward func4_pushforward(int x, int y, int _d_x, int _d_y) { -// CHECK-NEXT: return {x * x + y, _d_x * x + x * _d_x + _d_y}; -// CHECK-NEXT: } - -// CHECK: clad::ValueAndPushforward func3_pushforward(int x, int y, int _d_x, int _d_y) { -// CHECK-NEXT: clad::ValueAndPushforward _t0 = func4_pushforward(x, y, _d_x, _d_y); -// CHECK-NEXT: return {_t0.value, _t0.pushforward}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward func3_pushforward(int x, int y, int _d_x, int _d_y); // CHECK: int test_1_darg1(int x, int y) { // CHECK-NEXT: int _d_x = 0; @@ -68,31 +61,17 @@ namespace C { return 1; } - // CHECK: clad::ValueAndPushforward someFn_1_pushforward(double &i, double j, double k, double &_d_i, double _d_j, double _d_k) { - // CHECK-NEXT: _d_i = _d_j; - // CHECK-NEXT: i = j; - // CHECK-NEXT: return {1, 0}; - // CHECK-NEXT: } - double someFn_1(double& i, double j) { someFn_1(i, j, j); return 2; } - // CHECK: clad::ValueAndPushforward someFn_1_pushforward(double &i, double j, double &_d_i, double _d_j) { - // CHECK-NEXT: clad::ValueAndPushforward _t0 = someFn_1_pushforward(i, j, j, _d_i, _d_j, _d_j); - // CHECK-NEXT: return {2, 0}; - // CHECK-NEXT: } - double someFn(double& i, double& j) { someFn_1(i, j); return 3; } - // CHECK: clad::ValueAndPushforward someFn_pushforward(double &i, double &j, double &_d_i, double &_d_j) { - // CHECK-NEXT: clad::ValueAndPushforward _t0 = someFn_1_pushforward(i, j, _d_i, _d_j); - // CHECK-NEXT: return {3, 0}; - // CHECK-NEXT: } + // CHECK: clad::ValueAndPushforward someFn_pushforward(double &i, double &j, double &_d_i, double &_d_j); } // namespace C } // namespace B } // namespace A @@ -115,5 +94,38 @@ int main () { TEST_DIFFERENTIATE(test_1, 3, 5); // CHECK-EXEC: {1} TEST_DIFFERENTIATE(fn1, 3, 5); // CHECK-EXEC: {2.00} + + + // CHECK: clad::ValueAndPushforward func4_pushforward(int x, int y, int _d_x, int _d_y); + + // CHECK: clad::ValueAndPushforward func3_pushforward(int x, int y, int _d_x, int _d_y) { + // CHECK-NEXT: clad::ValueAndPushforward _t0 = func4_pushforward(x, y, _d_x, _d_y); + // CHECK-NEXT: return {_t0.value, _t0.pushforward}; + // CHECK-NEXT: } + + // CHECK: clad::ValueAndPushforward someFn_1_pushforward(double &i, double j, double &_d_i, double _d_j); + + // CHECK: clad::ValueAndPushforward someFn_pushforward(double &i, double &j, double &_d_i, double &_d_j) { + // CHECK-NEXT: clad::ValueAndPushforward _t0 = someFn_1_pushforward(i, j, _d_i, _d_j); + // CHECK-NEXT: return {3, 0}; + // CHECK-NEXT: } + + // CHECK: clad::ValueAndPushforward func4_pushforward(int x, int y, int _d_x, int _d_y) { + // CHECK-NEXT: return {x * x + y, _d_x * x + x * _d_x + _d_y}; + // CHECK-NEXT: } + + // CHECK: clad::ValueAndPushforward someFn_1_pushforward(double &i, double j, double k, double &_d_i, double _d_j, double _d_k); + + // CHECK: clad::ValueAndPushforward someFn_1_pushforward(double &i, double j, double &_d_i, double _d_j) { + // CHECK-NEXT: clad::ValueAndPushforward _t0 = someFn_1_pushforward(i, j, j, _d_i, _d_j, _d_j); + // CHECK-NEXT: return {2, 0}; + // CHECK-NEXT: } + + // CHECK: clad::ValueAndPushforward someFn_1_pushforward(double &i, double j, double k, double &_d_i, double _d_j, double _d_k) { + // CHECK-NEXT: _d_i = _d_j; + // CHECK-NEXT: i = j; + // CHECK-NEXT: return {1, 0}; + // CHECK-NEXT: } + return 0; } \ No newline at end of file diff --git a/test/FirstDerivative/Recursive.C b/test/FirstDerivative/Recursive.C index d4845da10..dd103aafd 100644 --- a/test/FirstDerivative/Recursive.C +++ b/test/FirstDerivative/Recursive.C @@ -14,14 +14,7 @@ int f_dec(int arg) { return f_dec(arg-1); } -// CHECK: clad::ValueAndPushforward f_dec_pushforward(int arg, int _d_arg) { -// CHECK-NEXT: if (arg == 0) -// CHECK-NEXT: return {arg, _d_arg}; -// CHECK-NEXT: else { -// CHECK-NEXT: clad::ValueAndPushforward _t0 = f_dec_pushforward(arg - 1, _d_arg - 0); -// CHECK-NEXT: return {_t0.value, _t0.pushforward}; -// CHECK-NEXT: } -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward f_dec_pushforward(int arg, int _d_arg); // CHECK: int f_dec_darg0(int arg) { // CHECK-NEXT: int _d_arg = 1; @@ -42,15 +35,7 @@ int f_pow(int arg, int p) { return arg * f_pow(arg, p - 1); } -// CHECK: clad::ValueAndPushforward f_pow_pushforward(int arg, int p, int _d_arg, int _d_p) { -// CHECK-NEXT: if (p == 0) -// CHECK-NEXT: return {1, 0}; -// CHECK-NEXT: else { -// CHECK-NEXT: clad::ValueAndPushforward _t0 = f_pow_pushforward(arg, p - 1, _d_arg, _d_p - 0); -// CHECK-NEXT: int &_t1 = _t0.value; -// CHECK-NEXT: return {arg * _t1, _d_arg * _t1 + arg * _t0.pushforward}; -// CHECK-NEXT: } -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward f_pow_pushforward(int arg, int p, int _d_arg, int _d_p); // CHECK: int f_pow_darg0(int arg, int p) { // CHECK-NEXT: int _d_arg = 1; @@ -71,4 +56,23 @@ int main() { printf("Result is = %d\n", f_dec_darg0(2)); // CHECK-EXEC: Result is = 1 clad::differentiate(f_pow, 0); printf("Result is = %d\n", f_pow_darg0(10, 2)); //CHECK-EXEC: Result is = 20 + +// CHECK: clad::ValueAndPushforward f_dec_pushforward(int arg, int _d_arg) { +// CHECK-NEXT: if (arg == 0) +// CHECK-NEXT: return {arg, _d_arg}; +// CHECK-NEXT: else { +// CHECK-NEXT: clad::ValueAndPushforward _t0 = f_dec_pushforward(arg - 1, _d_arg - 0); +// CHECK-NEXT: return {_t0.value, _t0.pushforward}; +// CHECK-NEXT: } +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward f_pow_pushforward(int arg, int p, int _d_arg, int _d_p) { +// CHECK-NEXT: if (p == 0) +// CHECK-NEXT: return {1, 0}; +// CHECK-NEXT: else { +// CHECK-NEXT: clad::ValueAndPushforward _t0 = f_pow_pushforward(arg, p - 1, _d_arg, _d_p - 0); +// CHECK-NEXT: int &_t1 = _t0.value; +// CHECK-NEXT: return {arg * _t1, _d_arg * _t1 + arg * _t0.pushforward}; +// CHECK-NEXT: } +// CHECK-NEXT: } } diff --git a/test/FirstDerivative/StructMethodCall.C b/test/FirstDerivative/StructMethodCall.C index 999d5f103..d00701afd 100644 --- a/test/FirstDerivative/StructMethodCall.C +++ b/test/FirstDerivative/StructMethodCall.C @@ -64,13 +64,9 @@ public: return f(x) + g_1(x, y); } - // CHECK: clad::ValueAndPushforward f_pushforward(int x, A *_d_this, int _d_x) { - // CHECK-NEXT: return {x, _d_x}; - // CHECK-NEXT: } + // CHECK: clad::ValueAndPushforward f_pushforward(int x, A *_d_this, int _d_x); - // CHECK: clad::ValueAndPushforward g_1_pushforward(int x, int y, A *_d_this, int _d_x, int _d_y) { - // CHECK-NEXT: return {x * x + y, _d_x * x + x * _d_x + _d_y}; - // CHECK-NEXT: } + // CHECK: clad::ValueAndPushforward g_1_pushforward(int x, int y, A *_d_this, int _d_x, int _d_y); // CHECK: int m_darg0(int x, int y) { // CHECK-NEXT: int _d_x = 1; @@ -110,4 +106,12 @@ int main () { auto m_dy = clad::differentiate(&A::m, 1); printf("Result is = {%d, %d}\n", m_dx.execute(a, 1, 2), m_dy.execute(a, 1, 2)); // CHECK-EXEC: Result is = {3, 1} return 0; + + // CHECK: clad::ValueAndPushforward f_pushforward(int x, A *_d_this, int _d_x) { + // CHECK-NEXT: return {x, _d_x}; + // CHECK-NEXT: } + + // CHECK: clad::ValueAndPushforward g_1_pushforward(int x, int y, A *_d_this, int _d_x, int _d_y) { + // CHECK-NEXT: return {x * x + y, _d_x * x + x * _d_x + _d_y}; + // CHECK-NEXT: } } diff --git a/test/ForwardMode/MemberFunctions.C b/test/ForwardMode/MemberFunctions.C index 16637f894..70c8a3c71 100644 --- a/test/ForwardMode/MemberFunctions.C +++ b/test/ForwardMode/MemberFunctions.C @@ -32,8 +32,7 @@ public: return; } - // CHECK: void mem_fn_with_void_return_pushforward(SimpleFunctions *_d_this) { - // CHECK-NEXT:} + // CHECK: void mem_fn_with_void_return_pushforward(SimpleFunctions *_d_this); double mem_fn_with_void_function_call(double i, double j) { mem_fn_with_void_return(); @@ -822,6 +821,9 @@ double multiplySimpleFunctionByValue(SimpleFunctions v, double value) { // CHECK-NEXT: return _d_v.x; // CHECK-NEXT: } + // CHECK: void mem_fn_with_void_return_pushforward(SimpleFunctions *_d_this) { + // CHECK-NEXT:} + #define TEST(name,i,j) \ auto d_##name = clad::differentiate(&SimpleFunctions::name,"i");\ diff --git a/test/ForwardMode/NonDifferentiable.C b/test/ForwardMode/NonDifferentiable.C index e4292e2ca..c6608d57c 100644 --- a/test/ForwardMode/NonDifferentiable.C +++ b/test/ForwardMode/NonDifferentiable.C @@ -120,11 +120,7 @@ int main() { // CHECK-NEXT: return (_d_this->x + 0.) * i + _t0 * _d_i + (_d_i * j + i * _d_j) * j + _t1 * _d_j; // CHECK-NEXT: } - // CHECK: clad::ValueAndPushforward mem_fn_1_pushforward(double i, double j, SimpleFunctions1 *_d_this, double _d_i, double _d_j) { - // CHECK-NEXT: double _t0 = (this->x + this->y); - // CHECK-NEXT: double _t1 = i * j; - // CHECK-NEXT: return {_t0 * i + _t1 * j, (_d_this->x + 0.) * i + _t0 * _d_i + (_d_i * j + i * _d_j) * j + _t1 * _d_j}; - // CHECK-NEXT: } + // CHECK: clad::ValueAndPushforward mem_fn_1_pushforward(double i, double j, SimpleFunctions1 *_d_this, double _d_i, double _d_j); // CHECK: double mem_fn_3_darg0(double i, double j) { // CHECK-NEXT: double _d_i = 1; @@ -174,9 +170,7 @@ int main() { // CHECK-NEXT: return _d_obj.x * _t1 + _t0 * 0. + _d_i * j + i * _d_j; // CHECK-NEXT: } - // CHECK: clad::ValueAndPushforward operator_plus_pushforward(const SimpleFunctions1 &other, const SimpleFunctions1 *_d_this, const SimpleFunctions1 &_d_other) const { - // CHECK-NEXT: return {SimpleFunctions1(this->x + other.x, this->y + other.y), SimpleFunctions1(_d_this->x + _d_other.x, 0. + 0.)}; - // CHECK-NEXT: } + // CHECK: clad::ValueAndPushforward operator_plus_pushforward(const SimpleFunctions1 &other, const SimpleFunctions1 *_d_this, const SimpleFunctions1 &_d_other) const; // CHECK: double fn_s1_operator_darg0(double i, double j) { // CHECK-NEXT: double _d_i = 1; @@ -214,5 +208,14 @@ int main() { // CHECK-NEXT: return 0; // CHECK-NEXT: } + // CHECK: clad::ValueAndPushforward mem_fn_1_pushforward(double i, double j, SimpleFunctions1 *_d_this, double _d_i, double _d_j) { + // CHECK-NEXT: double _t0 = (this->x + this->y); + // CHECK-NEXT: double _t1 = i * j; + // CHECK-NEXT: return {_t0 * i + _t1 * j, (_d_this->x + 0.) * i + _t0 * _d_i + (_d_i * j + i * _d_j) * j + _t1 * _d_j}; + // CHECK-NEXT: } + + // CHECK: clad::ValueAndPushforward operator_plus_pushforward(const SimpleFunctions1 &other, const SimpleFunctions1 *_d_this, const SimpleFunctions1 &_d_other) const { + // CHECK-NEXT: return {SimpleFunctions1(this->x + other.x, this->y + other.y), SimpleFunctions1(_d_this->x + _d_other.x, 0. + 0.)}; + // CHECK-NEXT: } } \ No newline at end of file diff --git a/test/ForwardMode/UserDefinedTypes.C b/test/ForwardMode/UserDefinedTypes.C index 232e6b51b..39b3353c7 100644 --- a/test/ForwardMode/UserDefinedTypes.C +++ b/test/ForwardMode/UserDefinedTypes.C @@ -444,41 +444,11 @@ double fn6(TensorD5 t, double i) { res += sum(t); return res; } -// CHECK: clad::ValueAndPushforward sum_pushforward(Tensor *_d_this) { -// CHECK-NEXT: double _d_res = 0; -// CHECK-NEXT: double res = 0; -// CHECK-NEXT: { -// CHECK-NEXT: int _d_i = 0; -// CHECK-NEXT: for (int i = 0; i < 5U; ++i) { -// CHECK-NEXT: _d_res += _d_this->data[i]; -// CHECK-NEXT: res += this->data[i]; -// CHECK-NEXT: } -// CHECK-NEXT: } -// CHECK-NEXT: return {res, _d_res}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward sum_pushforward(Tensor *_d_this); -// CHECK: void updateTo_pushforward(double val, Tensor *_d_this, double _d_val) { -// CHECK-NEXT: { -// CHECK-NEXT: int _d_i = 0; -// CHECK-NEXT: for (int i = 0; i < 5U; ++i) { -// CHECK-NEXT: _d_this->data[i] = _d_val; -// CHECK-NEXT: this->data[i] = val; -// CHECK-NEXT: } -// CHECK-NEXT: } -// CHECK-NEXT: } +// CHECK: void updateTo_pushforward(double val, Tensor *_d_this, double _d_val); -// CHECK: clad::ValueAndPushforward sum_pushforward(Tensor &t, Tensor &_d_t) { -// CHECK-NEXT: double _d_res = 0; -// CHECK-NEXT: double res = 0; -// CHECK-NEXT: { -// CHECK-NEXT: int _d_i = 0; -// CHECK-NEXT: for (int i = 0; i < 5U; ++i) { -// CHECK-NEXT: _d_res += _d_t.data[i]; -// CHECK-NEXT: res += t.data[i]; -// CHECK-NEXT: } -// CHECK-NEXT: } -// CHECK-NEXT: return {res, _d_res}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward sum_pushforward(Tensor &t, Tensor &_d_t); // CHECK: double fn6_darg1(TensorD5 t, double i) { // CHECK-NEXT: TensorD5 _d_t; @@ -520,15 +490,9 @@ complexD fn8(double i, TensorD5 t) { return c; } -// CHECK: void real_pushforward({{.*}} [[__val:.*]], std{{(::__1)?}}::complex *_d_this, {{.*}} [[_d___val:[a-zA-Z_]*]]){{.*}} { -// CHECK-NEXT: {{(__real)?}} _d_this->[[_M_value:.*]] = [[_d___val]]; -// CHECK-NEXT: {{(__real)?}} this->[[_M_value]] = [[__val]]; -// CHECK-NEXT: } +// CHECK: void real_pushforward({{.*}} [[__val:.*]], std{{(::__1)?}}::complex *_d_this, {{.*}} [[_d___val:[a-zA-Z_]*]]){{.*}}; -// CHECK: void imag_pushforward({{.*}} [[__val:.*]], std{{(::__1)?}}::complex *_d_this, {{.*}} [[_d___val:[a-zA-Z_]*]]){{.*}} { -// CHECK-NEXT: {{(__imag)?}} _d_this->[[_M_value:.*]] = [[_d___val]]; -// CHECK-NEXT: {{(__imag)?}} this->[[_M_value]] = [[__val]]; -// CHECK-NEXT: } +// CHECK: void imag_pushforward({{.*}} [[__val:.*]], std{{(::__1)?}}::complex *_d_this, {{.*}} [[_d___val:[a-zA-Z_]*]]){{.*}}; // CHECK: complexD fn8_darg0(double i, TensorD5 t) { // CHECK-NEXT: double _d_i = 1; @@ -554,13 +518,9 @@ complexD fn9(double i, complexD c) { return r; } -// CHECK: constexpr clad::ValueAndPushforward real_pushforward(const std{{(::__1)?}}::complex *_d_this){{.*}} { -// CHECK-NEXT: return {{[{](__real )?}}this->[[_M_value:[a-zA-Z_]+]],{{( __real)?}} _d_this->[[_M_value:[a-zA-Z_]+]]}; -// CHECK-NEXT: } +// CHECK: constexpr clad::ValueAndPushforward real_pushforward(const std{{(::__1)?}}::complex *_d_this){{.*}}; -// CHECK: constexpr clad::ValueAndPushforward imag_pushforward(const std{{(::__1)?}}::complex *_d_this){{.*}} { -// CHECK-NEXT: return {{[{](__imag )?}}this->[[_M_value:[a-zA-Z_]+]],{{( __imag)?}} _d_this->[[_M_value:[a-zA-Z_]+]]}; -// CHECK-NEXT: } +// CHECK: constexpr clad::ValueAndPushforward imag_pushforward(const std{{(::__1)?}}::complex *_d_this){{.*}}; // CHECK: complexD fn9_darg0(double i, complexD c) { // CHECK-NEXT: double _d_i = 1; @@ -633,160 +593,33 @@ TensorD5 fn11(double i, double j) { return res1; } -// CHECK: void operator_call_pushforward(double val, Tensor *_d_this, double _d_val) { -// CHECK-NEXT: { -// CHECK-NEXT: unsigned int _d_i = 0; -// CHECK-NEXT: for (unsigned int i = 0; i < 5U; ++i) { -// CHECK-NEXT: _d_this->data[i] = _d_val; -// CHECK-NEXT: this->data[i] = val; -// CHECK-NEXT: } -// CHECK-NEXT: } -// CHECK-NEXT: } +// CHECK: void operator_call_pushforward(double val, Tensor *_d_this, double _d_val); -// CHECK: clad::ValueAndPushforward operator_subscript_pushforward(std::size_t idx, Tensor *_d_this, std::size_t _d_idx) { -// CHECK-NEXT: return {this->data[idx], _d_this->data[idx]}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward operator_subscript_pushforward(std::size_t idx, Tensor *_d_this, std::size_t _d_idx); -// CHECK: clad::ValueAndPushforward, Tensor > operator_plus_pushforward(const Tensor &a, const Tensor &b, const Tensor &_d_a, const Tensor &_d_b) { -// CHECK-NEXT: Tensor _d_res; -// CHECK-NEXT: Tensor res; -// CHECK-NEXT: { -// CHECK-NEXT: unsigned int _d_i = 0; -// CHECK-NEXT: for (unsigned int i = 0; i < 5U; ++i) { -// CHECK-NEXT: _d_res.data[i] = _d_a.data[i] + _d_b.data[i]; -// CHECK-NEXT: res.data[i] = a.data[i] + b.data[i]; -// CHECK-NEXT: } -// CHECK-NEXT: } -// CHECK-NEXT: return {res, _d_res}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward, Tensor > operator_plus_pushforward(const Tensor &a, const Tensor &b, const Tensor &_d_a, const Tensor &_d_b); -// CHECK: clad::ValueAndPushforward, Tensor > operator_star_pushforward(const Tensor &a, const Tensor &b, const Tensor &_d_a, const Tensor &_d_b) { -// CHECK-NEXT: Tensor _d_res; -// CHECK-NEXT: Tensor res; -// CHECK-NEXT: { -// CHECK-NEXT: unsigned int _d_i = 0; -// CHECK-NEXT: for (unsigned int i = 0; i < 5U; ++i) { -// CHECK-NEXT: const double _t0 = a.data[i]; -// CHECK-NEXT: const double _t1 = b.data[i]; -// CHECK-NEXT: _d_res.data[i] = _d_a.data[i] * _t1 + _t0 * _d_b.data[i]; -// CHECK-NEXT: res.data[i] = _t0 * _t1; -// CHECK-NEXT: } -// CHECK-NEXT: } -// CHECK-NEXT: return {res, _d_res}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward, Tensor > operator_star_pushforward(const Tensor &a, const Tensor &b, const Tensor &_d_a, const Tensor &_d_b); -// CHECK: clad::ValueAndPushforward, Tensor > operator_minus_pushforward(const Tensor &t, const Tensor &_d_t) { -// CHECK-NEXT: Tensor _d_res; -// CHECK-NEXT: Tensor res; -// CHECK-NEXT: { -// CHECK-NEXT: unsigned int _d_i = 0; -// CHECK-NEXT: for (unsigned int i = 0; i < 5U; ++i) { -// CHECK-NEXT: _d_res.data[i] = -_d_t.data[i]; -// CHECK-NEXT: res.data[i] = -t.data[i]; -// CHECK-NEXT: } -// CHECK-NEXT: } -// CHECK-NEXT: return {res, _d_res}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward, Tensor > operator_minus_pushforward(const Tensor &t, const Tensor &_d_t); -// CHECK: clad::ValueAndPushforward, Tensor > operator_minus_pushforward(const Tensor &a, const Tensor &b, const Tensor &_d_a, const Tensor &_d_b) { -// CHECK-NEXT: Tensor _d_res; -// CHECK-NEXT: Tensor res; -// CHECK-NEXT: { -// CHECK-NEXT: unsigned int _d_i = 0; -// CHECK-NEXT: for (unsigned int i = 0; i < 5U; ++i) { -// CHECK-NEXT: _d_res.data[i] = _d_a.data[i] - _d_b.data[i]; -// CHECK-NEXT: res.data[i] = a.data[i] - b.data[i]; -// CHECK-NEXT: } -// CHECK-NEXT: } -// CHECK-NEXT: return {res, _d_res}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward, Tensor > operator_minus_pushforward(const Tensor &a, const Tensor &b, const Tensor &_d_a, const Tensor &_d_b); -// CHECK: clad::ValueAndPushforward, Tensor > operator_slash_pushforward(const Tensor &a, const Tensor &b, const Tensor &_d_a, const Tensor &_d_b) { -// CHECK-NEXT: Tensor _d_res; -// CHECK-NEXT: Tensor res; -// CHECK-NEXT: { -// CHECK-NEXT: unsigned int _d_i = 0; -// CHECK-NEXT: for (unsigned int i = 0; i < 5U; ++i) { -// CHECK-NEXT: const double _t0 = a.data[i]; -// CHECK-NEXT: const double _t1 = b.data[i]; -// CHECK-NEXT: _d_res.data[i] = (_d_a.data[i] * _t1 - _t0 * _d_b.data[i]) / (_t1 * _t1); -// CHECK-NEXT: res.data[i] = _t0 / _t1; -// CHECK-NEXT: } -// CHECK-NEXT: } -// CHECK-NEXT: return {res, _d_res}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward, Tensor > operator_slash_pushforward(const Tensor &a, const Tensor &b, const Tensor &_d_a, const Tensor &_d_b); -// CHECK: clad::ValueAndPushforward &, Tensor &> operator_equal_pushforward(const Tensor &t, Tensor *_d_this, const Tensor &_d_t) { -// CHECK-NEXT: { -// CHECK-NEXT: unsigned int _d_i = 0; -// CHECK-NEXT: for (unsigned int i = 0; i < 5U; ++i) { -// CHECK-NEXT: _d_this->data[i] = _d_t.data[i]; -// CHECK-NEXT: this->data[i] = t.data[i]; -// CHECK-NEXT: } -// CHECK-NEXT: } -// CHECK-NEXT: return {*this, *_d_this}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward &, Tensor &> operator_equal_pushforward(const Tensor &t, Tensor *_d_this, const Tensor &_d_t); -// CHECK: clad::ValueAndPushforward, Tensor > operator_caret_pushforward(const Tensor &a, const Tensor &b, const Tensor &_d_a, const Tensor &_d_b) { -// CHECK-NEXT: Tensor _d_res; -// CHECK-NEXT: Tensor res; -// CHECK-NEXT: { -// CHECK-NEXT: unsigned int _d_i = 0; -// CHECK-NEXT: for (unsigned int i = 0; i < 5U; ++i) { -// CHECK-NEXT: ValueAndPushforward _t0 = clad::custom_derivatives::pow_pushforward(a.data[i], b.data[i], _d_a.data[i], _d_b.data[i]); -// CHECK-NEXT: _d_res.data[i] = _t0.pushforward; -// CHECK-NEXT: res.data[i] = _t0.value; -// CHECK-NEXT: } -// CHECK-NEXT: } -// CHECK-NEXT: return {res, _d_res}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward, Tensor > operator_caret_pushforward(const Tensor &a, const Tensor &b, const Tensor &_d_a, const Tensor &_d_b); -// CHECK: clad::ValueAndPushforward &, Tensor &> operator_plus_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { -// CHECK-NEXT: clad::ValueAndPushforward, Tensor > _t0 = operator_plus_pushforward(lhs, rhs, _d_lhs, _d_rhs); -// CHECK-NEXT: clad::ValueAndPushforward &, Tensor &> _t1 = lhs.operator_equal_pushforward(_t0.value, & _d_lhs, _t0.pushforward); -// CHECK-NEXT: return {lhs, _d_lhs}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward &, Tensor &> operator_plus_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs); -// CHECK: clad::ValueAndPushforward &, Tensor &> operator_minus_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { -// CHECK-NEXT: clad::ValueAndPushforward, Tensor > _t0 = operator_minus_pushforward(lhs, rhs, _d_lhs, _d_rhs); -// CHECK-NEXT: clad::ValueAndPushforward &, Tensor &> _t1 = lhs.operator_equal_pushforward(_t0.value, & _d_lhs, _t0.pushforward); -// CHECK-NEXT: return {lhs, _d_lhs}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward &, Tensor &> operator_minus_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs); -// CHECK: clad::ValueAndPushforward &, Tensor &> operator_plus_plus_pushforward(Tensor *_d_this) { -// CHECK-NEXT: { -// CHECK-NEXT: unsigned int _d_i = 0; -// CHECK-NEXT: for (unsigned int i = 0; i < 5U; ++i) { -// CHECK-NEXT: _d_this->data[i] += 0; -// CHECK-NEXT: this->data[i] += 1; -// CHECK-NEXT: } -// CHECK-NEXT: } -// CHECK-NEXT: return {*this, *_d_this}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward &, Tensor &> operator_plus_plus_pushforward(Tensor *_d_this); -// CHECK: clad::ValueAndPushforward &, Tensor &> operator_minus_minus_pushforward(Tensor *_d_this) { -// CHECK-NEXT: { -// CHECK-NEXT: unsigned int _d_i = 0; -// CHECK-NEXT: for (unsigned int i = 0; i < 5U; ++i) { -// CHECK-NEXT: _d_this->data[i] += 0; -// CHECK-NEXT: this->data[i] += 1; -// CHECK-NEXT: } -// CHECK-NEXT: } -// CHECK-NEXT: return {*this, *_d_this}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward &, Tensor &> operator_minus_minus_pushforward(Tensor *_d_this); -// CHECK: clad::ValueAndPushforward, Tensor > operator_plus_plus_pushforward(int param, Tensor *_d_this, int _d_param) { -// CHECK-NEXT: Tensor _d_temp; -// CHECK-NEXT: Tensor temp; -// CHECK-NEXT: { -// CHECK-NEXT: unsigned int _d_i = 0; -// CHECK-NEXT: for (unsigned int i = 0; i < 5U; ++i) { -// CHECK-NEXT: _d_temp.data[i] += 0; -// CHECK-NEXT: temp.data[i] += 1; -// CHECK-NEXT: } -// CHECK-NEXT: } -// CHECK-NEXT: return {temp, _d_temp}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward, Tensor > operator_plus_plus_pushforward(int param, Tensor *_d_this, int _d_param); // CHECK: TensorD5 fn11_darg0(double i, double j) { // CHECK-NEXT: double _d_i = 1; @@ -851,23 +684,11 @@ TensorD5 fn12(double i, double j) { return res1; } -// CHECK: clad::ValueAndPushforward &, Tensor &> operator_star_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { -// CHECK-NEXT: clad::ValueAndPushforward, Tensor > _t0 = operator_star_pushforward(lhs, rhs, _d_lhs, _d_rhs); -// CHECK-NEXT: clad::ValueAndPushforward &, Tensor &> _t1 = lhs.operator_equal_pushforward(_t0.value, & _d_lhs, _t0.pushforward); -// CHECK-NEXT: return {lhs, _d_lhs}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward &, Tensor &> operator_star_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs); -// CHECK: clad::ValueAndPushforward &, Tensor &> operator_slash_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { -// CHECK-NEXT: clad::ValueAndPushforward, Tensor > _t0 = operator_slash_pushforward(lhs, rhs, _d_lhs, _d_rhs); -// CHECK-NEXT: clad::ValueAndPushforward &, Tensor &> _t1 = lhs.operator_equal_pushforward(_t0.value, & _d_lhs, _t0.pushforward); -// CHECK-NEXT: return {lhs, _d_lhs}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward &, Tensor &> operator_slash_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs); -// CHECK: clad::ValueAndPushforward &, Tensor &> operator_caret_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { -// CHECK-NEXT: clad::ValueAndPushforward, Tensor > _t0 = operator_slash_pushforward(lhs, rhs, _d_lhs, _d_rhs); -// CHECK-NEXT: clad::ValueAndPushforward &, Tensor &> _t1 = lhs.operator_equal_pushforward(_t0.value, & _d_lhs, _t0.pushforward); -// CHECK-NEXT: return {lhs, _d_lhs}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward &, Tensor &> operator_caret_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs); // CHECK: TensorD5 fn12_darg0(double i, double j) { // CHECK-NEXT: double _d_i = 1; @@ -930,120 +751,51 @@ TensorD5 fn13(double i, double j) { return a + b; } -// CHECK: clad::ValueAndPushforward operator_less_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { -// CHECK-NEXT: double _d_lsum, _d_rsum; -// CHECK-NEXT: double lsum, rsum; -// CHECK-NEXT: _d_lsum = _d_rsum = 0; -// CHECK-NEXT: lsum = rsum = 0; -// CHECK-NEXT: { -// CHECK-NEXT: unsigned int _d_i = 0; -// CHECK-NEXT: for (unsigned int i = 0; i < 5U; ++i) { -// CHECK-NEXT: _d_lsum += _d_lhs.data[i]; -// CHECK-NEXT: lsum += lhs.data[i]; -// CHECK-NEXT: _d_rsum += _d_lhs.data[i]; -// CHECK-NEXT: rsum += lhs.data[i]; -// CHECK-NEXT: } -// CHECK-NEXT: } -// CHECK-NEXT: return {1, 0}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward operator_less_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs); -// CHECK: clad::ValueAndPushforward operator_greater_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { -// CHECK-NEXT: double _d_lsum, _d_rsum; -// CHECK-NEXT: double lsum, rsum; -// CHECK-NEXT: _d_lsum = _d_rsum = 0; -// CHECK-NEXT: lsum = rsum = 0; -// CHECK-NEXT: { -// CHECK-NEXT: unsigned int _d_i = 0; -// CHECK-NEXT: for (unsigned int i = 0; i < 5U; ++i) { -// CHECK-NEXT: _d_lsum += _d_lhs.data[i]; -// CHECK-NEXT: lsum += lhs.data[i]; -// CHECK-NEXT: _d_rsum += _d_lhs.data[i]; -// CHECK-NEXT: rsum += lhs.data[i]; -// CHECK-NEXT: } -// CHECK-NEXT: } -// CHECK-NEXT: return {1, 0}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward operator_greater_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs); -// CHECK: clad::ValueAndPushforward operator_less_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { -// CHECK-NEXT: return {1, 0}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward operator_less_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs); -// CHECK: clad::ValueAndPushforward operator_greater_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { -// CHECK-NEXT: return {1, 0}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward operator_greater_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs); -// CHECK: clad::ValueAndPushforward operator_equal_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { -// CHECK-NEXT: return {1, 0}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward operator_equal_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs); -// CHECK: clad::ValueAndPushforward operator_exclaim_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { -// CHECK-NEXT: return {1, 0}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward operator_exclaim_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs); -// CHECK: void operator_comma_pushforward(const Tensor &lhs, const Tensor &rhs, const Tensor &_d_lhs, const Tensor &_d_rhs) { -// CHECK-NEXT: } +// CHECK: void operator_comma_pushforward(const Tensor &lhs, const Tensor &rhs, const Tensor &_d_lhs, const Tensor &_d_rhs); -// CHECK: void operator_exclaim_pushforward(const Tensor &lhs, const Tensor &_d_lhs) { -// CHECK-NEXT: } +// CHECK: void operator_exclaim_pushforward(const Tensor &lhs, const Tensor &_d_lhs); -// CHECK: clad::ValueAndPushforward *, Tensor *> operator_amp_pushforward(Tensor *_d_this) { -// CHECK-NEXT: return {this, _d_this}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward *, Tensor *> operator_amp_pushforward(Tensor *_d_this); -// CHECK: clad::ValueAndPushforward *, Tensor *> operator_arrow_pushforward(Tensor *_d_this) { -// CHECK-NEXT: return {this, _d_this}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward *, Tensor *> operator_arrow_pushforward(Tensor *_d_this); -// CHECK: clad::ValueAndPushforward, Tensor > operator_percent_pushforward(const Tensor &a, const Tensor &b, const Tensor &_d_a, const Tensor &_d_b) { -// CHECK-NEXT: return {a, _d_a}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward, Tensor > operator_percent_pushforward(const Tensor &a, const Tensor &b, const Tensor &_d_a, const Tensor &_d_b); -// CHECK: clad::ValueAndPushforward &, Tensor &> operator_percent_equal_pushforward(Tensor &a, const Tensor &b, Tensor &_d_a, const Tensor &_d_b) { -// CHECK-NEXT: return {a, _d_a}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward &, Tensor &> operator_percent_equal_pushforward(Tensor &a, const Tensor &b, Tensor &_d_a, const Tensor &_d_b); -// CHECK: void operator_tilde_pushforward(const Tensor &a, const Tensor &_d_a) { -// CHECK-NEXT: } +// CHECK: void operator_tilde_pushforward(const Tensor &a, const Tensor &_d_a); -// CHECK: clad::ValueAndPushforward operator_less_less_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { -// CHECK-NEXT: return {1, 0}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward operator_less_less_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs); -// CHECK: clad::ValueAndPushforward operator_greater_greater_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { -// CHECK-NEXT: return {1, 0}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward operator_greater_greater_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs); -// CHECK: clad::ValueAndPushforward operator_AmpAmp_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { -// CHECK-NEXT: return {1, 0}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward operator_AmpAmp_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs); -// CHECK: clad::ValueAndPushforward operator_pipe_pipe_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { -// CHECK-NEXT: return {1, 0}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward operator_pipe_pipe_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs); -// CHECK: clad::ValueAndPushforward operator_less_less_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { -// CHECK-NEXT: return {1, 0}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward operator_less_less_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs); -// CHECK: clad::ValueAndPushforward operator_greater_greater_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { -// CHECK-NEXT: return {1, 0}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward operator_greater_greater_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs); -// CHECK: clad::ValueAndPushforward operator_amp_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { -// CHECK-NEXT: return {1, 0}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward operator_amp_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs); -// CHECK: clad::ValueAndPushforward operator_pipe_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { -// CHECK-NEXT: return {1, 0}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward operator_pipe_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs); -// CHECK: clad::ValueAndPushforward operator_pipe_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { -// CHECK-NEXT: return {1, 0}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward operator_pipe_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs); -// CHECK: clad::ValueAndPushforward operator_amp_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { -// CHECK-NEXT: return {1, 0}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward operator_amp_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs); // CHECK: TensorD5 fn13_darg0(double i, double j) { // CHECK-NEXT: double _d_i = 1; @@ -1247,4 +999,346 @@ int main() { TEST_DIFFERENTIATE(fn15, pairdd(), pairdd()); // CHECK-EXEC: {1.00} TEST_DIFFERENTIATE(fn16, pair_of_pairdd(), pair_of_pairdd()); // CHECK-EXEC: {2.00} TEST_DIFFERENTIATE(fn17, A(3.00), B(5.00)); // CHECK-EXEC: {3.00} + +// CHECK: clad::ValueAndPushforward sum_pushforward(Tensor *_d_this) { +// CHECK-NEXT: double _d_res = 0; +// CHECK-NEXT: double res = 0; +// CHECK-NEXT: { +// CHECK-NEXT: int _d_i = 0; +// CHECK-NEXT: for (int i = 0; i < 5U; ++i) { +// CHECK-NEXT: _d_res += _d_this->data[i]; +// CHECK-NEXT: res += this->data[i]; +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: return {res, _d_res}; +// CHECK-NEXT: } + +// CHECK: void updateTo_pushforward(double val, Tensor *_d_this, double _d_val) { +// CHECK-NEXT: { +// CHECK-NEXT: int _d_i = 0; +// CHECK-NEXT: for (int i = 0; i < 5U; ++i) { +// CHECK-NEXT: _d_this->data[i] = _d_val; +// CHECK-NEXT: this->data[i] = val; +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward sum_pushforward(Tensor &t, Tensor &_d_t) { +// CHECK-NEXT: double _d_res = 0; +// CHECK-NEXT: double res = 0; +// CHECK-NEXT: { +// CHECK-NEXT: int _d_i = 0; +// CHECK-NEXT: for (int i = 0; i < 5U; ++i) { +// CHECK-NEXT: _d_res += _d_t.data[i]; +// CHECK-NEXT: res += t.data[i]; +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: return {res, _d_res}; +// CHECK-NEXT: } + +// CHECK: void real_pushforward({{.*}} [[__val:.*]], std{{(::__1)?}}::complex *_d_this, {{.*}} [[_d___val:[a-zA-Z_]*]]){{.*}} { +// CHECK-NEXT: {{(__real)?}} _d_this->[[_M_value:.*]] = [[_d___val]]; +// CHECK-NEXT: {{(__real)?}} this->[[_M_value]] = [[__val]]; +// CHECK-NEXT: } + +// CHECK: void imag_pushforward({{.*}} [[__val:.*]], std{{(::__1)?}}::complex *_d_this, {{.*}} [[_d___val:[a-zA-Z_]*]]){{.*}} { +// CHECK-NEXT: {{(__imag)?}} _d_this->[[_M_value:.*]] = [[_d___val]]; +// CHECK-NEXT: {{(__imag)?}} this->[[_M_value]] = [[__val]]; +// CHECK-NEXT: } + +// CHECK: constexpr clad::ValueAndPushforward real_pushforward(const std{{(::__1)?}}::complex *_d_this){{.*}} { +// CHECK-NEXT: return {{[{](__real )?}}this->[[_M_value:[a-zA-Z_]+]],{{( __real)?}} _d_this->[[_M_value:[a-zA-Z_]+]]}; +// CHECK-NEXT: } + +// CHECK: constexpr clad::ValueAndPushforward imag_pushforward(const std{{(::__1)?}}::complex *_d_this){{.*}} { +// CHECK-NEXT: return {{[{](__imag )?}}this->[[_M_value:[a-zA-Z_]+]],{{( __imag)?}} _d_this->[[_M_value:[a-zA-Z_]+]]}; +// CHECK-NEXT: } + +// CHECK: void operator_call_pushforward(double val, Tensor *_d_this, double _d_val) { +// CHECK-NEXT: { +// CHECK-NEXT: unsigned int _d_i = 0; +// CHECK-NEXT: for (unsigned int i = 0; i < 5U; ++i) { +// CHECK-NEXT: _d_this->data[i] = _d_val; +// CHECK-NEXT: this->data[i] = val; +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward operator_subscript_pushforward(std::size_t idx, Tensor *_d_this, std::size_t _d_idx) { +// CHECK-NEXT: return {this->data[idx], _d_this->data[idx]}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward, Tensor > operator_plus_pushforward(const Tensor &a, const Tensor &b, const Tensor &_d_a, const Tensor &_d_b) { +// CHECK-NEXT: Tensor _d_res; +// CHECK-NEXT: Tensor res; +// CHECK-NEXT: { +// CHECK-NEXT: unsigned int _d_i = 0; +// CHECK-NEXT: for (unsigned int i = 0; i < 5U; ++i) { +// CHECK-NEXT: _d_res.data[i] = _d_a.data[i] + _d_b.data[i]; +// CHECK-NEXT: res.data[i] = a.data[i] + b.data[i]; +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: return {res, _d_res}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward, Tensor > operator_star_pushforward(const Tensor &a, const Tensor &b, const Tensor &_d_a, const Tensor &_d_b) { +// CHECK-NEXT: Tensor _d_res; +// CHECK-NEXT: Tensor res; +// CHECK-NEXT: { +// CHECK-NEXT: unsigned int _d_i = 0; +// CHECK-NEXT: for (unsigned int i = 0; i < 5U; ++i) { +// CHECK-NEXT: const double _t0 = a.data[i]; +// CHECK-NEXT: const double _t1 = b.data[i]; +// CHECK-NEXT: _d_res.data[i] = _d_a.data[i] * _t1 + _t0 * _d_b.data[i]; +// CHECK-NEXT: res.data[i] = _t0 * _t1; +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: return {res, _d_res}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward, Tensor > operator_minus_pushforward(const Tensor &t, const Tensor &_d_t) { +// CHECK-NEXT: Tensor _d_res; +// CHECK-NEXT: Tensor res; +// CHECK-NEXT: { +// CHECK-NEXT: unsigned int _d_i = 0; +// CHECK-NEXT: for (unsigned int i = 0; i < 5U; ++i) { +// CHECK-NEXT: _d_res.data[i] = -_d_t.data[i]; +// CHECK-NEXT: res.data[i] = -t.data[i]; +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: return {res, _d_res}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward, Tensor > operator_minus_pushforward(const Tensor &a, const Tensor &b, const Tensor &_d_a, const Tensor &_d_b) { +// CHECK-NEXT: Tensor _d_res; +// CHECK-NEXT: Tensor res; +// CHECK-NEXT: { +// CHECK-NEXT: unsigned int _d_i = 0; +// CHECK-NEXT: for (unsigned int i = 0; i < 5U; ++i) { +// CHECK-NEXT: _d_res.data[i] = _d_a.data[i] - _d_b.data[i]; +// CHECK-NEXT: res.data[i] = a.data[i] - b.data[i]; +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: return {res, _d_res}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward, Tensor > operator_slash_pushforward(const Tensor &a, const Tensor &b, const Tensor &_d_a, const Tensor &_d_b) { +// CHECK-NEXT: Tensor _d_res; +// CHECK-NEXT: Tensor res; +// CHECK-NEXT: { +// CHECK-NEXT: unsigned int _d_i = 0; +// CHECK-NEXT: for (unsigned int i = 0; i < 5U; ++i) { +// CHECK-NEXT: const double _t0 = a.data[i]; +// CHECK-NEXT: const double _t1 = b.data[i]; +// CHECK-NEXT: _d_res.data[i] = (_d_a.data[i] * _t1 - _t0 * _d_b.data[i]) / (_t1 * _t1); +// CHECK-NEXT: res.data[i] = _t0 / _t1; +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: return {res, _d_res}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward &, Tensor &> operator_equal_pushforward(const Tensor &t, Tensor *_d_this, const Tensor &_d_t) { +// CHECK-NEXT: { +// CHECK-NEXT: unsigned int _d_i = 0; +// CHECK-NEXT: for (unsigned int i = 0; i < 5U; ++i) { +// CHECK-NEXT: _d_this->data[i] = _d_t.data[i]; +// CHECK-NEXT: this->data[i] = t.data[i]; +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: return {*this, *_d_this}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward, Tensor > operator_caret_pushforward(const Tensor &a, const Tensor &b, const Tensor &_d_a, const Tensor &_d_b) { +// CHECK-NEXT: Tensor _d_res; +// CHECK-NEXT: Tensor res; +// CHECK-NEXT: { +// CHECK-NEXT: unsigned int _d_i = 0; +// CHECK-NEXT: for (unsigned int i = 0; i < 5U; ++i) { +// CHECK-NEXT: ValueAndPushforward _t0 = clad::custom_derivatives::pow_pushforward(a.data[i], b.data[i], _d_a.data[i], _d_b.data[i]); +// CHECK-NEXT: _d_res.data[i] = _t0.pushforward; +// CHECK-NEXT: res.data[i] = _t0.value; +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: return {res, _d_res}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward &, Tensor &> operator_plus_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { +// CHECK-NEXT: clad::ValueAndPushforward, Tensor > _t0 = operator_plus_pushforward(lhs, rhs, _d_lhs, _d_rhs); +// CHECK-NEXT: clad::ValueAndPushforward &, Tensor &> _t1 = lhs.operator_equal_pushforward(_t0.value, & _d_lhs, _t0.pushforward); +// CHECK-NEXT: return {lhs, _d_lhs}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward &, Tensor &> operator_minus_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { +// CHECK-NEXT: clad::ValueAndPushforward, Tensor > _t0 = operator_minus_pushforward(lhs, rhs, _d_lhs, _d_rhs); +// CHECK-NEXT: clad::ValueAndPushforward &, Tensor &> _t1 = lhs.operator_equal_pushforward(_t0.value, & _d_lhs, _t0.pushforward); +// CHECK-NEXT: return {lhs, _d_lhs}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward &, Tensor &> operator_plus_plus_pushforward(Tensor *_d_this) { +// CHECK-NEXT: { +// CHECK-NEXT: unsigned int _d_i = 0; +// CHECK-NEXT: for (unsigned int i = 0; i < 5U; ++i) { +// CHECK-NEXT: _d_this->data[i] += 0; +// CHECK-NEXT: this->data[i] += 1; +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: return {*this, *_d_this}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward &, Tensor &> operator_minus_minus_pushforward(Tensor *_d_this) { +// CHECK-NEXT: { +// CHECK-NEXT: unsigned int _d_i = 0; +// CHECK-NEXT: for (unsigned int i = 0; i < 5U; ++i) { +// CHECK-NEXT: _d_this->data[i] += 0; +// CHECK-NEXT: this->data[i] += 1; +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: return {*this, *_d_this}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward, Tensor > operator_plus_plus_pushforward(int param, Tensor *_d_this, int _d_param) { +// CHECK-NEXT: Tensor _d_temp; +// CHECK-NEXT: Tensor temp; +// CHECK-NEXT: { +// CHECK-NEXT: unsigned int _d_i = 0; +// CHECK-NEXT: for (unsigned int i = 0; i < 5U; ++i) { +// CHECK-NEXT: _d_temp.data[i] += 0; +// CHECK-NEXT: temp.data[i] += 1; +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: return {temp, _d_temp}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward &, Tensor &> operator_star_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { +// CHECK-NEXT: clad::ValueAndPushforward, Tensor > _t0 = operator_star_pushforward(lhs, rhs, _d_lhs, _d_rhs); +// CHECK-NEXT: clad::ValueAndPushforward &, Tensor &> _t1 = lhs.operator_equal_pushforward(_t0.value, & _d_lhs, _t0.pushforward); +// CHECK-NEXT: return {lhs, _d_lhs}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward &, Tensor &> operator_slash_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { +// CHECK-NEXT: clad::ValueAndPushforward, Tensor > _t0 = operator_slash_pushforward(lhs, rhs, _d_lhs, _d_rhs); +// CHECK-NEXT: clad::ValueAndPushforward &, Tensor &> _t1 = lhs.operator_equal_pushforward(_t0.value, & _d_lhs, _t0.pushforward); +// CHECK-NEXT: return {lhs, _d_lhs}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward &, Tensor &> operator_caret_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { +// CHECK-NEXT: clad::ValueAndPushforward, Tensor > _t0 = operator_slash_pushforward(lhs, rhs, _d_lhs, _d_rhs); +// CHECK-NEXT: clad::ValueAndPushforward &, Tensor &> _t1 = lhs.operator_equal_pushforward(_t0.value, & _d_lhs, _t0.pushforward); +// CHECK-NEXT: return {lhs, _d_lhs}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward operator_less_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { +// CHECK-NEXT: double _d_lsum, _d_rsum; +// CHECK-NEXT: double lsum, rsum; +// CHECK-NEXT: _d_lsum = _d_rsum = 0; +// CHECK-NEXT: lsum = rsum = 0; +// CHECK-NEXT: { +// CHECK-NEXT: unsigned int _d_i = 0; +// CHECK-NEXT: for (unsigned int i = 0; i < 5U; ++i) { +// CHECK-NEXT: _d_lsum += _d_lhs.data[i]; +// CHECK-NEXT: lsum += lhs.data[i]; +// CHECK-NEXT: _d_rsum += _d_lhs.data[i]; +// CHECK-NEXT: rsum += lhs.data[i]; +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: return {1, 0}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward operator_greater_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { +// CHECK-NEXT: double _d_lsum, _d_rsum; +// CHECK-NEXT: double lsum, rsum; +// CHECK-NEXT: _d_lsum = _d_rsum = 0; +// CHECK-NEXT: lsum = rsum = 0; +// CHECK-NEXT: { +// CHECK-NEXT: unsigned int _d_i = 0; +// CHECK-NEXT: for (unsigned int i = 0; i < 5U; ++i) { +// CHECK-NEXT: _d_lsum += _d_lhs.data[i]; +// CHECK-NEXT: lsum += lhs.data[i]; +// CHECK-NEXT: _d_rsum += _d_lhs.data[i]; +// CHECK-NEXT: rsum += lhs.data[i]; +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: return {1, 0}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward operator_less_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { +// CHECK-NEXT: return {1, 0}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward operator_greater_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { +// CHECK-NEXT: return {1, 0}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward operator_equal_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { +// CHECK-NEXT: return {1, 0}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward operator_exclaim_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { +// CHECK-NEXT: return {1, 0}; +// CHECK-NEXT: } + +// CHECK: void operator_comma_pushforward(const Tensor &lhs, const Tensor &rhs, const Tensor &_d_lhs, const Tensor &_d_rhs) { +// CHECK-NEXT: } + +// CHECK: void operator_exclaim_pushforward(const Tensor &lhs, const Tensor &_d_lhs) { +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward *, Tensor *> operator_amp_pushforward(Tensor *_d_this) { +// CHECK-NEXT: return {this, _d_this}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward *, Tensor *> operator_arrow_pushforward(Tensor *_d_this) { +// CHECK-NEXT: return {this, _d_this}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward, Tensor > operator_percent_pushforward(const Tensor &a, const Tensor &b, const Tensor &_d_a, const Tensor &_d_b) { +// CHECK-NEXT: return {a, _d_a}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward &, Tensor &> operator_percent_equal_pushforward(Tensor &a, const Tensor &b, Tensor &_d_a, const Tensor &_d_b) { +// CHECK-NEXT: return {a, _d_a}; +// CHECK-NEXT: } + +// CHECK: void operator_tilde_pushforward(const Tensor &a, const Tensor &_d_a) { +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward operator_less_less_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { +// CHECK-NEXT: return {1, 0}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward operator_greater_greater_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { +// CHECK-NEXT: return {1, 0}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward operator_AmpAmp_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { +// CHECK-NEXT: return {1, 0}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward operator_pipe_pipe_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { +// CHECK-NEXT: return {1, 0}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward operator_less_less_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { +// CHECK-NEXT: return {1, 0}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward operator_greater_greater_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { +// CHECK-NEXT: return {1, 0}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward operator_amp_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { +// CHECK-NEXT: return {1, 0}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward operator_pipe_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { +// CHECK-NEXT: return {1, 0}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward operator_pipe_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { +// CHECK-NEXT: return {1, 0}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward operator_amp_equal_pushforward(Tensor &lhs, const Tensor &rhs, Tensor &_d_lhs, const Tensor &_d_rhs) { +// CHECK-NEXT: return {1, 0}; +// CHECK-NEXT: } } \ No newline at end of file diff --git a/test/ForwardMode/VectorMode.C b/test/ForwardMode/VectorMode.C index 17be014da..28828d251 100644 --- a/test/ForwardMode/VectorMode.C +++ b/test/ForwardMode/VectorMode.C @@ -199,12 +199,7 @@ double square(const double& x) { return z; } -// CHECK: clad::ValueAndPushforward > square_vector_pushforward(const double &x, const clad::array &_d_x) { -// CHECK-NEXT: unsigned long indepVarCount = _d_x.size(); -// CHECK-NEXT: clad::array _d_vector_z(clad::array(indepVarCount, _d_x * x + x * _d_x)); -// CHECK-NEXT: double z = x * x; -// CHECK-NEXT: return {z, _d_vector_z}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward > square_vector_pushforward(const double &x, const clad::array &_d_x); double f6(double x, double y) { return square(x) + square(y); @@ -232,25 +227,10 @@ double weighted_array_squared_sum(const double* arr, double w, int n) { return sum; } -// CHECK: clad::ValueAndPushforward > weighted_array_squared_sum_vector_pushforward(const double *arr, double w, int n, clad::matrix &_d_arr, clad::array _d_w, clad::array _d_n) { -// CHECK-NEXT: unsigned long indepVarCount = _d_n.size(); -// CHECK-NEXT: clad::array _d_vector_sum(clad::array(indepVarCount, 0)); -// CHECK-NEXT: double sum = 0; -// CHECK-NEXT: { -// CHECK-NEXT: clad::array _d_vector_i(clad::array(indepVarCount, 0)); -// CHECK-NEXT: for (int i = 0; i < n; ++i) { -// CHECK-NEXT: clad::ValueAndPushforward > _t0 = square_vector_pushforward(arr[i], _d_arr[i]); -// CHECK-NEXT: double &_t1 = _t0.value; -// CHECK-NEXT: _d_vector_sum += _d_w * _t1 + w * _t0.pushforward; -// CHECK-NEXT: sum += w * _t1; -// CHECK-NEXT: } -// CHECK-NEXT: } -// CHECK-NEXT: return {sum, _d_vector_sum}; -// CHECK-NEXT: } - double f7(const double* arr, double w, int n) { return weighted_array_squared_sum(arr, w, n); } +// CHECK: clad::ValueAndPushforward > weighted_array_squared_sum_vector_pushforward(const double *arr, double w, int n, clad::matrix &_d_arr, clad::array _d_w, clad::array _d_n); // CHECK: void f7_dvec_0_1(const double *arr, double w, int n, clad::array_ref _d_arr, double *_d_w) { // CHECK-NEXT: unsigned long indepVarCount = _d_arr.size() + 1UL; @@ -273,16 +253,7 @@ void sum_ref(double& res, int n, const double* arr) { return; } -// CHECK: void sum_ref_vector_pushforward(double &res, int n, const double *arr, clad::array &_d_res, clad::array _d_n, clad::matrix &_d_arr) { -// CHECK-NEXT: unsigned long indepVarCount = _d_arr[0].size(); -// CHECK-NEXT: { -// CHECK-NEXT: clad::array _d_vector_i(clad::array(indepVarCount, 0)); -// CHECK-NEXT: for (int i = 0; i < n; ++i) { -// CHECK-NEXT: _d_res += _d_arr[i]; -// CHECK-NEXT: res += arr[i]; -// CHECK-NEXT: } -// CHECK-NEXT: } -// CHECK-NEXT: } +// CHECK: void sum_ref_vector_pushforward(double &res, int n, const double *arr, clad::array &_d_res, clad::array _d_n, clad::matrix &_d_arr); double f8(int n, const double* arr) { double res = 0; @@ -304,6 +275,40 @@ double f8(int n, const double* arr) { // CHECK-NEXT: } // CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward > square_vector_pushforward(const double &x, const clad::array &_d_x) { +// CHECK-NEXT: unsigned long indepVarCount = _d_x.size(); +// CHECK-NEXT: clad::array _d_vector_z(clad::array(indepVarCount, _d_x * x + x * _d_x)); +// CHECK-NEXT: double z = x * x; +// CHECK-NEXT: return {z, _d_vector_z}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward > weighted_array_squared_sum_vector_pushforward(const double *arr, double w, int n, clad::matrix &_d_arr, clad::array _d_w, clad::array _d_n) { +// CHECK-NEXT: unsigned long indepVarCount = _d_n.size(); +// CHECK-NEXT: clad::array _d_vector_sum(clad::array(indepVarCount, 0)); +// CHECK-NEXT: double sum = 0; +// CHECK-NEXT: { +// CHECK-NEXT: clad::array _d_vector_i(clad::array(indepVarCount, 0)); +// CHECK-NEXT: for (int i = 0; i < n; ++i) { +// CHECK-NEXT: clad::ValueAndPushforward > _t0 = square_vector_pushforward(arr[i], _d_arr[i]); +// CHECK-NEXT: double &_t1 = _t0.value; +// CHECK-NEXT: _d_vector_sum += _d_w * _t1 + w * _t0.pushforward; +// CHECK-NEXT: sum += w * _t1; +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: return {sum, _d_vector_sum}; +// CHECK-NEXT: } + +// CHECK: void sum_ref_vector_pushforward(double &res, int n, const double *arr, clad::array &_d_res, clad::array _d_n, clad::matrix &_d_arr) { +// CHECK-NEXT: unsigned long indepVarCount = _d_arr[0].size(); +// CHECK-NEXT: { +// CHECK-NEXT: clad::array _d_vector_i(clad::array(indepVarCount, 0)); +// CHECK-NEXT: for (int i = 0; i < n; ++i) { +// CHECK-NEXT: _d_res += _d_arr[i]; +// CHECK-NEXT: res += arr[i]; +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: } + #define TEST(F, x, y) \ { \ result[0] = 0; \ diff --git a/test/NestedCalls/NestedCalls.C b/test/NestedCalls/NestedCalls.C index a7bb7ea6a..d44560018 100644 --- a/test/NestedCalls/NestedCalls.C +++ b/test/NestedCalls/NestedCalls.C @@ -12,19 +12,9 @@ extern "C" int printf(const char* fmt, ...); double sq(double x) { return x * x; } -// CHECK: clad::ValueAndPushforward sq_pushforward(double x, double _d_x) { -// CHECK-NEXT: return {x * x, _d_x * x + x * _d_x}; -// CHECK-NEXT: } - double one(double x) { return sq(std::sin(x)) + sq(std::cos(x)); } -// CHECK: clad::ValueAndPushforward one_pushforward(double x, double _d_x) { -// CHECK-NEXT: ValueAndPushforward _t0 = clad::custom_derivatives::sin_pushforward(x, _d_x); -// CHECK-NEXT: clad::ValueAndPushforward _t1 = sq_pushforward(_t0.value, _t0.pushforward); -// CHECK-NEXT: ValueAndPushforward _t2 = clad::custom_derivatives::cos_pushforward(x, _d_x); -// CHECK-NEXT: clad::ValueAndPushforward _t3 = sq_pushforward(_t2.value, _t2.pushforward); -// CHECK-NEXT: return {_t1.value + _t3.value, _t1.pushforward + _t3.pushforward}; -// CHECK-NEXT: } +// CHECK: clad::ValueAndPushforward one_pushforward(double x, double _d_x); double f(double x, double y) { double t = one(x); @@ -91,4 +81,18 @@ int main () { // expected-no-diagnostics gradf.execute(2, 3, &result[0], &result[1]); printf("{%.2f, %.2f}\n", result[0], result[1]); // CHECK-EXEC: {0.00, 1.00} return 0; + +// CHECK: clad::ValueAndPushforward sq_pushforward(double x, double _d_x); + +// CHECK: clad::ValueAndPushforward one_pushforward(double x, double _d_x) { +// CHECK-NEXT: ValueAndPushforward _t0 = clad::custom_derivatives::sin_pushforward(x, _d_x); +// CHECK-NEXT: clad::ValueAndPushforward _t1 = sq_pushforward(_t0.value, _t0.pushforward); +// CHECK-NEXT: ValueAndPushforward _t2 = clad::custom_derivatives::cos_pushforward(x, _d_x); +// CHECK-NEXT: clad::ValueAndPushforward _t3 = sq_pushforward(_t2.value, _t2.pushforward); +// CHECK-NEXT: return {_t1.value + _t3.value, _t1.pushforward + _t3.pushforward}; +// CHECK-NEXT: } + +// CHECK: clad::ValueAndPushforward sq_pushforward(double x, double _d_x) { +// CHECK-NEXT: return {x * x, _d_x * x + x * _d_x}; +// CHECK-NEXT: } } diff --git a/test/NthDerivative/CustomDerivatives.C b/test/NthDerivative/CustomDerivatives.C index 12de29b8e..676edbffc 100644 --- a/test/NthDerivative/CustomDerivatives.C +++ b/test/NthDerivative/CustomDerivatives.C @@ -124,12 +124,7 @@ float test_exp(float x) { // CHECK-NEXT: return _t0.pushforward; // CHECK-NEXT:} -// CHECK: clad::ValueAndPushforward, ValueAndPushforward > exp_pushforward_pushforward(float x, float d_x, float _d_x, float _d_d_x) { -// CHECK-NEXT: {{(clad::)?}}ValueAndPushforward _t0 = clad::custom_derivatives{{(::std)?}}::exp_pushforward(x, _d_x); -// CHECK-NEXT: {{(clad::)?}}ValueAndPushforward _t1 = clad::custom_derivatives{{(::std)?}}::exp_pushforward(x, _d_x); -// CHECK-NEXT: float &_t2 = _t1.value; -// CHECK-NEXT: return {{[{][{]}}_t0.value, _t2 * d_x}, {_t0.pushforward, _t1.pushforward * d_x + _t2 * _d_d_x{{[}][}]}}; -// CHECK-NEXT:} +// CHECK: clad::ValueAndPushforward, ValueAndPushforward > exp_pushforward_pushforward(float x, float d_x, float _d_x, float _d_d_x); // CHECK: float test_exp_d2arg0(float x) { // CHECK-NEXT: float _d_x = 1; @@ -164,4 +159,11 @@ int main() { clad::differentiate<2>(test_exp); printf("Result is = %f\n", test_exp_d2arg0(2)); // CHECK-EXEC: Result is = 982.766663 +// CHECK: clad::ValueAndPushforward, ValueAndPushforward > exp_pushforward_pushforward(float x, float d_x, float _d_x, float _d_d_x) { +// CHECK-NEXT: {{(clad::)?}}ValueAndPushforward _t0 = clad::custom_derivatives{{(::std)?}}::exp_pushforward(x, _d_x); +// CHECK-NEXT: {{(clad::)?}}ValueAndPushforward _t1 = clad::custom_derivatives{{(::std)?}}::exp_pushforward(x, _d_x); +// CHECK-NEXT: float &_t2 = _t1.value; +// CHECK-NEXT: return {{[{][{]}}_t0.value, _t2 * d_x}, {_t0.pushforward, _t1.pushforward * d_x + _t2 * _d_d_x{{[}][}]}}; +// CHECK-NEXT:} + } \ No newline at end of file diff --git a/tools/ClangPlugin.cpp b/tools/ClangPlugin.cpp index 9453e3c16..0096e7707 100644 --- a/tools/ClangPlugin.cpp +++ b/tools/ClangPlugin.cpp @@ -223,6 +223,8 @@ namespace clad { // if enabled, print source code of the derived functions if (m_DO.DumpDerivedFn) { DerivativeDecl->print(llvm::outs(), Policy); + if (request.DeclarationOnly) + llvm::outs() << ";\n"; } // if enabled, print ASTs of the derived functions @@ -236,6 +238,8 @@ namespace clad { llvm::raw_fd_ostream f("Derivatives.cpp", err, CLAD_COMPAT_llvm_sys_fs_Append); DerivativeDecl->print(f, Policy); + if (request.DeclarationOnly) + f << ";\n"; f.flush(); } @@ -393,8 +397,14 @@ namespace clad { Sema::GlobalEagerInstantiationScope GlobalInstantiations(S, Enabled); Sema::LocalEagerInstantiationScope LocalInstantiations(S); - for (DiffRequest& request : m_DiffSchedule) + // Use index based loop to avoid iterator invalidation as + // ProcessDiffRequest might add more requests to m_DiffSchedule. + for (size_t i = 0; i < m_DiffSchedule.size(); ++i) { + // make a copy of the request to avoid invalidating the reference + // when ProcessDiffRequest adds more requests to m_DiffSchedule. + DiffRequest request = m_DiffSchedule[i]; ProcessDiffRequest(request); + } // Put the TUScope in a consistent state after clad is done. S.TUScope = nullptr; // Force emission of the produced pending template instantiations. diff --git a/tools/ClangPlugin.h b/tools/ClangPlugin.h index c152a0482..b7f6075c2 100644 --- a/tools/ClangPlugin.h +++ b/tools/ClangPlugin.h @@ -262,6 +262,10 @@ namespace clad { m_Multiplexer->ForgetSema(); } + void AddRequestToSchedule(const DiffRequest& request) { + m_DiffSchedule.push_back(request); + } + // FIXME: We should hide ProcessDiffRequest when we implement proper // handling of the differentiation plans. clang::FunctionDecl* ProcessDiffRequest(DiffRequest& request); @@ -288,6 +292,10 @@ namespace clad { return P.ProcessDiffRequest(request); } + void AddRequestToSchedule(CladPlugin& P, const DiffRequest& request) { + P.AddRequestToSchedule(request); + } + template class Action : public clang::PluginASTAction { private: diff --git a/tools/DerivedFnInfo.cpp b/tools/DerivedFnInfo.cpp index a5c708dfa..21f97bce0 100644 --- a/tools/DerivedFnInfo.cpp +++ b/tools/DerivedFnInfo.cpp @@ -11,12 +11,14 @@ DerivedFnInfo::DerivedFnInfo(const DiffRequest& request, : m_OriginalFn(request.Function), m_DerivedFn(derivedFn), m_OverloadedDerivedFn(overloadedDerivedFn), m_Mode(request.Mode), m_DerivativeOrder(request.CurrentDerivativeOrder), - m_DiffVarsInfo(request.DVI), m_UsesEnzyme(request.use_enzyme) {} + m_DiffVarsInfo(request.DVI), m_UsesEnzyme(request.use_enzyme), + m_DeclarationOnly(request.DeclarationOnly) {} bool DerivedFnInfo::SatisfiesRequest(const DiffRequest& request) const { return (request.Function == m_OriginalFn && request.Mode == m_Mode && request.CurrentDerivativeOrder == m_DerivativeOrder && - request.DVI == m_DiffVarsInfo && request.use_enzyme == m_UsesEnzyme); + request.DVI == m_DiffVarsInfo && request.use_enzyme == m_UsesEnzyme && + request.DeclarationOnly == m_DeclarationOnly); } bool DerivedFnInfo::IsValid() const { return m_OriginalFn && m_DerivedFn; } @@ -27,6 +29,7 @@ bool DerivedFnInfo::SatisfiesRequest(const DiffRequest& request) const { lhs.m_DerivativeOrder == rhs.m_DerivativeOrder && lhs.m_Mode == rhs.m_Mode && lhs.m_DiffVarsInfo == rhs.m_DiffVarsInfo && - lhs.m_UsesEnzyme == rhs.m_UsesEnzyme; + lhs.m_UsesEnzyme == rhs.m_UsesEnzyme && + lhs.m_DeclarationOnly == rhs.m_DeclarationOnly; } } // namespace clad \ No newline at end of file diff --git a/tools/DerivedFnInfo.h b/tools/DerivedFnInfo.h index dc07c3cf2..955d51f98 100644 --- a/tools/DerivedFnInfo.h +++ b/tools/DerivedFnInfo.h @@ -18,6 +18,7 @@ namespace clad { unsigned m_DerivativeOrder = 0; DiffInputVarsInfo m_DiffVarsInfo; bool m_UsesEnzyme = false; + bool m_DeclarationOnly = false; DerivedFnInfo() {} DerivedFnInfo(const DiffRequest& request, clang::FunctionDecl* derivedFn, @@ -34,6 +35,7 @@ namespace clad { const clang::FunctionDecl* OriginalFn() const { return m_OriginalFn; } clang::FunctionDecl* DerivedFn() const { return m_DerivedFn; } clang::FunctionDecl* OverloadedDerivedFn() const { return m_OverloadedDerivedFn; } + bool DeclarationOnly() const { return m_DeclarationOnly; } /// Returns true if `lhs` and `rhs` represents same derivative. /// Here derivative is any function derived by clad.