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

github-actions Bot commented Sep 11, 2026 •

Copy link
Copy Markdown

Benchmark Results (Julia v1)

Time benchmarks
main 7052793... main / 7052793...
Constitutive models/Visco-elastic Ψ 0.0446 ± 0.0057 ms 22 ± 9.3 μs 2.02 ± 0.9
Constitutive models/Visco-elastic ∂Ψ∂F 0.0543 ± 0.019 ms 0.0321 ± 0.012 ms 1.69 ± 0.86
Constitutive models/Visco-elastic ∂∂Ψ∂FF 0.0968 ± 0.032 ms 0.0657 ± 0.022 ms 1.47 ± 0.69
Constitutive models/Visco-polyconvex Ψ 0.19 ± 0.001 μs 0.191 ± 0.01 μs 0.995 ± 0.052
Constitutive models/Visco-polyconvex ∂Ψ∂F 0.2 ± 0.009 μs 0.21 ± 0.001 μs 0.952 ± 0.043
Constitutive models/Visco-polyconvex ∂∂Ψ∂FF 12.1 ± 6.1 μs 0.792 ± 0.001 μs 15.3 ± 7.7
Simulations/StaticMechanicalDirichlet 0.18 ± 0.0051 s 0.18 ± 0.0052 s 1 ± 0.041
Simulations/StaticMechanicalNeumann 0.147 ± 0.011 s 0.148 ± 0.011 s 0.995 ± 0.1
Simulations/ViscoElastic 12.2 s 8.55 s 1.42
Tensor algebra/Cofactor 0.08 ± 0.01 μs 0.071 ± 0.01 μs 1.13 ± 0.21
Tensor algebra/Det(A)Inv(A') 0.11 ± 0.02 μs 0.111 ± 0.02 μs 0.991 ± 0.25
Tensor algebra/IIsym 0.07 ± 0 μs 0.08 ± 0.01 μs 0.875 ± 0.11
Tensor algebra/push_forward_C_to_F 0.3 ± 0.01 μs 0.301 ± 0.001 μs 0.997 ± 0.033
Tensor algebra/×ᵢ⁴ 0.06 ± 0.01 μs 0.07 ± 0.01 μs 0.857 ± 0.19
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.31 ± 0.015 s 2.31 ± 0.021 s 1 ± 0.011
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.205 k allocs: 11.9 kB 0.201 k allocs: 11.8 kB 1.02

@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

@miguelmaso miguelmaso closed this Sep 22, 2026
@miguelmaso
miguelmaso deleted the zero-alloc branch September 22, 2026 20:24
@miguelmaso
miguelmaso restored the zero-alloc branch September 22, 2026 20:26
@miguelmaso miguelmaso reopened this Sep 22, 2026

This branch has not been deployed

No deployments
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