Summary
I noticed that gather_free_values! and gather_dirichlet_values! are allocating unnecessary temporary vectors in the UnconstrainedFESpace implementation.
Problem
Both functions delegate to gather_free_and_dirichlet_values!, which requires two output buffers. Since each function only needs one output, the other is allocated and immediately discarded:
gather_free_values! allocates a throwaway dirichlet_values vector (~736 bytes on a 20×20 mesh)
gather_dirichlet_values! allocates a throwaway free_values vector (~3 KB on a 20×20 mesh, 82 KB on a 100×100 mesh)
The gather_dirichlet_values! waste is particularly bad because it scales linearly with the free DOF count.
Impact
I'm working on a neural operator reduced-order model that calls interpolate! thousands of times in parameter sweeps. On a typical workflow with 10,000 samples:
- 20×20 mesh: ~187 MB wasted
- 100×100 mesh: ~780 MB wasted
This creates unnecessary GC pressure during snapshot generation.
Measurements
| Function |
Mesh Size |
Current Allocation |
gather_free_values! |
20×20 |
4,320 bytes |
gather_dirichlet_values! |
20×20 |
6,624 bytes |
gather_dirichlet_values! |
100×100 |
82,064 bytes |
Summary
I noticed that
gather_free_values!andgather_dirichlet_values!are allocating unnecessary temporary vectors in theUnconstrainedFESpaceimplementation.Problem
Both functions delegate to
gather_free_and_dirichlet_values!, which requires two output buffers. Since each function only needs one output, the other is allocated and immediately discarded:gather_free_values!allocates a throwawaydirichlet_valuesvector (~736 bytes on a 20×20 mesh)gather_dirichlet_values!allocates a throwawayfree_valuesvector (~3 KB on a 20×20 mesh, 82 KB on a 100×100 mesh)The
gather_dirichlet_values!waste is particularly bad because it scales linearly with the free DOF count.Impact
I'm working on a neural operator reduced-order model that calls
interpolate!thousands of times in parameter sweeps. On a typical workflow with 10,000 samples:This creates unnecessary GC pressure during snapshot generation.
Measurements
gather_free_values!gather_dirichlet_values!gather_dirichlet_values!