Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle variable declarations in conditions of if-statements (#865) #891

Merged
merged 1 commit into from
May 17, 2024

Conversation

gojakuch
Copy link
Collaborator

@gojakuch gojakuch commented May 14, 2024

This patch handles variable declarations in conditions of if-statements in reverse mode differentiation. This is done by actually visiting the conditions instead of just cloning them inside the VisitIfStmt and by choosing the condition variable DeclStmt over cond when possible. This also helps to handle conditions that may affect derivatives as a side-effect. Also a couple of blocks have been added to wrap some statements and preserve the correct logic in the constructed derivatives and some unused code has been removed from the method.

Fixes: #865

Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

@gojakuch gojakuch marked this pull request as draft May 14, 2024 17:26
Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

Copy link

codecov bot commented May 15, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 94.83%. Comparing base (5bcb602) to head (8a9f873).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #891      +/-   ##
==========================================
+ Coverage   94.77%   94.83%   +0.05%     
==========================================
  Files          52       52              
  Lines        7715     7719       +4     
==========================================
+ Hits         7312     7320       +8     
+ Misses        403      399       -4     
Files Coverage Δ
lib/Differentiator/ReverseModeVisitor.cpp 97.36% <100.00%> (+0.18%) ⬆️
Files Coverage Δ
lib/Differentiator/ReverseModeVisitor.cpp 97.36% <100.00%> (+0.18%) ⬆️

Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

@gojakuch gojakuch marked this pull request as ready for review May 15, 2024 15:02
Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

@vgvassilev
Copy link
Owner

How about "Handle variable declarations in conditions of if-statements", then explain what this patch does and finish with fixes:...

We will need to update the PR description and title accordingly.

@vgvassilev vgvassilev requested review from parth-07 and vaithak May 15, 2024 16:56
@gojakuch gojakuch changed the title Fix issue #865 and allow conditions in if statements to affect the derivatives Handle variable declarations in conditions of if-statements (#865) May 15, 2024
@vgvassilev
Copy link
Owner

You need to update the commit message accordingly, too.

Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

Copy link
Collaborator

@parth-07 parth-07 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please add a test where if-condition has a side-effect that affects differentiation result?

@gojakuch gojakuch force-pushed the issue-865 branch 2 times, most recently from 86475d6 to 327a974 Compare May 16, 2024 13:38
Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

1 similar comment
Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

@gojakuch gojakuch requested a review from parth-07 May 16, 2024 13:49
// clad::push(..., _t);
// reverse:
// If we are inside for loop, condDiff will be stored in the following
// way: forward: _t = cond; if (_t) { ... } clad::push(..., _t); reverse:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this change? The old comments in multiple lines make more sense.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it has been changed automatically by my clang format for some reason

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe changing it into a multiline comment style (/* ... */) should fix it.

@@ -902,37 +898,21 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context,
StmtDiff thenDiff = VisitBranch(If->getThen());
StmtDiff elseDiff = VisitBranch(If->getElse());

// It is problematic to specify both condVarDecl and cond thorugh
// Sema::ActOnIfStmt, therefore we directly use the IfStmt constructor.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to delete this comment?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

condVarDecl is always set to nullptr here now, because it doesn't change anything, so I'm not sure if this is relevant. we generally don't need condVarDecl in the generated statement, only cond

Copy link
Collaborator

@vaithak vaithak May 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, would it make sense to use ActOnIfStmt now?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's possible, but I'm not sure what benefit that would have.

Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

Copy link
Collaborator

@vaithak vaithak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other than some clang formatting issues, this looks good to me.

Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

@vgvassilev
Copy link
Owner

Can we test the c++20 syntax:

if (int a = 12; a < 0) {
}

Copy link
Collaborator

@parth-07 parth-07 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me.

This patch does not handle if-condition side-effects for all cases. The below example gives incorrect derivative:

#include "clad/Differentiator/Differentiator.h"
#include <iostream>

#define show(x) std::cout << #x <<": " << x << "\n";

double fn(double u, double v) {
    double res = 0;
    double foo = v;
    res = foo;
    res += foo;
    if ((foo = u) > 10) {
        res += foo * v;
    }
    return res + foo;
}

int main() {
    auto fn_grad = clad::gradient(fn);
    double u, v;
    u = 3, v = 5;
    double du, dv;
    du = dv = 0;
    fn_grad.execute(u, v, &du, &dv);
    show(du);
    show(dv);
}

Output:
du: 0
dv: 3

Expected Output:
du: 1
dv: 2

This case can be handled separately in a different pull-request. Can you please create an issue for this example?

INIT_GRADIENT(fn_cond_decl);

INIT_GRADIENT(fn_cond_side_eff);
dx = 0;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need to explicitly reset the value to 0. TEST_GRADIENT takes care of that.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, I didn't know this, thanks

@gojakuch
Copy link
Collaborator Author

gojakuch commented May 17, 2024

This patch does not handle if-condition side-effects for all cases

yeah I was afraid that it would be the case but the simple things I tested worked out. I'll open up an issue about it. at least some of them work now.

@gojakuch
Copy link
Collaborator Author

Can we test the c++20 syntax:

if (int a = 12; a < 0) {
}

this doesn't work out well unfortunately. but it seems fixable.

@gojakuch
Copy link
Collaborator Author

if (int a = 12; a < 0) {
}

fixed it

Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

@vgvassilev
Copy link
Owner

if (int a = 12; a < 0) {
}

fixed it

I do not see a test case.

Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

@gojakuch
Copy link
Collaborator Author

I do not see a test case.

already added

This patch handles variable declarations in conditions of if-statements in reverse mode differentiation. This is done by actually visiting the conditions instead of just cloning them inside the VisitIfStmt and by choosing the condition variable DeclStmt over cond when possible. This also helps to handle conditions that may affect derivatives as a side-effect. Also a couple of blocks have been added to wrap some statements and preserve the correct logic in the constructed derivatives and some unused code has been removed from the method.

Fixes: vgvassilev#865
Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

@vgvassilev vgvassilev merged commit 1011b13 into vgvassilev:master May 17, 2024
89 checks passed
@gojakuch gojakuch deleted the issue-865 branch May 20, 2024 16:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Error in gradients for if conditions with declarations
4 participants