Support differentiation of lambdas with active captures - #1859
Support differentiation of lambdas with active captures#1859Fermats-Last-Theorem wants to merge 1 commit into
Conversation
| llvm::SmallVectorImpl<clang::Expr*>& clonedArgs, | ||
| llvm::SmallVectorImpl<clang::Expr*>& derivedArgs); | ||
|
|
||
| clang::QualType GetLambdaPushforwardType(const clang::LambdaExpr* LE); |
There was a problem hiding this comment.
warning: no header providing "clang::QualType" is directly included [misc-include-cleaner]
include/clad/Differentiator/BaseForwardModeVisitor.h:17:
- #include <stack>
+ #include <clang/AST/Type.h>
+ #include <stack>| if (LE->capture_size() == 0) | ||
| return baseTy; | ||
| clang::ASTContext& C = m_Sema.getASTContext(); | ||
| const auto* FPT = baseTy->castAs<clang::FunctionProtoType>(); |
There was a problem hiding this comment.
warning: no header providing "clang::FunctionProtoType" is directly included [misc-include-cleaner]
const auto* FPT = baseTy->castAs<clang::FunctionProtoType>();
^| if (!Capture.capturesVariable()) | ||
| continue; | ||
| const auto* capVD = | ||
| llvm::dyn_cast<clang::VarDecl>(Capture.getCapturedVar()); |
There was a problem hiding this comment.
warning: no header providing "llvm::dyn_cast" is directly included [misc-include-cleaner]
include/clad/Differentiator/ReverseModeVisitor.h:34:
- #include <memory>
+ #include <llvm/Support/Casting.h>
+ #include <memory>| /// Maps a (lambda, by value captured variable) to its creation snapshot | ||
| llvm::DenseMap<std::pair<const clang::LambdaExpr*, const clang::VarDecl*>, | ||
| clang::VarDecl*> | ||
| m_LambdaCaptureSnapshots; |
There was a problem hiding this comment.
warning: member variable 'm_LambdaCaptureSnapshots' has protected visibility [cppcoreguidelines-non-private-member-variables-in-classes]
m_LambdaCaptureSnapshots;
^| #if CLANG_VERSION_MAJOR > 16 | ||
| clang::Expr* | ||
| BaseForwardModeVisitor::buildPushforwardLambda(const LambdaExpr* LE) { | ||
| LambdaIntroducer Intro; |
There was a problem hiding this comment.
warning: no header providing "clang::LambdaIntroducer" is directly included [misc-include-cleaner]
LambdaIntroducer Intro;
^| clang::Expr* | ||
| BaseForwardModeVisitor::buildPushforwardLambda(const LambdaExpr* LE) { | ||
| LambdaIntroducer Intro; | ||
| Intro.Default = LCD_None; |
There was a problem hiding this comment.
warning: no header providing "clang::LCD_None" is directly included [misc-include-cleaner]
lib/Differentiator/BaseForwardModeVisitor.cpp:47:
- #include <string>
+ #include <clang/Basic/Lambda.h>
+ #include <string>| Intro.Default = LCD_None; | ||
| Intro.Range.setBegin(noLoc); | ||
| Intro.Range.setEnd(noLoc); | ||
| AttributeFactory AttrFactory; |
There was a problem hiding this comment.
warning: no header providing "clang::AttributeFactory" is directly included [misc-include-cleaner]
lib/Differentiator/BaseForwardModeVisitor.cpp:47:
- #include <string>
+ #include <clang/Sema/ParsedAttr.h>
+ #include <string>| Intro.Range.setBegin(noLoc); | ||
| Intro.Range.setEnd(noLoc); | ||
| AttributeFactory AttrFactory; | ||
| const DeclSpec DS(AttrFactory); |
There was a problem hiding this comment.
warning: no header providing "clang::DeclSpec" is directly included [misc-include-cleaner]
const DeclSpec DS(AttrFactory);
^| Intro.Range.setEnd(noLoc); | ||
| AttributeFactory AttrFactory; | ||
| const DeclSpec DS(AttrFactory); | ||
| Declarator D(DS, clang::ParsedAttributesView::none(), |
There was a problem hiding this comment.
warning: no header providing "clang::Declarator" is directly included [misc-include-cleaner]
Declarator D(DS, clang::ParsedAttributesView::none(),
^| Intro.Range.setEnd(noLoc); | ||
| AttributeFactory AttrFactory; | ||
| const DeclSpec DS(AttrFactory); | ||
| Declarator D(DS, clang::ParsedAttributesView::none(), |
There was a problem hiding this comment.
warning: no header providing "clang::ParsedAttributesView" is directly included [misc-include-cleaner]
Declarator D(DS, clang::ParsedAttributesView::none(),
^
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
08e8780 to
52a0edb
Compare
| AttributeFactory AttrFactory; | ||
| const DeclSpec DS(AttrFactory); | ||
| Declarator D(DS, clang::ParsedAttributesView::none(), | ||
| clang::DeclaratorContext::LambdaExpr); |
There was a problem hiding this comment.
warning: no header providing "clang::DeclaratorContext" is directly included [misc-include-cleaner]
clang::DeclaratorContext::LambdaExpr);
^|
|
||
| QualType dFnType = GetLambdaPushforwardType(LE); | ||
|
|
||
| auto* DC = const_cast<DeclContext*>(LE->getCallOperator()->getDeclContext()); |
There was a problem hiding this comment.
warning: redundant explicit casting to the same type 'DeclContext *' as the sub-expression, remove this casting [readability-redundant-casting]
| auto* DC = const_cast<DeclContext*>(LE->getCallOperator()->getDeclContext()); | |
| auto* DC = LE->getCallOperator()->getDeclContext(); |
Additional context
llvm/include/clang/AST/DeclBase.h:450: source type originates from the invocation of this method
DeclContext *getDeclContext() {
^| m_Sema.ActOnLambdaExpressionAfterIntroducer(Intro, getCurrentScope()); | ||
| beginScope(Scope::FunctionPrototypeScope | Scope::FunctionDeclarationScope | | ||
| Scope::DeclScope); | ||
| llvm::SmallVector<DeclaratorChunk::ParamInfo> ParamInfoLambda; |
There was a problem hiding this comment.
warning: no header providing "clang::DeclaratorChunk" is directly included [misc-include-cleaner]
llvm::SmallVector<DeclaratorChunk::ParamInfo> ParamInfoLambda;
^| /*EllipsisLoc=*/SourceLocation(), /*RParenLoc=*/paramListLoc, | ||
| /*RefQualifierIsLValueRef=*/true, | ||
| /*RefQualifierLoc=*/SourceLocation(), | ||
| /*MutableLoc=*/SourceLocation(), /*ESpecType=*/EST_None, |
There was a problem hiding this comment.
warning: no header providing "clang::EST_None" is directly included [misc-include-cleaner]
lib/Differentiator/BaseForwardModeVisitor.cpp:47:
- #include <string>
+ #include <clang/Basic/ExceptionSpecificationType.h>
+ #include <string>| const LambdaExpr* calledLambda = nullptr; | ||
| const VarDecl* lambdaVD = nullptr; | ||
| if (const auto* DRE = dyn_cast<DeclRefExpr>(origCallee)) | ||
| if ((lambdaVD = dyn_cast<VarDecl>(DRE->getDecl()))) |
There was a problem hiding this comment.
warning: an assignment within an 'if' condition is bug-prone [bugprone-assignment-in-if-condition]
if ((lambdaVD = dyn_cast<VarDecl>(DRE->getDecl())))
^Additional context
lib/Differentiator/BaseForwardModeVisitor.cpp:1205: if it should be an assignment, move it out of the 'if' condition
if ((lambdaVD = dyn_cast<VarDecl>(DRE->getDecl())))
^lib/Differentiator/BaseForwardModeVisitor.cpp:1205: if it is meant to be an equality check, change '=' to '=='
if ((lambdaVD = dyn_cast<VarDecl>(DRE->getDecl())))
^| continue; | ||
| QualType valTy = utils::getNonConstType( | ||
| capVD->getType().getNonReferenceType(), m_Sema); | ||
| if (Capture.getCaptureKind() == LCK_ByCopy) { |
There was a problem hiding this comment.
warning: no header providing "clang::LCK_ByCopy" is directly included [misc-include-cleaner]
if (Capture.getCaptureKind() == LCK_ByCopy) {
^| if (m_Sema.LookupName(R, getCurrentScope()) && R.isSingleResult()) | ||
| if (auto* found = dyn_cast<VarDecl>(R.getFoundDecl())) | ||
| return found; | ||
| return const_cast<VarDecl*>(capVD); |
There was a problem hiding this comment.
warning: do not use const_cast to remove const qualifier [cppcoreguidelines-pro-type-const-cast]
return const_cast<VarDecl*>(capVD);
^| #if CLANG_VERSION_MAJOR > 16 | ||
| clang::Expr* VisitorBase::buildPrimalLambda(const clang::LambdaExpr* LE) { | ||
| LambdaIntroducer Intro; | ||
| Intro.Default = LCD_None; |
There was a problem hiding this comment.
warning: no header providing "clang::LCD_None" is directly included [misc-include-cleaner]
lib/Differentiator/VisitorBase.cpp:47:
- #include <cstddef>
+ #include <clang/Basic/Lambda.h>
+ #include <cstddef>| Intro.Default = LCD_None; | ||
| Intro.Range.setBegin(noLoc); | ||
| Intro.Range.setEnd(noLoc); | ||
| AttributeFactory AttrFactory; |
There was a problem hiding this comment.
warning: no header providing "clang::AttributeFactory" is directly included [misc-include-cleaner]
lib/Differentiator/VisitorBase.cpp:47:
- #include <cstddef>
+ #include <clang/Sema/ParsedAttr.h>
+ #include <cstddef>| Intro.Range.setEnd(noLoc); | ||
| AttributeFactory AttrFactory; | ||
| const DeclSpec DS(AttrFactory); | ||
| Declarator D(DS, clang::ParsedAttributesView::none(), |
There was a problem hiding this comment.
warning: no header providing "clang::ParsedAttributesView" is directly included [misc-include-cleaner]
Declarator D(DS, clang::ParsedAttributesView::none(),
^ea2e2db to
dd26b81
Compare
| FPT->param_types().begin(), FPT->param_types().end()); | ||
| for (const clang::LambdaCapture& Capture : LE->captures()) { | ||
| const auto* capVD = | ||
| llvm::cast<clang::VarDecl>(Capture.getCapturedVar()); |
There was a problem hiding this comment.
warning: no header providing "llvm::cast" is directly included [misc-include-cleaner]
include/clad/Differentiator/ReverseModeVisitor.h:34:
- #include <memory>
+ #include <llvm/Support/Casting.h>
+ #include <memory>| const LambdaExpr* calledLambda = nullptr; | ||
| const VarDecl* lambdaVD = nullptr; | ||
| if (const auto* DRE = dyn_cast<DeclRefExpr>(origCallee)) | ||
| if ((lambdaVD = dyn_cast<VarDecl>(DRE->getDecl()))) |
There was a problem hiding this comment.
warning: an assignment within an 'if' condition is bug-prone [bugprone-assignment-in-if-condition]
if ((lambdaVD = dyn_cast<VarDecl>(DRE->getDecl())))
^Additional context
lib/Differentiator/BaseForwardModeVisitor.cpp:1203: if it should be an assignment, move it out of the 'if' condition
if ((lambdaVD = dyn_cast<VarDecl>(DRE->getDecl())))
^lib/Differentiator/BaseForwardModeVisitor.cpp:1203: if it is meant to be an equality check, change '=' to '=='
if ((lambdaVD = dyn_cast<VarDecl>(DRE->getDecl())))
^dd26b81 to
2d60e50
Compare
|
@vgvassilev This PR should now be ready for review. It now builds the primal closure using |
2d60e50 to
116799a
Compare
I have some version of that with some overall design improvements. Let me land this first and we can adapt that to these changes. |
Sounds good. The CI is finally green as well. |
116799a to
2e49a99
Compare
2e49a99 to
e63c741
Compare
Enables differentiation of lambdas with captures in clad. For each captured variable, the derivative lambda has an extra parameter pair. Captured Value and derivative for forward mode. Captured Value and a pointer to its adjoint for reverse mode.
Fixes #1053.
Fixes #1054.
Fixes #1769.