Skip to content

api: Symmetric interp gradients - #3001

Open
mloubout wants to merge 6 commits into
mainfrom
symmetric-interp-gradients
Open

api: Symmetric interp gradients#3001
mloubout wants to merge 6 commits into
mainfrom
symmetric-interp-gradients

Conversation

@mloubout

Copy link
Copy Markdown
Contributor

extend interp mode to cover corner cases. Needed for the recipes

@mloubout mloubout added the API api (symbolics, types, ...) label Aug 11, 2026
@review-notebook-app

Copy link
Copy Markdown

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

The symmetric placement costs an extra inline evaluation of the block, so it
is wanted on the handful of equations that need it rather than on a whole
operator. `Eq` takes an `interp_mode` and passes it down when it evaluates,
leaving `sym_opt` as the default for everything else.
Two changes to what `interp-mode='symmetric'` re-associates.

A derivative is where its `x0` puts it, not where the field it differentiates
lives. `div(v)` of a staggered velocity lands on the node, and reading the
operand's staggering instead made a node-centred kernel look off-node, so it
was re-associated onto the operands and its compact stencil replaced by an
interpolated one twice as wide. A composite is off only if one of its own
operands is, which is what makes a sum of derivatives -- a divergence, a trace
-- read as the node-centred quantity it is.

The block is then chosen among the factors that are actually off `func`, and
it takes two of them for there to be anything to re-associate. With one, the
single interpolation `direct` puts on it is already the transpose-consistent
form -- it is what makes the `i, j` entry of a stiffness matrix the transpose
of its `j, i` entry. With two, `direct` interpolates each separately, and
`I(a)*I(b)` is not `I(a*b)`: the discretized operator stops being the
transpose of itself, which is invisible in a forward simulation and shows up
as a first-order gradient in an adjoint one.

The mode also travels down the fallback now. A product that cannot itself be
re-associated is routinely wrapped around one that can -- a `dt` scaling, a
sum of per-component contractions -- and dropping it there evaluated all of
that in `direct`.
A zero-order derivative whose weights collapse to one is the identity, and it
comes back as whatever it was applied to. When that is a sum -- the
engineering shear strain of a staggered velocity, say -- the rebuild asserted
rather than accepting the degenerate result it already handles for a single
argument. It is reachable through the symmetric placement of a stiffness
contraction.
Four of the five fail without the preceding commits. The fifth guards against
over-reach and passes either way: a derivative already sitting on the target
must be left alone.
@mloubout
mloubout force-pushed the symmetric-interp-gradients branch from 35b3ece to 750eedb Compare August 11, 2026 18:13
@codecov

codecov Bot commented Aug 11, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 99.10714% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 83.01%. Comparing base (da56fad) to head (ec12fb1).

Files with missing lines Patch % Lines
devito/types/basic.py 93.75% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3001      +/-   ##
==========================================
+ Coverage   82.99%   83.01%   +0.02%     
==========================================
  Files         257      257              
  Lines       54019    54114      +95     
  Branches     4619     4622       +3     
==========================================
+ Hits        44832    44925      +93     
- Misses       8375     8377       +2     
  Partials      812      812              
Flag Coverage Δ
pytest-gpu-aomp-amdgpuX 68.53% <67.50%> (-0.03%) ⬇️
pytest-gpu-gcc- 78.25% <99.10%> (+0.04%) ⬆️
pytest-gpu-icx- 78.16% <99.10%> (+0.02%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@mloubout
mloubout force-pushed the symmetric-interp-gradients branch 3 times, most recently from b1cb3c1 to 05eba16 Compare August 11, 2026 19:39
The staggered-interpolation notebook showed the two modes but not a case that
needs the symmetric one. Add the gradient case it exists for: a nodal
parameter read at a staggered location, and the matching accumulation back
onto the node, where the standard placement is off by 4e-1 against 2e-7.
@mloubout
mloubout force-pushed the symmetric-interp-gradients branch from 05eba16 to a5a789c Compare August 11, 2026 20:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

API api (symbolics, types, ...)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant