dsl: Expand derivative
I want to be able to manipulate Devito derivative objects, more like sympy derivative objects.
(possibly only optionally)
Codecov Report
:x: Patch coverage is 89.58333% with 30 lines in your changes missing coverage. Please review.
:white_check_mark: Project coverage is 91.31%. Comparing base (e1fefb2) to head (1268740).
:warning: Report is 35 commits behind head on main.
| Files with missing lines | Patch % | Lines |
|---|---|---|
| devito/finite_differences/derivative.py | 85.00% | 11 Missing and 7 partials :warning: |
| devito/mpatches/as_independent.py | 75.51% | 7 Missing and 5 partials :warning: |
Additional details and impacted files
@@ Coverage Diff @@
## main #2559 +/- ##
==========================================
- Coverage 92.01% 91.31% -0.71%
==========================================
Files 247 248 +1
Lines 49158 49387 +229
Branches 4325 4355 +30
==========================================
- Hits 45234 45096 -138
- Misses 3221 3559 +338
- Partials 703 732 +29
| Flag | Coverage Δ | |
|---|---|---|
| pytest-gpu-aomp-amdgpuX | 72.37% <49.70%> (-0.12%) |
:arrow_down: |
| pytest-gpu-nvc-nvidiaX | ? |
Flags with carried forward coverage won't be shown. Click here to find out more.
:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.
:rocket: New features to boost your workflow:
- :snowflake: Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
Do you have some MFE (minimal failing example) of where this is popping up?
Here is a wonderful list of failing examples that this PR now addresses:
import devito as dv
import sympy as sym
grid = dv.Grid(shape=(11,), extent=(1,))
x = grid.dimensions[0]
u = dv.Function(name='u', grid=grid, space_order=4)
a = u.dx
b = a.subs({u: -5*u.dx + 4*u + 3})
# Substitution works!
print(b)
# Unintuitive results:
# .as_independent method on devito.finite_differences.differentiable.Mul doesn't work
print((-a).as_independent(x))
# Result:
## (1, -Derivative(u(x), x))
# devito.Derivatives aren't reconstructable from func and args (as per sympy docs)
du = u.dx
print(du.func(*du.args))
print(du.func(*du.args).args)
# Result
## Derivative(u(x), (x, 1))
## (u(x), ((x, 1), 1))
# default simplification causes different results:
du11 = dv.Derivative(u, x, x)
print(du11)
print(du11.deriv_order)
# Result
## Derivative(u(x), (x, 2))
## (1, 1)
du2 = dv.Derivative(u, (x, 2))
print(du2)
print(du2.deriv_order)
# Result
## Derivative(u(x), (x, 2))
## (2,)
# Whut!?
print(dv.Derivative(u, x, deriv_order=(2,4)))
# Result
## Derivative(u(x), (x, 2))
# Also pretty wild
print(dv.Derivative(u, (x, 0)))
# Result
## Derivative(u(x), x)
# Really? Double check this...
print(dv.Derivative(-1))
# Result
## Traceback (most recent call last):
## File "<stdin>", line 1, in <module>
## File "/media/devito/devito_py312/src/devito/devito/finite_differences/derivative.py", line 98, in __new__
## raise ValueError("`expr` must be a Differentiable object")
## ValueError: `expr` must be a Differentiable object
# Maybe it's sufficient to handle the case:
print(dv.Derivative(sym.sympify(-1)))
# Cannot expand
print(b.expand())
# Result
## ...
## RecursionError: maximum recursion depth exceeded
The missing functionality in Sympy is now addressed in the following PR:
https://github.com/sympy/sympy/pull/28248
The missing functionality in Sympy is now addressed in the following PR:
This has been merged
Results of profiling:
See all resources in the compressed folder
$ ./profiling_demo.sh | tee output.txt
Switched to branch 'worktree_py312'
Your branch is up to date with 'main'.
Operator `Kernel` generated in 13.10 s
* lowering.Clusters: 8.07 s (61.7 %)
* specializing.Clusters: 6.26 s (47.9 %)
* cire: 3.79 s (29.0 %)
* lowering.Expressions: 4.70 s (35.9 %)
Flops reduction after symbolic optimization: [10128 --> 215]
Operator `Kernel` generated in 12.88 s
* lowering.Clusters: 8.11 s (63.0 %)
* specializing.Clusters: 6.19 s (48.1 %)
* cire: 3.95 s (30.7 %)
* lowering.Expressions: 4.46 s (34.7 %)
Flops reduction after symbolic optimization: [10128 --> 215]
Operator `Kernel` generated in 2.29 s
* lowering.Clusters: 1.44 s (63.0 %)
* specializing.Clusters: 0.95 s (41.5 %)
* cire: 0.69 s (30.2 %)
* lowering.Expressions: 0.59 s (25.8 %)
Flops reduction after symbolic optimization: [7302 --> 291]
real 0m29.538s
user 0m31.264s
sys 0m0.277s
Operator `Kernel` generated in 30.31 s
* lowering.Clusters: 19.87 s (65.6 %)
* specializing.Clusters: 15.42 s (50.9 %)
* cire: 9.47 s (31.3 %)
* lowering.Expressions: 9.71 s (32.1 %)
Flops reduction after symbolic optimization: [10128 --> 215]
Operator `Kernel` generated in 29.79 s
* lowering.Clusters: 19.68 s (66.1 %)
* specializing.Clusters: 15.13 s (50.8 %)
* cire: 9.55 s (32.1 %)
* lowering.Expressions: 9.39 s (31.6 %)
Flops reduction after symbolic optimization: [10128 --> 215]
Operator `Kernel` generated in 5.39 s
* lowering.Clusters: 3.52 s (65.4 %)
* specializing.Clusters: 2.40 s (44.6 %)
* cire: 1.78 s (33.1 %)
* lowering.Expressions: 1.21 s (22.5 %)
Flops reduction after symbolic optimization: [7302 --> 291]
real 1m12.504s
user 1m13.780s
sys 0m0.482s
py-spy> Sampling process 500 times a second. Press Control-C to exit.
Operator `Kernel` generated in 25.37 s
* lowering.Clusters: 15.15 s (59.8 %)
* specializing.Clusters: 11.92 s (47.1 %)
* cire: 7.05 s (27.8 %)
* lowering.Expressions: 9.55 s (37.7 %)
Flops reduction after symbolic optimization: [10128 --> 215]
Operator `Kernel` generated in 25.28 s
* lowering.Clusters: 15.65 s (62.0 %)
* specializing.Clusters: 12.46 s (49.3 %)
* cire: 7.34 s (29.1 %)
* lowering.Expressions: 9.00 s (35.7 %)
Flops reduction after symbolic optimization: [10128 --> 215]
Operator `Kernel` generated in 4.38 s
* lowering.Clusters: 2.55 s (58.3 %)
* specializing.Clusters: 1.51 s (34.6 %)
* cire: 1.04 s (23.8 %)
* lowering.Expressions: 1.25 s (28.6 %)
Flops reduction after symbolic optimization: [7302 --> 291]
py-spy> Stopped sampling because process exited
py-spy> Wrote flamegraph data to 'main_pys.svg'. Samples: 28478 Errors: 35
Error: No child process (os error 10)
real 0m57.425s
user 0m40.719s
sys 0m28.169s
Switched to branch 'JDBetteridge/expand_derivative'
Your branch and 'origin/JDBetteridge/expand_derivative' have diverged,
and have 143 and 31 different commits each, respectively.
(use "git pull" if you want to integrate the remote branch with yours)
Operator `Kernel` generated in 13.09 s
* lowering.Clusters: 8.11 s (62.0 %)
* specializing.Clusters: 6.29 s (48.1 %)
* cire: 3.91 s (29.9 %)
* lowering.Expressions: 4.66 s (35.7 %)
Flops reduction after symbolic optimization: [10128 --> 215]
Operator `Kernel` generated in 12.96 s
* lowering.Clusters: 8.23 s (63.6 %)
* specializing.Clusters: 6.30 s (48.7 %)
* cire: 4.01 s (31.0 %)
* lowering.Expressions: 4.42 s (34.2 %)
Flops reduction after symbolic optimization: [10128 --> 215]
Operator `Kernel` generated in 2.31 s
* lowering.Clusters: 1.44 s (62.5 %)
* specializing.Clusters: 0.95 s (41.3 %)
* cire: 0.68 s (29.6 %)
* lowering.Expressions: 0.60 s (26.1 %)
Flops reduction after symbolic optimization: [7302 --> 291]
real 0m29.629s
user 0m31.293s
sys 0m0.267s
Operator `Kernel` generated in 29.64 s
* lowering.Clusters: 19.37 s (65.4 %)
* specializing.Clusters: 14.98 s (50.6 %)
* cire: 9.15 s (30.9 %)
* lowering.Expressions: 9.55 s (32.3 %)
Flops reduction after symbolic optimization: [10128 --> 215]
Operator `Kernel` generated in 29.27 s
* lowering.Clusters: 19.12 s (65.4 %)
* specializing.Clusters: 14.70 s (50.3 %)
* cire: 9.26 s (31.7 %)
* lowering.Expressions: 9.47 s (32.4 %)
Flops reduction after symbolic optimization: [10128 --> 215]
Operator `Kernel` generated in 5.19 s
* lowering.Clusters: 3.34 s (64.5 %)
* specializing.Clusters: 2.29 s (44.2 %)
* cire: 1.70 s (32.8 %)
* lowering.Expressions: 1.22 s (23.6 %)
Flops reduction after symbolic optimization: [7302 --> 291]
real 1m10.286s
user 1m11.559s
sys 0m0.511s
py-spy> Sampling process 500 times a second. Press Control-C to exit.
Operator `Kernel` generated in 25.57 s
* lowering.Clusters: 14.91 s (58.4 %)
* specializing.Clusters: 11.76 s (46.1 %)
* cire: 7.12 s (27.9 %)
* lowering.Expressions: 9.82 s (38.5 %)
Flops reduction after symbolic optimization: [10128 --> 215]
Operator `Kernel` generated in 24.50 s
* lowering.Clusters: 15.30 s (62.5 %)
* specializing.Clusters: 12.01 s (49.1 %)
* cire: 7.02 s (28.7 %)
* lowering.Expressions: 8.66 s (35.4 %)
Flops reduction after symbolic optimization: [10128 --> 215]
Operator `Kernel` generated in 4.20 s
* lowering.Clusters: 2.44 s (58.2 %)
* specializing.Clusters: 1.41 s (33.6 %)
* cire: 0.92 s (22.0 %)
* lowering.Expressions: 1.17 s (27.9 %)
Flops reduction after symbolic optimization: [7302 --> 291]
py-spy> Stopped sampling because process exited
py-spy> Wrote flamegraph data to 'expand_pys.svg'. Samples: 28088 Errors: 28
Error: No child process (os error 10)
real 0m56.759s
user 0m39.889s
sys 0m27.775s