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

FD for composite staggered expr #1247

Merged
merged 7 commits into from
May 6, 2020
Merged

FD for composite staggered expr #1247

merged 7 commits into from
May 6, 2020

Conversation

mloubout
Copy link
Contributor

@mloubout mloubout commented Apr 23, 2020

Fixes handling of expression with multiple Function and multiple staggering.

  • Add are split so that FD handles each staggering properly
  • Mul are "evaluated" at highest priority staggering before FD so that the expression has single indices

Important note. I had to make a choice on the priority levels of each staggering that is
param < not staggered, NODE < staggered

This example from slack now produce same output for bot operators

import numpy as np
from devito import *

grid = Grid(shape=(5,5))

v = VectorTimeFunction(name="v", grid=grid, time_order=1, space_order=4)
p1 = TimeFunction(name="p1", grid=grid, time_order=1, space_order=4, staggered=NODE)
p2 = TimeFunction(name="p2", grid=grid, time_order=1, space_order=4, staggered=NODE)

v[0].data[:] = 5.
v[1].data[:] = 5.

den = np.zeros((5,5), dtype=np.float32)
den[:] = 2.

A = Function(name="A", grid=grid, space_order=4, staggred=NODE)

initialize_function(A, 1./den, 0, dtype=np.float32)

av = VectorTimeFunction(name="av", grid=grid, time_order=1, space_order=4)

test =  div(A*v).args[0]._eval_at(p2).evaluate 

eq1 = Eq(av, A*v)
eq2 = Eq(p1, div(av))

op = Operator([eq1, eq2])
op.apply(time_M=0)

eq3 = Eq(p2, div(A*v))
op2 = Operator([eq3])
op2.apply(time_M=0)

print(p1.data)
print(p2.data)

fixes #1248

@codecov
Copy link

codecov bot commented Apr 23, 2020

Codecov Report

Merging #1247 into master will increase coverage by 0.06%.
The diff coverage is 96.40%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1247      +/-   ##
==========================================
+ Coverage   86.16%   86.23%   +0.06%     
==========================================
  Files         177      177              
  Lines       25182    25311     +129     
  Branches     3546     3561      +15     
==========================================
+ Hits        21699    21826     +127     
  Misses       3061     3061              
- Partials      422      424       +2     
Impacted Files Coverage Δ
devito/types/caching.py 94.44% <ø> (ø)
devito/finite_differences/differentiable.py 91.63% <87.50%> (-0.35%) ⬇️
devito/finite_differences/derivative.py 88.11% <100.00%> (+0.99%) ⬆️
devito/finite_differences/finite_difference.py 95.91% <100.00%> (-0.09%) ⬇️
devito/symbolics/manipulation.py 88.52% <100.00%> (+0.32%) ⬆️
devito/types/basic.py 94.75% <100.00%> (+0.07%) ⬆️
devito/types/dense.py 93.78% <100.00%> (+0.09%) ⬆️
tests/test_derivatives.py 100.00% <100.00%> (ø)
tests/test_staggered_utils.py 100.00% <100.00%> (ø)
... and 1 more

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 e918e26...31ba38d. Read the comment docs.

Copy link
Contributor

@FabioLuporini FabioLuporini left a comment

Choose a reason for hiding this comment

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

also, this should be added to some (new?) userapi notebook ?

@mloubout mloubout force-pushed the ind-ref-diff branch 4 times, most recently from 59dd033 to 1d4d7c3 Compare April 23, 2020 16:46
@mloubout
Copy link
Contributor Author

@FabioLuporini discovered some deeper issue I have to work on so lots of that may change. Maybe we want to put a small PR for Diff objects with single function in it first (one line change)

@mloubout mloubout force-pushed the ind-ref-diff branch 14 times, most recently from 91d93ad to 1077067 Compare April 28, 2020 11:23
@mloubout mloubout force-pushed the ind-ref-diff branch 2 times, most recently from 6f47540 to f519444 Compare April 30, 2020 12:57
@@ -421,7 +421,7 @@ def test_fd_adjoint(self, so, ndim, derivative, adjoint_name):
deriv = getattr(f, derivative)
coeff = 1 if derivative == 'dx2' else -1
expected = coeff * getattr(f, derivative).evaluate.subs({x.spacing: -x.spacing})
assert deriv.T.evaluate == expected
assert simplify(deriv.T.evaluate) == simplify(expected)
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is simplify now needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because now subs is ours fully here and creates (1/_h_x) * f(x) instead of f(x)/h_x so doesn match without simplify (compiler refactorize so no flop increase issue)

Copy link
Contributor

Choose a reason for hiding this comment

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

so is it missing a SymPy evaluation somewhere?

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 could make it evaluate but that's be quite expensive for more complex expressions and not necessary.

@@ -59,3 +76,87 @@ def test_is_param(ndim):
for dd in d:
avg = .5 * (avg + avg.subs({dd: dd - dd.spacing}))
assert f2._eval_at(var).evaluate == avg


@pytest.mark.parametrize('expr, expected', [
Copy link
Contributor

@rhodrin rhodrin Apr 30, 2020

Choose a reason for hiding this comment

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

Worth adding a more intricate composite expression also?

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 wrote above, yes, and perhaps x-fail it if it needs to

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No

@rhodrin
Copy link
Contributor

rhodrin commented Apr 30, 2020

Looks good. Some nitpicking above.

@@ -59,3 +76,87 @@ def test_is_param(ndim):
for dd in d:
avg = .5 * (avg + avg.subs({dd: dd - dd.spacing}))
assert f2._eval_at(var).evaluate == avg


@pytest.mark.parametrize('expr, expected', [
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 wrote above, yes, and perhaps x-fail it if it needs to

@mloubout mloubout force-pushed the ind-ref-diff branch 2 times, most recently from 4551021 to c6fe52d Compare May 1, 2020 11:45
@@ -421,7 +421,7 @@ def test_fd_adjoint(self, so, ndim, derivative, adjoint_name):
deriv = getattr(f, derivative)
coeff = 1 if derivative == 'dx2' else -1
expected = coeff * getattr(f, derivative).evaluate.subs({x.spacing: -x.spacing})
assert deriv.T.evaluate == expected
assert simplify(deriv.T.evaluate) == simplify(expected)
Copy link
Contributor

Choose a reason for hiding this comment

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

so is it missing a SymPy evaluation somewhere?

@mloubout mloubout force-pushed the ind-ref-diff branch 3 times, most recently from 2ec990b to 085f232 Compare May 1, 2020 14:51
Copy link
Contributor

@FabioLuporini FabioLuporini left a comment

Choose a reason for hiding this comment

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

so I still don't understand the dichotomy Add vs Mul, and I'd like to clarify that, potentially offline if that makes it quicker.

the PR is approved though

Copy link
Contributor

@FabioLuporini FabioLuporini left a comment

Choose a reason for hiding this comment

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

There are stylistic things I don't like (too many new functions/methods used in only one place), but they cannot be a stopper. So for me this is GTG.

@mloubout mloubout merged commit 6966dfb into master May 6, 2020
@mloubout mloubout deleted the ind-ref-diff branch May 6, 2020 16:19
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.

Handle expressions that involve multiple Functions with different staggering
3 participants