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

compiler: Move derivative.evaluate #1872

Merged
merged 2 commits into from Mar 16, 2022
Merged

compiler: Move derivative.evaluate #1872

merged 2 commits into from Mar 16, 2022

Conversation

FabioLuporini
Copy link
Contributor

This is in preparation for the "derivative evaluation overhaul" (DEO from now on!) that we've talked about recently.

-- A glimpse of the future --

I will need to introduce an evaluate_partial to Derivative (I cannot touch evaluate because we don't want API-level surprises). Such evaluate_partial (better name needed) will expand the Derivative to an intermediate high-level object, for example

Derivative(f, x).dx.evaluate_partial
->
DotDerivative(f, coeff)

Representing the dot product between f and an array of coefficients, that is, a "rolled" Derivative. This will be the object used by Devito throughout compilation and in particular throughout (and until) Cluster specialization.

So, back to this PR... moving that .evaluate will allow me to share the first two steps of Derivative.evaluate with Derivative.evaluate_partial by moving them to a common function, or perhaps better, by having Derivative.evaluate calling Derivative.evaluate_partial first. Not sure yet, still very much work in progress, and I'm doing this only part time

@@ -284,4 +284,7 @@ def indices_weights_to_fd(expr, dim, inds, weights, matvec=1):

deriv = EvalDerivative(*terms, base=expr)

# Evaluate remaining part of expression
deriv = deriv.evaluate
Copy link
Contributor

Choose a reason for hiding this comment

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

AS I said this is dangerous because now you can prevent shifts cancelling out and by forcing the "avg" to be evaluated this can lead to quite worse accuracy. This evaluate should always be the most last part in case there is half-node indices left.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

there are two issues here:

  1. there's no failing test in the test suite capturing the behavior you're describing. Could you add one? Pushing to this PR would be completely fine

This evaluate should always be the most last part in case there is half-node indices left.

I'm not sure I see how my change would alter the order? The return deriv below would return control to derivative.py._eval_fd, so... what am I missing? perhaps with the MFE I'll see it

Copy link
Contributor

Choose a reason for hiding this comment

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

my brain is not working very well these days, it doesn't change anything to have moved it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK, no problem

@codecov
Copy link

codecov bot commented Mar 14, 2022

Codecov Report

Merging #1872 (6c8b809) into master (9fa31b1) will increase coverage by 0.00%.
The diff coverage is 100.00%.

Impacted file tree graph

@@           Coverage Diff           @@
##           master    #1872   +/-   ##
=======================================
  Coverage   89.55%   89.55%           
=======================================
  Files         210      210           
  Lines       35020    35038   +18     
  Branches     5291     5295    +4     
=======================================
+ Hits        31362    31380   +18     
  Misses       3163     3163           
  Partials      495      495           
Impacted Files Coverage Δ
devito/finite_differences/derivative.py 86.33% <ø> (-0.09%) ⬇️
devito/finite_differences/finite_difference.py 96.36% <100.00%> (+0.36%) ⬆️
devito/types/basic.py 95.85% <0.00%> (-0.03%) ⬇️
tests/test_ir.py 94.06% <0.00%> (+0.13%) ⬆️
devito/ir/support/guards.py 72.52% <0.00%> (+2.28%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 9fa31b1...6c8b809. Read the comment docs.

# Pure number
pass

terms.append(term)
Copy link
Contributor

Choose a reason for hiding this comment

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

you could probably postponn the *c here as well, may be slightly more efficient (one less Mul built and evaluated). This also prevents the full travers of EvalDerivative so good catch

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch. Note that this PR already horribly conflicts with the changes in #1875 😬 so I'm going to rebase #1875 now on top of this one and will make the change there; I'll tag you there so that later you can give me green light here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried, but I'm getting (expected) unevaluation errors:

self = <test_derivatives.TestFD object at 0x109a5dfa0>

    def test_fd_new_lo(self):
        grid = Grid((10,))
        x = grid.dimensions[0]
        u = Function(name="u", grid=grid, space_order=2)

        dplus = "-1.0*u(x)/h_x + u(x + 1.0*h_x)/h_x"
        dminus = "u(x)/h_x - 1.0*u(x - 1.0*h_x)/h_x"
>       assert str(u.dx(x0=x + .5 * x.spacing).evaluate) == dplus
E       AssertionError: assert '-1.0*u(x)/h_... 1.0*h_x)/h_x' == '-1.0*u(x)/h_... 1.0*h_x)/h_x'
E         - -1.0*u(x)/h_x + u(x + 1.0*h_x)/h_x
E         + -1.0*u(x)/h_x + 1.0*u(x + 1.0*h_x)/h_x
E         ?                 ++++

test_derivatives.py:368: AssertionError

Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like it's introducing a weird 1.0* for some reason sympy being annoying again

@FabioLuporini FabioLuporini merged commit 68d7cf5 into master Mar 16, 2022
@FabioLuporini FabioLuporini deleted the move-evaluate branch March 16, 2022 07:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants