Perf #6: Replace Vector{Function} with FunctionWrapper for M_fns!/N_fns!#156
Open
hmzh-khn wants to merge 6 commits into
Open
Perf #6: Replace Vector{Function} with FunctionWrapper for M_fns!/N_fns!#156hmzh-khn wants to merge 6 commits into
hmzh-khn wants to merge 6 commits into
Conversation
Tests verify that M_fns!/N_fns! in setup_approximate_kkt_solver should use a concrete element type (not abstract Function) so that calls through the vector are type-stable and avoid runtime dispatch. Currently marked @test_broken: - Element type is Function (abstract), not concrete - @inferred fails because Vector{Function} indexing returns Any Correctness baseline tests pass (compute_K_evals produces correct results). Co-Authored-By: Claude Opus 4.6 <[email protected]>
…fns!
Use FunctionWrappers.jl to provide a concrete callable type for the M/N
evaluation functions stored in setup_approximate_kkt_solver's output.
Before: Vector{Function} caused runtime dispatch on every call because
Function is abstract — Julia cannot specialize on the element type.
After: Vector{MNFunctionWrapper} where MNFunctionWrapper is
FunctionWrapper{Matrix{Float64}, Tuple{Matrix{Float64}, Vector{Float64}}}.
Calls through the vector now resolve at compile time.
Changes:
- src/nonlinear_kkt.jl: Define MNFunctionWrapper type alias, use it for
M_fns_inplace/N_fns_inplace vectors, wrap build_function outputs
- src/MixedHierarchyGames.jl: Import FunctionWrappers, export MNFunctionWrapper
- Project.toml: Add FunctionWrappers v1.1.3 dependency
- test/test_type_stability.jl: Update assertion from Vector{Function} to
Vector{MNFunctionWrapper}
- test/test_typed_function_vectors.jl: Convert @test_broken to @test
Co-Authored-By: Claude Opus 4.6 <[email protected]>
- scripts/benchmark_typed_fn_vectors.jl: Benchmark showing FunctionWrapper eliminates dispatch overhead (155ns/call, zero allocations) - test/test_test_tiers.jl: Add test_typed_function_vectors.jl to expected lists Co-Authored-By: Claude Opus 4.6 <[email protected]>
build_function's in-place variant may return either the buffer or nothing depending on symbolic structure. Normalize to Nothing since callers only use the mutated buffer, not the return value. Wrap build_function outputs in a lambda that discards the return value. Co-Authored-By: Claude Opus 4.6 <[email protected]>
The test checked `isa Function` which fails for FunctionWrapper (not a subtype of Function). Updated to check `isa MNFunctionWrapper`. Co-Authored-By: Claude Opus 4.6 <[email protected]>
Co-Authored-By: Claude Opus 4.6 <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Replace
Vector{Function}withVector{MNFunctionWrapper}for M_fns!/N_fns! insetup_approximate_kkt_solver. This eliminates runtime dispatch on every M_fn/N_fn call in the hotcompute_K_evalspath by using FunctionWrappers.jl to provide a concrete callable type.Before:
Vector{Function}— indexing returns abstractFunction, causing runtime dispatch on every call.After:
Vector{FunctionWrapper{Nothing, Tuple{Matrix{Float64}, Vector{Float64}}}}— indexing returns a concrete type, enabling compile-time dispatch.Changes
src/nonlinear_kkt.jl: DefineMNFunctionWrappertype alias, use it for M_fns_inplace/N_fns_inplace vectors, wrapbuild_functionoutputs withletblock for proper closure capturesrc/MixedHierarchyGames.jl: Import FunctionWrappers, export MNFunctionWrapperProject.toml: Add FunctionWrappers v1.1.3 dependencytest/test_typed_function_vectors.jl: New test file verifying concrete element type, type-stable dispatch via@inferred, and compute_K_evals correctnesstest/test_type_stability.jl: Updated assertion fromVector{Function}toVector{MNFunctionWrapper}test/test_dict_to_vector_storage.jl: Updatedisa Functioncheck toisa MNFunctionWrappertest/test_tiers.jl,test/test_test_tiers.jl: Registered new test fileVerification
@code_warntypeconfirmsgetindexreturns concreteFunctionWrapper{...}type (notFUNCTION)@inferredpasses for calls through the wrapped vectorTesting
test_typed_function_vectors.jl(12 tests) covers:Function)@inferredverifies type-stable dispatchcompute_K_evalsproduces correct resultsChangelog
🤖 Generated with Claude Code