Skip to content

Zero-allocation tangent for ViscousPolyconvex - #231

Open
miguelmaso wants to merge 1 commit into
mainfrom
zero-alloc
Open

miguelmaso wants to merge 1 commit into
mainfrom
zero-alloc

Conversation

@miguelmaso

Copy link
Copy Markdown
Collaborator

Add generated implementations of - (binary and unary) for TensorValue, mirroring the existing +. Without them, subtraction of fourth-order tensors fell back to the generic Gridap implementation, which exceeds Julia's inlining threshold for TensorValue{9,9} and heap-allocates the result.

Those subtractions appear in ∂Sv∂C_Cᵥfix and ∂Cv⁻¹∂C, i.e. exactly on the path of the viscoelastic tangent operator, which is why only ∂∂Ψ∂FF allocated while Ψ and ∂Ψ∂F did not.

+ is also generalized from TensorValue{D,D} to TensorValue{D1,D2} so that non-square tensors are covered as well. No change in the mathematics.

Visco-polyconvex ∂∂Ψ∂FF: 187 allocs / 15552 B / 5367 ns -> 0 allocs / 0 B / 599 ns.
Visco-elastic ∂∂Ψ∂FF: 1021 allocs / 49600 ns -> 501 allocs / 34200 ns.

Also interpolate the arguments of the tensor algebra benchmarks. Without $, the benchmarked expressions read non-const globals, so the call is dynamically dispatched and the result is boxed: this is the source of the spurious "1 alloc of 0.656 kB" reported for IIsym, push_forward_C_to_F and ×ᵢ⁴, which are already allocation-free.

Add generated implementations of `-` (binary and unary) for `TensorValue`,
mirroring the existing `+`. Without them, subtraction of fourth-order tensors
fell back to the generic Gridap implementation, which exceeds Julia's inlining
threshold for `TensorValue{9,9}` and heap-allocates the result.

Those subtractions appear in `∂Sv∂C_Cᵥfix` and `∂Cv⁻¹∂C`, i.e. exactly on the
path of the viscoelastic tangent operator, which is why only `∂∂Ψ∂FF` allocated
while `Ψ` and `∂Ψ∂F` did not.

`+` is also generalized from `TensorValue{D,D}` to `TensorValue{D1,D2}` so that
non-square tensors are covered as well. No change in the mathematics.

Visco-polyconvex ∂∂Ψ∂FF: 187 allocs / 15552 B / 5367 ns -> 0 allocs / 0 B / 599 ns.
Visco-elastic ∂∂Ψ∂FF: 1021 allocs / 49600 ns -> 501 allocs / 34200 ns.

Also interpolate the arguments of the tensor algebra benchmarks. Without `$`,
the benchmarked expressions read non-const globals, so the call is dynamically
dispatched and the result is boxed: this is the source of the spurious "1 alloc
of 0.656 kB" reported for `IIsym`, `push_forward_C_to_F` and `×ᵢ⁴`, which are
already allocation-free.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Benchmark Results (Julia v1)

Time benchmarks
main 7052793... main / 7052793...
Constitutive models/Visco-elastic Ψ 0.0476 ± 0.0062 ms 23.8 ± 10 μs 2 ± 0.88
Constitutive models/Visco-elastic ∂Ψ∂F 0.0556 ± 0.01 ms 0.0323 ± 0.013 ms 1.72 ± 0.74
Constitutive models/Visco-elastic ∂∂Ψ∂FF 0.0986 ± 0.035 ms 0.0654 ± 0.023 ms 1.51 ± 0.74
Constitutive models/Visco-polyconvex Ψ 0.2 ± 0.01 μs 0.2 ± 0.01 μs 1 ± 0.071
Constitutive models/Visco-polyconvex ∂Ψ∂F 0.201 ± 0.01 μs 0.201 ± 0.01 μs 1 ± 0.07
Constitutive models/Visco-polyconvex ∂∂Ψ∂FF 13.6 ± 7.1 μs 0.781 ± 0.01 μs 17.5 ± 9.1
Simulations/StaticMechanicalDirichlet 0.188 ± 0.009 s 0.187 ± 0.0084 s 1 ± 0.066
Simulations/StaticMechanicalNeumann 0.15 ± 0.015 s 0.151 ± 0.016 s 0.987 ± 0.15
Simulations/ViscoElastic 12.3 s 8.54 s 1.44
Tensor algebra/Cofactor 0.08 ± 0 μs 0.08 ± 0 μs 1 ± 0
Tensor algebra/Det(A)Inv(A') 0.13 ± 0.03 μs 0.12 ± 0.021 μs 1.08 ± 0.31
Tensor algebra/IIsym 0.08 ± 0.001 μs 0.07 ± 0.001 μs 1.14 ± 0.022
Tensor algebra/push_forward_C_to_F 0.28 ± 0.001 μs 0.281 ± 0.01 μs 0.996 ± 0.036
Tensor algebra/×ᵢ⁴ 0.07 ± 0.01 μs 0.07 ± 0 μs 1 ± 0.14
Tensor algebra/δδ_λ_2d 30 ± 0 ns 30 ± 0 ns 1 ± 0
Tensor algebra/δδ_μ_2d 30 ± 0 ns 30 ± 0 ns 1 ± 0
time_to_load 2.41 ± 0.0017 s 2.43 ± 0.0085 s 0.992 ± 0.0035
Memory benchmarks
main 7052793... main / 7052793...
Constitutive models/Visco-elastic Ψ 0.56 k allocs: 0.044 MB 0.212 k allocs: 26.8 kB 1.68
Constitutive models/Visco-elastic ∂Ψ∂F 0.609 k allocs: 0.0489 MB 0.261 k allocs: 31.7 kB 1.58
Constitutive models/Visco-elastic ∂∂Ψ∂FF 1.03 k allocs: 0.0829 MB 0.508 k allocs: 0.0573 MB 1.45
Constitutive models/Visco-polyconvex Ψ 0 allocs: 0 B 0 allocs: 0 B
Constitutive models/Visco-polyconvex ∂Ψ∂F 0 allocs: 0 B 0 allocs: 0 B
Constitutive models/Visco-polyconvex ∂∂Ψ∂FF 0.187 k allocs: 15.2 kB 0 allocs: 0 B
Simulations/StaticMechanicalDirichlet 1.51 M allocs: 0.108 GB 1.51 M allocs: 0.108 GB 1
Simulations/StaticMechanicalNeumann 1.47 M allocs: 0.0922 GB 1.47 M allocs: 0.0922 GB 1
Simulations/ViscoElastic 0.16 G allocs: 12.5 GB 0.0801 G allocs: 8.52 GB 1.46
Tensor algebra/Cofactor 2 allocs: 0.156 kB 2 allocs: 0.156 kB 1
Tensor algebra/Det(A)Inv(A') 4 allocs: 0.25 kB 4 allocs: 0.25 kB 1
Tensor algebra/IIsym 1 allocs: 0.656 kB 1 allocs: 0.656 kB 1
Tensor algebra/push_forward_C_to_F 1 allocs: 0.656 kB 1 allocs: 0.656 kB 1
Tensor algebra/×ᵢ⁴ 1 allocs: 0.656 kB 1 allocs: 0.656 kB 1
Tensor algebra/δδ_λ_2d 0 allocs: 0 B 0 allocs: 0 B
Tensor algebra/δδ_μ_2d 0 allocs: 0 B 0 allocs: 0 B
time_to_load 0.201 k allocs: 11.8 kB 0.215 k allocs: 12.4 kB 0.951

@miguelmaso

miguelmaso commented Sep 11, 2026

Copy link
Copy Markdown
Collaborator Author

The ViscousPolyconvex model takes exactly 0 alloc!!!!!

Speed-up with respect to ViscousIncompressible at Gauss point evaluation:

  • ∂Ψ∂F: 160x
  • ∂∂Ψ∂FF: 100x

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.

1 participant